Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 06/12] ARM: dts: imx7d: cl-som-imx7: add / enable watchdog
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
In-Reply-To: <20190826153800.35400-1-git@andred.net>

add / enable watchdog which is connected via
WDOG_B to the PMIC, due to i.MX7 Errata e10574

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index 78046633d91b..ca3c5d95d6c3 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -207,6 +207,12 @@
 	status = "okay";
 };
 
+&wdog1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	fsl,ext-reset-output;
+};
+
 &iomuxc {
 	pinctrl_enet1: enet1grp {
 		fsl,pins = <
@@ -288,4 +294,10 @@
 			MX7D_PAD_LPSR_GPIO1_IO06__GPIO1_IO6	0x4000007f
 		>;
 	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins = <
+			MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B	0x74
+		>;
+	};
 };
-- 
2.23.0.rc1


_______________________________________________
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 05/12] ARM: dts: imx7d: cl-som-imx7: update pfuze3000 max voltage
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
In-Reply-To: <20190826153800.35400-1-git@andred.net>

The max voltage of SW1A is 3.3V on PF3000 as per
http://cache.freescale.com/files/analog/doc/data_sheet/PF3000.pdf?fsrch=1&sr=1&pageNum=1

While at it, remove the unnecessary leading zero from
the i2c address.

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index 481bd3971c55..78046633d91b 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -81,12 +81,12 @@
 
 	pmic: pmic@8 {
 		compatible = "fsl,pfuze3000";
-		reg = <0x08>;
+		reg = <0x8>;
 
 		regulators {
 			sw1a_reg: sw1a {
 				regulator-min-microvolt = <700000>;
-				regulator-max-microvolt = <1475000>;
+				regulator-max-microvolt = <3300000>;
 				regulator-boot-on;
 				regulator-always-on;
 				regulator-ramp-delay = <6250>;
-- 
2.23.0.rc1


_______________________________________________
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 04/12] ARM: dts: imx7d: cl-som-imx7: add emmicro,em3027 RTC
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
In-Reply-To: <20190826153800.35400-1-git@andred.net>

add/enable RTC support using the on-board EM3027 real time
clock on i2c2.

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index ec82f4738c4f..481bd3971c55 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -181,6 +181,11 @@
 		reg = <0x50>;
 		pagesize = <16>;
 	};
+
+	rtc@56 {
+		compatible = "emmicro,em3027";
+		reg = <0x56>;
+	};
 };
 
 &uart1 {
-- 
2.23.0.rc1


_______________________________________________
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 03/12] ARM: dts: imx7d: cl-som-imx7: fix i2c2
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
In-Reply-To: <20190826153800.35400-1-git@andred.net>

I2C2 is configured incorrectly at the moment:
* update i2c2 to actually work (fix incorrect pinctrl assignments)
* add the i2c2 bus recovery information [1]

[1] Note that scl is being marked as GPIO_OPEN_DRAIN even
though the i.MX pinctrl driver does not support enabling
open drain directly - it is enabled by the fixed pinmux
entry.
So while this flag has no effect in practice, it needs
to be there purely so as to fix the following warning
from gpiolib:
    gpio-6 (scl): enforced open drain please flag it properly in DT/ACPI DSDT/board file
as that is the mode requested by i2c-imx.c

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 26 +++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index e0432a3aa36f..ec82f4738c4f 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -72,8 +72,11 @@
 };
 
 &i2c2 {
-	pinctrl-names = "default";
+	pinctrl-names = "default", "gpio";
 	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_recovery>;
+	sda-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
+	scl-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 	status = "okay";
 
 	pmic: pmic@8 {
@@ -236,13 +239,6 @@
 		>;
 	};
 
-	pinctrl_i2c2: i2c2grp {
-		fsl,pins = <
-			MX7D_PAD_I2C2_SDA__I2C2_SDA		0x4000007f
-			MX7D_PAD_I2C2_SCL__I2C2_SCL		0x4000007f
-		>;
-	};
-
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
@@ -273,4 +269,18 @@
 			MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4	0x34
 		>;
 	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX7D_PAD_LPSR_GPIO1_IO07__I2C2_SDA	0x4000000f
+			MX7D_PAD_LPSR_GPIO1_IO06__I2C2_SCL	0x4000000f
+		>;
+	};
+
+	pinctrl_i2c2_recovery: i2c2recoverygrp {
+		fsl,pins = <
+			MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7	0x4000007f
+			MX7D_PAD_LPSR_GPIO1_IO06__GPIO1_IO6	0x4000007f
+		>;
+	};
 };
-- 
2.23.0.rc1


_______________________________________________
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 02/12] ARM: dts: imx7d: cl-som-imx7: add phy-reset-gpios
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team
In-Reply-To: <20190826153800.35400-1-git@andred.net>

According to the design team:
* reset input PHY0 is directly connected to the
  corresponding pin GPIO1_4 in the i.MX7
* reset for PHY1 is done using the gpio expander bit 4

While touching this area, also add a 'compatible'
to the phy to make it more clear what this is and
which driver handles this - an Ethernet phy attached
to mdio, handled by of_mdio.c

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index 6f7e85cf0c28..e0432a3aa36f 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -30,13 +30,14 @@
 
 &fec1 {
 	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_enet1>;
+	pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1phy>;
 	assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
 			  <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
 	assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
 	assigned-clock-rates = <0>, <100000000>;
 	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy0>;
+	phy-reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
 	fsl,magic-packet;
 	status = "okay";
 
@@ -45,10 +46,12 @@
 		#size-cells = <0>;
 
 		ethphy0: ethernet-phy@0 {
+			compatible = "ethernet-phy-ieee802.3-c22";
 			reg = <0>;
 		};
 
 		ethphy1: ethernet-phy@1 {
+			compatible = "ethernet-phy-ieee802.3-c22";
 			reg = <1>;
 		};
 	};
@@ -63,6 +66,7 @@
 	assigned-clock-rates = <0>, <100000000>;
 	phy-mode = "rgmii-id";
 	phy-handle = <&ethphy1>;
+	phy-reset-gpios = <&pca9555 4 GPIO_ACTIVE_LOW>;
 	fsl,magic-packet;
 	status = "okay";
 };
@@ -262,3 +266,11 @@
 		>;
 	};
 };
+
+&iomuxc_lpsr {
+	pinctrl_enet1phy: enet1phygrp {
+		fsl,pins = <
+			MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4	0x34
+		>;
+	};
+};
-- 
2.23.0.rc1


_______________________________________________
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 01/12] ARM: dts: imx7d: cl-som-imx7 imx7d-sbc-imx7: move USB
From: André Draszik @ 2019-08-26 15:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Mark Rutland, devicetree, Fabio Estevam, linux-arm-kernel,
	André Draszik, Sascha Hauer, Rob Herring, Igor Grinberg,
	Pengutronix Kernel Team, Shawn Guo, Ilya Ledvich, NXP Linux Team

Whether and which USB port is enabled and how they
are powered is a function of the carrier board, not
of the SoM. Different carrier boards can have different
ports enabled / wired up, and power them differently;
so this should really move into the respective DTS.

Do so and update the USB power supply to reflect
the actual situation on the sbc-imx7 carrier board.

Signed-off-by: André Draszik <git@andred.net>
Cc: Ilya Ledvich <ilya@compulab.co.il>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/boot/dts/imx7d-cl-som-imx7.dts | 24 ------------------------
 arch/arm/boot/dts/imx7d-sbc-imx7.dts    | 13 +++++++++++++
 2 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
index 62d5e9a4a781..6f7e85cf0c28 100644
--- a/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-cl-som-imx7.dts
@@ -22,15 +22,6 @@
 		device_type = "memory";
 		reg = <0x80000000 0x10000000>; /* 256 MB - minimal configuration */
 	};
-
-	reg_usb_otg1_vbus: regulator-vbus {
-		compatible = "regulator-fixed";
-		regulator-name = "usb_otg1_vbus";
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-	};
 };
 
 &cpu0 {
@@ -193,13 +184,6 @@
 	status = "okay";
 };
 
-&usbotg1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_usbotg1>;
-	vbus-supply = <&reg_usb_otg1_vbus>;
-	status = "okay";
-};
-
 &usdhc3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_usdhc3>;
@@ -278,11 +262,3 @@
 		>;
 	};
 };
-
-&iomuxc_lpsr {
-	pinctrl_usbotg1: usbotg1grp {
-		fsl,pins = <
-			MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5	0x14 /* OTG PWREN */
-		>;
-	};
-};
diff --git a/arch/arm/boot/dts/imx7d-sbc-imx7.dts b/arch/arm/boot/dts/imx7d-sbc-imx7.dts
index f8a868552707..aab646903de3 100644
--- a/arch/arm/boot/dts/imx7d-sbc-imx7.dts
+++ b/arch/arm/boot/dts/imx7d-sbc-imx7.dts
@@ -15,6 +15,14 @@
 / {
 	model = "CompuLab SBC-iMX7";
 	compatible = "compulab,sbc-imx7", "compulab,cl-som-imx7", "fsl,imx7d";
+
+	reg_usb_vbus: regulator-usb-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "usb_vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
 };
 
 &usdhc1 {
@@ -26,6 +34,11 @@
 	status = "okay";
 };
 
+&&usbotg1 {
+	vbus-supply = <&reg_usb_vbus>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_usdhc1: usdhc1grp {
 		fsl,pins = <
-- 
2.23.0.rc1


_______________________________________________
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 1/3] perf: imx8_ddr_perf: add AXI ID filter support
From: Frank Li @ 2019-08-26 15:36 UTC (permalink / raw)
  To: Joakim Zhang, Mark Rutland
  Cc: will@kernel.org, robin.murphy@arm.com, dl-linux-imx,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <DB7PR04MB4618D2474D4A3574118F07AFE6A10@DB7PR04MB4618.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Joakim Zhang
> Sent: Monday, August 26, 2019 2:12 AM
> To: Mark Rutland <mark.rutland@arm.com>
> Cc: robin.murphy@arm.com; will@kernel.org; Frank Li <frank.li@nxp.com>;
> linux-arm-kernel@lists.infradead.org; dl-linux-imx <linux-imx@nxp.com>
> Subject: RE: [PATCH V5 1/3] perf: imx8_ddr_perf: add AXI ID filter support
> 
> 
> > -----Original Message-----
> > From: Mark Rutland <mark.rutland@arm.com>
> > Sent: 2019年8月23日 20:57
> > To: Joakim Zhang <qiangqing.zhang@nxp.com>
> > Cc: robin.murphy@arm.com; will@kernel.org; Frank Li
> > <frank.li@nxp.com>; linux-arm-kernel@lists.infradead.org; dl-linux-imx
> > <linux-imx@nxp.com>
> > Subject: Re: [PATCH V5 1/3] perf: imx8_ddr_perf: add AXI ID filter
> > support
> >
> > On Thu, Aug 08, 2019 at 06:45:29AM +0000, Joakim Zhang wrote:
> > > AXI filtering is used by CSV modes 0x41 and 0x42 to count reads or
> > > writes with an ARID or AXID matching filter setting. Granularity is
> > > at subsystem level. Implementation does not allow filtring between
> > > masters within a subsystem. Filter is defined with 2 configuration registers.
> > >
> > > --AXI_ID defines AxID matching value --AXI_MASKING defines which
> > > bits of AxID are meaningful for the matching
> > >
> > > When non-masked bits are matching corresponding AXI_ID bits then
> > > counter is incremented. This filter allows counting read or write
> > > access from a subsystem or multiple subsystems.
> > >
> > > Perf counter is incremented if AxID && AXI_MASKING == AXI_ID &&
> > > AXI_MASKING
> >
> > Just to check, the filter does not affect other events, right?
> 
> [Joakim] Yes, this filter is only for events 0x41 and 0x42.
> 
> > >
> > > AXI_ID and AXI_MASKING are mapped on DPCR1 register in performance
> > counter.
> > >
> > > Read and write AXI ID filter should write same value to DPCR1 if
> > > want to specify at the same time as this filter is shared between counters.
> > >
> > > e.g.
> > > perf stat -a -e
> > >
> > imx8_ddr0/axi-id-read,axi_id=0xMMMMDDDD/,imx8_ddr0/axi-id-write,axi_id
> > > =0xMMMMDDDD/ cmd
> > > MMMM: AXI_MASKING
> > > DDDD: AXI_ID
> >
> > You might want to expose this to userspace as two fields:
> >
> > 	axi_id=DDDD
> > 	axi_mask=MMMM
> >
> > ... where axi_mask is inverted (i.e. set bits are bits to ignore), so
> > that the user can just specify axi_id to monitor a specific id, rather
> > than having to specifiy axi_id=0xffff<id>.
> 
> [Joakim] No, axi_mask is not inverted, should specify axi_id = 0xffff<id> for the
> particular AXI ID. I will improve the commit message.
> 		0: corresponding bit is masked
> 		1: corresponding bit is not masked, i.e. used to do the matching
> 

 [Frank Li] Joakim,  mark's means is that revert it at your driver.
Most case user just want to filter a AXID. For example 0x12

If you revert mask at driver,  user just need input axi_id = 0x12 instead of axi_id=0xffff0012.


> > >
> > > ChangeLog:
> > > V1 -> V2:
> > > 	* add error log if user specifies read/write AXI ID filter at
> > > 	the same time.
> > > 	* of_device_get_match_data() instead of of_match_device(), and
> > > 	remove the check of return value.
> > > V2 -> V3:
> > > 	* move the AXI ID check to event_add().
> > > 	* add support for same value of axi_id.
> > > V3 -> V4:
> > > 	* move the AXI ID check to event_init().
> > > V4 -> V5:
> > > 	* reject event group if AXI ID not consistent in event_init().
> > >
> > > Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
> > > ---
> > >  drivers/perf/fsl_imx8_ddr_perf.c | 63
> > > +++++++++++++++++++++++++++++++-
> > >  1 file changed, 61 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/perf/fsl_imx8_ddr_perf.c
> > > b/drivers/perf/fsl_imx8_ddr_perf.c
> > > index 63fe21600072..f25cf5cbe156 100644
> > > --- a/drivers/perf/fsl_imx8_ddr_perf.c
> > > +++ b/drivers/perf/fsl_imx8_ddr_perf.c
> > > @@ -42,9 +42,22 @@
> > >
> > >  static DEFINE_IDA(ddr_ida);
> > >
> > > +/* DDR Perf hardware feature */
> > > +#define DDR_CAP_AXI_ID_FILTER		0x1	/* support AXI ID filter
> */
> > > +
> > > +struct fsl_ddr_devtype_data {
> > > +	unsigned int quirks;	/* quirks needed for different DDR Perf core */
> > > +};
> > > +
> > > +static const struct fsl_ddr_devtype_data imx8_devtype_data;
> > > +
> > > +static const struct fsl_ddr_devtype_data imx8m_devtype_data = {
> > > +	.quirks = DDR_CAP_AXI_ID_FILTER,
> > > +};
> > > +
> > >  static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
> > > -	{ .compatible = "fsl,imx8-ddr-pmu",},
> > > -	{ .compatible = "fsl,imx8m-ddr-pmu",},
> > > +	{ .compatible = "fsl,imx8-ddr-pmu", .data = &imx8_devtype_data},
> > > +	{ .compatible = "fsl,imx8m-ddr-pmu", .data = &imx8m_devtype_data},
> > >  	{ /* sentinel */ }
> > >  };
> >
> > Are new DDR PMUs going to lack this feature?
> >
> > If all PMUs the driver supports have it, then we don't need this
> > quirk/feature list.
> >
> > That would make the subsequent code a bit nicer, as all the filtering
> > code would lose a level of indentation.
> 
> [Joakim] This feature may drop, some coming SOCs will improve this AXI ID
> filtering, let it can filter from different ID separately, and ang other extensions.
> 
> > >
> > > @@ -57,6 +70,7 @@ struct ddr_pmu {
> > >  	struct perf_event *events[NUM_COUNTERS];
> > >  	int active_events;
> > >  	enum cpuhp_state cpuhp_state;
> > > +	const struct fsl_ddr_devtype_data *devtype_data;
> > >  	int irq;
> > >  	int id;
> > >  };
> > > @@ -128,6 +142,8 @@ static struct attribute *ddr_perf_events_attrs[] = {
> > >  	IMX8_DDR_PMU_EVENT_ATTR(refresh, 0x37),
> > >  	IMX8_DDR_PMU_EVENT_ATTR(write, 0x38),
> > >  	IMX8_DDR_PMU_EVENT_ATTR(raw-hazard, 0x39),
> > > +	IMX8_DDR_PMU_EVENT_ATTR(axi-id-read, 0x41),
> > > +	IMX8_DDR_PMU_EVENT_ATTR(axi-id-write, 0x42),
> > >  	NULL,
> > >  };
> > >
> > > @@ -137,9 +153,11 @@ static struct attribute_group
> > > ddr_perf_events_attr_group = {  };
> > >
> > >  PMU_FORMAT_ATTR(event, "config:0-7");
> > > +PMU_FORMAT_ATTR(axi_id, "config1:0-31");
> > >
> > >  static struct attribute *ddr_perf_format_attrs[] = {
> > >  	&format_attr_event.attr,
> > > +	&format_attr_axi_id.attr,
> > >  	NULL,
> > >  };
> > >
> > > @@ -189,6 +207,16 @@ static u32 ddr_perf_read_counter(struct ddr_pmu
> > *pmu, int counter)
> > >  	return readl_relaxed(pmu->base + COUNTER_READ + counter * 4);  }
> > >
> > > +static bool ddr_perf_is_filtered(struct perf_event *event) {
> > > +	return event->attr.config == 0x41 || event->attr.config == 0x42; }
> > > +
> > > +static u32 ddr_perf_filter_val(struct perf_event *event) {
> > > +	return event->attr.config1;
> > > +}
> > > +
> >
> > Let's add another helper:
> >
> > static bool ddr_perf_filters_compatible(struct perf_event *a,
> > 					struct perf_event *b)
> > {
> > 	if (!ddr_perf_is_filtered(a))
> > 		return true;
> > 	if (!ddr_perf_is_filtered(b))
> > 		return true;
> > 	return ddr_perf_filter_val(a) == ddr_perf_filter_val(b); }
> >
> > >  static int ddr_perf_event_init(struct perf_event *event)  {
> > >  	struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); @@ -215,6 +243,18
> > @@
> > > static int ddr_perf_event_init(struct perf_event *event)
> > >  			!is_software_event(event->group_leader))
> > >  		return -EINVAL;
> > >
> > > +	if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
> > > +		bool is_filtered = ddr_perf_is_filtered(event);
> > > +		u32 filter_val = ddr_perf_filter_val(event);
> > > +
> > > +		for_each_sibling_event(sibling, event->group_leader) {
> > > +			if (is_filtered && ddr_perf_is_filtered(sibling) &&
> > > +			    ddr_perf_filter_val(sibling) != filter_val) {
> > > +				return -EINVAL;
> > > +			}
> > > +		}
> > > +	}
> >
> > ... so this can be:
> >
> > 	if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
> > 		if (!ddr_perf_filters_compatible(event, event->group_leader))
> > 			return -EINVAL;
> > 		for_each_sibling_event(sibling, event->group_leader) {
> > 			if (!ddr_perf_filters_compatible(event, sibling))
> > 				return -EINVAL;
> > 		}
> > 	}
> 
> [Joakim] Got it.
> 
> > Note: that checks group_leader, which you mised above. When the event
> > is the group leader, it's trivially compatible with itself, so we
> > don't need a special case there.
> >
> > > +
> > >  	for_each_sibling_event(sibling, event->group_leader) {
> > >  		if (sibling->pmu != event->pmu &&
> > >  				!is_software_event(sibling))
> > > @@ -288,6 +328,23 @@ static int ddr_perf_event_add(struct perf_event
> > *event, int flags)
> > >  	int counter;
> > >  	int cfg = event->attr.config;
> > >
> > > +	if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
> > > +		int i;
> > > +		bool is_filtered = ddr_perf_is_filtered(event);
> > > +		u32 filter_val = ddr_perf_filter_val(event);
> > > +
> > > +		for (i = 1; i < NUM_COUNTERS; i++) {
> > > +			if (is_filtered && pmu->events[i] &&
> > > +			    ddr_perf_is_filtered(pmu->events[i]) &&
> > > +			    ddr_perf_filter_val(pmu->events[i]) != filter_val) {
> > > +				dev_dbg(pmu->dev, "Contradictory axi id filter
> value\n");
> > > +				return -EINVAL;
> > > +			}
> > > +		}
> >
> > ... and likewise:
> >
> > 	if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
> > 		int i;
> >
> > 		for (i = 1; i < NUM_COUNTERS; i++) {
> > 			if (!ddr_perf_filters_compatible(event, pmu->events[i]))
> > 				return -EINVAL;
> > 		}
> > 	}
> >
> > Please drop the dev_dbg() here, since when perf rotates events this
> > can happen many times per second, and it's entirely legitimate.
> 
> [Joakim] Got it.
> 
> > Otherwise, this looks good to me.
> 
> [Joakim] Thanks Mark, I will sent out a V6, please help review.
> 
> Best Regards,
> Joakim Zhang
> > Thanks,
> > Mark.
> >
> > > +
> > > +		writel(filter_val, pmu->base + COUNTER_DPCR1);
> > > +	}
> > > +
> > >  	counter = ddr_perf_alloc_counter(pmu, cfg);
> > >  	if (counter < 0) {
> > >  		dev_dbg(pmu->dev, "There are not enough counters\n"); @@ -
> 472,6
> > > +529,8 @@ static int ddr_perf_probe(struct platform_device *pdev)
> > >  	if (!name)
> > >  		return -ENOMEM;
> > >
> > > +	pmu->devtype_data = of_device_get_match_data(&pdev->dev);
> > > +
> > >  	pmu->cpu = raw_smp_processor_id();
> > >  	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
> > >  				      DDR_CPUHP_CB_NAME,
> > > --
> > > 2.17.1
> > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [RFC PATCH 0/7] Unify SMP stop generic logic to common code
From: Christoph Hellwig @ 2019-08-26 15:34 UTC (permalink / raw)
  To: Cristian Marussi
  Cc: linux-arch, mark.rutland, peterz, catalin.marinas, linux-kernel,
	takahiro.akashi, james.morse, hidehiro.kawai.ez, tglx, will,
	dave.martin, linux-arm-kernel
In-Reply-To: <20190823115720.605-1-cristian.marussi@arm.com>

On Fri, Aug 23, 2019 at 12:57:13PM +0100, Cristian Marussi wrote:
> An architecture willing to rely on this SMP common logic has to define its
> own helpers and set CONFIG_ARCH_USE_COMMON_SMP_STOP=y.
> The series wire this up for arm64.
> 
> Behaviour is not changed for architectures not adopting this new common
> logic.

Seens like this common code only covers arm64.  I think we should
generally have at least two users for common code.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [RFC PATCH 5/7] arm64: smp: use generic SMP stop common code
From: Christoph Hellwig @ 2019-08-26 15:32 UTC (permalink / raw)
  To: Cristian Marussi
  Cc: linux-arch, mark.rutland, peterz, catalin.marinas, linux-kernel,
	takahiro.akashi, james.morse, hidehiro.kawai.ez, tglx, will,
	dave.martin, linux-arm-kernel
In-Reply-To: <20190823115720.605-6-cristian.marussi@arm.com>

> +config ARCH_USE_COMMON_SMP_STOP
> +	def_bool y if SMP

The option belongs into common code and the arch code shoud only
select it.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [RESEND PATCHv4 1/1] drivers/amba: add reset control to amba bus probe
From: Dinh Nguyen @ 2019-08-26 15:27 UTC (permalink / raw)
  To: Philipp Zabel, Linus Walleij
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Daniel Thompson, Tony Luck, Manivannan Sadhasivam, Kees Cook,
	Rob Herring, Anton Vorontsov, Russell King,
	linux-kernel@vger.kernel.org, Colin Cross, Frank Rowand,
	Linux ARM
In-Reply-To: <1566809829.3842.4.camel@pengutronix.de>

Hi Philipp,

On 8/26/19 3:57 AM, Philipp Zabel wrote:
> Hi Dinh, Linus,
> 
> On Fri, 2019-08-23 at 10:42 -0500, Dinh Nguyen wrote:
>>
>> On 8/23/19 4:19 AM, Linus Walleij wrote:
>>> On Tue, Aug 20, 2019 at 4:58 PM Dinh Nguyen <dinguyen@kernel.org> wrote:
>>>
>>>> @@ -401,6 +402,26 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
>>>>         ret = amba_get_enable_pclk(dev);
>>>>         if (ret == 0) {
>>>>                 u32 pid, cid;
>>>> +               int count;
>>>> +               struct reset_control *rstc;
>>>> +
>>>> +               /*
>>>> +                * Find reset control(s) of the amba bus and de-assert them.
>>>> +                */
>>>> +               count = reset_control_get_count(&dev->dev);
> 
> The reset_control_get_count() inline stub returns -ENOENT, so the
> compiler can throw away the complete loop.
> 
>>>> +               while (count > 0) {
>>>> +                       rstc = of_reset_control_get_shared_by_index(dev->dev.of_node, count - 1);
> 
> Since resets are looked up with of_reset_control_get, I'd use
> of_reset_control_get_count() above for consistency. But see below:
> 

reset_control_get_count() ultimately calls of_reset_control_get_count()
and it looks like of_reset_control_get_count() is not exported.

>>>> +                       if (IS_ERR(rstc)) {
>>>> +                               if (PTR_ERR(rstc) == -EPROBE_DEFER)
>>>> +                                       ret = -EPROBE_DEFER;
>>>> +                               else
>>>> +                                       dev_err(&dev->dev, "Can't get amba reset!\n");
>>>> +                               break;
>>>> +                       }
>>>> +                       reset_control_deassert(rstc);
>>>> +                       reset_control_put(rstc);
>>>> +                       count--;
>>>> +               }
> 
> It looks like the order of deassertions is irrelevant. If so,
> You can use of_reset_control_array_get() to simplify this:
> 
> +		rstc = of_reset_control_array_get_optional_shared(dev->dev.of_node);
> +		if (IS_ERR(rstc)) {
> +			if (PTR_ERR(rstc) != -EPROBE_DEFER)
> +				dev_err(&dev->dev, "Can't get amba reset!\n");
> +			return PTR_ERR(rstc);
> +		}
> +		reset_control_deassert(rstc);
> +		reset_control_put(rstc);
> 

Thanks for the review! I'll post v5 shortly.

Dinh

_______________________________________________
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] bus: imx-weim: remove __init from 2 functions
From: Nathan Chancellor @ 2019-08-26 15:15 UTC (permalink / raw)
  To: Ilie Halip
  Cc: clang-built-linux, Sascha Hauer, Shawn Guo, linux-kernel,
	linux-arm-kernel
In-Reply-To: <20190826095828.8948-1-ilie.halip@gmail.com>

On Mon, Aug 26, 2019 at 12:58:28PM +0300, Ilie Halip wrote:
> A previous commit removed __init from weim_probe(), but this attribute is
> still present for other functions called from it. Thus, these warnings
> are triggered:
>     WARNING: Section mismatch in reference from the function weim_probe() to the function .init.text:imx_weim_gpr_setup()
>     WARNING: Section mismatch in reference from the function weim_probe() to the function .init.text:weim_timing_setup()
> 
> Remove the __init attribute from these functions as well, since they
> don't seem to be used anywhere else.
> 
> Signed-off-by: Ilie Halip <ilie.halip@gmail.com>
> Reported-by: "kernelci.org bot" <bot@kernelci.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: clang-built-linux@googlegroups.com
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org

Reviewed-by: Nathan Chancellor <natechancellor@gmail.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: [PATCH 3/7] media: aspeed-video: address a protential usage of an unit var
From: Eddie James @ 2019-08-26 15:12 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Linux Media Mailing List
  Cc: linux-aspeed, Andrew Jeffery, openbmc, Eddie James,
	Mauro Carvalho Chehab, linux-arm-kernel
In-Reply-To: <7c85f7dc159927a7316dc13f52697f157fb6e2bd.1566502743.git.mchehab+samsung@kernel.org>


On 8/22/19 2:39 PM, Mauro Carvalho Chehab wrote:
> While this might not occur in practice, if the device is doing
> the right thing, it would be teoretically be possible to have
> both hsync_counter and vsync_counter negatives.
>
> If this ever happen, ctrl will be undefined, but the driver
> will still call:
>
> 	aspeed_video_update(video, VE_CTRL, 0, ctrl);
>
> Change the code to prevent this to happen.
>
> This was warned by cppcheck:
>
> 	[drivers/media/platform/aspeed-video.c:653]: (error) Uninitialized variable: ctrl


Thanks Mauro.


Reviewed-by: Eddie James <eajames@linux.ibm.com>


>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
> ---
>   drivers/media/platform/aspeed-video.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
> index f899ac3b4a61..4ef37cfc8446 100644
> --- a/drivers/media/platform/aspeed-video.c
> +++ b/drivers/media/platform/aspeed-video.c
> @@ -630,7 +630,7 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
>   	}
>   
>   	if (hsync_counter < 0 || vsync_counter < 0) {
> -		u32 ctrl;
> +		u32 ctrl = 0;
>   
>   		if (hsync_counter < 0) {
>   			ctrl = VE_CTRL_HSYNC_POL;
> @@ -650,7 +650,8 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video)
>   				V4L2_DV_VSYNC_POS_POL;
>   		}
>   
> -		aspeed_video_update(video, VE_CTRL, 0, ctrl);
> +		if (ctrl)
> +			aspeed_video_update(video, VE_CTRL, 0, ctrl);
>   	}
>   }
>   

_______________________________________________
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 0/2] coresight: Add barrier packet when moving offset forward
From: Mathieu Poirier @ 2019-08-26 14:59 UTC (permalink / raw)
  To: Yabin Cui
  Cc: Suzuki K Poulose, Alexander Shishkin, Linux Kernel Mailing List,
	Mike Leach, Leo Yan, linux-arm-kernel
In-Reply-To: <20190824003002.87657-1-yabinc@google.com>

Hi Yabin,

On Fri, 23 Aug 2019 at 18:30, Yabin Cui <yabinc@google.com> wrote:
>
> Thanks for fixing this problem. I didn't realize it because I usually use a
> buffer size >= the default ETR buffer size, which is harder to reproduce the
> problem.
> The patches LGTM, maybe you also want to fix the problem commented by Leo Yan.

I will look into the issue reported by Leo later today.

> I tested the patches by recording etm data with a buffer size smaller than the
> default ETR buffer size. Then I saw barrier packets when decoding with OpenCSD.
> And I could decode successfully without error message.

Can I add your Tested-by ?

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] drm/meson: vclk: use the correct G12A frac max value
From: Neil Armstrong @ 2019-08-26 14:46 UTC (permalink / raw)
  To: dri-devel; +Cc: linux-amlogic, linux-kernel, linux-arm-kernel, Neil Armstrong

When calculating the HDMI PLL settings for a DMT mode PHY frequency,
use the correct max fractional PLL value for G12A VPU.

With this fix, we can finally setup the 1024x76-60 mode.

Fixes: 202b9808f8ed ("drm/meson: Add G12A Video Clock setup")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 drivers/gpu/drm/meson/meson_vclk.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index ac491a781952..f690793ae2d5 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -638,13 +638,18 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
 		if (frac >= HDMI_FRAC_MAX_GXBB)
 			return false;
 	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) ||
-		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) ||
-		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		   meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) {
 		/* Empiric supported min/max dividers */
 		if (m < 106 || m > 247)
 			return false;
 		if (frac >= HDMI_FRAC_MAX_GXL)
 			return false;
+	} else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		/* Empiric supported min/max dividers */
+		if (m < 106 || m > 247)
+			return false;
+		if (frac >= HDMI_FRAC_MAX_G12A)
+			return false;
 	}
 
 	return true;
-- 
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 v3 00/15] Improvements and fixes for mxsfb DRM driver
From: Stefan Agner @ 2019-08-26 14:35 UTC (permalink / raw)
  To: Guido Günther
  Cc: Marek Vasut, Mark Rutland, Pengutronix Kernel Team, devicetree,
	David Airlie, Fabio Estevam, Sascha Hauer, linux-kernel,
	dri-devel, Rob Herring, NXP Linux Team, Daniel Vetter,
	Robert Chiras, Shawn Guo, linux-arm-kernel
In-Reply-To: <20190826120548.GA14316@bogon.m.sigxcpu.org>

On 2019-08-26 14:05, Guido Günther wrote:
> Hi,
> On Wed, Aug 21, 2019 at 01:15:40PM +0300, Robert Chiras wrote:
>> This patch-set improves the use of eLCDIF block on iMX 8 SoCs (like 8MQ, 8MM
>> and 8QXP). Following, are the new features added and fixes from this
>> patch-set:
> 
> I've applied this whole series on top of my NWL work and it looks good
> with a DSI panel. Applying the whole series also fixes an issue where
> after unblank the output was sometimes shifted about half a screen width
> to the right (which didn't happen with DCSS). So at least from the parts
> I could test:
> 
>   Tested-by: Guido Günther <agx@sigxcpu.org> 
> 
> for the whole thing.

Thanks for testing! What SoC did you use? I think it would be good to
also give this a try on i.MX 7 or i.MX 6ULL before merging.

--
Stefan


> Cheers,
>  -- Guido
>>
>> 1. Add support for drm_bridge
>> On 8MQ and 8MM, the LCDIF block is not directly connected to a parallel
>> display connector, where an LCD panel can be attached, but instead it is
>> connected to DSI controller. Since this DSI stands between the display
>> controller (eLCDIF) and the physical connector, the DSI can be implemented
>> as a DRM bridge. So, in order to be able to connect the mxsfb driver to
>> the DSI driver, the support for a drm_bridge was needed in mxsfb DRM
>> driver (the actual driver for the eLCDIF block).
>>
>> 2. Add support for additional pixel formats
>> Some of the pixel formats needed by Android were not implemented in this
>> driver, but they were actually supported. So, add support for them.
>>
>> 3. Add support for horizontal stride
>> Having support for horizontal stride allows the use of eLCDIF with a GPU
>> (for example) that can only output resolution sizes multiple of a power of
>> 8. For example, 1080 is not a power of 16, so in order to support 1920x1080
>> output from GPUs that can produce linear buffers only in sizes multiple to 16,
>> this feature is needed.
>>
>> 3. Few minor features and bug-fixing
>> The addition of max-res DT property was actually needed in order to limit
>> the bandwidth usage of the eLCDIF block. This is need on systems where
>> multiple display controllers are presend and the memory bandwidth is not
>> enough to handle all of them at maximum capacity (like it is the case on
>> 8MQ, where there are two display controllers: DCSS and eLCDIF).
>> The rest of the patches are bug-fixes.
>>
>> v3:
>> - Removed the max-res property patches and added support for
>>   max-memory-bandwidth property, as it is also implemented in other drivers
>> - Removed unnecessary drm_vblank_off in probe
>>
>> v2:
>> - Collected Tested-by from Guido
>> - Split the first patch, which added more than one feature into relevant
>>   patches, explaining each feature added
>> - Also split the second patch into more patches, to differentiate between
>>   the feature itself (additional pixel formats support) and the cleanup
>>   of the register definitions for a better representation (guido)
>> - Included a patch submitted by Guido, while he was testing my patch-set
>>
>> Guido Günther (1):
>>   drm/mxsfb: Read bus flags from bridge if present
>>
>> Mirela Rabulea (1):
>>   drm/mxsfb: Signal mode changed when bpp changed
>>
>> Robert Chiras (13):
>>   drm/mxsfb: Update mxsfb to support a bridge
>>   drm/mxsfb: Add defines for the rest of registers
>>   drm/mxsfb: Reset vital registers for a proper initialization
>>   drm/mxsfb: Update register definitions using bit manipulation defines
>>   drm/mxsfb: Update mxsfb with additional pixel formats
>>   drm/mxsfb: Fix the vblank events
>>   drm/mxsfb: Add max-memory-bandwidth property for MXSFB
>>   dt-bindings: display: Add max-memory-bandwidth property for mxsfb
>>   drm/mxsfb: Update mxsfb to support LCD reset
>>   drm/mxsfb: Improve the axi clock usage
>>   drm/mxsfb: Clear OUTSTANDING_REQS bits
>>   drm/mxsfb: Add support for horizontal stride
>>   drm/mxsfb: Add support for live pixel format change
>>
>>  .../devicetree/bindings/display/mxsfb.txt          |   5 +
>>  drivers/gpu/drm/mxsfb/mxsfb_crtc.c                 | 287 ++++++++++++++++++---
>>  drivers/gpu/drm/mxsfb/mxsfb_drv.c                  | 203 +++++++++++++--
>>  drivers/gpu/drm/mxsfb/mxsfb_drv.h                  |  12 +-
>>  drivers/gpu/drm/mxsfb/mxsfb_out.c                  |  26 +-
>>  drivers/gpu/drm/mxsfb/mxsfb_regs.h                 | 193 +++++++++-----
>>  6 files changed, 589 insertions(+), 137 deletions(-)
>>
>> --
>> 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

* Re: [PATCH v4 01/14] dt-bindings: Add binding for MT2712 MIPI-CSI2
From: Sakari Ailus @ 2019-08-26 14:05 UTC (permalink / raw)
  To: Stu Hsieh
  Cc: Mark Rutland, devicetree, srv_heupstream,
	Linux Kernel Mailing List, Tomasz Figa, Matthias Brugger,
	Rob Herring, moderated list:ARM/Mediatek SoC support, CK Hu,
	Mauro Carvalho Chehab,
	list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
	Linux Media Mailing List
In-Reply-To: <CAAFQd5DDE-L7mW8sTXVYOTLZ8yi3+X6Q3O73fJ61e1aUoeddgg@mail.gmail.com>

On Mon, Jun 10, 2019 at 04:58:02PM +0900, Tomasz Figa wrote:
> On Mon, Jun 10, 2019 at 4:51 PM CK Hu <ck.hu@mediatek.com> wrote:
> >
> > Hi, Tomasz:
> >
> > On Mon, 2019-06-10 at 12:32 +0900, Tomasz Figa wrote:
> > > Hi CK, Stu,
> > >
> > > On Mon, Jun 10, 2019 at 11:34 AM CK Hu <ck.hu@mediatek.com> wrote:
> > > >
> > > > Hi, Stu:
> > > >
> > > > "mediatek,mt2712-mipicsi" and "mediatek,mt2712-mipicsi-common" have many
> > > > common part with "mediatek,mt8183-seninf", and I've a discussion in [1],
> > > > so I would like these two to be merged together.
> > > >
> > > > [1] https://patchwork.kernel.org/patch/10979131/
> > > >
> > >
> > > Thanks CK for spotting this.
> > >
> > > I also noticed that the driver in fact handles two hardware blocks at
> > > the same time - SenInf and CamSV. Unless the architecture is very
> > > different from MT8183, I'd suggest splitting it.
> > >
> > > On a general note, the MT8183 SenInf driver has received several
> > > rounds of review comments already, but I couldn't find any comments
> > > posted for this one.
> > >
> > > Given the two aspects above and also based on my quick look at code
> > > added by this series, I'd recommend adding MT2712 support on top of
> > > the MT8183 series.
> >
> > In [1], "mediatek,mt8183-seninf" use one device to control multiple csi
> > instance, so it duplicate many register definition. In [2], one
> > "mediatek,mt2712-mipicsi" device control one csi instance, so there are
> > multiple device and the register definition does not duplicate.
> 
> I guess we didn't catch that in the review yet. It should be fixed.
> 
> > You
> > recommend adding MT2712 support on top of the MT8183 series, do you mean
> > that "mediatek,mt2712-mipicsi" should use one device to control multiple
> > csi instance and duplicate the register setting?
> 
> There are some aspects of MT8183 series that are done better than the
> MT2712 series, but apparently there are also some better aspects in
> MT2712. We should take the best aspects of both series. :)

Stu: Are the two devices similar enough or not; does this look like a
feasible approach to you?

-- 
Sakari Ailus

_______________________________________________
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 v2 01/11] asm-generic: add dma_zone_size
From: Nicolas Saenz Julienne @ 2019-08-26 13:46 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: catalin.marinas, linux-mm, linux-riscv, will, m.szyprowski,
	linux-arch, f.fainelli, frowand.list, devicetree, Arnd Bergmann,
	marc.zyngier, robh+dt, linux-rpi-kernel, linux-arm-kernel, phill,
	mbrugger, eric, linux-kernel, iommu, wahrenst, akpm, Robin Murphy
In-Reply-To: <20190826070939.GD11331@lst.de>


[-- Attachment #1.1: Type: text/plain, Size: 1724 bytes --]

On Mon, 2019-08-26 at 09:09 +0200, Christoph Hellwig wrote:
> On Tue, Aug 20, 2019 at 04:58:09PM +0200, Nicolas Saenz Julienne wrote:
> > Some architectures have platform specific DMA addressing limitations.
> > This will allow for hardware description code to provide the constraints
> > in a generic manner, so as for arch code to properly setup it's memory
> > zones and DMA mask.
> 
> I know this just spreads the arm code, but I still kinda hate it.

Rob's main concern was finding a way to pass the constraint from HW definition
to arch without widening fdt's architecture specific function surface. I'd say
it's fair to argue that having a generic mechanism makes sense as it'll now
traverse multiple archs and subsystems.

I get adding globals like this is not very appealing, yet I went with it as it
was the easier to integrate with arm's code. Any alternative suggestions?

> MAX_DMA_ADDRESS is such an oddly defined concepts.  We have the mm
> code that uses it to start allocating after the dma zones, but
> I think that would better be done using a function returning
> 1 << max(zone_dma_bits, 32) or so.  Then we have about a handful
> of drivers using it that all seem rather bogus, and one of which
> I think are usable on arm64.

Is it safe to assume DMA limitations will always be a power of 2? I ask as RPi4
kinda isn't: ZONE_DMA is 0x3c000000 bytes big, I'm approximating the zone mask
to 30 as [0x3c000000 0x3fffffff] isn't defined as memory so it's unlikely that
we´ll encounter buffers there. But I don't know how it could affect mm
initialization code.

This also rules out 'zone_dma_bits' as a mechanism to pass ZONE_DMA's size from
HW definition code to arch's.


[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 488 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

* [PATCH v4 3/6] PM / devfreq: Introduce devfreq_get_freq_range
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

Moving handling of min/max freq to a single function and call it from
update_devfreq and for printing min/max freq values in sysfs.

This changes the behavior of out-of-range min_freq/max_freq: clamping
is now done at evaluation time. This means that if an out-of-range
constraint is imposed by sysfs and it later becomes valid then it will
be enforced.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c | 111 +++++++++++++++++++++-----------------
 1 file changed, 63 insertions(+), 48 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 9b3bf64dc37d..96e218b07771 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -24,10 +24,12 @@
 #include <linux/printk.h>
 #include <linux/hrtimer.h>
 #include <linux/of.h>
 #include "governor.h"
 
+#define HZ_PER_KHZ 1000
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/devfreq.h>
 
 static struct class *devfreq_class;
 
@@ -96,10 +98,50 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
 		dev_pm_opp_put(opp);
 
 	return max_freq;
 }
 
+/**
+ * devfreq_get_freq_range() - Get the current freq range
+ * @devfreq:	the devfreq instance
+ * @min_freq:	the min frequency
+ * @max_freq:	the max frequency
+ *
+ * This takes into consideration all constraints.
+ */
+static void devfreq_get_freq_range(struct devfreq *devfreq,
+				   unsigned long *min_freq,
+				   unsigned long *max_freq)
+{
+	unsigned long *freq_table = devfreq->profile->freq_table;
+
+	lockdep_assert_held(&devfreq->lock);
+
+	/* Init min/max frequency from freq table */
+	if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) {
+		*min_freq = freq_table[0];
+		*max_freq = freq_table[devfreq->profile->max_state - 1];
+	} else {
+		*min_freq = freq_table[devfreq->profile->max_state - 1];
+		*max_freq = freq_table[0];
+	}
+
+	/* constraints from sysfs: */
+	*min_freq = max(*min_freq, devfreq->min_freq);
+	*max_freq = min(*max_freq, devfreq->max_freq);
+
+	/* constraints from opp interface: */
+	*min_freq = max(*min_freq, devfreq->scaling_min_freq);
+	/* scaling_max_freq can be zero on error */
+	if (devfreq->scaling_max_freq)
+		*max_freq = min(*max_freq, devfreq->scaling_max_freq);
+
+	/* max_freq takes precedence over min_freq */
+	if (*min_freq > *max_freq)
+		*min_freq = *max_freq;
+}
+
 /**
  * devfreq_get_freq_level() - Lookup freq_table for the frequency
  * @devfreq:	the devfreq instance
  * @freq:	the target frequency
  */
@@ -348,21 +390,13 @@ int update_devfreq(struct devfreq *devfreq)
 
 	/* Reevaluate the proper frequency */
 	err = devfreq->governor->get_target_freq(devfreq, &freq);
 	if (err)
 		return err;
+	devfreq_get_freq_range(devfreq, &min_freq, &max_freq);
 
-	/*
-	 * Adjust the frequency with user freq, QoS and available freq.
-	 *
-	 * List from the highest priority
-	 * max_freq
-	 * min_freq
-	 */
-	max_freq = min(devfreq->scaling_max_freq, devfreq->max_freq);
-	min_freq = max(devfreq->scaling_min_freq, devfreq->min_freq);
-
+	/* max freq takes priority over min freq */
 	if (freq < min_freq) {
 		freq = min_freq;
 		flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */
 	}
 	if (freq > max_freq) {
@@ -1297,40 +1331,28 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
 	ret = sscanf(buf, "%lu", &value);
 	if (ret != 1)
 		return -EINVAL;
 
 	mutex_lock(&df->lock);
-
-	if (value) {
-		if (value > df->max_freq) {
-			ret = -EINVAL;
-			goto unlock;
-		}
-	} else {
-		unsigned long *freq_table = df->profile->freq_table;
-
-		/* Get minimum frequency according to sorting order */
-		if (freq_table[0] < freq_table[df->profile->max_state - 1])
-			value = freq_table[0];
-		else
-			value = freq_table[df->profile->max_state - 1];
-	}
-
 	df->min_freq = value;
 	update_devfreq(df);
-	ret = count;
-unlock:
 	mutex_unlock(&df->lock);
-	return ret;
+
+	return count;
 }
 
 static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
 	struct devfreq *df = to_devfreq(dev);
+	unsigned long min_freq, max_freq;
 
-	return sprintf(buf, "%lu\n", max(df->scaling_min_freq, df->min_freq));
+	mutex_lock(&df->lock);
+	devfreq_get_freq_range(df, &min_freq, &max_freq);
+	mutex_unlock(&df->lock);
+
+	return sprintf(buf, "%lu\n", min_freq);
 }
 
 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 {
@@ -1342,40 +1364,33 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 	if (ret != 1)
 		return -EINVAL;
 
 	mutex_lock(&df->lock);
 
-	if (value) {
-		if (value < df->min_freq) {
-			ret = -EINVAL;
-			goto unlock;
-		}
-	} else {
-		unsigned long *freq_table = df->profile->freq_table;
-
-		/* Get maximum frequency according to sorting order */
-		if (freq_table[0] < freq_table[df->profile->max_state - 1])
-			value = freq_table[df->profile->max_state - 1];
-		else
-			value = freq_table[0];
-	}
+	/* Interpret zero as "don't care" */
+	if (!value)
+		value = ULONG_MAX;
 
 	df->max_freq = value;
 	update_devfreq(df);
-	ret = count;
-unlock:
 	mutex_unlock(&df->lock);
-	return ret;
+
+	return count;
 }
 static DEVICE_ATTR_RW(min_freq);
 
 static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 {
 	struct devfreq *df = to_devfreq(dev);
+	unsigned long min_freq, max_freq;
+
+	mutex_lock(&df->lock);
+	devfreq_get_freq_range(df, &min_freq, &max_freq);
+	mutex_unlock(&df->lock);
 
-	return sprintf(buf, "%lu\n", min(df->scaling_max_freq, df->max_freq));
+	return sprintf(buf, "%lu\n", max_freq);
 }
 static DEVICE_ATTR_RW(max_freq);
 
 static ssize_t available_frequencies_show(struct device *d,
 					  struct device_attribute *attr,
-- 
2.17.1


_______________________________________________
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 v4 4/6] PM / devfreq: Add dev_pm_qos support
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

Register notifiers with the pm_qos framework in order to respond to
requests for MIN_FREQUENCY and MAX_FREQUENCY.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c | 70 +++++++++++++++++++++++++++++++++++++++
 include/linux/devfreq.h   |  5 +++
 2 files changed, 75 insertions(+)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 96e218b07771..42c10b8b239e 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -22,17 +22,20 @@
 #include <linux/platform_device.h>
 #include <linux/list.h>
 #include <linux/printk.h>
 #include <linux/hrtimer.h>
 #include <linux/of.h>
+#include <linux/pm_qos.h>
 #include "governor.h"
 
 #define HZ_PER_KHZ 1000
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/devfreq.h>
 
+#define HZ_PER_KHZ	1000
+
 static struct class *devfreq_class;
 
 /*
  * devfreq core provides delayed work based load monitoring helper
  * functions. Governors can use these or can implement their own
@@ -123,10 +126,16 @@ static void devfreq_get_freq_range(struct devfreq *devfreq,
 	} else {
 		*min_freq = freq_table[devfreq->profile->max_state - 1];
 		*max_freq = freq_table[0];
 	}
 
+	/* constraints from dev_pm_qos: */
+	*min_freq = max(*min_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
+				devfreq->dev.parent, DEV_PM_QOS_MIN_FREQUENCY));
+	*max_freq = min(*max_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
+				devfreq->dev.parent, DEV_PM_QOS_MAX_FREQUENCY));
+
 	/* constraints from sysfs: */
 	*min_freq = max(*min_freq, devfreq->min_freq);
 	*max_freq = min(*max_freq, devfreq->max_freq);
 
 	/* constraints from opp interface: */
@@ -604,10 +613,49 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
 	mutex_unlock(&devfreq->lock);
 
 	return ret;
 }
 
+/**
+ * devfreq_qos_notifier_call() - Common handler for qos freq changes.
+ * @devfreq:    the devfreq instance.
+ */
+static int devfreq_qos_notifier_call(struct devfreq *devfreq)
+{
+	int ret;
+
+	mutex_lock(&devfreq->lock);
+	ret = update_devfreq(devfreq);
+	mutex_unlock(&devfreq->lock);
+
+	return ret;
+}
+
+/**
+ * devfreq_qos_min_notifier_call() - Callback for qos min_freq changes.
+ * @nb:		Should to be devfreq->nb_min
+ */
+static int devfreq_qos_min_notifier_call(struct notifier_block *nb,
+					 unsigned long val, void *ptr)
+{
+	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_min);
+
+	return devfreq_qos_notifier_call(devfreq);
+}
+
+/**
+ * devfreq_qos_max_notifier_call() - Callback for qos min_freq changes.
+ * @nb:		Should to be devfreq->nb_max
+ */
+static int devfreq_qos_max_notifier_call(struct notifier_block *nb,
+					 unsigned long val, void *ptr)
+{
+	struct devfreq *devfreq = container_of(nb, struct devfreq, nb_max);
+
+	return devfreq_qos_notifier_call(devfreq);
+}
+
 /**
  * devfreq_dev_release() - Callback for struct device to release the device.
  * @dev:	the devfreq device
  *
  * Remove devfreq from the list and release its resources.
@@ -623,10 +671,15 @@ static void devfreq_dev_release(struct device *dev)
 		return;
 	}
 	list_del(&devfreq->node);
 	mutex_unlock(&devfreq_list_lock);
 
+	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
+			DEV_PM_QOS_MAX_FREQUENCY);
+	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
+			DEV_PM_QOS_MIN_FREQUENCY);
+
 	if (devfreq->profile->exit)
 		devfreq->profile->exit(devfreq->dev.parent);
 
 	mutex_destroy(&devfreq->lock);
 	kfree(devfreq);
@@ -739,10 +792,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
 	devfreq->last_stat_updated = jiffies;
 
 	srcu_init_notifier_head(&devfreq->transition_notifier_list);
 
+	/*
+	 * Register notifiers for updates to min_freq/max_freq after device is
+	 * initialized (and we can handle notifications) but before the governor
+	 * is started (which should do an initial enforcement of constraints)
+	 */
+	devfreq->nb_min.notifier_call = devfreq_qos_min_notifier_call;
+	err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_min,
+				      DEV_PM_QOS_MIN_FREQUENCY);
+	if (err)
+		goto err_devfreq;
+
+	devfreq->nb_max.notifier_call = devfreq_qos_max_notifier_call;
+	err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_max,
+				      DEV_PM_QOS_MAX_FREQUENCY);
+	if (err)
+		goto err_devfreq;
+
 	mutex_lock(&devfreq_list_lock);
 
 	governor = try_then_request_governor(devfreq->governor_name);
 	if (IS_ERR(governor)) {
 		dev_err(dev, "%s: Unable to find governor for the device\n",
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index c3cbc15fdf08..dac0dffeabb4 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -134,10 +134,12 @@ struct devfreq_dev_profile {
  * @total_trans:	Number of devfreq transitions
  * @trans_table:	Statistics of devfreq transitions
  * @time_in_state:	Statistics of devfreq states
  * @last_stat_updated:	The last time stat updated
  * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier
+ * @nb_min:		Notifier block for DEV_PM_QOS_MIN_FREQUENCY
+ * @nb_max:		Notifier block for DEV_PM_QOS_MAX_FREQUENCY
  *
  * This structure stores the devfreq information for a give device.
  *
  * Note that when a governor accesses entries in struct devfreq in its
  * functions except for the context of callbacks defined in struct
@@ -176,10 +178,13 @@ struct devfreq {
 	unsigned int *trans_table;
 	unsigned long *time_in_state;
 	unsigned long last_stat_updated;
 
 	struct srcu_notifier_head transition_notifier_list;
+
+	struct notifier_block nb_min;
+	struct notifier_block nb_max;
 };
 
 struct devfreq_freqs {
 	unsigned long old;
 	unsigned long new;
-- 
2.17.1


_______________________________________________
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 v4 6/6] PM / devfreq: Move opp notifier registration to core
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

An opp notifier can be registered by devfreq in order to respond to OPPs
being enabled or disabled at runtime (for example by thermal). This is
currently handled explicitly by drivers.

Move notifier handling to devfreq_add_device because this shouldn't be
hardware-specific.

Handling this inside the core also takes less code.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c    | 84 +++---------------------------------
 drivers/devfreq/exynos-bus.c |  7 ---
 drivers/devfreq/rk3399_dmc.c |  6 ---
 include/linux/devfreq.h      |  8 ----
 4 files changed, 6 insertions(+), 99 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index f85c6628249f..c7123d8b6a33 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -667,20 +667,22 @@ static void devfreq_dev_release(struct device *dev)
 		return;
 	}
 	list_del(&devfreq->node);
 	mutex_unlock(&devfreq_list_lock);
 
+	dev_pm_opp_unregister_notifier(dev, &devfreq->nb);
 	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_max,
 			DEV_PM_QOS_MAX_FREQUENCY);
 	dev_pm_qos_remove_notifier(devfreq->dev.parent, &devfreq->nb_min,
 			DEV_PM_QOS_MIN_FREQUENCY);
 
 	if (devfreq->profile->exit)
 		devfreq->profile->exit(devfreq->dev.parent);
 
 	dev_pm_qos_remove_request(&devfreq->max_freq_req);
 	dev_pm_qos_remove_request(&devfreq->min_freq_req);
+	dev_pm_opp_unregister_notifier(dev, &devfreq->nb);
 	mutex_destroy(&devfreq->lock);
 	kfree(devfreq);
 }
 
 /**
@@ -729,11 +731,10 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	devfreq->profile = profile;
 	strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
 	devfreq->previous_freq = profile->initial_freq;
 	devfreq->last_status.current_frequency = profile->initial_freq;
 	devfreq->data = data;
-	devfreq->nb.notifier_call = devfreq_notifier_call;
 
 	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
 		err = set_freq_table(devfreq);
 		if (err < 0)
 			goto err_dev;
@@ -816,10 +817,14 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	devfreq->nb_max.notifier_call = devfreq_qos_max_notifier_call;
 	err = dev_pm_qos_add_notifier(devfreq->dev.parent, &devfreq->nb_max,
 				      DEV_PM_QOS_MAX_FREQUENCY);
 	if (err)
 		goto err_devfreq;
+	devfreq->nb.notifier_call = devfreq_notifier_call;
+	err = dev_pm_opp_register_notifier(dev, &devfreq->nb);
+	if (err)
+		goto err_devfreq;
 
 	mutex_lock(&devfreq_list_lock);
 
 	governor = try_then_request_governor(devfreq->governor_name);
 	if (IS_ERR(governor)) {
@@ -1619,87 +1624,10 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
 
 	return opp;
 }
 EXPORT_SYMBOL(devfreq_recommended_opp);
 
-/**
- * devfreq_register_opp_notifier() - Helper function to get devfreq notified
- *				     for any changes in the OPP availability
- *				     changes
- * @dev:	The devfreq user device. (parent of devfreq)
- * @devfreq:	The devfreq object.
- */
-int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq)
-{
-	return dev_pm_opp_register_notifier(dev, &devfreq->nb);
-}
-EXPORT_SYMBOL(devfreq_register_opp_notifier);
-
-/**
- * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq
- *				       notified for any changes in the OPP
- *				       availability changes anymore.
- * @dev:	The devfreq user device. (parent of devfreq)
- * @devfreq:	The devfreq object.
- *
- * At exit() callback of devfreq_dev_profile, this must be included if
- * devfreq_recommended_opp is used.
- */
-int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq)
-{
-	return dev_pm_opp_unregister_notifier(dev, &devfreq->nb);
-}
-EXPORT_SYMBOL(devfreq_unregister_opp_notifier);
-
-static void devm_devfreq_opp_release(struct device *dev, void *res)
-{
-	devfreq_unregister_opp_notifier(dev, *(struct devfreq **)res);
-}
-
-/**
- * devm_devfreq_register_opp_notifier() - Resource-managed
- *					  devfreq_register_opp_notifier()
- * @dev:	The devfreq user device. (parent of devfreq)
- * @devfreq:	The devfreq object.
- */
-int devm_devfreq_register_opp_notifier(struct device *dev,
-				       struct devfreq *devfreq)
-{
-	struct devfreq **ptr;
-	int ret;
-
-	ptr = devres_alloc(devm_devfreq_opp_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return -ENOMEM;
-
-	ret = devfreq_register_opp_notifier(dev, devfreq);
-	if (ret) {
-		devres_free(ptr);
-		return ret;
-	}
-
-	*ptr = devfreq;
-	devres_add(dev, ptr);
-
-	return 0;
-}
-EXPORT_SYMBOL(devm_devfreq_register_opp_notifier);
-
-/**
- * devm_devfreq_unregister_opp_notifier() - Resource-managed
- *					    devfreq_unregister_opp_notifier()
- * @dev:	The devfreq user device. (parent of devfreq)
- * @devfreq:	The devfreq object.
- */
-void devm_devfreq_unregister_opp_notifier(struct device *dev,
-					 struct devfreq *devfreq)
-{
-	WARN_ON(devres_release(dev, devm_devfreq_opp_release,
-			       devm_devfreq_dev_match, devfreq));
-}
-EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier);
-
 /**
  * devfreq_register_notifier() - Register a driver with devfreq
  * @devfreq:	The devfreq object.
  * @nb:		The notifier block to register.
  * @list:	DEVFREQ_TRANSITION_NOTIFIER.
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index d9f377912c10..2d9a4781f401 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -440,17 +440,10 @@ static int exynos_bus_probe(struct platform_device *pdev)
 		dev_err(dev, "failed to add devfreq device\n");
 		ret = PTR_ERR(bus->devfreq);
 		goto err;
 	}
 
-	/* Register opp_notifier to catch the change of OPP  */
-	ret = devm_devfreq_register_opp_notifier(dev, bus->devfreq);
-	if (ret < 0) {
-		dev_err(dev, "failed to register opp notifier\n");
-		goto err;
-	}
-
 	/*
 	 * Enable devfreq-event to get raw data which is used to determine
 	 * current bus load.
 	 */
 	ret = exynos_bus_enable_edev(bus);
diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 2e65d7279d79..f660d2031e8a 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -454,12 +454,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	if (IS_ERR(data->devfreq)) {
 		ret = PTR_ERR(data->devfreq);
 		goto err_free_opp;
 	}
 
-	devm_devfreq_register_opp_notifier(dev, data->devfreq);
-
 	data->dev = dev;
 	platform_set_drvdata(pdev, data);
 
 	return 0;
 
@@ -470,14 +468,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 
 static int rk3399_dmcfreq_remove(struct platform_device *pdev)
 {
 	struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
 
-	/*
-	 * Before remove the opp table we need to unregister the opp notifier.
-	 */
-	devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
 	dev_pm_opp_of_remove_table(dmcfreq->dev);
 
 	return 0;
 }
 
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 4b5cc80abbe3..bf6ebfbc1e8a 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -220,18 +220,10 @@ extern void devfreq_resume(void);
 extern int update_devfreq(struct devfreq *devfreq);
 
 /* Helper functions for devfreq user device driver with OPP. */
 extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
 					   unsigned long *freq, u32 flags);
-extern int devfreq_register_opp_notifier(struct device *dev,
-					 struct devfreq *devfreq);
-extern int devfreq_unregister_opp_notifier(struct device *dev,
-					   struct devfreq *devfreq);
-extern int devm_devfreq_register_opp_notifier(struct device *dev,
-					      struct devfreq *devfreq);
-extern void devm_devfreq_unregister_opp_notifier(struct device *dev,
-						struct devfreq *devfreq);
 extern int devfreq_register_notifier(struct devfreq *devfreq,
 					struct notifier_block *nb,
 					unsigned int list);
 extern int devfreq_unregister_notifier(struct devfreq *devfreq,
 					struct notifier_block *nb,
-- 
2.17.1


_______________________________________________
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 v4 0/6] PM / devfreq: Add dev_pm_qos support
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai

Add dev_pm_qos notifies to devfreq core in order to support frequency
limits via the dev_pm_qos_add_request.

Unlike the rest of devfreq the dev_pm_qos frequency is measured in Khz,
this is consistent with current dev_pm_qos usage for cpufreq and
allows frequencies above 2Ghz (pm_qos expresses limits as s32).

Like with cpufreq the handling of min_freq/max_freq is moved to the
dev_pm_qos mechanism.

Patches 1/2 are technically bugfixes; as far as I can tell the paths
that "goto err_devfreq" in devfreq_add_device never worked correctly.

Constraints from userspace are no longer clamped on store, instead all
values are allowed and we only check against OPPs in a new
devfreq_get_freq_range function. This is consistent with the design of
dev_pm_qos design.

Changes since v3:
* Cleanup locking and error-handling in devfreq_add_device
* Register notifiers after device registration but before governor start
* Keep the initialization of min_req/max_req ahead of device_register
because it's used for sysfs handling
* Use HZ_PER_KHZ instead of 1000
* Add kernel-doc comments
* Move OPP notifier to core
Link to v3: https://patchwork.kernel.org/cover/11104061/

Changes since v2:
* Handle sysfs via dev_pm_qos (in separate patch)
* Add locking to {min,max}_freq_show
* Fix checkpatch issues (long lines etc)
Link to v2: https://patchwork.kernel.org/patch/11084279/

Changes since v1:
* Add doxygen comments for min_nb/max_nb
* Remove notifiers on error/cleanup paths. Keep gotos simple by relying on
dev_pm_qos_remove_notifier ignoring notifiers which were not added.
Link to v1: https://patchwork.kernel.org/patch/11078475/

Leonard Crestez (6):
  PM / devfreq: Don't take lock in devfreq_add_device
  PM / devfreq: Add to devfreq_list immediately after registration
  PM / devfreq: Introduce devfreq_get_freq_range
  PM / devfreq: Add dev_pm_qos support
  PM / devfreq: Use dev_pm_qos for sysfs min/max_freq
  PM / devfreq: Move opp notifier registration to core

 drivers/devfreq/devfreq.c    | 313 +++++++++++++++++++----------------
 drivers/devfreq/exynos-bus.c |   7 -
 drivers/devfreq/rk3399_dmc.c |   6 -
 include/linux/devfreq.h      |  22 ++-
 4 files changed, 177 insertions(+), 171 deletions(-)

-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 5/6] PM / devfreq: Use dev_pm_qos for sysfs min/max_freq
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

Switch the handling of min_freq and max_freq from sysfs to use the
dev_pm_qos interface.

Since dev_pm_qos handles frequencies as kHz this change reduces the
precision of min_freq and max_freq. This shouldn't introduce problems
because frequencies which are not an integer number of kHz are likely
not an integer number of Hz either.

Try to ensure compatibilitity by rounding min values down and rounding
max values up.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c | 53 +++++++++++++++++++++++++--------------
 include/linux/devfreq.h   |  9 ++++---
 2 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 42c10b8b239e..f85c6628249f 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -132,14 +132,10 @@ static void devfreq_get_freq_range(struct devfreq *devfreq,
 	*min_freq = max(*min_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
 				devfreq->dev.parent, DEV_PM_QOS_MIN_FREQUENCY));
 	*max_freq = min(*max_freq, HZ_PER_KHZ * (unsigned long)dev_pm_qos_read_value(
 				devfreq->dev.parent, DEV_PM_QOS_MAX_FREQUENCY));
 
-	/* constraints from sysfs: */
-	*min_freq = max(*min_freq, devfreq->min_freq);
-	*max_freq = min(*max_freq, devfreq->max_freq);
-
 	/* constraints from opp interface: */
 	*min_freq = max(*min_freq, devfreq->scaling_min_freq);
 	/* scaling_max_freq can be zero on error */
 	if (devfreq->scaling_max_freq)
 		*max_freq = min(*max_freq, devfreq->scaling_max_freq);
@@ -679,10 +675,12 @@ static void devfreq_dev_release(struct device *dev)
 			DEV_PM_QOS_MIN_FREQUENCY);
 
 	if (devfreq->profile->exit)
 		devfreq->profile->exit(devfreq->dev.parent);
 
+	dev_pm_qos_remove_request(&devfreq->max_freq_req);
+	dev_pm_qos_remove_request(&devfreq->min_freq_req);
 	mutex_destroy(&devfreq->lock);
 	kfree(devfreq);
 }
 
 /**
@@ -744,18 +742,28 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
 	if (!devfreq->scaling_min_freq) {
 		err = -EINVAL;
 		goto err_dev;
 	}
-	devfreq->min_freq = devfreq->scaling_min_freq;
 
 	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
 	if (!devfreq->scaling_max_freq) {
 		err = -EINVAL;
 		goto err_dev;
 	}
-	devfreq->max_freq = devfreq->scaling_max_freq;
+
+	/* dev_pm_qos requests for min/max freq from sysfs */
+	err = dev_pm_qos_add_request(dev, &devfreq->min_freq_req,
+				     DEV_PM_QOS_MIN_FREQUENCY, 0);
+	if (err < 0) {
+		goto err_dev;
+	}
+	err = dev_pm_qos_add_request(dev, &devfreq->max_freq_req,
+				     DEV_PM_QOS_MAX_FREQUENCY, S32_MAX);
+	if (err < 0) {
+		goto err_dev;
+	}
 
 	devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev);
 	atomic_set(&devfreq->suspend_count, 0);
 
 	dev_set_name(&devfreq->dev, "devfreq%d",
@@ -836,12 +844,16 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
 err_init:
 	mutex_unlock(&devfreq_list_lock);
 err_devfreq:
 	devfreq_remove_device(devfreq);
-	devfreq = NULL;
+	return ERR_PTR(err);
 err_dev:
+	if (dev_pm_qos_request_active(&devfreq->max_freq_req))
+		dev_pm_qos_remove_request(&devfreq->max_freq_req);
+	if (dev_pm_qos_request_active(&devfreq->min_freq_req))
+		dev_pm_qos_remove_request(&devfreq->min_freq_req);
 	kfree(devfreq);
 err_out:
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL(devfreq_add_device);
@@ -1400,14 +1412,17 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
 
 	ret = sscanf(buf, "%lu", &value);
 	if (ret != 1)
 		return -EINVAL;
 
-	mutex_lock(&df->lock);
-	df->min_freq = value;
-	update_devfreq(df);
-	mutex_unlock(&df->lock);
+	/* round down to kHz for dev_pm_qos */
+	if (value)
+		value = value / HZ_PER_KHZ;
+
+	ret = dev_pm_qos_update_request(&df->min_freq_req, value);
+	if (ret < 0)
+		return ret;
 
 	return count;
 }
 
 static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
@@ -1432,19 +1447,19 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 
 	ret = sscanf(buf, "%lu", &value);
 	if (ret != 1)
 		return -EINVAL;
 
-	mutex_lock(&df->lock);
-
-	/* Interpret zero as "don't care" */
-	if (!value)
-		value = ULONG_MAX;
+	/* round up to kHz for dev_pm_qos and interpret zero as "don't care" */
+	if (value)
+		value = DIV_ROUND_UP(value, HZ_PER_KHZ);
+	else
+		value = S32_MAX;
 
-	df->max_freq = value;
-	update_devfreq(df);
-	mutex_unlock(&df->lock);
+	ret = dev_pm_qos_update_request(&df->max_freq_req, value);
+	if (ret < 0)
+		return ret;
 
 	return count;
 }
 static DEVICE_ATTR_RW(min_freq);
 
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index dac0dffeabb4..4b5cc80abbe3 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -11,10 +11,11 @@
 #define __LINUX_DEVFREQ_H__
 
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
 
 #define DEVFREQ_NAME_LEN 16
 
 /* DEVFREQ governor name */
 #define DEVFREQ_GOV_SIMPLE_ONDEMAND	"simple_ondemand"
@@ -121,12 +122,12 @@ struct devfreq_dev_profile {
  *		devfreq.nb to the corresponding register notifier call chain.
  * @work:	delayed work for load monitoring.
  * @previous_freq:	previously configured frequency value.
  * @data:	Private data of the governor. The devfreq framework does not
  *		touch this.
- * @min_freq:	Limit minimum frequency requested by user (0: none)
- * @max_freq:	Limit maximum frequency requested by user (0: none)
+ * @min_freq_req:	Limit minimum frequency requested by user (0: none)
+ * @max_freq_req:	Limit maximum frequency requested by user (0: none)
  * @scaling_min_freq:	Limit minimum frequency requested by OPP interface
  * @scaling_max_freq:	Limit maximum frequency requested by OPP interface
  * @stop_polling:	 devfreq polling status of a device.
  * @suspend_freq:	 frequency of a device set during suspend phase.
  * @resume_freq:	 frequency of a device set in resume phase.
@@ -161,12 +162,12 @@ struct devfreq {
 	unsigned long previous_freq;
 	struct devfreq_dev_status last_status;
 
 	void *data; /* private data for governors */
 
-	unsigned long min_freq;
-	unsigned long max_freq;
+	struct dev_pm_qos_request min_freq_req;
+	struct dev_pm_qos_request max_freq_req;
 	unsigned long scaling_min_freq;
 	unsigned long scaling_max_freq;
 	bool stop_polling;
 
 	unsigned long suspend_freq;
-- 
2.17.1


_______________________________________________
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 v4 1/6] PM / devfreq: Don't take lock in devfreq_add_device
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

A device usually doesn't need to lock itself during initialization
because it is not yet reachable from other threads.

This simplifies the code and helps avoid recursive lock warnings.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index afbe2a8f7529..15270293bea9 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -636,11 +636,10 @@ struct devfreq *devfreq_add_device(struct device *dev,
 		err = -ENOMEM;
 		goto err_out;
 	}
 
 	mutex_init(&devfreq->lock);
-	mutex_lock(&devfreq->lock);
 	devfreq->dev.parent = dev;
 	devfreq->dev.class = devfreq_class;
 	devfreq->dev.release = devfreq_dev_release;
 	devfreq->profile = profile;
 	strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN);
@@ -648,28 +647,24 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	devfreq->last_status.current_frequency = profile->initial_freq;
 	devfreq->data = data;
 	devfreq->nb.notifier_call = devfreq_notifier_call;
 
 	if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
-		mutex_unlock(&devfreq->lock);
 		err = set_freq_table(devfreq);
 		if (err < 0)
 			goto err_dev;
-		mutex_lock(&devfreq->lock);
 	}
 
 	devfreq->scaling_min_freq = find_available_min_freq(devfreq);
 	if (!devfreq->scaling_min_freq) {
-		mutex_unlock(&devfreq->lock);
 		err = -EINVAL;
 		goto err_dev;
 	}
 	devfreq->min_freq = devfreq->scaling_min_freq;
 
 	devfreq->scaling_max_freq = find_available_max_freq(devfreq);
 	if (!devfreq->scaling_max_freq) {
-		mutex_unlock(&devfreq->lock);
 		err = -EINVAL;
 		goto err_dev;
 	}
 	devfreq->max_freq = devfreq->scaling_max_freq;
 
@@ -678,42 +673,37 @@ struct devfreq *devfreq_add_device(struct device *dev,
 
 	dev_set_name(&devfreq->dev, "devfreq%d",
 				atomic_inc_return(&devfreq_no));
 	err = device_register(&devfreq->dev);
 	if (err) {
-		mutex_unlock(&devfreq->lock);
 		put_device(&devfreq->dev);
 		goto err_out;
 	}
 
 	devfreq->trans_table = devm_kzalloc(&devfreq->dev,
 			array3_size(sizeof(unsigned int),
 				    devfreq->profile->max_state,
 				    devfreq->profile->max_state),
 			GFP_KERNEL);
 	if (!devfreq->trans_table) {
-		mutex_unlock(&devfreq->lock);
 		err = -ENOMEM;
 		goto err_devfreq;
 	}
 
 	devfreq->time_in_state = devm_kcalloc(&devfreq->dev,
 			devfreq->profile->max_state,
 			sizeof(unsigned long),
 			GFP_KERNEL);
 	if (!devfreq->time_in_state) {
-		mutex_unlock(&devfreq->lock);
 		err = -ENOMEM;
 		goto err_devfreq;
 	}
 
 	devfreq->last_stat_updated = jiffies;
 
 	srcu_init_notifier_head(&devfreq->transition_notifier_list);
 
-	mutex_unlock(&devfreq->lock);
-
 	mutex_lock(&devfreq_list_lock);
 
 	governor = try_then_request_governor(devfreq->governor_name);
 	if (IS_ERR(governor)) {
 		dev_err(dev, "%s: Unable to find governor for the device\n",
-- 
2.17.1


_______________________________________________
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 v4 2/6] PM / devfreq: Add to devfreq_list immediately after registration
From: Leonard Crestez @ 2019-08-26 13:44 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham
  Cc: Artur Świgoń, Abel Vesa, Saravana Kannan, linux-pm,
	Viresh Kumar, Krzysztof Kozlowski, Kyungmin Park,
	Alexandre Bailon, Georgi Djakov, linux-arm-kernel, Jacky Bai
In-Reply-To: <cover.1566826075.git.leonard.crestez@nxp.com>

After the devfreq->dev is registered all error cleanup paths call
devfreq_dev_release which fails if the devfreq instance is not in the
global devfreq_list.

Fix by adding to the list immediately after registration.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
---
 drivers/devfreq/devfreq.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Alternatively we could make devfreq_dev_release accept devfreq instance
not in the list.

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 15270293bea9..9b3bf64dc37d 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -677,10 +677,15 @@ struct devfreq *devfreq_add_device(struct device *dev,
 	if (err) {
 		put_device(&devfreq->dev);
 		goto err_out;
 	}
 
+	/* Add to global list of devfreq instances */
+	mutex_lock(&devfreq_list_lock);
+	list_add(&devfreq->node, &devfreq_list);
+	mutex_unlock(&devfreq_list_lock);
+
 	devfreq->trans_table = devm_kzalloc(&devfreq->dev,
 			array3_size(sizeof(unsigned int),
 				    devfreq->profile->max_state,
 				    devfreq->profile->max_state),
 			GFP_KERNEL);
@@ -719,12 +724,10 @@ struct devfreq *devfreq_add_device(struct device *dev,
 		dev_err(dev, "%s: Unable to start governor for the device\n",
 			__func__);
 		goto err_init;
 	}
 
-	list_add(&devfreq->node, &devfreq_list);
-
 	mutex_unlock(&devfreq_list_lock);
 
 	return devfreq;
 
 err_init:
-- 
2.17.1


_______________________________________________
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] ARM: davinci: dm646x: Fix a typo in the comment
From: Sekhar Nori @ 2019-08-26 13:34 UTC (permalink / raw)
  To: Christophe JAILLET, bgolaszewski, linux
  Cc: kernel-janitors, linux-kernel, linux-arm-kernel
In-Reply-To: <20190722213657.27175-1-christophe.jaillet@wanadoo.fr>

On 23/07/19 3:06 AM, Christophe JAILLET wrote:
> The driver is dedicated to DM646x. So update the description in the top
> most comment accordingly.
> 
> It must have been derived from dm644x.c, but looks DM646 speecific now.
> 
> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>

Applied to my v5.4/soc branch.

Thanks,
Sekhar

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox