Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] net/wireless: Delete unnecessary checks before the macro call “dev_kfree_skb”
From: Markus Elfring @ 2019-08-22  8:30 UTC (permalink / raw)
  To: linux-wireless, linux-arm-kernel, linux-mediatek, ath10k,
	David S. Miller, Felix Fietkau, Kalle Valo, Lorenzo Bianconi,
	Matthias Brugger, Roy Luo, Ryder Lee, Solomon Peachy,
	Stanislaw Gruszka
  Cc: kernel-janitors, LKML

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Thu, 22 Aug 2019 10:20:10 +0200

The dev_kfree_skb() function performs also input parameter validation.
Thus the test around the shown calls is not needed.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/net/wireless/ath/ath10k/wmi.c               | 4 +---
 drivers/net/wireless/intel/iwlegacy/3945-mac.c      | 8 ++------
 drivers/net/wireless/intel/iwlegacy/common.c        | 8 ++------
 drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c | 5 +----
 drivers/net/wireless/st/cw1200/scan.c               | 3 +--
 5 files changed, 7 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 4f707c6394bb..d384293429b4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -9440,7 +9440,5 @@ void ath10k_wmi_detach(struct ath10k *ar)
 	}

 	cancel_work_sync(&ar->svc_rdy_work);
-
-	if (ar->svc_rdy_skb)
-		dev_kfree_skb(ar->svc_rdy_skb);
+	dev_kfree_skb(ar->svc_rdy_skb);
 }
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index b82da75a9ae3..4b3b166f6f2a 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -2302,9 +2302,7 @@ __il3945_down(struct il_priv *il)
 	il3945_hw_txq_ctx_free(il);
 exit:
 	memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
-
-	if (il->beacon_skb)
-		dev_kfree_skb(il->beacon_skb);
+	dev_kfree_skb(il->beacon_skb);
 	il->beacon_skb = NULL;

 	/* clear out any free frames */
@@ -3847,9 +3845,7 @@ il3945_pci_remove(struct pci_dev *pdev)
 	il_free_channel_map(il);
 	il_free_geos(il);
 	kfree(il->scan_cmd);
-	if (il->beacon_skb)
-		dev_kfree_skb(il->beacon_skb);
-
+	dev_kfree_skb(il->beacon_skb);
 	ieee80211_free_hw(il->hw);
 }

diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c
index 73f7bbf742bc..4e7e64f46ea8 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -5182,8 +5182,7 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));

 	/* new association get rid of ibss beacon skb */
-	if (il->beacon_skb)
-		dev_kfree_skb(il->beacon_skb);
+	dev_kfree_skb(il->beacon_skb);
 	il->beacon_skb = NULL;
 	il->timestamp = 0;

@@ -5302,10 +5301,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	}

 	spin_lock_irqsave(&il->lock, flags);
-
-	if (il->beacon_skb)
-		dev_kfree_skb(il->beacon_skb);
-
+	dev_kfree_skb(il->beacon_skb);
 	il->beacon_skb = skb;

 	timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index d61c686e08de..d6487cd67cca 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -88,10 +88,7 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
 	for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
 		if (vif_idx == i) {
 			force_update = !!dev->beacons[i] ^ !!skb;
-
-			if (dev->beacons[i])
-				dev_kfree_skb(dev->beacons[i]);
-
+			dev_kfree_skb(dev->beacons[i]);
 			dev->beacons[i] = skb;
 			__mt76x02_mac_set_beacon(dev, bcn_idx, skb);
 		} else if (force_update && dev->beacons[i]) {
diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c
index c46b044b7f7b..988581cc134b 100644
--- a/drivers/net/wireless/st/cw1200/scan.c
+++ b/drivers/net/wireless/st/cw1200/scan.c
@@ -120,8 +120,7 @@ int cw1200_hw_scan(struct ieee80211_hw *hw,
 		++priv->scan.n_ssids;
 	}

-	if (frame.skb)
-		dev_kfree_skb(frame.skb);
+	dev_kfree_skb(frame.skb);
 	mutex_unlock(&priv->conf_mutex);
 	queue_work(priv->workqueue, &priv->scan.work);
 	return 0;
--
2.23.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 2/4 v2] misc: xilinx_sdfec: Return -EFAULT if copy_from_user() fails
From: Dan Carpenter @ 2019-08-22  8:31 UTC (permalink / raw)
  To: Derek Kiernan, Dragan Cvetic
  Cc: Arnd Bergmann, Greg Kroah-Hartman, kernel-janitors, Michal Simek,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20190821070702.GB26957@mwanda>

The copy_from_user() function returns the number of bytes remaining to
be copied but we want to return -EFAULT to the user.

Fixes: 20ec628e8007 ("misc: xilinx_sdfec: Add ability to configure LDPC")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Michal Simek <michal.simek@xilinx.com>
---
v2: Fix a typo in the commit message.  funciton --> function

 drivers/misc/xilinx_sdfec.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
index dc1b8b412712..813b82c59360 100644
--- a/drivers/misc/xilinx_sdfec.c
+++ b/drivers/misc/xilinx_sdfec.c
@@ -651,9 +651,10 @@ static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
 	if (!ldpc)
 		return -ENOMEM;
 
-	ret = copy_from_user(ldpc, arg, sizeof(*ldpc));
-	if (ret)
+	if (copy_from_user(ldpc, arg, sizeof(*ldpc))) {
+		ret = -EFAULT;
 		goto err_out;
+	}
 
 	if (xsdfec->config.code == XSDFEC_TURBO_CODE) {
 		ret = -EIO;
-- 
2.20.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 1/4] misc: xilinx_sdfec: Fix a couple small information leaks
From: Dan Carpenter @ 2019-08-22  8:28 UTC (permalink / raw)
  To: Michal Simek
  Cc: Arnd Bergmann, Greg Kroah-Hartman, Dragan Cvetic, kernel-janitors,
	linux-kernel, Derek Kiernan, linux-arm-kernel
In-Reply-To: <58e9a151-3d92-c730-eea6-5cfde90934a4@xilinx.com>

On Thu, Aug 22, 2019 at 10:14:12AM +0200, Michal Simek wrote:
> Hi Dan,
> 
> On 21. 08. 19 9:06, Dan Carpenter wrote:
> > These structs have holes in them so we end up disclosing a few bytes of
> > uninitialized stack data.
> > 
> > drivers/misc/xilinx_sdfec.c:305 xsdfec_get_status() warn: check that 'status' doesn't leak information (struct has a hole after 'activity')
> > drivers/misc/xilinx_sdfec.c:449 xsdfec_get_turbo() warn: check that 'turbo_params' doesn't leak information (struct has a hole after 'scale')
> 
> Who is generating these warnings? Is this any new GCC or different tool?
> I see that 3byte padding but never seen these warnings.

This is a Smatch check.

regards,
dan carpenter


_______________________________________________
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 4/4] misc: xilinx_sdfec: Prevent integer overflow in xsdfec_table_write()
From: Michal Simek @ 2019-08-22  8:27 UTC (permalink / raw)
  To: Dan Carpenter, Derek Kiernan, Dragan Cvetic
  Cc: Arnd Bergmann, Greg Kroah-Hartman, kernel-janitors, Michal Simek,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20190821071122.GD26957@mwanda>

On 21. 08. 19 9:11, Dan Carpenter wrote:
> The checking here needs to handle integer overflows because "offset" and
> "len" come from the user.
> 
> Fixes: 20ec628e8007 ("misc: xilinx_sdfec: Add ability to configure LDPC")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
>  drivers/misc/xilinx_sdfec.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
> index 3fc53d20abf3..0bf3bcc8e1ef 100644
> --- a/drivers/misc/xilinx_sdfec.c
> +++ b/drivers/misc/xilinx_sdfec.c
> @@ -611,7 +611,9 @@ static int xsdfec_table_write(struct xsdfec_dev *xsdfec, u32 offset,
>  	 * Writes that go beyond the length of
>  	 * Shared Scale(SC) table should fail
>  	 */
> -	if ((XSDFEC_REG_WIDTH_JUMP * (offset + len)) > depth) {
> +	if (offset > depth / XSDFEC_REG_WIDTH_JUMP ||
> +	    len > depth / XSDFEC_REG_WIDTH_JUMP ||
> +	    offset + len > depth / XSDFEC_REG_WIDTH_JUMP) {
>  		dev_dbg(xsdfec->dev, "Write exceeds SC table length");
>  		return -EINVAL;
>  	}
> 

Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

_______________________________________________
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 RESEND] i2c: mediatek: disable zero-length transfers for mt8183
From: Yingjoe Chen @ 2019-08-22  8:24 UTC (permalink / raw)
  To: Hsin-Yi Wang
  Cc: Nicolas Boichat, Qii Wang, Alexandru M Stan, Wolfram Sang,
	Jun Gao, linux-kernel, linux-mediatek, linux-i2c,
	Matthias Brugger, Thomas Gleixner, linux-arm-kernel
In-Reply-To: <20190822055737.142384-1-hsinyi@chromium.org>

On Thu, 2019-08-22 at 13:57 +0800, Hsin-Yi Wang wrote:
> When doing i2cdetect quick write mode, we would get transfer
> error ENOMEM, and i2cdetect shows there's no device at the address.
> Quoting from mt8183 datasheet, the number of transfers to be
> transferred in one transaction should be set to bigger than 1,
> so we should forbid zero-length transfer and update functionality.


<...>

> @@ -933,8 +942,8 @@ static int mtk_i2c_probe(struct platform_device *pdev)
>  	i2c->dev = &pdev->dev;
>  	i2c->adap.dev.parent = &pdev->dev;
>  	i2c->adap.owner = THIS_MODULE;
> -	i2c->adap.algo = &mtk_i2c_algorithm;
>  	i2c->adap.quirks = i2c->dev_comp->quirks;
> +	i2c->adap.algo = &mtk_i2c_algorithm;
>  	i2c->adap.timeout = 2 * HZ;
>  	i2c->adap.retries = 1;
>  

Why do you need to change this part?

Joe.C




_______________________________________________
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 4/5] arm64: dts: meson-sm1-sei610: add HDMI display support
From: Neil Armstrong @ 2019-08-22  8:23 UTC (permalink / raw)
  To: Kevin Hilman, ulf.hansson
  Cc: linux-amlogic, linux-kernel, linux-arm-kernel, linux-pm
In-Reply-To: <7ho90i5c41.fsf@baylibre.com>

On 22/08/2019 01:31, Kevin Hilman wrote:
> Neil Armstrong <narmstrong@baylibre.com> writes:
> 
>> Update compatible of the pwc-vpu node and add the HDMI support nodes
>> for the Amlogic SM1 Based SEI610 Board.
> 
> I think this changelog is out of date.  It's not doing anything with the
> VPU pwrc node.

Exact, thanks for pointing it

> 
> Kevin
> 
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  .../boot/dts/amlogic/meson-sm1-sei610.dts     | 23 +++++++++++++++++++
>>  1 file changed, 23 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
>> index 12dab0ba2f26..66bd3bfbaf91 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
>> @@ -51,6 +51,17 @@
>>  		};
>>  	};
>>  
>> +	hdmi-connector {
>> +		compatible = "hdmi-connector";
>> +		type = "a";
>> +
>> +		port {
>> +			hdmi_connector_in: endpoint {
>> +				remote-endpoint = <&hdmi_tx_tmds_out>;
>> +			};
>> +		};
>> +	};
>> +
>>  	leds {
>>  		compatible = "gpio-leds";
>>  
>> @@ -177,6 +188,18 @@
>>  	phy-mode = "rmii";
>>  };
>>  
>> +&hdmi_tx {
>> +	status = "okay";
>> +	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
>> +	pinctrl-names = "default";
>> +};
>> +
>> +&hdmi_tx_tmds_port {
>> +	hdmi_tx_tmds_out: endpoint {
>> +		remote-endpoint = <&hdmi_connector_in>;
>> +	};
>> +};
>> +
>>  &i2c3 {
>>  	status = "okay";
>>  	pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
>> -- 
>> 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 v8 4/5] ARM: dts: sun7i: Add CSI0 controller
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel,
	Chen-Yu Tsai, Rob Herring, Laurent Pinchart, Thomas Petazzoni,
	Frank Rowand, linux-arm-kernel, linux-media
In-Reply-To: <cover.85d78dd1a3b44fe4cde1b65a9b1eb3b95daea7cc.1566462064.git-series.maxime.ripard@bootlin.com>

From: Maxime Ripard <maxime.ripard@bootlin.com>

The CSI controller embedded in the A20 can be supported by our new driver.
Let's add it to our DT.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 arch/arm/boot/dts/sun7i-a20.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 9ad8e445b240..713c20be8c7a 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -376,6 +376,17 @@
 			num-cs = <1>;
 		};
 
+		csi0: csi@1c09000 {
+			compatible = "allwinner,sun7i-a20-csi0";
+			reg = <0x01c09000 0x1000>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>,
+				 <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>;
+			clock-names = "bus", "mod", "isp", "ram";
+			resets = <&ccu RST_CSI0>;
+			status = "disabled";
+		};
+
 		emac: ethernet@1c0b000 {
 			compatible = "allwinner,sun4i-a10-emac";
 			reg = <0x01c0b000 0x1000>;
@@ -775,6 +786,20 @@
 			};
 
 			/omit-if-no-ref/
+			csi0_8bits_pins: csi-8bits-pins {
+				pins = "PE0", "PE2", "PE3", "PE4", "PE5",
+				       "PE6", "PE7", "PE8", "PE9", "PE10",
+				       "PE11";
+				function = "csi0";
+			};
+
+			/omit-if-no-ref/
+			csi0_clk_pin: csi-clk-pin {
+				pins = "PE1";
+				function = "csi0";
+			};
+
+			/omit-if-no-ref/
 			emac_pa_pins: emac-pa-pins {
 				pins = "PA0", "PA1", "PA2",
 				       "PA3", "PA4", "PA5", "PA6",
-- 
git-series 0.9.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 v8 5/5] DO NOT MERGE: ARM: dts: bananapi: Add Camera support
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel,
	Chen-Yu Tsai, Rob Herring, Laurent Pinchart, Thomas Petazzoni,
	Frank Rowand, linux-arm-kernel, linux-media
In-Reply-To: <cover.85d78dd1a3b44fe4cde1b65a9b1eb3b95daea7cc.1566462064.git-series.maxime.ripard@bootlin.com>

From: Maxime Ripard <maxime.ripard@bootlin.com>

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 arch/arm/boot/dts/sun7i-a20-bananapi.dts | 87 +++++++++++++++++++++++++-
 1 file changed, 87 insertions(+)

diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index c5730b30a15d..d3f23ce041b2 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -54,6 +54,9 @@
 	compatible = "lemaker,bananapi", "allwinner,sun7i-a20";
 
 	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
 		serial0 = &uart0;
 		serial1 = &uart3;
 		serial2 = &uart7;
@@ -63,6 +66,41 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	reg_cam: cam {
+		compatible = "regulator-fixed";
+		regulator-name = "cam";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&reg_vcc5v0>;
+		gpio = <&pio 7 16 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+        reg_cam_avdd: cam-avdd {
+                compatible = "regulator-fixed";
+                regulator-name = "cam500b-avdd";
+                regulator-min-microvolt = <2800000>;
+                regulator-max-microvolt = <2800000>;
+                vin-supply = <&reg_cam>;
+        };
+
+        reg_cam_dovdd: cam-dovdd {
+                compatible = "regulator-fixed";
+                regulator-name = "cam500b-dovdd";
+                regulator-min-microvolt = <1800000>;
+                regulator-max-microvolt = <1800000>;
+                vin-supply = <&reg_cam>;
+        };
+
+        reg_cam_dvdd: cam-dvdd {
+                compatible = "regulator-fixed";
+                regulator-name = "cam500b-dvdd";
+                regulator-min-microvolt = <1500000>;
+                regulator-max-microvolt = <1500000>;
+                vin-supply = <&reg_cam>;
+        };
+
 	hdmi-connector {
 		compatible = "hdmi-connector";
 		type = "a";
@@ -116,6 +154,23 @@
 		>;
 };
 
+&csi0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&csi0_8bits_pins>;
+	status = "okay";
+
+	port {
+		csi_from_ov5640: endpoint {
+                        remote-endpoint = <&ov5640_to_csi>;
+                        bus-width = <8>;
+                        hsync-active = <1>; /* Active high */
+                        vsync-active = <0>; /* Active low */
+                        data-active = <1>;  /* Active high */
+                        pclk-sample = <1>;  /* Rising */
+                };
+	};
+};
+
 &de {
 	status = "okay";
 };
@@ -161,6 +216,38 @@
 	};
 };
 
+&i2c1 {
+	status = "okay";
+
+	camera: camera@21 {
+		compatible = "ovti,ov5640";
+		reg = <0x21>;
+		clocks = <&ccu CLK_CSI0>;
+		clock-names = "xclk";
+		assigned-clocks = <&ccu CLK_CSI0>;
+		assigned-clock-rates = <24000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&csi0_clk_pin>;
+
+		reset-gpios = <&pio 7 14 GPIO_ACTIVE_LOW>;
+		powerdown-gpios = <&pio 7 19 GPIO_ACTIVE_HIGH>;
+		AVDD-supply = <&reg_cam_avdd>;
+		DOVDD-supply = <&reg_cam_dovdd>;
+		DVDD-supply = <&reg_cam_dvdd>;
+
+		port {
+			ov5640_to_csi: endpoint {
+				remote-endpoint = <&csi_from_ov5640>;
+				bus-width = <8>;
+				hsync-active = <1>; /* Active high */
+				vsync-active = <0>; /* Active low */
+				data-active = <1>;  /* Active high */
+				pclk-sample = <1>;  /* Rising */
+			};
+		};
+	};
+};
+
 &i2c2 {
 	status = "okay";
 };
-- 
git-series 0.9.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 v8 3/5] media: sunxi: Add A10 CSI driver
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel,
	Chen-Yu Tsai, Rob Herring, Laurent Pinchart, Thomas Petazzoni,
	Frank Rowand, linux-arm-kernel, linux-media
In-Reply-To: <cover.85d78dd1a3b44fe4cde1b65a9b1eb3b95daea7cc.1566462064.git-series.maxime.ripard@bootlin.com>

From: Maxime Ripard <maxime.ripard@bootlin.com>

The older CSI drivers have camera capture interface different from the one
in the newer ones.

This IP is pretty simple. Some variants (one controller out of two
instances on some SoCs) have an ISP embedded, but there's no code that make
use of it, so we ignored that part for now.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 MAINTAINERS                                         |   1 +-
 drivers/media/platform/sunxi/Kconfig                |   1 +-
 drivers/media/platform/sunxi/Makefile               |   1 +-
 drivers/media/platform/sunxi/sun4i-csi/Kconfig      |  11 +-
 drivers/media/platform/sunxi/sun4i-csi/Makefile     |   5 +-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c  | 312 +++++++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h  | 160 +++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c  | 453 +++++++++++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c | 385 +++++++++++-
 9 files changed, 1329 insertions(+)
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/Kconfig
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/Makefile
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 65af586defcc..1cdc7fc20ad9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1424,6 +1424,7 @@ Allwinner A10 CSI driver
 M:	Maxime Ripard <mripard@kernel.org>
 L:	linux-media@vger.kernel.org
 T:	git git://linuxtv.org/media_tree.git
+F:	drivers/media/platform/sunxi/sun4i-csi/
 F:	Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
 S:	Maintained
 
diff --git a/drivers/media/platform/sunxi/Kconfig b/drivers/media/platform/sunxi/Kconfig
index 1b6e89cb78b2..71808e93ac2e 100644
--- a/drivers/media/platform/sunxi/Kconfig
+++ b/drivers/media/platform/sunxi/Kconfig
@@ -1 +1,2 @@
+source "drivers/media/platform/sunxi/sun4i-csi/Kconfig"
 source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
diff --git a/drivers/media/platform/sunxi/Makefile b/drivers/media/platform/sunxi/Makefile
index 8d06f98500ee..a05127529006 100644
--- a/drivers/media/platform/sunxi/Makefile
+++ b/drivers/media/platform/sunxi/Makefile
@@ -1 +1,2 @@
+obj-y		+= sun4i-csi/
 obj-y		+= sun6i-csi/
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
new file mode 100644
index 000000000000..e86e29b6a603
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig
@@ -0,0 +1,11 @@
+config VIDEO_SUN4I_CSI
+	tristate "Allwinner A10 CMOS Sensor Interface Support"
+	depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA
+	depends on ARCH_SUNXI || COMPILE_TEST
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  This is a V4L2 driver for the Allwinner A10 CSI
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called sun4i_csi.
diff --git a/drivers/media/platform/sunxi/sun4i-csi/Makefile b/drivers/media/platform/sunxi/sun4i-csi/Makefile
new file mode 100644
index 000000000000..7c790a57f5ee
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/Makefile
@@ -0,0 +1,5 @@
+sun4i-csi-y += sun4i_csi.o
+sun4i-csi-y += sun4i_dma.o
+sun4i-csi-y += sun4i_v4l2.o
+
+obj-$(CONFIG_VIDEO_SUN4I_CSI)	+= sun4i-csi.o
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
new file mode 100644
index 000000000000..1929b3a85039
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mediabus.h>
+
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "sun4i_csi.h"
+
+static const struct media_entity_operations sun4i_csi_video_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier,
+				  struct v4l2_subdev *subdev,
+				  struct v4l2_async_subdev *asd)
+{
+	struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi,
+					     notifier);
+
+	csi->src_subdev = subdev;
+	csi->src_pad = media_entity_get_fwnode_pad(&subdev->entity,
+						   subdev->fwnode,
+						   MEDIA_PAD_FL_SOURCE);
+	if (csi->src_pad < 0) {
+		dev_err(csi->dev, "Couldn't find output pad for subdev %s\n",
+			subdev->name);
+		return csi->src_pad;
+	}
+
+	dev_dbg(csi->dev, "Bound %s pad: %d\n", subdev->name, csi->src_pad);
+	return 0;
+}
+
+static int sun4i_csi_notify_complete(struct v4l2_async_notifier *notifier)
+{
+	struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi,
+					     notifier);
+	struct v4l2_subdev *subdev = &csi->subdev;
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	ret = v4l2_device_register_subdev(&csi->v4l, subdev);
+	if (ret < 0)
+		return ret;
+
+	ret = sun4i_csi_v4l2_register(csi);
+	if (ret < 0)
+		return ret;
+
+	ret = media_device_register(&csi->mdev);
+	if (ret)
+		return ret;
+
+	/* Create link from subdev to main device */
+	ret = media_create_pad_link(&subdev->entity, CSI_SUBDEV_SOURCE,
+				    &vdev->entity, 0,
+				    MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		goto err_clean_media;
+
+	ret = media_create_pad_link(&csi->src_subdev->entity, csi->src_pad,
+				    &subdev->entity, CSI_SUBDEV_SINK,
+				    MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		goto err_clean_media;
+
+	ret = v4l2_device_register_subdev_nodes(&csi->v4l);
+	if (ret < 0)
+		goto err_clean_media;
+
+	return 0;
+
+err_clean_media:
+	media_device_unregister(&csi->mdev);
+
+	return ret;
+}
+
+static const struct v4l2_async_notifier_operations sun4i_csi_notify_ops = {
+	.bound		= sun4i_csi_notify_bound,
+	.complete	= sun4i_csi_notify_complete,
+};
+
+static int sun4i_csi_notifier_init(struct sun4i_csi *csi)
+{
+	struct v4l2_fwnode_endpoint vep = {
+		.bus_type = V4L2_MBUS_PARALLEL,
+	};
+	struct fwnode_handle *ep;
+	int ret;
+
+	v4l2_async_notifier_init(&csi->notifier);
+
+	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
+					     FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!ep)
+		return -EINVAL;
+
+	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
+	if (ret)
+		goto out;
+
+	csi->bus = vep.bus.parallel;
+
+	ret = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier,
+							   ep, &csi->asd);
+	if (ret)
+		goto out;
+
+	csi->notifier.ops = &sun4i_csi_notify_ops;
+
+out:
+	fwnode_handle_put(ep);
+	return ret;
+}
+
+static int sun4i_csi_probe(struct platform_device *pdev)
+{
+	struct v4l2_subdev *subdev;
+	struct video_device *vdev;
+	struct sun4i_csi *csi;
+	struct resource *res;
+	int ret;
+	int irq;
+
+	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
+	if (!csi)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, csi);
+	csi->dev = &pdev->dev;
+	subdev = &csi->subdev;
+	vdev = &csi->vdev;
+
+	csi->mdev.dev = csi->dev;
+	strscpy(csi->mdev.model, "Allwinner Video Capture Device",
+		sizeof(csi->mdev.model));
+	csi->mdev.hw_revision = 0;
+	media_device_init(&csi->mdev);
+	csi->v4l.mdev = &csi->mdev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	csi->regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(csi->regs))
+		return PTR_ERR(csi->regs);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	csi->bus_clk = devm_clk_get(&pdev->dev, "bus");
+	if (IS_ERR(csi->bus_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our bus clock\n");
+		return PTR_ERR(csi->bus_clk);
+	}
+
+	csi->isp_clk = devm_clk_get(&pdev->dev, "isp");
+	if (IS_ERR(csi->isp_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our ISP clock\n");
+		return PTR_ERR(csi->isp_clk);
+	}
+
+	csi->ram_clk = devm_clk_get(&pdev->dev, "ram");
+	if (IS_ERR(csi->ram_clk)) {
+		dev_err(&pdev->dev, "Couldn't get our ram clock\n");
+		return PTR_ERR(csi->ram_clk);
+	}
+
+	csi->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(csi->rst)) {
+		dev_err(&pdev->dev, "Couldn't get our reset line\n");
+		return PTR_ERR(csi->rst);
+	}
+
+	/* Initialize subdev */
+	v4l2_subdev_init(subdev, &sun4i_csi_subdev_ops);
+	subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+	subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	subdev->owner = THIS_MODULE;
+	snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0");
+	v4l2_set_subdevdata(subdev, csi);
+
+	csi->subdev_pads[CSI_SUBDEV_SINK].flags =
+		MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+	csi->subdev_pads[CSI_SUBDEV_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&subdev->entity, CSI_SUBDEV_PADS,
+				     csi->subdev_pads);
+	if (ret < 0)
+		return ret;
+
+	csi->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+	vdev->entity.ops = &sun4i_csi_video_entity_ops;
+	ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad);
+	if (ret < 0)
+		return ret;
+
+	ret = sun4i_csi_dma_register(csi, irq);
+	if (ret)
+		goto err_clean_pad;
+
+	ret = sun4i_csi_notifier_init(csi);
+	if (ret)
+		goto err_unregister_media;
+
+	ret = v4l2_async_notifier_register(&csi->v4l, &csi->notifier);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register our notifier.\n");
+		goto err_unregister_media;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+err_unregister_media:
+	media_device_unregister(&csi->mdev);
+	sun4i_csi_dma_unregister(csi);
+
+err_clean_pad:
+	media_device_cleanup(&csi->mdev);
+
+	return ret;
+}
+
+static int sun4i_csi_remove(struct platform_device *pdev)
+{
+	struct sun4i_csi *csi = platform_get_drvdata(pdev);
+
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
+	media_device_unregister(&csi->mdev);
+	sun4i_csi_dma_unregister(csi);
+	media_device_cleanup(&csi->mdev);
+
+	return 0;
+}
+
+static const struct of_device_id sun4i_csi_of_match[] = {
+	{ .compatible = "allwinner,sun7i-a20-csi0" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sun4i_csi_of_match);
+
+static int __maybe_unused sun4i_csi_runtime_resume(struct device *dev)
+{
+	struct sun4i_csi *csi = dev_get_drvdata(dev);
+
+	reset_control_deassert(csi->rst);
+	clk_prepare_enable(csi->bus_clk);
+	clk_prepare_enable(csi->ram_clk);
+	clk_set_rate(csi->isp_clk, 80000000);
+	clk_prepare_enable(csi->isp_clk);
+
+	writel(1, csi->regs + CSI_EN_REG);
+
+	return 0;
+}
+
+static int __maybe_unused sun4i_csi_runtime_suspend(struct device *dev)
+{
+	struct sun4i_csi *csi = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(csi->isp_clk);
+	clk_disable_unprepare(csi->ram_clk);
+	clk_disable_unprepare(csi->bus_clk);
+
+	reset_control_assert(csi->rst);
+
+	return 0;
+}
+
+static const struct dev_pm_ops sun4i_csi_pm_ops = {
+	SET_RUNTIME_PM_OPS(sun4i_csi_runtime_suspend,
+			   sun4i_csi_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver sun4i_csi_driver = {
+	.probe	= sun4i_csi_probe,
+	.remove	= sun4i_csi_remove,
+	.driver	= {
+		.name		= "sun4i-csi",
+		.of_match_table	= sun4i_csi_of_match,
+		.pm		= &sun4i_csi_pm_ops,
+	},
+};
+module_platform_driver(sun4i_csi_driver);
+
+MODULE_DESCRIPTION("Allwinner A10 Camera Sensor Interface driver");
+MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
new file mode 100644
index 000000000000..001c8bde006c
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#ifndef _SUN4I_CSI_H_
+#define _SUN4I_CSI_H_
+
+#include <media/media-device.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-fwnode.h>
+#include <media/videobuf2-core.h>
+
+#define CSI_EN_REG			0x00
+
+#define CSI_CFG_REG			0x04
+#define CSI_CFG_INPUT_FMT(fmt)			((fmt) << 20)
+#define CSI_CFG_OUTPUT_FMT(fmt)			((fmt) << 16)
+#define CSI_CFG_YUV_DATA_SEQ(seq)		((seq) << 8)
+#define CSI_CFG_VSYNC_POL(pol)			((pol) << 2)
+#define CSI_CFG_HSYNC_POL(pol)			((pol) << 1)
+#define CSI_CFG_PCLK_POL(pol)			((pol) << 0)
+
+#define CSI_CPT_CTRL_REG		0x08
+#define CSI_CPT_CTRL_VIDEO_START		BIT(1)
+#define CSI_CPT_CTRL_IMAGE_START		BIT(0)
+
+#define CSI_BUF_ADDR_REG(fifo, buf)	(0x10 + (0x8 * (fifo)) + (0x4 * (buf)))
+
+#define CSI_BUF_CTRL_REG		0x28
+#define CSI_BUF_CTRL_DBN			BIT(2)
+#define CSI_BUF_CTRL_DBS			BIT(1)
+#define CSI_BUF_CTRL_DBE			BIT(0)
+
+#define CSI_INT_EN_REG			0x30
+#define CSI_INT_FRM_DONE			BIT(1)
+#define CSI_INT_CPT_DONE			BIT(0)
+
+#define CSI_INT_STA_REG			0x34
+
+#define CSI_WIN_CTRL_W_REG		0x40
+#define CSI_WIN_CTRL_W_ACTIVE(w)		((w) << 16)
+
+#define CSI_WIN_CTRL_H_REG		0x44
+#define CSI_WIN_CTRL_H_ACTIVE(h)		((h) << 16)
+
+#define CSI_BUF_LEN_REG			0x48
+
+#define CSI_MAX_BUFFER		2
+#define CSI_MAX_HEIGHT		8192U
+#define CSI_MAX_WIDTH		8192U
+
+enum csi_input {
+	CSI_INPUT_RAW	= 0,
+	CSI_INPUT_BT656	= 2,
+	CSI_INPUT_YUV	= 3,
+};
+
+enum csi_output_raw {
+	CSI_OUTPUT_RAW_PASSTHROUGH = 0,
+};
+
+enum csi_output_yuv {
+	CSI_OUTPUT_YUV_422_PLANAR	= 0,
+	CSI_OUTPUT_YUV_420_PLANAR	= 1,
+	CSI_OUTPUT_YUV_422_UV		= 4,
+	CSI_OUTPUT_YUV_420_UV		= 5,
+	CSI_OUTPUT_YUV_422_MACRO	= 8,
+	CSI_OUTPUT_YUV_420_MACRO	= 9,
+};
+
+enum csi_yuv_data_seq {
+	CSI_YUV_DATA_SEQ_YUYV	= 0,
+	CSI_YUV_DATA_SEQ_YVYU	= 1,
+	CSI_YUV_DATA_SEQ_UYVY	= 2,
+	CSI_YUV_DATA_SEQ_VYUY	= 3,
+};
+
+enum csi_subdev_pads {
+	CSI_SUBDEV_SINK,
+	CSI_SUBDEV_SOURCE,
+
+	CSI_SUBDEV_PADS,
+};
+
+extern const struct v4l2_subdev_ops sun4i_csi_subdev_ops;
+
+struct sun4i_csi_format {
+	u32			mbus;
+	u32			fourcc;
+	enum csi_input		input;
+	u32			output;
+	unsigned int		num_planes;
+	u8			bpp[3];
+	unsigned int		hsub;
+	unsigned int		vsub;
+};
+
+const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc,
+						     const u32 *mbus);
+
+struct sun4i_csi {
+	/* Device resources */
+	struct device			*dev;
+
+	void __iomem			*regs;
+	struct clk			*bus_clk;
+	struct clk			*isp_clk;
+	struct clk			*ram_clk;
+	struct reset_control		*rst;
+
+	struct vb2_v4l2_buffer		*current_buf[CSI_MAX_BUFFER];
+
+	struct {
+		size_t			size;
+		void			*vaddr;
+		dma_addr_t		paddr;
+	} scratch;
+
+	struct v4l2_fwnode_bus_parallel	bus;
+
+	/* Main Device */
+	struct v4l2_device		v4l;
+	struct media_device		mdev;
+	struct video_device		vdev;
+	struct media_pad		vdev_pad;
+	struct v4l2_pix_format_mplane	fmt;
+
+	/* Local subdev */
+	struct v4l2_subdev		subdev;
+	struct media_pad		subdev_pads[CSI_SUBDEV_PADS];
+	struct v4l2_mbus_framefmt	subdev_fmt;
+
+	/* V4L2 Async variables */
+	struct v4l2_async_subdev	asd;
+	struct v4l2_async_notifier	notifier;
+	struct v4l2_subdev		*src_subdev;
+	int				src_pad;
+
+	/* V4L2 variables */
+	struct mutex			lock;
+
+	/* Videobuf2 */
+	struct vb2_queue		queue;
+	struct list_head		buf_list;
+	spinlock_t			qlock;
+	unsigned int			sequence;
+};
+
+int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq);
+void sun4i_csi_dma_unregister(struct sun4i_csi *csi);
+
+int sun4i_csi_v4l2_register(struct sun4i_csi *csi);
+
+#endif /* _SUN4I_CSI_H_ */
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
new file mode 100644
index 000000000000..fe1803375dd4
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "sun4i_csi.h"
+
+struct sun4i_csi_buffer {
+	struct vb2_v4l2_buffer	vb;
+	struct list_head	list;
+};
+
+static inline struct sun4i_csi_buffer *
+vb2_v4l2_to_csi_buffer(const struct vb2_v4l2_buffer *p)
+{
+	return container_of(p, struct sun4i_csi_buffer, vb);
+}
+
+static inline struct sun4i_csi_buffer *
+vb2_to_csi_buffer(const struct vb2_buffer *p)
+{
+	return vb2_v4l2_to_csi_buffer(to_vb2_v4l2_buffer(p));
+}
+
+static void sun4i_csi_capture_start(struct sun4i_csi *csi)
+{
+	writel(CSI_CPT_CTRL_VIDEO_START, csi->regs + CSI_CPT_CTRL_REG);
+}
+
+static void sun4i_csi_capture_stop(struct sun4i_csi *csi)
+{
+	writel(0, csi->regs + CSI_CPT_CTRL_REG);
+}
+
+static int sun4i_csi_queue_setup(struct vb2_queue *vq,
+				 unsigned int *nbuffers,
+				 unsigned int *nplanes,
+				 unsigned int sizes[],
+				 struct device *alloc_devs[])
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	unsigned int num_planes = csi->fmt.num_planes;
+	unsigned int i;
+
+	if (*nplanes) {
+		if (*nplanes != num_planes)
+			return -EINVAL;
+
+		for (i = 0; i < num_planes; i++)
+			if (sizes[i] < csi->fmt.plane_fmt[i].sizeimage)
+				return -EINVAL;
+		return 0;
+	}
+
+	*nplanes = num_planes;
+	for (i = 0; i < num_planes; i++)
+		sizes[i] = csi->fmt.plane_fmt[i].sizeimage;
+
+	return 0;
+};
+
+static int sun4i_csi_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned int i;
+
+	for (i = 0; i < csi->fmt.num_planes; i++) {
+		unsigned long size = csi->fmt.plane_fmt[i].sizeimage;
+
+		if (vb2_plane_size(vb, i) < size) {
+			dev_err(csi->dev, "buffer too small (%lu < %lu)\n",
+				vb2_plane_size(vb, i), size);
+			return -EINVAL;
+		}
+
+		vb2_set_plane_payload(vb, i, size);
+	}
+
+	return 0;
+}
+
+static int sun4i_csi_setup_scratch_buffer(struct sun4i_csi *csi, unsigned int slot)
+{
+	dma_addr_t addr = csi->scratch.paddr;
+	unsigned int plane;
+
+	dev_dbg(csi->dev,
+		"No more available buffer, using the scratch buffer\n");
+
+	for (plane = 0; plane < csi->fmt.num_planes; plane++) {
+		writel(addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot));
+		addr += csi->fmt.plane_fmt[plane].sizeimage;
+	}
+
+	csi->current_buf[slot] = NULL;
+	return 0;
+}
+
+static int sun4i_csi_buffer_fill_slot(struct sun4i_csi *csi, unsigned int slot)
+{
+	struct sun4i_csi_buffer *c_buf;
+	struct vb2_v4l2_buffer *v_buf;
+	unsigned int plane;
+
+	/*
+	 * We should never end up in a situation where we overwrite an
+	 * already filled slot.
+	 */
+	if (WARN_ON(csi->current_buf[slot]))
+		return -EINVAL;
+
+	if (list_empty(&csi->buf_list))
+		return sun4i_csi_setup_scratch_buffer(csi, slot);
+
+	c_buf = list_first_entry(&csi->buf_list, struct sun4i_csi_buffer, list);
+	list_del_init(&c_buf->list);
+
+	v_buf = &c_buf->vb;
+	csi->current_buf[slot] = v_buf;
+
+	for (plane = 0; plane < csi->fmt.num_planes; plane++) {
+		dma_addr_t buf_addr;
+
+		buf_addr = vb2_dma_contig_plane_dma_addr(&v_buf->vb2_buf,
+							 plane);
+		writel(buf_addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot));
+	}
+
+	return 0;
+}
+
+static int sun4i_csi_buffer_fill_all(struct sun4i_csi *csi)
+{
+	unsigned int slot;
+	int ret;
+
+	for (slot = 0; slot < CSI_MAX_BUFFER; slot++) {
+		ret = sun4i_csi_buffer_fill_slot(csi, slot);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void sun4i_csi_buffer_mark_done(struct sun4i_csi *csi,
+				       unsigned int slot,
+				       unsigned int sequence)
+{
+	struct vb2_v4l2_buffer *v_buf;
+
+	if (!csi->current_buf[slot]) {
+		dev_dbg(csi->dev, "Scratch buffer was used, ignoring..\n");
+		return;
+	}
+
+	v_buf = csi->current_buf[slot];
+	v_buf->field = csi->fmt.field;
+	v_buf->sequence = sequence;
+	v_buf->vb2_buf.timestamp = ktime_get_ns();
+	vb2_buffer_done(&v_buf->vb2_buf, VB2_BUF_STATE_DONE);
+
+	csi->current_buf[slot] = NULL;
+}
+
+static int sun4i_csi_buffer_flip(struct sun4i_csi *csi, unsigned int sequence)
+{
+	u32 reg = readl(csi->regs + CSI_BUF_CTRL_REG);
+	unsigned int next;
+
+	/* Our next buffer is not the current buffer */
+	next = !(reg & CSI_BUF_CTRL_DBS);
+
+	/* Report the previous buffer as done */
+	sun4i_csi_buffer_mark_done(csi, next, sequence);
+
+	/* Put a new buffer in there */
+	return sun4i_csi_buffer_fill_slot(csi, next);
+}
+
+static void sun4i_csi_buffer_queue(struct vb2_buffer *vb)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue);
+	struct sun4i_csi_buffer *buf = vb2_to_csi_buffer(vb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&csi->qlock, flags);
+	list_add_tail(&buf->list, &csi->buf_list);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+}
+
+static void return_all_buffers(struct sun4i_csi *csi,
+			       enum vb2_buffer_state state)
+{
+	struct sun4i_csi_buffer *buf, *node;
+	unsigned int slot;
+
+	list_for_each_entry_safe(buf, node, &csi->buf_list, list) {
+		vb2_buffer_done(&buf->vb.vb2_buf, state);
+		list_del(&buf->list);
+	}
+
+	for (slot = 0; slot < CSI_MAX_BUFFER; slot++) {
+		struct vb2_v4l2_buffer *v_buf = csi->current_buf[slot];
+
+		if (!v_buf)
+			continue;
+
+		vb2_buffer_done(&v_buf->vb2_buf, state);
+		csi->current_buf[slot] = NULL;
+	}
+}
+
+static int sun4i_csi_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	struct v4l2_fwnode_bus_parallel *bus = &csi->bus;
+	const struct sun4i_csi_format *csi_fmt;
+	unsigned long hsync_pol, pclk_pol, vsync_pol;
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+
+	csi_fmt = sun4i_csi_find_format(&csi->fmt.pixelformat, NULL);
+	if (!csi_fmt)
+		return -EINVAL;
+
+	dev_dbg(csi->dev, "Starting capture\n");
+
+	csi->sequence = 0;
+
+	/*
+	 * We need a scratch buffer in case where we'll not have any
+	 * more buffer queued so that we don't error out. One of those
+	 * cases is when you end up at the last frame to capture, you
+	 * don't havea any buffer queued any more, and yet it doesn't
+	 * really matter since you'll never reach the next buffer.
+	 *
+	 * Since we support the multi-planar API, we need to have a
+	 * buffer for each plane. Allocating a single one large enough
+	 * to hold all the buffers is simpler, so let's go for that.
+	 */
+	csi->scratch.size = 0;
+	for (i = 0; i < csi->fmt.num_planes; i++)
+		csi->scratch.size += csi->fmt.plane_fmt[i].sizeimage;
+
+	csi->scratch.vaddr = dma_alloc_coherent(csi->dev,
+						csi->scratch.size,
+						&csi->scratch.paddr,
+						GFP_KERNEL);
+	if (!csi->scratch.vaddr) {
+		dev_err(csi->dev, "Failed to allocate scratch buffer\n");
+		ret = -ENOMEM;
+		goto err_clear_dma_queue;
+	}
+
+	ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe);
+	if (ret < 0)
+		goto err_free_scratch_buffer;
+
+	spin_lock_irqsave(&csi->qlock, flags);
+
+	/* Setup timings */
+	writel(CSI_WIN_CTRL_W_ACTIVE(csi->fmt.width * 2),
+	       csi->regs + CSI_WIN_CTRL_W_REG);
+	writel(CSI_WIN_CTRL_H_ACTIVE(csi->fmt.height),
+	       csi->regs + CSI_WIN_CTRL_H_REG);
+
+	hsync_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH);
+	pclk_pol = !!(bus->flags & V4L2_MBUS_DATA_ACTIVE_HIGH);
+	vsync_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH);
+	writel(CSI_CFG_INPUT_FMT(csi_fmt->input) |
+	       CSI_CFG_OUTPUT_FMT(csi_fmt->output) |
+	       CSI_CFG_VSYNC_POL(vsync_pol) |
+	       CSI_CFG_HSYNC_POL(hsync_pol) |
+	       CSI_CFG_PCLK_POL(pclk_pol),
+	       csi->regs + CSI_CFG_REG);
+
+	/* Setup buffer length */
+	writel(csi->fmt.plane_fmt[0].bytesperline,
+	       csi->regs + CSI_BUF_LEN_REG);
+
+	/* Prepare our buffers in hardware */
+	ret = sun4i_csi_buffer_fill_all(csi);
+	if (ret) {
+		spin_unlock_irqrestore(&csi->qlock, flags);
+		goto err_disable_pipeline;
+	}
+
+	/* Enable double buffering */
+	writel(CSI_BUF_CTRL_DBE, csi->regs + CSI_BUF_CTRL_REG);
+
+	/* Clear the pending interrupts */
+	writel(CSI_INT_FRM_DONE, csi->regs + 0x34);
+
+	/* Enable frame done interrupt */
+	writel(CSI_INT_FRM_DONE, csi->regs + CSI_INT_EN_REG);
+
+	sun4i_csi_capture_start(csi);
+
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	ret = v4l2_subdev_call(csi->src_subdev, video, s_stream, 1);
+	if (ret < 0 && ret != -ENOIOCTLCMD)
+		goto err_disable_device;
+
+	return 0;
+
+err_disable_device:
+	sun4i_csi_capture_stop(csi);
+
+err_disable_pipeline:
+	media_pipeline_stop(&csi->vdev.entity);
+
+err_free_scratch_buffer:
+	dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr,
+			  csi->scratch.paddr);
+
+err_clear_dma_queue:
+	spin_lock_irqsave(&csi->qlock, flags);
+	return_all_buffers(csi, VB2_BUF_STATE_QUEUED);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	return ret;
+}
+
+static void sun4i_csi_stop_streaming(struct vb2_queue *vq)
+{
+	struct sun4i_csi *csi = vb2_get_drv_priv(vq);
+	unsigned long flags;
+
+	dev_dbg(csi->dev, "Stopping capture\n");
+
+	v4l2_subdev_call(csi->src_subdev, video, s_stream, 0);
+	sun4i_csi_capture_stop(csi);
+
+	/* Release all active buffers */
+	spin_lock_irqsave(&csi->qlock, flags);
+	return_all_buffers(csi, VB2_BUF_STATE_ERROR);
+	spin_unlock_irqrestore(&csi->qlock, flags);
+
+	media_pipeline_stop(&csi->vdev.entity);
+
+	dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr,
+			  csi->scratch.paddr);
+}
+
+static const struct vb2_ops sun4i_csi_qops = {
+	.queue_setup		= sun4i_csi_queue_setup,
+	.buf_prepare		= sun4i_csi_buffer_prepare,
+	.buf_queue		= sun4i_csi_buffer_queue,
+	.start_streaming	= sun4i_csi_start_streaming,
+	.stop_streaming		= sun4i_csi_stop_streaming,
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+};
+
+static irqreturn_t sun4i_csi_irq(int irq, void *data)
+{
+	struct sun4i_csi *csi = data;
+	u32 reg;
+
+	reg = readl(csi->regs + CSI_INT_STA_REG);
+
+	/* Acknowledge the interrupts */
+	writel(reg, csi->regs + CSI_INT_STA_REG);
+
+	if (!(reg & CSI_INT_FRM_DONE))
+		return IRQ_HANDLED;
+
+	spin_lock(&csi->qlock);
+	if (sun4i_csi_buffer_flip(csi, csi->sequence++)) {
+		dev_warn(csi->dev, "%s: Flip failed\n", __func__);
+		sun4i_csi_capture_stop(csi);
+	}
+	spin_unlock(&csi->qlock);
+
+	return IRQ_HANDLED;
+}
+
+int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq)
+{
+	struct vb2_queue *q = &csi->queue;
+	int ret;
+	int i;
+
+	spin_lock_init(&csi->qlock);
+	mutex_init(&csi->lock);
+
+	INIT_LIST_HEAD(&csi->buf_list);
+	for (i = 0; i < CSI_MAX_BUFFER; i++)
+		csi->current_buf[i] = NULL;
+
+	q->min_buffers_needed = 3;
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	q->io_modes = VB2_MMAP;
+	q->lock = &csi->lock;
+	q->drv_priv = csi;
+	q->buf_struct_size = sizeof(struct sun4i_csi_buffer);
+	q->ops = &sun4i_csi_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->dev = csi->dev;
+
+	ret = vb2_queue_init(q);
+	if (ret < 0) {
+		dev_err(csi->dev, "failed to initialize VB2 queue\n");
+		goto err_free_mutex;
+	}
+
+	ret = v4l2_device_register(csi->dev, &csi->v4l);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register the v4l2 device\n");
+		goto err_free_queue;
+	}
+
+	ret = devm_request_irq(csi->dev, irq, sun4i_csi_irq, 0,
+			       dev_name(csi->dev), csi);
+	if (ret) {
+		dev_err(csi->dev, "Couldn't register our interrupt\n");
+		goto err_unregister_device;
+	}
+
+	return 0;
+
+err_unregister_device:
+	v4l2_device_unregister(&csi->v4l);
+
+err_free_queue:
+	vb2_queue_release(q);
+
+err_free_mutex:
+	mutex_destroy(&csi->lock);
+	return ret;
+}
+
+void sun4i_csi_dma_unregister(struct sun4i_csi *csi)
+{
+	v4l2_device_unregister(&csi->v4l);
+	vb2_queue_release(&csi->queue);
+	mutex_destroy(&csi->lock);
+}
diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c
new file mode 100644
index 000000000000..d52b6fe68a09
--- /dev/null
+++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 NextThing Co
+ * Copyright (C) 2016-2019 Bootlin
+ *
+ * Author: Maxime Ripard <maxime.ripard@bootlin.com>
+ */
+
+#include <linux/device.h>
+#include <linux/pm_runtime.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-mc.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "sun4i_csi.h"
+
+#define CSI_DEFAULT_WIDTH	640
+#define CSI_DEFAULT_HEIGHT	480
+
+const struct sun4i_csi_format sun4i_csi_formats[] = {
+	/* YUV422 inputs */
+	{
+		.mbus		= MEDIA_BUS_FMT_YUYV8_2X8,
+		.fourcc		= V4L2_PIX_FMT_YUV420M,
+		.input		= CSI_INPUT_YUV,
+		.output		= CSI_OUTPUT_YUV_420_PLANAR,
+		.num_planes	= 3,
+		.bpp		= { 8, 8, 8 },
+		.hsub		= 2,
+		.vsub		= 2,
+	},
+};
+
+const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc,
+						     const u32 *mbus)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(sun4i_csi_formats); i++) {
+		if (fourcc && *fourcc != sun4i_csi_formats[i].fourcc)
+			continue;
+
+		if (mbus && *mbus != sun4i_csi_formats[i].mbus)
+			continue;
+
+		return &sun4i_csi_formats[i];
+	}
+
+	return NULL;
+}
+
+static int sun4i_csi_querycap(struct file *file, void *priv,
+			      struct v4l2_capability *cap)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
+	strscpy(cap->card, "sun4i-csi", sizeof(cap->card));
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+		 dev_name(csi->dev));
+
+	return 0;
+}
+
+static int sun4i_csi_enum_input(struct file *file, void *priv,
+				struct v4l2_input *inp)
+{
+	if (inp->index != 0)
+		return -EINVAL;
+
+	inp->type = V4L2_INPUT_TYPE_CAMERA;
+	strscpy(inp->name, "Camera", sizeof(inp->name));
+
+	return 0;
+}
+
+static int sun4i_csi_g_input(struct file *file, void *fh,
+			     unsigned int *i)
+{
+	*i = 0;
+
+	return 0;
+}
+
+static int sun4i_csi_s_input(struct file *file, void *fh,
+			     unsigned int i)
+{
+	if (i != 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void _sun4i_csi_try_fmt(struct sun4i_csi *csi,
+			       struct v4l2_pix_format_mplane *pix)
+{
+	const struct sun4i_csi_format *_fmt;
+	unsigned int height, width;
+	unsigned int i;
+
+	_fmt = sun4i_csi_find_format(&pix->pixelformat, NULL);
+	if (!_fmt)
+		_fmt = &sun4i_csi_formats[0];
+
+	pix->field = V4L2_FIELD_NONE;
+	pix->colorspace = V4L2_COLORSPACE_SRGB;
+	pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace);
+	pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace);
+	pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace,
+							  pix->ycbcr_enc);
+
+	pix->num_planes = _fmt->num_planes;
+	pix->pixelformat = _fmt->fourcc;
+
+	memset(pix->reserved, 0, sizeof(pix->reserved));
+
+	/* Align the width and height on the subsampling */
+	width = ALIGN(pix->width, _fmt->hsub);
+	height = ALIGN(pix->height, _fmt->vsub);
+
+	/* Clamp the width and height to our capabilities */
+	pix->width = clamp(width, _fmt->hsub, CSI_MAX_WIDTH);
+	pix->height = clamp(height, _fmt->vsub, CSI_MAX_HEIGHT);
+
+	for (i = 0; i < _fmt->num_planes; i++) {
+		unsigned int hsub = i > 0 ? _fmt->hsub : 1;
+		unsigned int vsub = i > 0 ? _fmt->vsub : 1;
+		unsigned int bpl;
+
+		bpl = pix->width / hsub * _fmt->bpp[i] / 8;
+		pix->plane_fmt[i].bytesperline = bpl;
+		pix->plane_fmt[i].sizeimage = bpl * pix->height / vsub;
+		memset(pix->plane_fmt[i].reserved, 0,
+		       sizeof(pix->plane_fmt[i].reserved));
+	}
+}
+
+static int sun4i_csi_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	_sun4i_csi_try_fmt(csi, &f->fmt.pix_mp);
+
+	return 0;
+}
+
+static int sun4i_csi_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	_sun4i_csi_try_fmt(csi, &f->fmt.pix_mp);
+	csi->fmt = f->fmt.pix_mp;
+
+	return 0;
+}
+
+static int sun4i_csi_g_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	f->fmt.pix_mp = csi->fmt;
+
+	return 0;
+}
+
+static int sun4i_csi_enum_fmt_vid_cap(struct file *file, void *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	if (f->index >= ARRAY_SIZE(sun4i_csi_formats))
+		return -EINVAL;
+
+	f->pixelformat = sun4i_csi_formats[f->index].fourcc;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops sun4i_csi_ioctl_ops = {
+	.vidioc_querycap		= sun4i_csi_querycap,
+
+	.vidioc_enum_fmt_vid_cap	= sun4i_csi_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap_mplane	= sun4i_csi_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap_mplane	= sun4i_csi_s_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap_mplane	= sun4i_csi_try_fmt_vid_cap,
+
+	.vidioc_enum_input		= sun4i_csi_enum_input,
+	.vidioc_g_input			= sun4i_csi_g_input,
+	.vidioc_s_input			= sun4i_csi_s_input,
+
+	.vidioc_reqbufs			= vb2_ioctl_reqbufs,
+	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
+	.vidioc_querybuf		= vb2_ioctl_querybuf,
+	.vidioc_qbuf			= vb2_ioctl_qbuf,
+	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
+	.vidioc_expbuf			= vb2_ioctl_expbuf,
+	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
+	.vidioc_streamon		= vb2_ioctl_streamon,
+	.vidioc_streamoff		= vb2_ioctl_streamoff,
+};
+
+static int sun4i_csi_open(struct file *file)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+	int ret;
+
+	ret = mutex_lock_interruptible(&csi->lock);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_get_sync(csi->dev);
+	if (ret < 0)
+		goto err_pm_put;
+
+	ret = v4l2_pipeline_pm_use(&csi->vdev.entity, 1);
+	if (ret)
+		goto err_pm_put;
+
+	ret = v4l2_fh_open(file);
+	if (ret)
+		goto err_pipeline_pm_put;
+
+	mutex_unlock(&csi->lock);
+
+	return 0;
+
+err_pipeline_pm_put:
+	v4l2_pipeline_pm_use(&csi->vdev.entity, 0);
+
+err_pm_put:
+	pm_runtime_put(csi->dev);
+	mutex_unlock(&csi->lock);
+
+	return ret;
+}
+
+static int sun4i_csi_release(struct file *file)
+{
+	struct sun4i_csi *csi = video_drvdata(file);
+
+	mutex_lock(&csi->lock);
+
+	v4l2_fh_release(file);
+	v4l2_pipeline_pm_use(&csi->vdev.entity, 0);
+	pm_runtime_put(csi->dev);
+
+	mutex_unlock(&csi->lock);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations sun4i_csi_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sun4i_csi_open,
+	.release	= sun4i_csi_release,
+	.unlocked_ioctl	= video_ioctl2,
+	.read		= vb2_fop_read,
+	.write		= vb2_fop_write,
+	.poll		= vb2_fop_poll,
+	.mmap		= vb2_fop_mmap,
+};
+
+static const struct v4l2_mbus_framefmt sun4i_csi_pad_fmt_default = {
+	.width = CSI_DEFAULT_WIDTH,
+	.height = CSI_DEFAULT_HEIGHT,
+	.code = sun4i_csi_formats[0].mbus,
+	.field = V4L2_FIELD_NONE,
+	.colorspace = V4L2_COLORSPACE_RAW,
+	.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+	.quantization = V4L2_QUANTIZATION_DEFAULT,
+	.xfer_func = V4L2_XFER_FUNC_DEFAULT,
+};
+
+static int sun4i_csi_subdev_init_cfg(struct v4l2_subdev *subdev,
+				     struct v4l2_subdev_pad_config *cfg)
+{
+	struct v4l2_mbus_framefmt *fmt;
+
+	fmt = v4l2_subdev_get_try_format(subdev, cfg, CSI_SUBDEV_SINK);
+	*fmt = sun4i_csi_pad_fmt_default;
+
+	return 0;
+}
+
+static int sun4i_csi_subdev_get_fmt(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_format *fmt)
+{
+	struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev);
+	struct v4l2_mbus_framefmt *subdev_fmt;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad);
+	else
+		subdev_fmt = &csi->subdev_fmt;
+
+	fmt->format = *subdev_fmt;
+
+	return 0;
+}
+
+static int sun4i_csi_subdev_set_fmt(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_pad_config *cfg,
+				    struct v4l2_subdev_format *fmt)
+{
+	struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev);
+	struct v4l2_mbus_framefmt *subdev_fmt;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad);
+	else
+		subdev_fmt = &csi->subdev_fmt;
+
+	/* We can only set the format on the sink pad */
+	if (fmt->pad == CSI_SUBDEV_SINK) {
+		/* It's the sink, only allow changing the frame size */
+		subdev_fmt->width = fmt->format.width;
+		subdev_fmt->height = fmt->format.height;
+		subdev_fmt->code = fmt->format.code;
+	}
+
+	fmt->format = *subdev_fmt;
+
+	return 0;
+}
+
+static int
+sun4i_csi_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_pad_config *cfg,
+				struct v4l2_subdev_mbus_code_enum *mbus)
+{
+	if (mbus->index >= ARRAY_SIZE(sun4i_csi_formats))
+		return -EINVAL;
+
+	mbus->code = sun4i_csi_formats[mbus->index].mbus;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops sun4i_csi_subdev_pad_ops = {
+	.link_validate	= v4l2_subdev_link_validate_default,
+	.init_cfg	= sun4i_csi_subdev_init_cfg,
+	.get_fmt	= sun4i_csi_subdev_get_fmt,
+	.set_fmt	= sun4i_csi_subdev_set_fmt,
+	.enum_mbus_code	= sun4i_csi_subdev_enum_mbus_code,
+};
+
+const struct v4l2_subdev_ops sun4i_csi_subdev_ops = {
+	.pad = &sun4i_csi_subdev_pad_ops,
+};
+
+int sun4i_csi_v4l2_register(struct sun4i_csi *csi)
+{
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
+	vdev->v4l2_dev = &csi->v4l;
+	vdev->queue = &csi->queue;
+	strscpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
+	vdev->release = video_device_release_empty;
+	vdev->lock = &csi->lock;
+
+	/* Set a default format */
+	csi->fmt.pixelformat = sun4i_csi_formats[0].fourcc,
+	csi->fmt.width = CSI_DEFAULT_WIDTH;
+	csi->fmt.height = CSI_DEFAULT_HEIGHT;
+	_sun4i_csi_try_fmt(csi, &csi->fmt);
+	csi->subdev_fmt = sun4i_csi_pad_fmt_default;
+
+	vdev->fops = &sun4i_csi_fops;
+	vdev->ioctl_ops = &sun4i_csi_ioctl_ops;
+	video_set_drvdata(vdev, csi);
+
+	ret = video_register_device(&csi->vdev, VFL_TYPE_GRABBER, -1);
+	if (ret)
+		return ret;
+
+	dev_info(csi->dev, "Device registered as %s\n",
+		 video_device_node_name(vdev));
+
+	return 0;
+}
-- 
git-series 0.9.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 v8 2/5] media: sunxi: Refactor the Makefile and Kconfig
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel,
	Chen-Yu Tsai, Rob Herring, Laurent Pinchart, Thomas Petazzoni,
	Frank Rowand, linux-arm-kernel, linux-media
In-Reply-To: <cover.85d78dd1a3b44fe4cde1b65a9b1eb3b95daea7cc.1566462064.git-series.maxime.ripard@bootlin.com>

From: Maxime Ripard <maxime.ripard@bootlin.com>

The Makefile and Kconfig for the sun6i CSI driver are included in the main
Makefile / KConfig file. Since we're going to add a new CSI driver for an
older chip, and the Cedrus driver eventually, it makes more sense to put
those in our directory.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/media/platform/Kconfig        | 2 +-
 drivers/media/platform/Makefile       | 2 +-
 drivers/media/platform/sunxi/Kconfig  | 1 +
 drivers/media/platform/sunxi/Makefile | 1 +
 4 files changed, 4 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/platform/sunxi/Kconfig
 create mode 100644 drivers/media/platform/sunxi/Makefile

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 89555f9a813f..2fda8036d11d 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -146,7 +146,7 @@ source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 source "drivers/media/platform/rcar-vin/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
-source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
+source "drivers/media/platform/sunxi/Kconfig"
 
 config VIDEO_TI_CAL
 	tristate "TI CAL (Camera Adaptation Layer) driver"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 7cbbd925124c..6ee7eb0d36f4 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -100,4 +100,4 @@ obj-y					+= meson/
 
 obj-y					+= cros-ec-cec/
 
-obj-$(CONFIG_VIDEO_SUN6I_CSI)		+= sunxi/sun6i-csi/
+obj-y					+= sunxi/
diff --git a/drivers/media/platform/sunxi/Kconfig b/drivers/media/platform/sunxi/Kconfig
new file mode 100644
index 000000000000..1b6e89cb78b2
--- /dev/null
+++ b/drivers/media/platform/sunxi/Kconfig
@@ -0,0 +1 @@
+source "drivers/media/platform/sunxi/sun6i-csi/Kconfig"
diff --git a/drivers/media/platform/sunxi/Makefile b/drivers/media/platform/sunxi/Makefile
new file mode 100644
index 000000000000..8d06f98500ee
--- /dev/null
+++ b/drivers/media/platform/sunxi/Makefile
@@ -0,0 +1 @@
+obj-y		+= sun6i-csi/
-- 
git-series 0.9.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 v8 1/5] dt-bindings: media: Add Allwinner A10 CSI binding
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Rob Herring, Maxime Ripard,
	linux-kernel, Chen-Yu Tsai, Rob Herring, Laurent Pinchart,
	Thomas Petazzoni, Frank Rowand, linux-arm-kernel, linux-media
In-Reply-To: <cover.85d78dd1a3b44fe4cde1b65a9b1eb3b95daea7cc.1566462064.git-series.maxime.ripard@bootlin.com>

From: Maxime Ripard <maxime.ripard@bootlin.com>

The Allwinner A10 CMOS Sensor Interface is a camera capture interface also
used in later (A10s, A13, A20, R8 and GR8) SoCs.

On some SoCs, like the A10, there's multiple instances of that controller,
with one instance supporting more channels and having an ISP.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 MAINTAINERS                                                          |   7 +++++-
 2 files changed, 114 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml

diff --git a/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
new file mode 100644
index 000000000000..c994a4092a4f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/allwinner,sun4i-a10-csi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 CMOS Sensor Interface (CSI) Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+description: |-
+  The Allwinner A10 and later has a CMOS Sensor Interface to retrieve
+  frames from a parallel or BT656 sensor.
+
+properties:
+  compatible:
+    const: allwinner,sun7i-a20-csi0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: The CSI interface clock
+      - description: The CSI module clock
+      - description: The CSI ISP clock
+      - description: The CSI DRAM clock
+
+  clock-names:
+    items:
+      - const: bus
+      - const: mod
+      - const: isp
+      - const: ram
+
+  resets:
+    maxItems: 1
+
+  # See ./video-interfaces.txt for details
+  port:
+    type: object
+    additionalProperties: false
+
+    properties:
+      endpoint:
+        properties:
+          bus-width:
+            enum: [8, 16]
+
+          data-active: true
+          hsync-active: true
+          pclk-sample: true
+          remote-endpoint: true
+          vsync-active: true
+
+        required:
+          - bus-width
+          - data-active
+          - hsync-active
+          - pclk-sample
+          - remote-endpoint
+          - vsync-active
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/sun7i-a20-ccu.h>
+    #include <dt-bindings/reset/sun4i-a10-ccu.h>
+
+    csi0: csi@1c09000 {
+        compatible = "allwinner,sun7i-a20-csi0";
+        reg = <0x01c09000 0x1000>;
+        interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>,
+                 <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>;
+        clock-names = "bus", "mod", "isp", "ram";
+        resets = <&ccu RST_CSI0>;
+
+        port {
+            csi_from_ov5640: endpoint {
+                remote-endpoint = <&ov5640_to_csi>;
+                bus-width = <8>;
+                hsync-active = <1>; /* Active high */
+                vsync-active = <0>; /* Active low */
+                data-active = <1>;  /* Active high */
+                pclk-sample = <1>;  /* Rising */
+            };
+        };
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 30bf852e6d6b..65af586defcc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1420,6 +1420,13 @@ F:	drivers/pinctrl/sunxi/
 F:	drivers/soc/sunxi/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git
 
+Allwinner A10 CSI driver
+M:	Maxime Ripard <mripard@kernel.org>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+F:	Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
+S:	Maintained
+
 ARM/Amlogic Meson SoC CLOCK FRAMEWORK
 M:	Neil Armstrong <narmstrong@baylibre.com>
 M:	Jerome Brunet <jbrunet@baylibre.com>
-- 
git-series 0.9.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 v8 0/5] media: Allwinner A10 CSI support
From: Maxime Ripard @ 2019-08-22  8:21 UTC (permalink / raw)
  To: Hans Verkuil, Sakari Ailus, Mauro Carvalho Chehab
  Cc: Mark Rutland, devicetree, Maxime Ripard, linux-kernel,
	Chen-Yu Tsai, Rob Herring, Laurent Pinchart, Thomas Petazzoni,
	Frank Rowand, linux-arm-kernel, linux-media

From: Maxime Ripard <maxime.ripard@bootlin.com>

Hi,

Here is a series introducing the support for the A10 (and SoCs of the same
generation) CMOS Sensor Interface (called CSI, not to be confused with
MIPI-CSI, which isn't support by that IP).

That interface is pretty straightforward, but the driver has a few issues
that I wanted to bring up:

  * The only board I've been testing this with has an ov5640 sensor
    attached, which doesn't work with the upstream driver. Copying the
    Allwinner init sequence works though, and this is how it has been
    tested. Testing with a second sensor would allow to see if it's an
    issue on the CSI side or the sensor side.
  * We don't have support for the ISP at the moment, but this can be added
    eventually.

Here is the v4l2-compliance output (commit f61132e81d79 of v4l-utils)
v4l2-compliance SHA: not available, 32 bits

Compliance test for device /dev/video1:

Driver Info:
	Driver name      : sun4i_csi
	Card type        : sun4i-csi
	Bus info         : platform:1c09000.csi
	Driver version   : 5.3.0
	Capabilities     : 0x84201000
		Video Capture Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04201000
		Video Capture Multiplanar
		Streaming
		Extended Pix Format
Media Driver Info:
	Driver name      : sun4i-csi
	Model            : Allwinner Video Capture Device
	Serial           :
	Bus info         :
	Media version    : 5.3.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.3.0
Interface Info:
	ID               : 0x03000008
	Type             : V4L Video
Entity Info:
	ID               : 0x00000006 (6)
	Name             : sun4i_csi
	Function         : V4L2 I/O
	Pad 0x01000007   : 0: Sink, Must Connect
	  Link 0x0200000a: from remote pad 0x1000005 of entity 'sun4i-csi-0': Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK

Allow for multiple opens:
	test second /dev/video1 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 1 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls (Input 0):
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
	test VIDIOC_QUERYCTRL: OK (Not Supported)
	test VIDIOC_G/S_CTRL: OK (Not Supported)
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 0 Private Controls: 0

Format ioctls (Input 0):
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK (Not Supported)
	test Scaling: OK

Codec ioctls (Input 0):
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls (Input 0):
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK

Test input 0:

Streaming ioctls:
	test read/write: OK (Not Supported)
	test blocking wait: OK
	test MMAP: OK
	test USERPTR: OK (Not Supported)
	test DMABUF: OK (Not Supported)

Total: 49, Succeeded: 49, Failed: 0, Warnings: 0

media-ctl -p -d /dev/media1 output after boot:
Media controller API version 5.3.0

Media device information
------------------------
driver          sun4i-csi
model           Allwinner Video Capture Device
serial
bus info
hw revision     0x0
driver version  5.3.0

Device topology
- entity 1: ov5640 1-0021 (1 pad, 1 link)
            type V4L2 subdev subtype Sensor flags 0
            device node name /dev/v4l-subdev0
	pad0: Source
		[fmt:YUYV8_2X8/640x480@1/30 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
		-> "sun4i-csi-0":0 [ENABLED,IMMUTABLE]

- entity 3: sun4i-csi-0 (2 pads, 2 links)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev1
	pad0: Sink
		[fmt:YUYV8_2X8/640x480 field:none colorspace:raw]
		<- "ov5640 1-0021":0 [ENABLED,IMMUTABLE]
	pad1: Source
		[fmt:YUYV8_2X8/640x480 field:none colorspace:raw]
		-> "sun4i_csi":0 [ENABLED,IMMUTABLE]

- entity 6: sun4i_csi (1 pad, 1 link)
            type Node subtype V4L flags 0
            device node name /dev/video1
	pad0: Sink
		<- "sun4i-csi-0":1 [ENABLED,IMMUTABLE]

Let me know what you think,
Maxime

Changes from v7:
  - Add a comment refering to video-interfaces.txt to the binding
  - Rework the error path of registration
  - Fix 80 chars issue on a function
  - Add the 16bits width option to the dt binding
  - Remove out label in the interrupt handler and just return
  - Just compute the next buffer in buffer_flip, instead of going through
    the current buffer.
  - Fix indentation
  - Convert to v4l2_fwnode_endpoint_parse /
    v4l2_async_notifier_add_fwnode_remote_subdev

Changes from v6:
  - Add init_cfg callback on the pads
  - Use v4l2_subdev_link_validate instead of hand-rolled link validate
  - Make sun4i_csi_qops const
  - Add MODULE_DESCRIPTION, MODULE_AUTHOR and MODULE_LICENSE
  - Remove the mod clock handling from the CSI driver
  - Remove the A10 compatible fallback
  - Rework the CSI pinctrl groups
  - Add an example to the binding

Changes from v5:
  - Add link_validate/get_fmt/set_fmt/enum_mbus_code to the subdevice
  - Create a device file for the subdevice
  - Add link_validate to the video device
  - Remove the storage of both the v4l2_pix_format_mplane structure and the
    sun4i_csi_format structure, since the latter can be retrieved easily
    from the former, and this is actually needed in a single place.
  - Fix the copyright year notice

Changes from v4:
  - Created an intermediate sub-device

Changes from v3:
  - Rebased on v5.1-rc
  - Fixed the YAML binding according to Rob's review

Changes from v2:
  - Address a few minors comments on the error path, the return type of
    some functions, the type of some variables
  - Disable the device if the subdev call fails in start_streaming
  - Use __maybe_unused and SET_RUNTIME_PM_OPS for the runtime PM hooks
  - Call media_device_cleanup in the remove function
  - Add a dependency on the subdev API and the common clock framework
  - Fix the MAINTAINERS entry to point to the yaml file
  - Add the of graph bindings to the YAML schemas
  - Rebase on next

Changes from v1:
  - Make sure it's compliant with a much newer v4l2-compliance
  - Conversion of the DT bindings to a JSON schema
  - Drop the vendor properties and use a separate compatible instead
  - Fix an issue on the last frame where we would not have any buffer
    queued and would report an error by using a scratch buffer
  - Fix the warnings reported by v4l2-compliance
  - Rebase on top of 5.0-rc1
  - Added a MAINTAINERS entry
  - Switched to strscpy
  - Fixed SPDX header

Maxime Ripard (5):
  dt-bindings: media: Add Allwinner A10 CSI binding
  media: sunxi: Refactor the Makefile and Kconfig
  media: sunxi: Add A10 CSI driver
  ARM: dts: sun7i: Add CSI0 controller
  DO NOT MERGE: ARM: dts: bananapi: Add Camera support

 Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml | 107 +++++++++++++++++-
 MAINTAINERS                                                          |   8 +-
 arch/arm/boot/dts/sun7i-a20-bananapi.dts                             |  87 ++++++++++++++-
 arch/arm/boot/dts/sun7i-a20.dtsi                                     |  25 ++++-
 drivers/media/platform/Kconfig                                       |   2 +-
 drivers/media/platform/Makefile                                      |   2 +-
 drivers/media/platform/sunxi/Kconfig                                 |   2 +-
 drivers/media/platform/sunxi/Makefile                                |   2 +-
 drivers/media/platform/sunxi/sun4i-csi/Kconfig                       |  11 ++-
 drivers/media/platform/sunxi/sun4i-csi/Makefile                      |   5 +-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c                   | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h                   | 160 +++++++++++++++++++++++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c                   | 453 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c                  | 385 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 14 files changed, 1559 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/allwinner,sun4i-a10-csi.yaml
 create mode 100644 drivers/media/platform/sunxi/Kconfig
 create mode 100644 drivers/media/platform/sunxi/Makefile
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/Kconfig
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/Makefile
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c
 create mode 100644 drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c

base-commit: 85b8819be27eab140d280bbee4f01385beb11e7d
-- 
git-series 0.9.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: [PATCH] clk: imx: pll14xx: avoid glitch when set rate
From: Leonard Crestez @ 2019-08-22  8:20 UTC (permalink / raw)
  To: Peng Fan, sboyd@kernel.org, Jacky Bai
  Cc: Abel Vesa, Anson Huang, shawnguo@kernel.org,
	mturquette@baylibre.com, linux-kernel@vger.kernel.org,
	linux-clk@vger.kernel.org, dl-linux-imx, kernel@pengutronix.de,
	festevam@gmail.com, s.hauer@pengutronix.de,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <1566266337-21597-1-git-send-email-peng.fan@nxp.com>

On 20.08.2019 05:17, Peng Fan wrote:
> According to PLL1443XA and PLL1416X spec,
> "When BYPASS is 0 and RESETB is changed from 0 to 1, FOUT starts to
> output unstable clock until lock time passes. PLL1416X/PLL1443XA may
> generate a glitch at FOUT."
> 
> So set BYPASS when RESETB is changed from 0 to 1 to avoid glitch.
> In the end of set rate, BYPASS will be cleared.
> 
> @@ -191,6 +191,10 @@ static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate,
>   	tmp &= ~RST_MASK;
>   	writel_relaxed(tmp, pll->base);
>   
> +	/* Enable BYPASS */
> +	tmp |= BYPASS_MASK;
> +	writel(tmp, pll->base);
> +

Shouldn't BYPASS be set before reset?

Also, isn't a similar bypass/unbypass dance also needed in 
clk_pll14xx_prepare? As far as I understand that could also output 
glitches until the PLL is locked. It could be a separate patch.

It's strange that this BYPASS bit is also handled by muxes like 
audio_pll1_bypass in clk-imx8mm.c but that's a separate issue not 
strictly related to the glitches you're trying to fix here.

--
Regards,
Leonard

_______________________________________________
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/4] misc: xilinx_sdfec: Prevent a divide by zero in xsdfec_reg0_write()
From: Michal Simek @ 2019-08-22  8:18 UTC (permalink / raw)
  To: Dan Carpenter, Derek Kiernan, Dragan Cvetic
  Cc: Arnd Bergmann, Greg Kroah-Hartman, kernel-janitors, Michal Simek,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20190821070953.GC26957@mwanda>

On 21. 08. 19 9:09, Dan Carpenter wrote:
> The "psize" value comes from the user so we need to verify that it's
> non-zero before we check if "n % psize" or it will crash.
> 
> Fixes: 20ec628e8007 ("misc: xilinx_sdfec: Add ability to configure LDPC")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> The parentheses in this condition are a no-op.  They're just confusing.
> Perhaps something else was intended?
> 
>  drivers/misc/xilinx_sdfec.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
> index 813b82c59360..3fc53d20abf3 100644
> --- a/drivers/misc/xilinx_sdfec.c
> +++ b/drivers/misc/xilinx_sdfec.c
> @@ -460,7 +460,7 @@ static int xsdfec_reg0_write(struct xsdfec_dev *xsdfec, u32 n, u32 k, u32 psize,
>  {
>  	u32 wdata;
>  
> -	if (n < XSDFEC_REG0_N_MIN || n > XSDFEC_REG0_N_MAX ||
> +	if (n < XSDFEC_REG0_N_MIN || n > XSDFEC_REG0_N_MAX || psize == 0 ||
>  	    (n > XSDFEC_REG0_N_MUL_P * psize) || n <= k || ((n % psize) != 0)) {
>  		dev_dbg(xsdfec->dev, "N value is not in range");
>  		return -EINVAL;
> 

Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

_______________________________________________
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/4] misc: xilinx_sdfec: Return -EFAULT if copy_from_user() fails
From: Michal Simek @ 2019-08-22  8:16 UTC (permalink / raw)
  To: Dan Carpenter, Derek Kiernan, Dragan Cvetic
  Cc: Arnd Bergmann, Greg Kroah-Hartman, kernel-janitors, Michal Simek,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20190821070702.GB26957@mwanda>

On 21. 08. 19 9:07, Dan Carpenter wrote:
> The copy_from_user() funciton returns the number of bytes remaining to

typo here.

> be copied but we want to return -EFAULT to the user.
> 
> Fixes: 20ec628e8007 ("misc: xilinx_sdfec: Add ability to configure LDPC")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
>  drivers/misc/xilinx_sdfec.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
> index dc1b8b412712..813b82c59360 100644
> --- a/drivers/misc/xilinx_sdfec.c
> +++ b/drivers/misc/xilinx_sdfec.c
> @@ -651,9 +651,10 @@ static int xsdfec_add_ldpc(struct xsdfec_dev *xsdfec, void __user *arg)
>  	if (!ldpc)
>  		return -ENOMEM;
>  
> -	ret = copy_from_user(ldpc, arg, sizeof(*ldpc));
> -	if (ret)
> +	if (copy_from_user(ldpc, arg, sizeof(*ldpc))) {
> +		ret = -EFAULT;
>  		goto err_out;
> +	}
>  
>  	if (xsdfec->config.code == XSDFEC_TURBO_CODE) {
>  		ret = -EIO;
> 

When typo fixed feel free to add my
Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

_______________________________________________
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 1/4] misc: xilinx_sdfec: Fix a couple small information leaks
From: Michal Simek @ 2019-08-22  8:14 UTC (permalink / raw)
  To: Dan Carpenter, Derek Kiernan, Dragan Cvetic
  Cc: Arnd Bergmann, Greg Kroah-Hartman, kernel-janitors, Michal Simek,
	linux-kernel, linux-arm-kernel
In-Reply-To: <20190821070606.GA26957@mwanda>

Hi Dan,

On 21. 08. 19 9:06, Dan Carpenter wrote:
> These structs have holes in them so we end up disclosing a few bytes of
> uninitialized stack data.
> 
> drivers/misc/xilinx_sdfec.c:305 xsdfec_get_status() warn: check that 'status' doesn't leak information (struct has a hole after 'activity')
> drivers/misc/xilinx_sdfec.c:449 xsdfec_get_turbo() warn: check that 'turbo_params' doesn't leak information (struct has a hole after 'scale')

Who is generating these warnings? Is this any new GCC or different tool?
I see that 3byte padding but never seen these warnings.

> We need to zero out the holes with memset().
> 
> Fixes: 6bd6a690c2e7 ("misc: xilinx_sdfec: Add stats & status ioctls")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
>  drivers/misc/xilinx_sdfec.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c
> index 912e939dec62..dc1b8b412712 100644
> --- a/drivers/misc/xilinx_sdfec.c
> +++ b/drivers/misc/xilinx_sdfec.c
> @@ -295,6 +295,7 @@ static int xsdfec_get_status(struct xsdfec_dev *xsdfec, void __user *arg)
>  	struct xsdfec_status status;
>  	int err;
>  
> +	memset(&status, 0, sizeof(status));
>  	spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags);
>  	status.state = xsdfec->state;
>  	xsdfec->state_updated = false;
> @@ -440,6 +441,7 @@ static int xsdfec_get_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
>  	if (xsdfec->config.code == XSDFEC_LDPC_CODE)
>  		return -EIO;
>  
> +	memset(&turbo_params, 0, sizeof(turbo_params));
>  	reg_value = xsdfec_regread(xsdfec, XSDFEC_TURBO_ADDR);
>  
>  	turbo_params.scale = (reg_value & XSDFEC_TURBO_SCALE_MASK) >>
> 

Reviewed-by: Michal Simek <michal.simek@xilinx.com>

Thanks,
Michal

_______________________________________________
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 02/19] dt-bindings: arm: mrvl: Document MMP3 compatible string
From: Lubomir Rintel @ 2019-08-22  8:12 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, devicetree, Jason Cooper, Stephen Boyd,
	Marc Zyngier, Michael Turquette, Russell King,
	Kishon Vijay Abraham I, linux-arm-kernel, Olof Johansson,
	Thomas Gleixner, linux-clk, linux-kernel
In-Reply-To: <20190821210349.GA29732@bogus>

On Wed, 2019-08-21 at 16:03 -0500, Rob Herring wrote:
> On Fri, Aug 09, 2019 at 11:31:41AM +0200, Lubomir Rintel wrote:
> > Marvel MMP3 is a successor to MMP2, containing similar peripherals with two
> > PJ4B cores.
> > 
> > Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> > ---
> >  Documentation/devicetree/bindings/arm/mrvl/mrvl.txt | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
> > index 951687528efb0..66e1e1414245b 100644
> > --- a/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
> > +++ b/Documentation/devicetree/bindings/arm/mrvl/mrvl.txt
> > @@ -12,3 +12,7 @@ Required root node properties:
> >  MMP2 Brownstone Board
> >  Required root node properties:
> >  	- compatible = "mrvl,mmp2-brownstone", "mrvl,mmp2";
> > +
> > +MMP3 SoC
> > +Required root node properties:
> > +	- compatible = "marvell,mmp3";
> 
> Please convert this file to DT schema before adding new SoCs.

Is this something that should generally be done for all new or changed
DT bindings?

> 
> Rob

Thanks
Lubo


_______________________________________________
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] soc: imx: gpcv2: Print the correct error code
From: Daniel Baluta @ 2019-08-22  8:12 UTC (permalink / raw)
  To: dl-linux-imx, linux-kernel@vger.kernel.org, festevam@gmail.com,
	agx@sigxcpu.org, robh@kernel.org, shawnguo@kernel.org,
	andrew.smirnov@gmail.com, Anson Huang,
	linux-arm-kernel@lists.infradead.org, l.stach@pengutronix.de,
	kernel@pengutronix.de, s.hauer@pengutronix.de
In-Reply-To: <ceab1bb4984d0a4f59a580cd9956c1fd6d6a78f3.1566405120.git.agx@sigxcpu.org>

On Wed, 2019-08-21 at 18:33 +0200, Guido Günther wrote:
> The current code prints 'ret' (thus 0) while it should use 'err'.
> 
> Signed-off-by: Guido Günther <agx@sigxcpu.org>

Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>

> ---
>  drivers/soc/imx/gpcv2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
> index 31b8d002d855..b0dffb06c05d 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -198,7 +198,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct
> generic_pm_domain *genpd,
>  		err = regulator_disable(domain->regulator);
>  		if (err)
>  			dev_err(domain->dev,
> -				"failed to disable regulator: %d\n",
> ret);
> +				"failed to disable regulator: %d\n",
> err);
>  		/* Preserve earlier error code */
>  		ret = ret ?: err;
>  	}
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* RE: perf tool issue following 'perf stat: Fix --no-scale' patch integration
From: Gerald BAEZA @ 2019-08-22  7:17 UTC (permalink / raw)
  To: acme@kernel.org, Andi Kleen, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
  Cc: Alexandre TORGUE, mathieu.poirier@linaro.org,
	suzuki.poulose@arm.com, peterz@infradead.org,
	alexander.shishkin@linux.intel.com, mingo@redhat.com,
	namhyung@kernel.org, jolsa@redhat.com
In-Reply-To: <20190821195451.GG3929@kernel.org>

Hello Arnaldo and Andi

Indeed, 'aligned(8)' instead of 'aligned(64)'.
Thanks for your quick feedbacks and I am going to prepare the patch.

Gérald
 


> Em Wed, Aug 21, 2019 at 09:26:35AM -0700, Andi Kleen escreveu:
> > >
> > >    +             char contents[] __attribute__((aligned(64)));
> >
> > I think you want aligned(8). The parameter is bytes, not bits.
> >
> > >
> > >
> > >    But the xyarray structure is generic so I think this patch cannot be the
> > >    final one.
> >
> > I think it's fine actually to just apply this generically (with 8). It
> > will only waste a few bytes on other 32bit architectures and should be
> > a nop on 64bit, not worth doing anything more sophisticated.
> >
> > I would just submit a patch to do that.
> 
> Agreed.
> 
> - Arnaldo

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

^ permalink raw reply

* [PATCH v9 3/3] arm64: kexec_file: add rng-seed support
From: Hsin-Yi Wang @ 2019-08-22  7:15 UTC (permalink / raw)
  To: linux-arm-kernel, Theodore Y . Ts'o
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Grzegorz Halat, H . Peter Anvin, Guenter Roeck, Will Deacon,
	Marek Szyprowski, Rob Herring, Daniel Thompson, Anders Roxell,
	Yury Norov, Marc Zyngier, Russell King, Aaro Koskinen,
	Ingo Molnar, Viresh Kumar, Waiman Long, Paul E . McKenney, Wei Li,
	Alexey Dobriyan, Julien Thierry, Len Brown, Kees Cook,
	Arnd Bergmann, Rik van Riel, Stephen Boyd, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Josh Poimboeuf, Thomas Gleixner,
	Greg Kroah-Hartman, Marcelo Tosatti, linux-kernel, Armijn Hemel,
	Jiri Kosina, Mathieu Desnoyers, Andrew Morton, Tim Chen,
	David S . Miller
In-Reply-To: <20190822071522.143986-1-hsinyi@chromium.org>

Adding "rng-seed" to dtb. It's fine to add this property if original
fdt doesn't contain it. Since original seed will be wiped after
read, so use a default size 128 bytes here.

Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
---
No change since v7.
---
 arch/arm64/kernel/machine_kexec_file.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index ba78ee7ca990..7b08bf9499b6 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -27,6 +27,8 @@
 #define FDT_PROP_INITRD_END	"linux,initrd-end"
 #define FDT_PROP_BOOTARGS	"bootargs"
 #define FDT_PROP_KASLR_SEED	"kaslr-seed"
+#define FDT_PROP_RNG_SEED	"rng-seed"
+#define RNG_SEED_SIZE		128
 
 const struct kexec_file_ops * const kexec_file_loaders[] = {
 	&kexec_image_ops,
@@ -102,6 +104,19 @@ static int setup_dtb(struct kimage *image,
 				FDT_PROP_KASLR_SEED);
 	}
 
+	/* add rng-seed */
+	if (rng_is_initialized()) {
+		u8 rng_seed[RNG_SEED_SIZE];
+		get_random_bytes(rng_seed, RNG_SEED_SIZE);
+		ret = fdt_setprop(dtb, off, FDT_PROP_RNG_SEED, rng_seed,
+				RNG_SEED_SIZE);
+		if (ret)
+			goto out;
+	} else {
+		pr_notice("RNG is not initialised: omitting \"%s\" property\n",
+				FDT_PROP_RNG_SEED);
+	}
+
 out:
 	if (ret)
 		return (ret == -FDT_ERR_NOSPACE) ? -ENOMEM : -EINVAL;
@@ -110,7 +125,8 @@ static int setup_dtb(struct kimage *image,
 }
 
 /*
- * More space needed so that we can add initrd, bootargs and kaslr-seed.
+ * More space needed so that we can add initrd, bootargs, kaslr-seed, and
+ * rng-seed.
  */
 #define DTB_EXTRA_SPACE 0x1000
 
-- 
2.20.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 v9 2/3] fdt: add support for rng-seed
From: Hsin-Yi Wang @ 2019-08-22  7:15 UTC (permalink / raw)
  To: linux-arm-kernel, Theodore Y . Ts'o
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Grzegorz Halat, H . Peter Anvin, Guenter Roeck, Will Deacon,
	Marek Szyprowski, Rob Herring, Daniel Thompson, Anders Roxell,
	Yury Norov, Marc Zyngier, Russell King, Aaro Koskinen,
	Ingo Molnar, Viresh Kumar, Waiman Long, Paul E . McKenney, Wei Li,
	Alexey Dobriyan, Julien Thierry, Len Brown, Kees Cook,
	Arnd Bergmann, Rik van Riel, Stephen Boyd, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Josh Poimboeuf, Thomas Gleixner,
	Greg Kroah-Hartman, Marcelo Tosatti, linux-kernel, Armijn Hemel,
	Jiri Kosina, Mathieu Desnoyers, Andrew Morton, Tim Chen,
	David S . Miller
In-Reply-To: <20190822071522.143986-1-hsinyi@chromium.org>

Introducing a chosen node, rng-seed, which is an entropy that can be
passed to kernel called very early to increase initial device
randomness. Bootloader should provide this entropy and the value is
read from /chosen/rng-seed in DT.

Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.

Add a new interface add_bootloader_randomness() for rng-seed use case.
Depends on whether the seed is trustworthy, rng seed would be passed to
add_hwgenerator_randomness(). Otherwise it would be passed to
add_device_randomness(). Decision is controlled by kernel config
RANDOM_TRUST_BOOTLOADER.

Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Change from v8:
* Add a new interface add_bootloader_randomness
* Add a new kernel config
---
 drivers/char/Kconfig   | 10 ++++++++++
 drivers/char/random.c  | 15 +++++++++++++++
 drivers/of/fdt.c       | 14 ++++++++++++--
 include/linux/random.h |  1 +
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 96156c729a31..5974a5906fd0 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -551,3 +551,13 @@ config RANDOM_TRUST_CPU
 	has not installed a hidden back door to compromise the CPU's
 	random number generation facilities. This can also be configured
 	at boot with "random.trust_cpu=on/off".
+
+config RANDOM_TRUST_BOOTLOADER
+	bool "Trust the bootloader to initialize Linux's CRNG"
+	default n
+	help
+	Bootloader could provide rng-seed set in /chosen/rng-seed in DT to help
+	increase initial device randomness. Assume the entropy provided is
+	trustworthy, it would be regarded as true hardware RNGs and update the
+	entropy estimate. Otherwise it would be regarded as device input that
+	could help mix the entropy pool, but won't be added to actual entropy.
\ No newline at end of file
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5d5ea4ce1442..29d3ff3de1e1 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2445,3 +2445,18 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
 	credit_entropy_bits(poolp, entropy);
 }
 EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
+
+/* Handle random seed passed by bootloader.
+ * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
+ * it would be regarded as device data.
+ * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
+ */
+void add_bootloader_randomness(const void *buf, unsigned int size)
+{
+#ifdef CONFIG_RANDOM_TRUST_BOOTLOADER
+	add_hwgenerator_randomness(buf, size, size * 8);
+#else
+	add_device_randomness(buf, size);
+#endif
+}
+EXPORT_SYMBOL_GPL(add_bootloader_randomness);
\ No newline at end of file
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 9cdf14b9aaab..7d97ab6d0e31 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -24,6 +24,7 @@
 #include <linux/debugfs.h>
 #include <linux/serial_core.h>
 #include <linux/sysfs.h>
+#include <linux/random.h>
 
 #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
 #include <asm/page.h>
@@ -1044,6 +1045,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 {
 	int l;
 	const char *p;
+	const void *rng_seed;
 
 	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
@@ -1078,6 +1080,14 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 
 	pr_debug("Command line is: %s\n", (char*)data);
 
+	rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
+	if (rng_seed && l > 0) {
+		add_bootloader_randomness(rng_seed, l);
+
+		/* try to clear seed so it won't be found. */
+		fdt_nop_property(initial_boot_params, node, "rng-seed");
+	}
+
 	/* break now */
 	return 1;
 }
@@ -1166,8 +1176,6 @@ bool __init early_init_dt_verify(void *params)
 
 	/* Setup flat device-tree pointer */
 	initial_boot_params = params;
-	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
-				fdt_totalsize(initial_boot_params));
 	return true;
 }
 
@@ -1197,6 +1205,8 @@ bool __init early_init_dt_scan(void *params)
 		return false;
 
 	early_init_dt_scan_nodes();
+	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+				fdt_totalsize(initial_boot_params));
 	return true;
 }
 
diff --git a/include/linux/random.h b/include/linux/random.h
index 1f7dced2bba6..f189c927fdea 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -19,6 +19,7 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+extern void add_bootloader_randomness(const void *, unsigned int);
 
 #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
 static inline void add_latent_entropy(void)
-- 
2.20.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 v9 1/3] arm64: map FDT as RW for early_init_dt_scan()
From: Hsin-Yi Wang @ 2019-08-22  7:15 UTC (permalink / raw)
  To: linux-arm-kernel, Theodore Y . Ts'o
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Grzegorz Halat, H . Peter Anvin, Guenter Roeck, Will Deacon,
	Marek Szyprowski, Rob Herring, Daniel Thompson, Anders Roxell,
	Yury Norov, Marc Zyngier, Russell King, Aaro Koskinen,
	Ingo Molnar, Viresh Kumar, Waiman Long, Paul E . McKenney, Wei Li,
	Alexey Dobriyan, Julien Thierry, Len Brown, Kees Cook,
	Arnd Bergmann, Rik van Riel, Stephen Boyd, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Josh Poimboeuf, Thomas Gleixner,
	Greg Kroah-Hartman, Marcelo Tosatti, linux-kernel, Armijn Hemel,
	Jiri Kosina, Mathieu Desnoyers, Andrew Morton, Tim Chen,
	David S . Miller
In-Reply-To: <20190822071522.143986-1-hsinyi@chromium.org>

Currently in arm64, FDT is mapped to RO before it's passed to
early_init_dt_scan(). However, there might be some codes
(eg. commit "fdt: add support for rng-seed") that need to modify FDT
during init. Map FDT to RO after early fixups are done.

Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Mike Rapoport <rppt@linux.ibm.com>
---
No change since v7.
---
 arch/arm64/include/asm/mmu.h |  2 +-
 arch/arm64/kernel/kaslr.c    |  5 +----
 arch/arm64/kernel/setup.c    |  9 ++++++++-
 arch/arm64/mm/mmu.c          | 15 +--------------
 4 files changed, 11 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index fd6161336653..f217e3292919 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -126,7 +126,7 @@ extern void init_mem_pgprot(void);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 			       unsigned long virt, phys_addr_t size,
 			       pgprot_t prot, bool page_mappings_only);
-extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
+extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
 extern void mark_linear_text_alias_ro(void);
 
 #define INIT_MM_CONTEXT(name)	\
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 5a59f7567f9c..416f537bf614 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -62,9 +62,6 @@ static __init const u8 *kaslr_get_cmdline(void *fdt)
 	return default_cmdline;
 }
 
-extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
-				       pgprot_t prot);
-
 /*
  * This routine will be executed with the kernel mapped at its default virtual
  * address, and if it returns successfully, the kernel will be remapped, and
@@ -93,7 +90,7 @@ u64 __init kaslr_early_init(u64 dt_phys)
 	 * attempt at mapping the FDT in setup_machine()
 	 */
 	early_fixmap_init();
-	fdt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
+	fdt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
 	if (!fdt)
 		return 0;
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 57ff38600828..56f664561754 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -170,9 +170,13 @@ static void __init smp_build_mpidr_hash(void)
 
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
-	void *dt_virt = fixmap_remap_fdt(dt_phys);
+	int size;
+	void *dt_virt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
 	const char *name;
 
+	if (dt_virt)
+		memblock_reserve(dt_phys, size);
+
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
 		pr_crit("\n"
 			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
@@ -184,6 +188,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
 			cpu_relax();
 	}
 
+	/* Early fixups are done, map the FDT as read-only now */
+	fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
+
 	name = of_flat_dt_get_machine_name();
 	if (!name)
 		return;
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index e67bab4d613e..1586d7fbf26a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -877,7 +877,7 @@ void __set_fixmap(enum fixed_addresses idx,
 	}
 }
 
-void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
+void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
 {
 	const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
 	int offset;
@@ -930,19 +930,6 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
 	return dt_virt;
 }
 
-void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
-{
-	void *dt_virt;
-	int size;
-
-	dt_virt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
-	if (!dt_virt)
-		return NULL;
-
-	memblock_reserve(dt_phys, size);
-	return dt_virt;
-}
-
 int __init arch_ioremap_p4d_supported(void)
 {
 	return 0;
-- 
2.20.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 v9 0/3] add support for rng-seed
From: Hsin-Yi Wang @ 2019-08-22  7:15 UTC (permalink / raw)
  To: linux-arm-kernel, Theodore Y . Ts'o
  Cc: Kate Stewart, Peter Zijlstra, Catalin Marinas, Mukesh Ojha,
	Grzegorz Halat, H . Peter Anvin, Guenter Roeck, Will Deacon,
	Marek Szyprowski, Rob Herring, Daniel Thompson, Anders Roxell,
	Yury Norov, Marc Zyngier, Russell King, Aaro Koskinen,
	Ingo Molnar, Viresh Kumar, Waiman Long, Paul E . McKenney, Wei Li,
	Alexey Dobriyan, Julien Thierry, Len Brown, Kees Cook,
	Arnd Bergmann, Rik van Riel, Stephen Boyd, Shaokun Zhang,
	Mike Rapoport, Borislav Petkov, Josh Poimboeuf, Thomas Gleixner,
	Greg Kroah-Hartman, Marcelo Tosatti, linux-kernel, Armijn Hemel,
	Jiri Kosina, Mathieu Desnoyers, Andrew Morton, Tim Chen,
	David S . Miller

Introducing a chosen node, rng-seed, which is an entropy that can be
passed to kernel called very early to increase initial device
randomness. This can be used for adding sufficient initial entropy
for stack canary. Especially architectures that lack per-stack canary.

Hsin-Yi Wang (3):
  arm64: map FDT as RW for early_init_dt_scan()
  fdt: add support for rng-seed
  arm64: kexec_file: add rng-seed support

 arch/arm64/include/asm/mmu.h           |  2 +-
 arch/arm64/kernel/kaslr.c              |  5 +----
 arch/arm64/kernel/machine_kexec_file.c | 18 +++++++++++++++++-
 arch/arm64/kernel/setup.c              |  9 ++++++++-
 arch/arm64/mm/mmu.c                    | 15 +--------------
 drivers/char/Kconfig                   | 10 ++++++++++
 drivers/char/random.c                  | 15 +++++++++++++++
 drivers/of/fdt.c                       | 14 ++++++++++++--
 include/linux/random.h                 |  1 +
 9 files changed, 66 insertions(+), 23 deletions(-)

--
Change from v8:
* Add a new interface add_bootloader_randomness
--
2.20.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 -next] usb: udc: lpc32xx: remove set but not used 3 variables
From: Mao Wenan @ 2019-08-22  7:05 UTC (permalink / raw)
  To: balbi, gregkh, vz, slemieux.tyco, linux-usb, linux-arm-kernel,
	linux-kernel
  Cc: kernel-janitors, Mao Wenan

Fixes gcc '-Wunused-but-set-variable' warning:
drivers/usb/gadget/udc/lpc32xx_udc.c: In function ‘udc_protocol_cmd_r’:
drivers/usb/gadget/udc/lpc32xx_udc.c:744:6: warning: variable ‘tmp’ set but not used [-Wunused-but-set-variable]

drivers/usb/gadget/udc/lpc32xx_udc.c: In function ‘udc_handle_dma_ep’:
drivers/usb/gadget/udc/lpc32xx_udc.c:1994:14: warning: variable ‘epstatus’ set but not used [-Wunused-but-set-variable]

drivers/usb/gadget/udc/lpc32xx_udc.c: In function ‘udc_handle_ep0_setup’:
drivers/usb/gadget/udc/lpc32xx_udc.c:2200:22: warning: variable ‘wLength’ set but not used [-Wunused-but-set-variable]

It is not used since commit 90fccb529d24 ("usb: gadget: Gadget directory cleanup - group UDC drivers")

Signed-off-by: Mao Wenan <maowenan@huawei.com>
---
 drivers/usb/gadget/udc/lpc32xx_udc.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c
index 606c8bc..b3e073f 100644
--- a/drivers/usb/gadget/udc/lpc32xx_udc.c
+++ b/drivers/usb/gadget/udc/lpc32xx_udc.c
@@ -741,7 +741,6 @@ static inline void udc_protocol_cmd_data_w(struct lpc32xx_udc *udc, u32 cmd,
  * response data */
 static u32 udc_protocol_cmd_r(struct lpc32xx_udc *udc, u32 cmd)
 {
-	u32 tmp;
 	int to = 1000;
 
 	/* Write a command and read data from the protocol engine */
@@ -751,7 +750,6 @@ static u32 udc_protocol_cmd_r(struct lpc32xx_udc *udc, u32 cmd)
 	/* Write command code */
 	udc_protocol_cmd_w(udc, cmd);
 
-	tmp = readl(USBD_DEVINTST(udc->udp_baseaddr));
 	while ((!(readl(USBD_DEVINTST(udc->udp_baseaddr)) & USBD_CDFULL))
 	       && (to > 0))
 		to--;
@@ -1991,7 +1989,7 @@ void udc_handle_eps(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
 /* DMA end of transfer completion */
 static void udc_handle_dma_ep(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
 {
-	u32 status, epstatus;
+	u32 status;
 	struct lpc32xx_request *req;
 	struct lpc32xx_usbd_dd_gad *dd;
 
@@ -2085,7 +2083,7 @@ static void udc_handle_dma_ep(struct lpc32xx_udc *udc, struct lpc32xx_ep *ep)
 		if (udc_clearep_getsts(udc, ep->hwep_num) & EP_SEL_F) {
 			udc_clearep_getsts(udc, ep->hwep_num);
 			uda_enable_hwepint(udc, ep->hwep_num);
-			epstatus = udc_clearep_getsts(udc, ep->hwep_num);
+			udc_clearep_getsts(udc, ep->hwep_num);
 
 			/* Let the EP interrupt handle the ZLP */
 			return;
@@ -2197,7 +2195,7 @@ static void udc_handle_ep0_setup(struct lpc32xx_udc *udc)
 	struct lpc32xx_ep *ep, *ep0 = &udc->ep[0];
 	struct usb_ctrlrequest ctrlpkt;
 	int i, bytes;
-	u16 wIndex, wValue, wLength, reqtype, req, tmp;
+	u16 wIndex, wValue, reqtype, req, tmp;
 
 	/* Nuke previous transfers */
 	nuke(ep0, -EPROTO);
@@ -2213,7 +2211,6 @@ static void udc_handle_ep0_setup(struct lpc32xx_udc *udc)
 	/* Native endianness */
 	wIndex = le16_to_cpu(ctrlpkt.wIndex);
 	wValue = le16_to_cpu(ctrlpkt.wValue);
-	wLength = le16_to_cpu(ctrlpkt.wLength);
 	reqtype = le16_to_cpu(ctrlpkt.bRequestType);
 
 	/* Set direction of EP0 */
-- 
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

* Regression in 5.3-rc1 and later
From: Chris Clayton @ 2019-08-22  6:57 UTC (permalink / raw)
  To: LKML
  Cc: linux-arch, shuah, sthotton, andre.przywara, arnd, salyzyn, huw,
	catalin.marinas, daniel.lezcano, will.deacon, linux-mips, ralf,
	linux, 0x7f454c46, paul.burton, linux-kselftest, linux, tglx,
	vincenzo.frascino, pcc, linux-arm-kernel

Hi everyone,

Firstly, apologies to anyone on the long cc list that turns out not to be particularly interested in the following, but
you were all marked as cc'd in the commit message below.

I've found a problem that isn't present in 5.2 series or 4.19 series kernels, and seems to have arrived in 5.3-rc1. The
problem is that if I suspend (to ram) my laptop, on resume 14 minutes or more after suspending, I have no networking
functionality. If I resume the laptop after 13 minutes or less, networking works fine. I haven't tried to get finer
grained timings between 13 and 14 minutes, but can do if it would help.

ifconfig shows that wlan0 is still up and still has its assigned ip address but, for instance, a ping of any other
device on my network, fails as does pinging, say, kernel.org. I've tried "downing" the network with (/sbin/ifdown) and
unloading the iwlmvm module and then reloading the module and "upping" (/sbin/ifup) the network, but my network is still
unusable. I should add that the problem also manifests if I hibernate the laptop, although my testing of this has been
minimal. I can do more if required.

As I say, the problem first appears in 5.3-rc1, so I've bisected between 5.2.0 and 5.3-rc1 and that concluded with:

[chris:~/kernel/linux]$ git bisect good
7ac8707479886c75f353bfb6a8273f423cfccb23 is the first bad commit
commit 7ac8707479886c75f353bfb6a8273f423cfccb23
Author: Vincenzo Frascino <vincenzo.frascino@arm.com>
Date:   Fri Jun 21 10:52:49 2019 +0100

    x86/vdso: Switch to generic vDSO implementation

    The x86 vDSO library requires some adaptations to take advantage of the
    newly introduced generic vDSO library.

    Introduce the following changes:
     - Modification of vdso.c to be compliant with the common vdso datapage
     - Use of lib/vdso for gettimeofday

    [ tglx: Massaged changelog and cleaned up the function signature formatting ]

    Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Cc: linux-arch@vger.kernel.org
    Cc: linux-arm-kernel@lists.infradead.org
    Cc: linux-mips@vger.kernel.org
    Cc: linux-kselftest@vger.kernel.org
    Cc: Catalin Marinas <catalin.marinas@arm.com>
    Cc: Will Deacon <will.deacon@arm.com>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Russell King <linux@armlinux.org.uk>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: Paul Burton <paul.burton@mips.com>
    Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
    Cc: Mark Salyzyn <salyzyn@android.com>
    Cc: Peter Collingbourne <pcc@google.com>
    Cc: Shuah Khan <shuah@kernel.org>
    Cc: Dmitry Safonov <0x7f454c46@gmail.com>
    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    Cc: Huw Davies <huw@codeweavers.com>
    Cc: Shijith Thotton <sthotton@marvell.com>
    Cc: Andre Przywara <andre.przywara@arm.com>
    Link: https://lkml.kernel.org/r/20190621095252.32307-23-vincenzo.frascino@arm.com

 arch/x86/Kconfig                         |   3 +
 arch/x86/entry/vdso/Makefile             |   9 ++
 arch/x86/entry/vdso/vclock_gettime.c     | 245 ++++---------------------------
 arch/x86/entry/vdso/vdsox32.lds.S        |   1 +
 arch/x86/entry/vsyscall/Makefile         |   2 -
 arch/x86/entry/vsyscall/vsyscall_gtod.c  |  83 -----------
 arch/x86/include/asm/pvclock.h           |   2 +-
 arch/x86/include/asm/vdso/gettimeofday.h | 191 ++++++++++++++++++++++++
 arch/x86/include/asm/vdso/vsyscall.h     |  44 ++++++
 arch/x86/include/asm/vgtod.h             |  75 +---------
 arch/x86/include/asm/vvar.h              |   7 +-
 arch/x86/kernel/pvclock.c                |   1 +
 12 files changed, 284 insertions(+), 379 deletions(-)
 delete mode 100644 arch/x86/entry/vsyscall/vsyscall_gtod.c
 create mode 100644 arch/x86/include/asm/vdso/gettimeofday.h
 create mode 100644 arch/x86/include/asm/vdso/vsyscall.h

To confirm my bisection was correct, I did a git checkout of 7ac8707479886c75f353bfb6a8273f423cfccb2. As expected, the
kernel exhibited the problem I've described. However, a kernel built at the immediately preceding (parent?) commit
(bfe801ebe84f42b4666d3f0adde90f504d56e35b) has a working network after a (>= 14minute) suspend/resume cycle.

As the module name implies, I'm using wireless networking. The hardware is detected as "Intel(R) Wireless-AC 9260
160MHz, REV=0x324" by iwlwifi.

I'm more than happy to provide additional diagnostics (but may need a little hand-holding) and to apply diagnostic or
fix patches, but please cc me on any reply as I'm not subscribed to any of the kernel-related mailing lists.

Chris

_______________________________________________
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