Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 2/6] dt-bindings: add binding for atmel-usart in SPI mode
From: Rob Herring @ 2018-05-31  1:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180525171941.26766-3-radu.pirea@microchip.com>

On Fri, May 25, 2018 at 08:19:37PM +0300, Radu Pirea wrote:
> This patch moves the bindings for serial from serial/atmel-usart.txt to
> mfd/atmel-usart.txt and adds bindings for USART in SPI mode.
> 
> Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
> ---
>  .../bindings/{serial => mfd}/atmel-usart.txt  | 25 +++++++++++++++++--
>  1 file changed, 23 insertions(+), 2 deletions(-)
>  rename Documentation/devicetree/bindings/{serial => mfd}/atmel-usart.txt (76%)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v4 3/6] mfd: at91-usart: added mfd driver for usart
From: Rob Herring @ 2018-05-31  1:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180525171941.26766-4-radu.pirea@microchip.com>

On Fri, May 25, 2018 at 08:19:38PM +0300, Radu Pirea wrote:
> This mfd driver is just a wrapper over atmel_serial driver and
> spi-at91-usart driver. Selection of one of the drivers is based on a
> property from device tree. If the property is not specified, the default
> driver is atmel_serial.
> 
> Signed-off-by: Radu Pirea <radu.pirea@microchip.com>
> ---
>  drivers/mfd/Kconfig                  | 10 ++++
>  drivers/mfd/Makefile                 |  1 +
>  drivers/mfd/at91-usart.c             | 75 ++++++++++++++++++++++++++++

>  include/dt-bindings/mfd/at91-usart.h | 17 +++++++

This really should be part of the binding patch.

Acked-by: Rob Herring <robh@kernel.org>

>  4 files changed, 103 insertions(+)
>  create mode 100644 drivers/mfd/at91-usart.c
>  create mode 100644 include/dt-bindings/mfd/at91-usart.h

^ permalink raw reply

* [PATCH v4 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-05-31  1:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAD=FV=VNVE5ttNg+7xmgh-p1sFbCxCY1DJiri0JtHFax+zVsnA@mail.gmail.com>

Hi Doug,

On 05/30/2018 05:34 PM, Doug Anderson wrote:
> On Wed, May 30, 2018 at 4:39 PM, David Collins <collinsd@codeaurora.org> wrote:
>> Consider the case of a regulator with physical 10 mA LPM max current. Say
>> that modem and application processors each have a load on the regulator
>> that draws 9 mA. If they each respect the 10 mA limit, then they'd each
>> vote for LPM. The VRM block in RPMh hardware will aggregate these requests
>> together using a max function which will result in the regulator being set
>> to LPM, even though the total load is 18 mA (which would require high
>> power mode (HPM)). To get around this corner case, a LPM max current of 1
>> uA can be used for all LDO supplies that have non-application processor
>> consumers. Thus, any non-zero regulator_set_load() current request will
>> result in setting the regulator to HPM (which is always safe).
> 
> Is there any plan to change the way this works for future versions of RPMh?

As far as I know, no.  Adding VRM logic to sum RPMh client load current
requests, compare the sums to thresholds, select corresponding modes, and
override with explicit modes was determined to be too complex for RPMh.
Instead, much simpler max aggregation was implemented along with design
guidelines for PMICs to ensure that mode values are ordered from strictly
lower to higher power.

Take care,
David

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* [PATCH 3/3] ARM: imx: remove i.MX6SLL support in i.MX6SL cpu idle driver
From: Fabio Estevam @ 2018-05-31  1:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <AM3PR04MB1315345C3578D0644B82E8E9F5630@AM3PR04MB1315.eurprd04.prod.outlook.com>

On Wed, May 30, 2018 at 9:59 PM, Anson Huang <anson.huang@nxp.com> wrote:

> It is in arch/arm/mach-imx/mxc.h included by hardware.h, it is added by commit
> (dee5dee ARM: imx: Add basic msl support for imx6sll), so I removed it since we
> no longer need it.

Ah, OK: "mxc.h" is included by "hardware.h". Got it!

^ permalink raw reply

* [PATCH V3 2/2] scsi: hpsa: drop shutdown callback
From: okaya at codeaurora.org @ 2018-05-31  1:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <af772e6434e645f4a42d22821442a3bd@microsemi.com>

On 2018-05-30 15:25, Don Brace wrote:
>> -----Original Message-----
>> From: Ryan Finnie [mailto:ryan at finnie.org]
>> Sent: Tuesday, May 29, 2018 8:50 PM
>> To: Sinan Kaya <okaya@codeaurora.org>; linux-pci at vger.kernel.org;
>> timur at codeaurora.org
>> Cc: linux-arm-msm at vger.kernel.org; 
>> linux-arm-kernel at lists.infradead.org;
>> stable at vger.kernel.org; Don Brace <don.brace@microsemi.com>; James 
>> E.J.
>> Bottomley <jejb@linux.vnet.ibm.com>; Martin K. Petersen
>> <martin.petersen@oracle.com>; esc.storagedev
>> <esc.storagedev@microsemi.com>; open list:HEWLETT-PACKARD SMART ARRAY
>> RAID DRIVER (hpsa) <linux-scsi@vger.kernel.org>; open list <linux-
>> kernel at vger.kernel.org>
>> Subject: Re: [PATCH V3 2/2] scsi: hpsa: drop shutdown callback
>> 
>> EXTERNAL EMAIL
>> 
>> 
>> On 05/28/2018 02:21 PM, Sinan Kaya wrote:
>> > 'Commit cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during
>> > shutdown")' has been added to kernel to shutdown pending PCIe port
>> > service interrupts during reboot so that a newly started kexec kernel
>> > wouldn't observe pending interrupts.
>> >
>> > pcie_port_device_remove() is disabling the root port and switches by
>> > calling pci_disable_device() after all PCIe service drivers are shutdown.
>> >
>> > This has been found to cause crashes on HP DL360 Gen9 machines during
>> > reboot due to hpsa driver not clearing the bus master bit during the
>> > shutdown procedure by calling pci_disable_device().
>> >
>> > Drop the shutdown API and do an orderly clean up by using the remove.
>> >
>> > Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=199779
>> > Fixes: cc27b735ad3a ("PCI/portdrv: Turn off PCIe services during shutdown")
>> > Cc: stable at vger.kernel.org
>> > Reported-by: Ryan Finnie <ryan@finnie.org>
>> 
>> Tested successfully on DL360 Gen9 and DL380 Gen9.
>> 
>> Tested-by: Ryan Finnie <ryan@finnie.org>
> 
> The shutdown path issues a cache flush to the controller.
> Without this flush, you will see "Dirty Cache" messages at POST.
> It is best to keep the shutdown path.
> 

I have seen that shutdown() is also called from remove().

remove() is supposed to do a safe cleanup too. If it is leaving the hw 
in inconsistent state even though it is c lling shutdown , it is yet 
another bug.

> Thanks,
> Don Brace
> ESC - Smart Storage
> Microsemi Corporation

^ permalink raw reply

* [PATCH 2/2] media: v4l: xilinx: Add Xilinx MIPI CSI-2 Rx Subsystem driver
From: Hyun Kwon @ 2018-05-31  1:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527620084-94864-3-git-send-email-vishal.sagar@xilinx.com>

Hi Vishal,

Thanks for the patch.

On Tue, 2018-05-29 at 11:54:44 -0700, Vishal Sagar wrote:
> The Xilinx MIPI CSI-2 Rx Subsystem soft IP is used to capture images
> from MIPI CSI-2 camera sensors and output AXI4-Stream video data ready
> for image processing.
> 
> It supports upto 4 lanes, filtering based on Virtual Channel selected in
> IP, an optional Xilinx IIC controller, optional register interface for
> the DPHY, multiple color formats, short packet capture,
> 
> This driver helps configure the number of active lanes to be set,
> setting and handling interrupts and IP core enable.
> It logs the count of events occurring according to their type between
> streaming ON and OFF. The short packet reception is notified to
> application via v4l2_event.
> 
> Signed-off-by: Vishal Sagar <vishal.sagar@xilinx.com>
> ---
>  drivers/media/platform/xilinx/Kconfig           |   12 +
>  drivers/media/platform/xilinx/Makefile          |    1 +
>  drivers/media/platform/xilinx/xilinx-csi2rxss.c | 1751 +++++++++++++++++++++++
>  include/uapi/linux/xilinx-csi2rxss.h            |   25 +
>  include/uapi/linux/xilinx-v4l2-controls.h       |   14 +
>  5 files changed, 1803 insertions(+)
>  create mode 100644 drivers/media/platform/xilinx/xilinx-csi2rxss.c
>  create mode 100644 include/uapi/linux/xilinx-csi2rxss.h
> 
> diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
> index a5d21b7..06d5944 100644
> --- a/drivers/media/platform/xilinx/Kconfig
> +++ b/drivers/media/platform/xilinx/Kconfig
> @@ -8,6 +8,18 @@ config VIDEO_XILINX
>  
>  if VIDEO_XILINX
>  
> +config VIDEO_XILINX_CSI2RXSS
> +	tristate "Xilinx CSI2 Rx Subsystem"
> +	depends on VIDEO_XILINX
> +	help
> +	  Driver for Xilinx MIPI CSI2 Rx Subsystem. This is a V4L sub-device
> +	  based driver that takes input from CSI2 Tx source and converts
> +	  it into an AXI4-Stream. It has a DPHY (whose register interface
> +	  can be enabled, an optional I2C controller and an optional Video
> +	  Format Bridge which converts the AXI4-Stream data to Xilinx Video
> +	  Bus formats based on UG934. The driver is used to set the number
> +	  of active lanes and get short packet data.
> +
>  config VIDEO_XILINX_TPG
>  	tristate "Xilinx Video Test Pattern Generator"
>  	depends on VIDEO_XILINX
> diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
> index e8a0f2a..768f079 100644
> --- a/drivers/media/platform/xilinx/Makefile
> +++ b/drivers/media/platform/xilinx/Makefile
> @@ -1,5 +1,6 @@
>  xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
>  
>  obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
> +obj-$(CONFIG_VIDEO_XILINX_CSI2RXSS) += xilinx-csi2rxss.o
>  obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
>  obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
> diff --git a/drivers/media/platform/xilinx/xilinx-csi2rxss.c b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> new file mode 100644
> index 0000000..03f387c
> --- /dev/null
> +++ b/drivers/media/platform/xilinx/xilinx-csi2rxss.c
> @@ -0,0 +1,1751 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Driver for Xilinx MIPI CSI2 Rx Subsystem
> + *
> + * Copyright (C) 2016 - 2018 Xilinx, Inc.
> + *
> + * Contacts: Vishal Sagar <vishal.sagar@xilinx.com>
> + *
> + */
> +
> +#include <dt-bindings/media/xilinx-vip.h>
> +#include <linux/bitops.h>
> +#include <linux/compiler.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/spinlock_types.h>
> +#include <linux/types.h>
> +#include <linux/v4l2-subdev.h>
> +#include <linux/xilinx-csi2rxss.h>
> +#include <linux/xilinx-v4l2-controls.h>
> +#include <media/media-entity.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +#include "xilinx-vip.h"
> +
> +/*
> + * MIPI CSI2 Rx register map, bitmask and offsets
> + */
> +#define XCSI_CCR_OFFSET			0x00000000
> +#define XCSI_CCR_SOFTRESET_SHIFT	1
> +#define XCSI_CCR_COREENB_SHIFT		0
> +#define XCSI_CCR_SOFTRESET_MASK		BIT(XCSI_CCR_SOFTRESET_SHIFT)
> +#define XCSI_CCR_COREENB_MASK		BIT(XCSI_CCR_COREENB_SHIFT)

Single bit field doesn't have to be called as '_MASK', and thus the shift is not
needed. So,

#define XCSI_CCR_COREENB	BIT(0)

would be enough. Same for the rest.

> +
> +#define XCSI_PCR_OFFSET			0x00000004
> +#define XCSI_PCR_MAXLANES_MASK		0x00000018
> +#define XCSI_PCR_ACTLANES_MASK		0x00000003

You can use GENMASK().

> +#define XCSI_PCR_MAXLANES_SHIFT		3
> +#define XCSI_PCR_ACTLANES_SHIFT		0

These are not even used. You can remove these.

> +
> +#define XCSI_CSR_OFFSET			0x00000010
> +#define XCSI_CSR_PKTCOUNT_SHIFT		16
> +#define XCSI_CSR_SPFIFOFULL_SHIFT	3
> +#define XCSI_CSR_SPFIFONE_SHIFT		2
> +#define XCSI_CSR_SLBF_SHIFT		1
> +#define XCSI_CSR_RIPCD_SHIFT		0
> +#define XCSI_CSR_PKTCOUNT_MASK		0xFFFF0000

I prefer the low case for hex values, but maybe it's just me.

> +#define XCSI_CSR_SPFIFOFULL_MASK	BIT(XCSI_CSR_SPFIFOFULL_SHIFT)
> +#define XCSI_CSR_SPFIFONE_MASK		BIT(XCSI_CSR_SPFIFONE_SHIFT)
> +#define XCSI_CSR_SLBF_MASK		BIT(XCSI_CSR_SLBF_SHIFT)
> +#define XCSI_CSR_RIPCD_MASK		BIT(XCSI_CSR_RIPCD_SHIFT)
> +
> +#define XCSI_GIER_OFFSET		0x00000020
> +#define XCSI_GIER_GIE_SHIFT		0
> +#define XCSI_GIER_GIE_MASK		BIT(XCSI_GIER_GIE_SHIFT)
> +#define XCSI_GIER_SET			1
> +#define XCSI_GIER_RESET			0
> +
> +#define XCSI_ISR_OFFSET			0x00000024
> +#define XCSI_ISR_FR_SHIFT		31
> +#define XCSI_ISR_ILC_SHIFT		21
> +#define XCSI_ISR_SPFIFOF_SHIFT		20
> +#define XCSI_ISR_SPFIFONE_SHIFT		19
> +#define XCSI_ISR_SLBF_SHIFT		18
> +#define XCSI_ISR_STOP_SHIFT		17
> +#define XCSI_ISR_SOTERR_SHIFT		13
> +#define XCSI_ISR_SOTSYNCERR_SHIFT	12
> +#define XCSI_ISR_ECC2BERR_SHIFT		11
> +#define XCSI_ISR_ECC1BERR_SHIFT		10
> +#define XCSI_ISR_CRCERR_SHIFT		9
> +#define XCSI_ISR_DATAIDERR_SHIFT	8
> +#define XCSI_ISR_VC3FSYNCERR_SHIFT	7
> +#define XCSI_ISR_VC3FLVLERR_SHIFT	6
> +#define XCSI_ISR_VC2FSYNCERR_SHIFT	5
> +#define XCSI_ISR_VC2FLVLERR_SHIFT	4
> +#define XCSI_ISR_VC1FSYNCERR_SHIFT	3
> +#define XCSI_ISR_VC1FLVLERR_SHIFT	2
> +#define XCSI_ISR_VC0FSYNCERR_SHIFT	1
> +#define XCSI_ISR_VC0FLVLERR_SHIFT	0
> +#define XCSI_ISR_FR_MASK		BIT(XCSI_ISR_FR_SHIFT)
> +#define XCSI_ISR_ILC_MASK		BIT(XCSI_ISR_ILC_SHIFT)
> +#define XCSI_ISR_SPFIFOF_MASK		BIT(XCSI_ISR_SPFIFOF_SHIFT)
> +#define XCSI_ISR_SPFIFONE_MASK		BIT(XCSI_ISR_SPFIFONE_SHIFT)
> +#define XCSI_ISR_SLBF_MASK		BIT(XCSI_ISR_SLBF_SHIFT)
> +#define XCSI_ISR_STOP_MASK		BIT(XCSI_ISR_STOP_SHIFT)
> +#define XCSI_ISR_SOTERR_MASK		BIT(XCSI_ISR_SOTERR_SHIFT)
> +#define XCSI_ISR_SOTSYNCERR_MASK	BIT(XCSI_ISR_SOTSYNCERR_SHIFT)
> +#define XCSI_ISR_ECC2BERR_MASK		BIT(XCSI_ISR_ECC2BERR_SHIFT)
> +#define XCSI_ISR_ECC1BERR_MASK		BIT(XCSI_ISR_ECC1BERR_SHIFT)
> +#define XCSI_ISR_CRCERR_MASK		BIT(XCSI_ISR_CRCERR_SHIFT)
> +#define XCSI_ISR_DATAIDERR_MASK		BIT(XCSI_ISR_DATAIDERR_SHIFT)
> +#define XCSI_ISR_VC3FSYNCERR_MASK	BIT(XCSI_ISR_VC3FSYNCERR_SHIFT)
> +#define XCSI_ISR_VC3FLVLERR_MASK	BIT(XCSI_ISR_VC3FLVLERR_SHIFT)
> +#define XCSI_ISR_VC2FSYNCERR_MASK	BIT(XCSI_ISR_VC2FSYNCERR_SHIFT)
> +#define XCSI_ISR_VC2FLVLERR_MASK	BIT(XCSI_ISR_VC2FLVLERR_SHIFT)
> +#define XCSI_ISR_VC1FSYNCERR_MASK	BIT(XCSI_ISR_VC1FSYNCERR_SHIFT)
> +#define XCSI_ISR_VC1FLVLERR_MASK	BIT(XCSI_ISR_VC1FLVLERR_SHIFT)
> +#define XCSI_ISR_VC0FSYNCERR_MASK	BIT(XCSI_ISR_VC0FSYNCERR_SHIFT)
> +#define XCSI_ISR_VC0FLVLERR_MASK	BIT(XCSI_ISR_VC0FLVLERR_SHIFT)

Ditto for mask / shift and unused ones.

> +#define XCSI_ISR_ALLINTR_MASK		0x803FFFFF

You can OR maskes below to get this too, at least to be consistent with below.
But up to you.

> +
> +#define XCSI_INTR_PROT_MASK	(XCSI_ISR_VC3FSYNCERR_MASK |	\
> +				 XCSI_ISR_VC3FLVLERR_MASK |	\
> +				 XCSI_ISR_VC2FSYNCERR_MASK |	\
> +				 XCSI_ISR_VC2FLVLERR_MASK |	\
> +				 XCSI_ISR_VC1FSYNCERR_MASK |	\
> +				 XCSI_ISR_VC1FLVLERR_MASK |	\
> +				 XCSI_ISR_VC0FSYNCERR_MASK |	\
> +				 XCSI_ISR_VC0FLVLERR_MASK)
> +
> +#define XCSI_INTR_PKTLVL_MASK	(XCSI_ISR_ECC2BERR_MASK |	\
> +				 XCSI_ISR_ECC1BERR_MASK |	\
> +				 XCSI_ISR_CRCERR_MASK   |	\
> +				 XCSI_ISR_DATAIDERR_MASK)
> +
> +#define XCSI_INTR_DPHY_MASK	(XCSI_ISR_SOTERR_MASK	|	\
> +				 XCSI_ISR_SOTSYNCERR_MASK)
> +
> +#define XCSI_INTR_SPKT_MASK	(XCSI_ISR_SPFIFOF_MASK |	\
> +				 XCSI_ISR_SPFIFONE_MASK)
> +
> +#define XCSI_INTR_FRAMERCVD_MASK	(XCSI_ISR_FR_MASK)
> +
> +#define XCSI_INTR_ERR_MASK	(XCSI_ISR_ILC_MASK |	\
> +				 XCSI_ISR_SLBF_MASK |	\
> +				 XCSI_ISR_STOP_MASK)
> +
> +#define XCSI_IER_OFFSET			0x00000028
> +#define XCSI_IER_FR_SHIFT		31
> +#define XCSI_IER_ILC_SHIFT		21
> +#define XCSI_IER_SPFIFOF_SHIFT		20
> +#define XCSI_IER_SPFIFONE_SHIFT		19
> +#define XCSI_IER_SLBF_SHIFT		18
> +#define XCSI_IER_STOP_SHIFT		17
> +#define XCSI_IER_SOTERR_SHIFT		13
> +#define XCSI_IER_SOTSYNCERR_SHIFT	12
> +#define XCSI_IER_ECC2BERR_SHIFT		11
> +#define XCSI_IER_ECC1BERR_SHIFT		10
> +#define XCSI_IER_CRCERR_SHIFT		9
> +#define XCSI_IER_DATAIDERR_SHIFT	8
> +#define XCSI_IER_VC3FSYNCERR_SHIFT	7
> +#define XCSI_IER_VC3FLVLERR_SHIFT	6
> +#define XCSI_IER_VC2FSYNCERR_SHIFT	5
> +#define XCSI_IER_VC2FLVLERR_SHIFT	4
> +#define XCSI_IER_VC1FSYNCERR_SHIFT	3
> +#define XCSI_IER_VC1FLVLERR_SHIFT	2
> +#define XCSI_IER_VC0FSYNCERR_SHIFT	1
> +#define XCSI_IER_VC0FLVLERR_SHIFT	0
> +#define XCSI_IER_FR_MASK		BIT(XCSI_IER_FR_SHIFT)
> +#define XCSI_IER_ILC_MASK		BIT(XCSI_IER_ILC_SHIFT)
> +#define XCSI_IER_SPFIFOF_MASK		BIT(XCSI_IER_SPFIFOF_SHIFT)
> +#define XCSI_IER_SPFIFONE_MASK		BIT(XCSI_IER_SPFIFONE_SHIFT)
> +#define XCSI_IER_SLBF_MASK		BIT(XCSI_IER_SLBF_SHIFT)
> +#define XCSI_IER_STOP_MASK		BIT(XCSI_IER_STOP_SHIFT)
> +#define XCSI_IER_SOTERR_MASK		BIT(XCSI_IER_SOTERR_SHIFT)
> +#define XCSI_IER_SOTSYNCERR_MASK	BIT(XCSI_IER_SOTSYNCERR_SHIFT)
> +#define XCSI_IER_ECC2BERR_MASK		BIT(XCSI_IER_ECC2BERR_SHIFT)
> +#define XCSI_IER_ECC1BERR_MASK		BIT(XCSI_IER_ECC1BERR_SHIFT)
> +#define XCSI_IER_CRCERR_MASK		BIT(XCSI_IER_CRCERR_SHIFT)
> +#define XCSI_IER_DATAIDERR_MASK		BIT(XCSI_IER_DATAIDERR_SHIFT)
> +#define XCSI_IER_VC3FSYNCERR_MASK	BIT(XCSI_IER_VC3FSYNCERR_SHIFT)
> +#define XCSI_IER_VC3FLVLERR_MASK	BIT(XCSI_IER_VC3FLVLERR_SHIFT)
> +#define XCSI_IER_VC2FSYNCERR_MASK	BIT(XCSI_IER_VC2FSYNCERR_SHIFT)
> +#define XCSI_IER_VC2FLVLERR_MASK	BIT(XCSI_IER_VC2FLVLERR_SHIFT)
> +#define XCSI_IER_VC1FSYNCERR_MASK	BIT(XCSI_IER_VC1FSYNCERR_SHIFT)
> +#define XCSI_IER_VC1FLVLERR_MASK	BIT(XCSI_IER_VC1FLVLERR_SHIFT)
> +#define XCSI_IER_VC0FSYNCERR_MASK	BIT(XCSI_IER_VC0FSYNCERR_SHIFT)
> +#define XCSI_IER_VC0FLVLERR_MASK	BIT(XCSI_IER_VC0FLVLERR_SHIFT)
> +#define XCSI_IER_ALLINTR_MASK		0x803FFFFF

This is simply repeatation of above, XCSI_ISR_*. One common one can be used.

> +
> +#define XCSI_SPKTR_OFFSET		0x00000030
> +#define XCSI_SPKTR_DATA_SHIFT		8
> +#define XCSI_SPKTR_VC_SHIFT		6
> +#define XCSI_SPKTR_DT_SHIFT		0
> +#define XCSI_SPKTR_DATA_MASK		0x00FFFF00
> +#define XCSI_SPKTR_VC_MASK		0x000000C0
> +#define XCSI_SPKTR_DT_MASK		0x0000003F

GENMASK().

> +
> +#define XCSI_CLKINFR_OFFSET		0x0000003C
> +#define XCSI_CLKINFR_STOP_SHIFT		1
> +#define XCSI_CLKINFR_STOP_MASK		BIT(XCSI_CLKINFR_STOP_SHIFT)
> +
> +#define XCSI_L0INFR_OFFSET		0x00000040
> +#define XCSI_L1INFR_OFFSET		0x00000044
> +#define XCSI_L2INFR_OFFSET		0x00000048
> +#define XCSI_L3INFR_OFFSET		0x0000004C
> +#define XCSI_LXINFR_STOP_SHIFT		5
> +#define XCSI_LXINFR_SOTERR_SHIFT	1
> +#define XCSI_LXINFR_SOTSYNCERR_SHIFT	0
> +#define XCSI_LXINFR_STOP_MASK		BIT(XCSI_LXINFR_STOP_SHIFT)
> +#define XCSI_LXINFR_SOTERR_MASK		BIT(XCSI_LXINFR_SOTERR_SHIFT)
> +#define XCSI_LXINFR_SOTSYNCERR_MASK	BIT(XCSI_LXINFR_SOTSYNCERR_SHIFT)
> +
> +#define XCSI_VC0INF1R_OFFSET		0x00000060
> +#define XCSI_VC1INF1R_OFFSET		0x00000068
> +#define XCSI_VC2INF1R_OFFSET		0x00000070
> +#define XCSI_VC3INF1R_OFFSET		0x00000078
> +#define XCSI_VCXINF1R_LINECOUNT_SHIFT	16
> +#define XCSI_VCXINF1R_BYTECOUNT_SHIFT	0
> +#define XCSI_VCXINF1R_LINECOUNT_MASK	0xFFFF0000
> +#define XCSI_VCXINF1R_BYTECOUNT_MASK	0x0000FFFF
> +
> +#define XCSI_VC0INF2R_OFFSET		0x00000064
> +#define XCSI_VC1INF2R_OFFSET		0x0000006C
> +#define XCSI_VC2INF2R_OFFSET		0x00000074
> +#define XCSI_VC3INF2R_OFFSET		0x0000007C
> +#define XCSI_VCXINF2R_DATATYPE_SHIFT	0
> +#define XCSI_VCXINF2R_DATATYPE_MASK	0x0000003F
> +
> +#define XDPHY_CTRLREG_OFFSET		0x0
> +#define XDPHY_CTRLREG_DPHYEN_SHIFT	1
> +#define XDPHY_CTRLREG_DPHYEN_MASK	BIT(XDPHY_CTRLREG_DPHYEN_SHIFT)
> +
> +#define XDPHY_CLKSTATREG_OFFSET		0x18
> +#define XDPHY_CLKSTATREG_MODE_SHIFT	0
> +#define XDPHY_CLKSTATREG_MODE_MASK	0x3
> +#define XDPHY_LOW_POWER_MODE		0x0
> +#define XDPHY_HI_SPEED_MODE		0x1
> +#define XDPHY_ESC_MODE			0x2

Can d-phy be used for dsi or as a separate IP, so shoudln't it be
a separate phy driver?

> +
> +/*
> + * Interrupt mask
> + */
> +#define XCSI_INTR_MASK		(XCSI_ISR_ALLINTR_MASK & ~XCSI_ISR_STOP_MASK)

This can be grouped with interrupt register definitions.

> +/*
> + * Timeout for reset
> + */
> +#define XCSI_TIMEOUT_VAL	(1000) /* us */

Where do we get this value from? If not specified in any spec, this deserves
a comment how this value is derived.

> +
> +/*
> + * Max string length for CSI Data type string
> + */
> +#define MAX_XIL_CSIDT_STR_LENGTH 64
> +
> +/*
> + * Maximum number of short packet events per file handle.
> + */
> +#define XCSI_MAX_SPKT		(512)

Could you please explain how frequently the short packets can arrive?
'512' seems somewhat large, so some explanation may help.

> +
> +/* Number of media pads */
> +#define XILINX_CSI_MEDIA_PADS	(2)
> +
> +#define XCSI_DEFAULT_WIDTH	(1920)
> +#define XCSI_DEFAULT_HEIGHT	(1080)
> +
> +/*
> + * Macro to return "true" or "false" string if bit is set
> + */
> +#define XCSI_GET_BITSET_STR(val, mask)	(val) & (mask) ? "true" : "false"
> +
> +enum csi_datatypes {
> +	MIPI_CSI_DT_FRAME_START_CODE = 0x00,
> +	MIPI_CSI_DT_FRAME_END_CODE,
> +	MIPI_CSI_DT_LINE_START_CODE,
> +	MIPI_CSI_DT_LINE_END_CODE,
> +	MIPI_CSI_DT_SYNC_RSVD_04,
> +	MIPI_CSI_DT_SYNC_RSVD_05,
> +	MIPI_CSI_DT_SYNC_RSVD_06,
> +	MIPI_CSI_DT_SYNC_RSVD_07,
> +	MIPI_CSI_DT_GSPKT_08,
> +	MIPI_CSI_DT_GSPKT_09,
> +	MIPI_CSI_DT_GSPKT_0A,
> +	MIPI_CSI_DT_GSPKT_0B,
> +	MIPI_CSI_DT_GSPKT_0C,
> +	MIPI_CSI_DT_GSPKT_0D,
> +	MIPI_CSI_DT_GSPKT_0E,
> +	MIPI_CSI_DT_GSPKT_0F,
> +	MIPI_CSI_DT_GLPKT_10,
> +	MIPI_CSI_DT_GLPKT_11,
> +	MIPI_CSI_DT_GLPKT_12,
> +	MIPI_CSI_DT_GLPKT_13,
> +	MIPI_CSI_DT_GLPKT_14,
> +	MIPI_CSI_DT_GLPKT_15,
> +	MIPI_CSI_DT_GLPKT_16,
> +	MIPI_CSI_DT_GLPKT_17,
> +	MIPI_CSI_DT_YUV_420_8B,
> +	MIPI_CSI_DT_YUV_420_10B,
> +	MIPI_CSI_DT_YUV_420_8B_LEGACY,
> +	MIPI_CSI_DT_YUV_RSVD,
> +	MIPI_CSI_DT_YUV_420_8B_CSPS,
> +	MIPI_CSI_DT_YUV_420_10B_CSPS,
> +	MIPI_CSI_DT_YUV_422_8B,
> +	MIPI_CSI_DT_YUV_422_10B,
> +	MIPI_CSI_DT_RGB_444,
> +	MIPI_CSI_DT_RGB_555,
> +	MIPI_CSI_DT_RGB_565,
> +	MIPI_CSI_DT_RGB_666,
> +	MIPI_CSI_DT_RGB_888,
> +	MIPI_CSI_DT_RGB_RSVD_25,
> +	MIPI_CSI_DT_RGB_RSVD_26,
> +	MIPI_CSI_DT_RGB_RSVD_27,
> +	MIPI_CSI_DT_RAW_6,
> +	MIPI_CSI_DT_RAW_7,
> +	MIPI_CSI_DT_RAW_8,
> +	MIPI_CSI_DT_RAW_10,
> +	MIPI_CSI_DT_RAW_12,
> +	MIPI_CSI_DT_RAW_14,
> +	MIPI_CSI_DT_RAW_RSVD_2E,
> +	MIPI_CSI_DT_RAW_RSVD_2F,
> +	MIPI_CSI_DT_USER_30,
> +	MIPI_CSI_DT_USER_31,
> +	MIPI_CSI_DT_USER_32,
> +	MIPI_CSI_DT_USER_33,
> +	MIPI_CSI_DT_USER_34,
> +	MIPI_CSI_DT_USER_35,
> +	MIPI_CSI_DT_USER_36,
> +	MIPI_CSI_DT_USER_37,
> +	MIPI_CSI_DT_RSVD_38,
> +	MIPI_CSI_DT_RSVD_39,
> +	MIPI_CSI_DT_RSVD_3A,
> +	MIPI_CSI_DT_RSVD_3B,
> +	MIPI_CSI_DT_RSVD_3C,
> +	MIPI_CSI_DT_RSVD_3D,
> +	MIPI_CSI_DT_RSVD_3E,
> +	MIPI_CSI_DT_RSVD_3F
> +};

This seems to map to possible values for XCSI_VC*INF1R_OFFSET.
Then I'm not sure if enum is right type. You can have this under
the register definition. But up to you.

> +
> +/**
> + * struct pixel_format - Data Type to string name structure
> + * @pixelformat: MIPI CSI2 Data type
> + * @pixelformatstr: String name of Data Type
> + */
> +struct pixel_format {
> +	enum csi_datatypes pixelformat;
> +	char pixelformatstr[MAX_XIL_CSIDT_STR_LENGTH];
> +};
> +
> +/**
> + * struct xcsi2rxss_event - Event log structure
> + * @mask: Event mask
> + * @name: Name of the event
> + * @counter: Count number of events
> + */
> +struct xcsi2rxss_event {
> +	u32 mask;
> +	const char * const name;

Nit. Extra space.

> +	unsigned int counter;
> +};
> +
> +/*
> + * struct xcsi2rxss_core - Core configuration CSI2 Rx Subsystem device structure
> + * @dev: Platform structure

Incorrect description.

> + * @iomem: Base address of subsystem
> + * @irq: requested irq number
> + * @dphy_present: Flag for DPHY register interface presence
> + * @dphy_offset: DPHY registers offset
> + * @enable_active_lanes: If number of active lanes can be modified
> + * @max_num_lanes: Maximum number of lanes present
> + * @vfb: Video Format Bridge enabled or not
> + * @ppc: pixels per clock
> + * @vc: Virtual Channel
> + * @axis_tdata_width: AXI Stream data width
> + * @datatype: Data type filter
> + * @pxlformat: String with CSI pixel format from IP
> + * @num_lanes: Number of lanes requested from application
> + * @events: Structure to maintain event logs
> + */
> +struct xcsi2rxss_core {
> +	struct device *dev;
> +	void __iomem *iomem;
> +	int irq;
> +	u32 dphy_offset;

Is it guaranteed that the dphy register can be addressed with offset to
the csi register?

> +	bool dphy_present;
> +	bool enable_active_lanes;
> +	u32 max_num_lanes;
> +	bool vfb;
> +	u32 ppc;

This is parsed but not used.

> +	u32 vc;
> +	u32 axis_tdata_width;

This is not used. Do you want to keep it in sync with IP configs?

> +	u32 datatype;

Isn't this enum csi_datatypes?

> +	const char *pxlformat;
> +	u32 num_lanes;
> +	struct xcsi2rxss_event *events;
> +};
> +
> +/**
> + * struct xcsi2rxss_state - CSI2 Rx Subsystem device structure
> + * @core: Core structure for MIPI CSI2 Rx Subsystem
> + * @subdev: The v4l2 subdev structure
> + * @ctrl_handler: control handler
> + * @formats: Active V4L2 formats on each pad
> + * @default_format: default V4L2 media bus format
> + * @vip_format: format information corresponding to the active format
> + * @event: Holds the short packet event
> + * @lock: mutex for serializing operations
> + * @pads: media pads
> + * @npads: number of pads
> + * @streaming: Flag for storing streaming state
> + * @suspended: Flag for storing suspended state
> + *
> + * This structure contains the device driver related parameters
> + */
> +struct xcsi2rxss_state {
> +	struct xcsi2rxss_core core;
> +	struct v4l2_subdev subdev;
> +	struct v4l2_ctrl_handler ctrl_handler;
> +	struct v4l2_mbus_framefmt formats[2];
> +	struct v4l2_mbus_framefmt default_format;
> +	const struct xvip_video_format *vip_format;
> +	struct v4l2_event event;
> +	/*
> +	 * Used to serialize access.
> +	 */

It's a little not clear what access. It would be better to describe
what the lock protects.

> +	struct mutex lock;
> +	struct media_pad pads[XILINX_CSI_MEDIA_PADS];
> +	unsigned int npads;
> +	bool streaming;
> +	bool suspended;
> +};
> +
> +static inline struct xcsi2rxss_state *
> +to_xcsi2rxssstate(struct v4l2_subdev *subdev)
> +{
> +	return container_of(subdev, struct xcsi2rxss_state, subdev);
> +}
> +
> +/*
> + * Register related operations
> + */
> +static inline u32 xcsi2rxss_read(struct xcsi2rxss_core *xcsi2rxss,
> +				 u32 addr)
> +{
> +	return ioread32(xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_write(struct xcsi2rxss_core *xcsi2rxss,
> +				   u32 addr, u32 value)
> +{
> +	iowrite32(value, xcsi2rxss->iomem + addr);
> +}
> +
> +static inline void xcsi2rxss_clr(struct xcsi2rxss_core *xcsi2rxss,
> +				 u32 addr, u32 clr)
> +{
> +	xcsi2rxss_write(xcsi2rxss,
> +			addr,

I'd put this in the line above. But maybe it's just me.

> +			xcsi2rxss_read(xcsi2rxss, addr) & ~clr);
> +}
> +
> +static inline void xcsi2rxss_set(struct xcsi2rxss_core *xcsi2rxss,
> +				 u32 addr, u32 set)
> +{
> +	xcsi2rxss_write(xcsi2rxss,
> +			addr,
> +			xcsi2rxss_read(xcsi2rxss, addr) | set);
> +}
> +
> +static const struct pixel_format pixel_formats[] = {
> +	{ MIPI_CSI_DT_YUV_420_8B, "YUV420_8bit" },
> +	{ MIPI_CSI_DT_YUV_420_10B, "YUV420_10bit" },
> +	{ MIPI_CSI_DT_YUV_420_8B_LEGACY, "Legacy_YUV420_8bit" },
> +	{ MIPI_CSI_DT_YUV_420_8B_CSPS, "YUV420_8bit_CSPS" },
> +	{ MIPI_CSI_DT_YUV_420_10B_CSPS, "YUV420_10bit_CSPS" },
> +	{ MIPI_CSI_DT_YUV_422_8B, "YUV422_8bit" },
> +	{ MIPI_CSI_DT_YUV_422_10B, "YUV422_10bit" },
> +	{ MIPI_CSI_DT_RGB_444, "RGB444" },
> +	{ MIPI_CSI_DT_RGB_555, "RGB555" },
> +	{ MIPI_CSI_DT_RGB_565, "RGB565" },
> +	{ MIPI_CSI_DT_RGB_666, "RGB666" },
> +	{ MIPI_CSI_DT_RGB_888, "RGB888" },
> +	{ MIPI_CSI_DT_RAW_6, "RAW6" },
> +	{ MIPI_CSI_DT_RAW_7, "RAW7" },
> +	{ MIPI_CSI_DT_RAW_8, "RAW8" },
> +	{ MIPI_CSI_DT_RAW_10, "RAW10" },
> +	{ MIPI_CSI_DT_RAW_12, "RAW12" },
> +	{ MIPI_CSI_DT_RAW_14, "RAW14 "}
> +};
> +
> +static struct xcsi2rxss_event xcsi2rxss_events[] = {
> +	{ XCSI_ISR_FR_MASK, "Frame Received", 0 },
> +	{ XCSI_ISR_ILC_MASK, "Invalid Lane Count Error", 0 },
> +	{ XCSI_ISR_SPFIFOF_MASK, "Short Packet FIFO OverFlow Error", 0 },
> +	{ XCSI_ISR_SPFIFONE_MASK, "Short Packet FIFO Not Empty", 0 },
> +	{ XCSI_ISR_SLBF_MASK, "Streamline Buffer Full Error", 0 },
> +	{ XCSI_ISR_STOP_MASK, "Lane Stop State", 0 },
> +	{ XCSI_ISR_SOTERR_MASK, "SOT Error", 0 },
> +	{ XCSI_ISR_SOTSYNCERR_MASK, "SOT Sync Error", 0 },
> +	{ XCSI_ISR_ECC2BERR_MASK, "2 Bit ECC Unrecoverable Error", 0 },
> +	{ XCSI_ISR_ECC1BERR_MASK, "1 Bit ECC Recoverable Error", 0 },
> +	{ XCSI_ISR_CRCERR_MASK,	"CRC Error", 0 },
> +	{ XCSI_ISR_DATAIDERR_MASK, "Data Id Error", 0 },
> +	{ XCSI_ISR_VC3FSYNCERR_MASK, "Virtual Channel 3 Frame Sync Error", 0 },
> +	{ XCSI_ISR_VC3FLVLERR_MASK, "Virtual Channel 3 Frame Level Error", 0 },
> +	{ XCSI_ISR_VC2FSYNCERR_MASK, "Virtual Channel 2 Frame Sync Error", 0 },
> +	{ XCSI_ISR_VC2FLVLERR_MASK, "Virtual Channel 2 Frame Level Error", 0 },
> +	{ XCSI_ISR_VC1FSYNCERR_MASK, "Virtual Channel 1 Frame Sync Error", 0 },
> +	{ XCSI_ISR_VC1FLVLERR_MASK, "Virtual Channel 1 Frame Level Error", 0 },
> +	{ XCSI_ISR_VC0FSYNCERR_MASK, "Virtual Channel 0 Frame Sync Error", 0 },
> +	{ XCSI_ISR_VC0FLVLERR_MASK, "Virtual Channel 0 Frame Level Error", 0 }
> +};
> +
> +#define XMIPICSISS_NUM_EVENTS ARRAY_SIZE(xcsi2rxss_events)
> +
> +/**
> + * xcsi2rxss_clr_and_set - Clear and set the register with a bitmask
> + * @xcsi2rxss: Xilinx MIPI CSI2 Rx Subsystem subdev core struct
> + * @addr: address of register
> + * @clr: bitmask to be cleared
> + * @set: bitmask to be set
> + *
> + * Clear a bit(s) of mask @clr in the register at address @addr, then set
> + * a bit(s) of mask @set in the register after.
> + */
> +static void xcsi2rxss_clr_and_set(struct xcsi2rxss_core *xcsi2rxss,
> +				  u32 addr, u32 clr, u32 set)
> +{
> +	u32 reg;
> +
> +	reg = xcsi2rxss_read(xcsi2rxss, addr);
> +	reg &= ~clr;
> +	reg |= set;
> +	xcsi2rxss_write(xcsi2rxss, addr, reg);
> +}

This can be grouped with io operations above.

> +
> +/**
> + * xcsi2rxss_pxlfmtstrtodt - Convert pixel format string got from dts
> + * to data type.
> + * @pxlfmtstr: String obtained while parsing device node
> + *
> + * This function takes a CSI pixel format string obtained while parsing
> + * device tree node and converts it to data type.
> + *
> + * Eg. "RAW8" string is converted to 0x2A.
> + * Refer to MIPI CSI2 specification for details.
> + *
> + * Return: Equivalent pixel format value from table
> + */
> +static u32 xcsi2rxss_pxlfmtstrtodt(const char *pxlfmtstr)

Isn't this return type enum csi_datatypes?

> +{
> +	u32 i;
> +	u32 maxentries = ARRAY_SIZE(pixel_formats);

You can inline ARRAY_SIZE. Up to you.

> +
> +	for (i = 0; i < maxentries; i++) {
> +		if (!strncmp(pixel_formats[i].pixelformatstr,
> +			     pxlfmtstr, MAX_XIL_CSIDT_STR_LENGTH))
> +			return pixel_formats[i].pixelformat;
> +	}
> +
> +	return -EINVAL;

The return type is unsigned.

> +}
> +
> +/**
> + * xcsi2rxss_pxlfmtdttostr - Convert pixel format data type to string.
> + * @datatype: MIPI CSI-2 Data Type
> + *
> + * This function takes a CSI pixel format data type and returns a
> + * pointer to the string name.
> + *
> + * Eg. 0x2A returns "RAW8" string.
> + * Refer to MIPI CSI2 specification for details.
> + *
> + * Return: Equivalent pixel format string from table
> + */
> +static const char *xcsi2rxss_pxlfmtdttostr(u32 datatype)

Isn't this argument enum csi_datatypes?

> +{
> +	u32 i;
> +	u32 maxentries = ARRAY_SIZE(pixel_formats);
> +
> +	for (i = 0; i < maxentries; i++) {
> +		if (pixel_formats[i].pixelformat == datatype)
> +			return pixel_formats[i].pixelformatstr;
> +	}
> +
> +	return NULL;
> +}
> +
> +/**
> + * xcsi2rxss_enable - Enable or disable the CSI Core
> + * @core: Core Xilinx CSI2 Rx Subsystem structure pointer
> + * @flag: true for enabling, false for disabling
> + *
> + * This function enables/disables the MIPI CSI2 Rx Subsystem core.
> + * After enabling the CSI2 Rx core, the DPHY is enabled in case the
> + * register interface for it is present.
> + */
> +static void xcsi2rxss_enable(struct xcsi2rxss_core *core, bool flag)
> +{
> +	u32 dphyctrlregoffset = core->dphy_offset + XDPHY_CTRLREG_OFFSET;
> +
> +	if (flag) {
> +		xcsi2rxss_write(core, XCSI_CCR_OFFSET, XCSI_CCR_COREENB_MASK);
> +		if (core->dphy_present)
> +			xcsi2rxss_write(core, dphyctrlregoffset,
> +					XDPHY_CTRLREG_DPHYEN_MASK);
> +	} else {
> +		xcsi2rxss_write(core, XCSI_CCR_OFFSET, 0);
> +		if (core->dphy_present)
> +			xcsi2rxss_write(core, dphyctrlregoffset, 0);
> +	}
> +}
> +
> +/**
> + * xcsi2rxss_interrupts_enable - Enable or disable CSI interrupts
> + * @core: Core Xilinx CSI2 Rx Subsystem structure pointer
> + * @flag: true for enabling, false for disabling
> + *
> + * This function enables/disables the interrupts for the MIPI CSI2
> + * Rx Subsystem.
> + */
> +static void xcsi2rxss_interrupts_enable(struct xcsi2rxss_core *core, bool flag)
> +{
> +	if (flag) {
> +		xcsi2rxss_clr(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE_MASK);
> +		xcsi2rxss_write(core, XCSI_IER_OFFSET, XCSI_INTR_MASK);
> +		xcsi2rxss_set(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE_MASK);
> +	} else {
> +		xcsi2rxss_clr(core, XCSI_IER_OFFSET, XCSI_INTR_MASK);
> +		xcsi2rxss_clr(core, XCSI_GIER_OFFSET, XCSI_GIER_GIE_MASK);
> +	}
> +}

It would be cleaner if enable / disable functions are split. But up to you.

> +
> +/**
> + * xcsi2rxss_reset - Does a soft reset of the MIPI CSI2 Rx Subsystem
> + * @core: Core Xilinx CSI2 Rx Subsystem structure pointer
> + *
> + * Return: 0 - on success OR -ETIME if reset times out

Wouldn't -ETIMEDOUT be better for this? Up to you.

> + */
> +static int xcsi2rxss_reset(struct xcsi2rxss_core *core)
> +{
> +	u32 timeout = XCSI_TIMEOUT_VAL;
> +
> +	xcsi2rxss_set(core, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET_MASK);
> +
> +	while (xcsi2rxss_read(core, XCSI_CSR_OFFSET) & XCSI_CSR_RIPCD_MASK) {
> +		if (timeout == 0) {
> +			dev_err(core->dev, "Xilinx CSI2 Rx Subsystem Soft Reset Timeout!\n");
> +			return -ETIME;
> +		}
> +
> +		timeout--;
> +		udelay(1);
> +	}
> +
> +	xcsi2rxss_clr(core, XCSI_CCR_OFFSET, XCSI_CCR_SOFTRESET_MASK);
> +	return 0;
> +}
> +
> +/**
> + * xcsi2rxss_irq_handler - Interrupt handler for CSI-2
> + * @irq: IRQ number
> + * @dev_id: Pointer to device state
> + *
> + * In the interrupt handler, a list of event counters are updated for
> + * corresponding interrupts. This is useful to get status / debug.
> + * If the short packet FIFO not empty or overflow interrupt is received
> + * capture the short packet and notify of event occurrence
> + *
> + * Return: IRQ_HANDLED after handling interrupts
> + */
> +static irqreturn_t xcsi2rxss_irq_handler(int irq, void *dev_id)
> +{
> +	struct xcsi2rxss_state *state = (struct xcsi2rxss_state *)dev_id;
> +	struct xcsi2rxss_core *core = &state->core;
> +	u32 status;
> +
> +	status = xcsi2rxss_read(core, XCSI_ISR_OFFSET) & XCSI_INTR_MASK;
> +	dev_dbg(core->dev, "interrupt status = 0x%08x\n", status);
> +
> +	if (!status)
> +		return IRQ_NONE;
> +
> +	if (status & XCSI_ISR_SPFIFONE_MASK) {
> +		memset(&state->event, 0, sizeof(state->event));
> +
> +		state->event.type = V4L2_EVENT_XLNXCSIRX_SPKT;
> +
> +		*((u32 *)(&state->event.u.data)) =
> +			xcsi2rxss_read(core, XCSI_SPKTR_OFFSET);
> +
> +		v4l2_subdev_notify_event(&state->subdev, &state->event);
> +	}
> +
> +	if (status & XCSI_ISR_SPFIFOF_MASK) {
> +		dev_alert(core->dev, "Short packet FIFO overflowed\n");
> +
> +		memset(&state->event, 0, sizeof(state->event));
> +
> +		state->event.type = V4L2_EVENT_XLNXCSIRX_SPKT_OVF;
> +
> +		v4l2_subdev_notify_event(&state->subdev, &state->event);
> +	}
> +
> +	if (status & XCSI_ISR_SLBF_MASK) {
> +		dev_alert(core->dev, "Stream Line Buffer Full!\n");
> +
> +		memset(&state->event, 0, sizeof(state->event));
> +
> +		state->event.type = V4L2_EVENT_XLNXCSIRX_SLBF;
> +
> +		v4l2_subdev_notify_event(&state->subdev, &state->event);
> +	}
> +
> +	if (status & XCSI_ISR_ALLINTR_MASK) {
> +		unsigned int i;
> +
> +		for (i = 0; i < XMIPICSISS_NUM_EVENTS; i++) {
> +			if (!(status & core->events[i].mask))
> +				continue;
> +			core->events[i].counter++;
> +			dev_dbg(core->dev, "%s: %d\n", core->events[i].name,
> +				core->events[i].counter);
> +		}
> +	}
> +
> +	xcsi2rxss_write(core, XCSI_ISR_OFFSET, status);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void xcsi2rxss_reset_event_counters(struct xcsi2rxss_state *state)
> +{
> +	u32 i;
> +
> +	for (i = 0; i < XMIPICSISS_NUM_EVENTS; i++)
> +		state->core.events[i].counter = 0;
> +}
> +
> +/**
> + * xcsi2rxss_log_counters - Print out the event counters.
> + * @state: Pointer to device state
> + *
> + */
> +static void xcsi2rxss_log_counters(struct xcsi2rxss_state *state)
> +{
> +	u32 i;
> +
> +	for (i = 0; i < XMIPICSISS_NUM_EVENTS; i++) {
> +		if (state->core.events[i].counter > 0)
> +			v4l2_info(&state->subdev, "%s events: %d\n",
> +				  state->core.events[i].name,
> +				  state->core.events[i].counter);
> +	}
> +}
> +
> +/**
> + * xcsi2rxss_log_status - Logs the status of the CSI-2 Receiver
> + * @sd: Pointer to V4L2 subdevice structure
> + *
> + * This function prints the current status of Xilinx MIPI CSI-2
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_log_status(struct v4l2_subdev *sd)
> +{
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +	struct xcsi2rxss_core *core = &xcsi2rxss->core;
> +	u32 reg, data, i;
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	xcsi2rxss_log_counters(xcsi2rxss);
> +
> +	v4l2_info(sd, "***** Core Status *****\n");
> +	data = xcsi2rxss_read(core, XCSI_CSR_OFFSET);
> +	v4l2_info(sd, "Short Packet FIFO Full = %s\n",
> +		  XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFOFULL_MASK));
> +	v4l2_info(sd, "Short Packet FIFO Not Empty = %s\n",
> +		  XCSI_GET_BITSET_STR(data, XCSI_CSR_SPFIFONE_MASK));
> +	v4l2_info(sd, "Stream line buffer full = %s\n",
> +		  XCSI_GET_BITSET_STR(data, XCSI_CSR_SLBF_MASK));
> +	v4l2_info(sd, "Soft reset/Core disable in progress = %s\n",
> +		  XCSI_GET_BITSET_STR(data, XCSI_CSR_RIPCD_MASK));
> +
> +	/* Clk & Lane Info  */
> +	v4l2_info(sd, "******** Clock Lane Info *********\n");
> +	data = xcsi2rxss_read(core, XCSI_CLKINFR_OFFSET);
> +	v4l2_info(sd, "Clock Lane in Stop State = %s\n",
> +		  XCSI_GET_BITSET_STR(data, XCSI_CLKINFR_STOP_MASK));
> +
> +	v4l2_info(sd, "******** Data Lane Info *********\n");
> +	v4l2_info(sd, "Lane\tSoT Error\tSoT Sync Error\tStop State\n");
> +	reg = XCSI_L0INFR_OFFSET;
> +	for (i = 0; i < 4; i++) {
> +		data = xcsi2rxss_read(core, reg);
> +
> +		v4l2_info(sd, "%d\t%s\t\t%s\t\t%s\n",
> +			  i,
> +			  XCSI_GET_BITSET_STR(data, XCSI_LXINFR_SOTERR_MASK),
> +			  data & XCSI_LXINFR_SOTSYNCERR_MASK ? "true" : "false",

XCSI_GET_BITSET_STR()?

> +			  XCSI_GET_BITSET_STR(data, XCSI_LXINFR_STOP_MASK));
> +
> +		reg += 4;
> +	}
> +
> +	/* Virtual Channel Image Information */
> +	v4l2_info(sd, "********** Virtual Channel Info ************\n");
> +	v4l2_info(sd, "VC\tLine Count\tByte Count\tData Type\n");
> +	reg = XCSI_VC0INF1R_OFFSET;
> +	for (i = 0; i < 4; i++) {
> +		u32 line_count, byte_count, data_type;
> +		char *datatypestr;
> +
> +		/* Get line and byte count from VCXINFR1 Register */
> +		data = xcsi2rxss_read(core, reg);
> +		byte_count = (data & XCSI_VCXINF1R_BYTECOUNT_MASK) >>
> +				XCSI_VCXINF1R_BYTECOUNT_SHIFT;
> +		line_count = (data & XCSI_VCXINF1R_LINECOUNT_MASK) >>
> +				XCSI_VCXINF1R_LINECOUNT_SHIFT;
> +
> +		/* Get data type from VCXINFR2 Register */
> +		reg += 4;
> +		data = xcsi2rxss_read(core, reg);
> +		data_type = (data & XCSI_VCXINF2R_DATATYPE_MASK) >>
> +				XCSI_VCXINF2R_DATATYPE_SHIFT;
> +		datatypestr = (char *)xcsi2rxss_pxlfmtdttostr(data_type);
> +
> +		v4l2_info(sd, "%d\t%d\t\t%d\t\t%s\n",
> +			  i, line_count, byte_count, datatypestr);
> +
> +		/* Move to next pair of VC Info registers */
> +		reg += 4;
> +	}
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return 0;
> +}
> +
> +/*
> + * xcsi2rxss_subscribe_event - Subscribe to the custom short packet
> + * receive event.
> + * @sd: V4L2 Sub device
> + * @fh: V4L2 File Handle
> + * @sub: Subcribe event structure
> + *
> + * There are two types of events to be subscribed.
> + *
> + * First is to register for receiving a short packet.
> + * The short packets received are queued up in a FIFO.
> + * On reception of a short packet, an event will be generated
> + * with the short packet contents copied to its data area.
> + * Application subscribed to this event will poll for POLLPRI.
> + * On getting the event, the app dequeues the event to get the short packet
> + * data.
> + *
> + * Second is to register for Short packet FIFO overflow
> + * In case the rate of receiving short packets is high and
> + * the short packet FIFO overflows, this event will be triggered.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_subscribe_event(struct v4l2_subdev *sd,
> +				     struct v4l2_fh *fh,
> +				     struct v4l2_event_subscription *sub)
> +{
> +	int ret;
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	switch (sub->type) {
> +	case V4L2_EVENT_XLNXCSIRX_SPKT:
> +	case V4L2_EVENT_XLNXCSIRX_SPKT_OVF:
> +	case V4L2_EVENT_XLNXCSIRX_SLBF:
> +		ret = v4l2_event_subscribe(fh, sub, XCSI_MAX_SPKT, NULL);
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return ret;
> +}
> +
> +/**
> + * xcsi2rxss_unsubscribe_event - Unsubscribe from all events registered
> + * @sd: V4L2 Sub device
> + * @fh: V4L2 file handle
> + * @sub: pointer to Event unsubscription structure
> + *
> + * Return: zero on success, else a negative error code.
> + */
> +static int xcsi2rxss_unsubscribe_event(struct v4l2_subdev *sd,
> +				       struct v4l2_fh *fh,
> +				       struct v4l2_event_subscription *sub)
> +{
> +	int ret = 0;

No need to initialize.

> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +	ret = v4l2_event_unsubscribe(fh, sub);
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return ret;
> +}
> +
> +/**
> + * xcsi2rxss_s_ctrl - This is used to set the Xilinx MIPI CSI-2 V4L2 controls
> + * @ctrl: V4L2 control to be set
> + *
> + * This function is used to set the V4L2 controls for the Xilinx MIPI
> + * CSI-2 Rx Subsystem. It is used to set the active lanes in the system.
> + * The event counters can be reset.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	int ret = 0;
> +	u32 timeout = XCSI_TIMEOUT_VAL;
> +	u32 active_lanes = 1;
> +
> +	struct xcsi2rxss_state *xcsi2rxss =
> +		container_of(ctrl->handler,
> +			     struct xcsi2rxss_state, ctrl_handler);
> +	struct xcsi2rxss_core *core = &xcsi2rxss->core;
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_XILINX_MIPICSISS_ACT_LANES:
> +		/*
> +		 * This will be called only when "Enable Active Lanes" parameter
> +		 * is set in design
> +		 */

Then shouldn't it be checked here?

> +		xcsi2rxss_clr_and_set(core, XCSI_PCR_OFFSET,
> +				      XCSI_PCR_ACTLANES_MASK, ctrl->val - 1);
> +
> +		/*
> +		 * If the core is enabled, wait for active lanes to be
> +		 * set.
> +		 *
> +		 * If core is disabled or there is no clock from DPHY Tx
> +		 * then the read back won't reflect the updated value
> +		 * as the PPI clock will not be present.
> +		 */
> +
> +		if (core->dphy_present) {
> +			u32 dphyclkstatregoffset = core->dphy_offset +
> +							XDPHY_CLKSTATREG_OFFSET;
> +
> +			u32 dphyclkstat =
> +				xcsi2rxss_read(core, dphyclkstatregoffset) &
> +					XDPHY_CLKSTATREG_MODE_MASK;
> +
> +			u32 coreenable =
> +				xcsi2rxss_read(core, XCSI_CCR_OFFSET) &
> +					       XCSI_CCR_COREENB_MASK;
> +
> +			char lpmstr[] = "Low Power";
> +			char hsmstr[] = "High Speed";
> +			char esmstr[] = "Escape";

These can be removed and inlined directly.

> +			char *modestr;
> +
> +			switch (dphyclkstat) {
> +			case 0:
> +				modestr = lpmstr;
> +				break;
> +			case 1:
> +				modestr = hsmstr;
> +				break;
> +			case 2:
> +				modestr = esmstr;
> +				break;
> +			default:
> +				modestr = NULL;
> +				break;
> +			}
> +
> +			dev_dbg(core->dev, "DPHY Clock Lane in %s mode\n",
> +				modestr);

I'd do an array of strings, and do modestr[dphyclkstat]. But the dphyclkstate
should be checked to be in valid range

> +
> +			if (dphyclkstat == XDPHY_HI_SPEED_MODE &&
> +			    coreenable) {
> +				/* Wait for core to apply new active lanes */
> +				while (timeout--)
> +					udelay(1);

udelay(1000). Please specify where the delay is defined or from
some heuristics.

> +
> +				active_lanes =
> +					xcsi2rxss_read(core, XCSI_PCR_OFFSET);
> +				active_lanes &=	XCSI_PCR_ACTLANES_MASK;
> +				active_lanes++;
> +
> +				if (active_lanes != (u32)ctrl->val) {
> +					dev_err(core->dev, "Failed to set active lanes!\n");
> +					ret = -EAGAIN;
> +				}
> +			}
> +		} else {
> +			dev_dbg(core->dev, "No read back as no DPHY present.\n");

This should be more verbose level, ex info.

> +		}
> +
> +		dev_dbg(core->dev, "Set active lanes: requested = %d, active = %d\n",
> +			ctrl->val, active_lanes);
> +		break;
> +	case V4L2_CID_XILINX_MIPICSISS_RESET_COUNTERS:
> +		xcsi2rxss_reset_event_counters(xcsi2rxss);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return ret;
> +}
> +
> +/**
> + * xcsi2rxss_g_volatile_ctrl - get the Xilinx MIPI CSI-2 Rx controls
> + * @ctrl: Pointer to V4L2 control
> + *
> + * This is used to get the number of frames received by the Xilinx
> + * MIPI CSI-2 Rx.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	int ret = 0;
> +	struct xcsi2rxss_state *xcsi2rxss =
> +		container_of(ctrl->handler,
> +			     struct xcsi2rxss_state, ctrl_handler);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER:
> +		ctrl->val = xcsi2rxss->core.events[0].counter;
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return ret;
> +}
> +
> +static int xcsi2rxss_start_stream(struct xcsi2rxss_state *xcsi2rxss)
> +{
> +	int ret;
> +
> +	xcsi2rxss_enable(&xcsi2rxss->core, true);
> +
> +	ret = xcsi2rxss_reset(&xcsi2rxss->core);
> +	if (ret < 0)
> +		return ret;
> +
> +	xcsi2rxss_interrupts_enable(&xcsi2rxss->core, true);
> +
> +	return 0;
> +}
> +
> +static void xcsi2rxss_stop_stream(struct xcsi2rxss_state *xcsi2rxss)
> +{
> +	xcsi2rxss_interrupts_enable(&xcsi2rxss->core, false);
> +	xcsi2rxss_enable(&xcsi2rxss->core, false);
> +}
> +
> +/**
> + * xcsi2rxss_s_stream - It is used to start/stop the streaming.
> + * @sd: V4L2 Sub device
> + * @enable: Flag (True / False)
> + *
> + * This function controls the start or stop of streaming for the
> + * Xilinx MIPI CSI-2 Rx Subsystem provided the device isn't in
> + * suspended state.
> + *
> + * Return: 0 on success, errors otherwise
> + */
> +static int xcsi2rxss_s_stream(struct v4l2_subdev *sd, int enable)
> +{
> +	int ret = 0;
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	if (xcsi2rxss->suspended) {
> +		ret = -EBUSY;
> +		goto unlock;
> +	}
> +
> +	if (enable) {
> +		if (!xcsi2rxss->streaming) {
> +			/* reset the event counters */
> +			xcsi2rxss_reset_event_counters(xcsi2rxss);
> +
> +			ret = xcsi2rxss_start_stream(xcsi2rxss);
> +			if (ret == 0)
> +				xcsi2rxss->streaming = true;


Checking and Setting this 'streaming' flag in xcsi2rxss_start_stream()
would make more sense.

> +		}
> +	} else {
> +		if (xcsi2rxss->streaming) {
> +			xcsi2rxss_stop_stream(xcsi2rxss);
> +			xcsi2rxss->streaming = false;
> +		}
> +	}
> +unlock:
> +	mutex_unlock(&xcsi2rxss->lock);
> +	return ret;
> +}
> +
> +static struct v4l2_mbus_framefmt *
> +__xcsi2rxss_get_pad_format(struct xcsi2rxss_state *xcsi2rxss,
> +			   struct v4l2_subdev_pad_config *cfg,
> +			   unsigned int pad, u32 which)
> +{
> +	switch (which) {
> +	case V4L2_SUBDEV_FORMAT_TRY:
> +		return v4l2_subdev_get_try_format(&xcsi2rxss->subdev, cfg, pad);
> +	case V4L2_SUBDEV_FORMAT_ACTIVE:
> +		return &xcsi2rxss->formats[pad];
> +	default:
> +		return NULL;
> +	}
> +}
> +
> +/**
> + * xcsi2rxss_get_format - Get the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to get the pad format information.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_get_format(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_pad_config *cfg,
> +				struct v4l2_subdev_format *fmt)
> +{
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +	fmt->format = *__xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
> +						  fmt->pad, fmt->which);
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return 0;
> +}
> +
> +/**
> + * xcsi2rxss_set_format - This is used to set the pad format
> + * @sd: Pointer to V4L2 Sub device structure
> + * @cfg: Pointer to sub device pad information structure
> + * @fmt: Pointer to pad level media bus format
> + *
> + * This function is used to set the pad format.
> + * Since the pad format is fixed in hardware, it can't be
> + * modified on run time. So when a format set is requested by
> + * application, all parameters except the format type is
> + * saved for the pad and the original pad format is sent
> + * back to the application.

You can have a little more characters per line. :-)

> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_set_format(struct v4l2_subdev *sd,
> +				struct v4l2_subdev_pad_config *cfg,
> +				struct v4l2_subdev_format *fmt)
> +{
> +	struct v4l2_mbus_framefmt *__format;
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +	struct xcsi2rxss_core *core = &xcsi2rxss->core;
> +	u32 code;
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	/*
> +	 * Only the format->code parameter matters for CSI as the
> +	 * CSI format cannot be changed at runtime.
> +	 * Ensure that format to set is copied to over to CSI pad format
> +	 */
> +	__format = __xcsi2rxss_get_pad_format(xcsi2rxss, cfg,
> +					      fmt->pad, fmt->which);
> +
> +	/* Save the pad format code */
> +	code = __format->code;
> +
> +	/* If the bayer pattern to be set is SXXXX8 then only 1x8 type
> +	 * is supported and core's data type doesn't matter.
> +	 * In case the bayer pattern being set is SXXX10 then only
> +	 * 1x10 type are supported and core should be configured for RAW10.
> +	 * In case the bayer pattern being set is SXXX12 then only
> +	 * 1x12 type are supported and core should be configured for RAW12.
> +	 *
> +	 * Otherwise don't allow change.
> +	 */

Nit. Mutiline comment style.

> +	if ((fmt->format.code == MEDIA_BUS_FMT_SBGGR8_1X8 ||
> +	     fmt->format.code == MEDIA_BUS_FMT_SGBRG8_1X8 ||
> +	     fmt->format.code == MEDIA_BUS_FMT_SGRBG8_1X8 ||
> +	     fmt->format.code == MEDIA_BUS_FMT_SRGGB8_1X8) ||
> +	     (core->datatype == MIPI_CSI_DT_RAW_10 &&
> +	     (fmt->format.code == MEDIA_BUS_FMT_SBGGR10_1X10 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SGBRG10_1X10 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SGRBG10_1X10 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SRGGB10_1X10)) ||
> +	     (core->datatype == MIPI_CSI_DT_RAW_12 &&
> +	     (fmt->format.code == MEDIA_BUS_FMT_SBGGR12_1X12 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SGBRG12_1X12 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SGRBG12_1X12 ||
> +	      fmt->format.code == MEDIA_BUS_FMT_SRGGB12_1X12))) {
> +		/* Copy over the format to be set */
> +		*__format = fmt->format;
> +	} else {
> +		/* Restore the original pad format code */
> +		fmt->format.code = code;
> +		__format->code = code;
> +	}
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return 0;
> +}
> +
> +/**
> + * xcsi2rxss_open - Called on v4l2_open()
> + * @sd: Pointer to V4L2 sub device structure
> + * @fh: Pointer to V4L2 File handle
> + *
> + * This function is called on v4l2_open(). It sets the default format
> + * for both pads.
> + *
> + * Return: 0 on success
> + */
> +static int xcsi2rxss_open(struct v4l2_subdev *sd,
> +			  struct v4l2_subdev_fh *fh)
> +{
> +	struct v4l2_mbus_framefmt *format;
> +	struct xcsi2rxss_state *xcsi2rxss = to_xcsi2rxssstate(sd);
> +
> +	format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
> +	*format = xcsi2rxss->default_format;
> +
> +	format = v4l2_subdev_get_try_format(sd, fh->pad, 1);
> +	*format = xcsi2rxss->default_format;
> +
> +	return 0;
> +}
> +
> +static int xcsi2rxss_close(struct v4l2_subdev *sd,
> +			   struct v4l2_subdev_fh *fh)
> +{
> +	return 0;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Media Operations
> + */
> +
> +static const struct media_entity_operations xcsi2rxss_media_ops = {
> +	.link_validate = v4l2_subdev_link_validate
> +};
> +
> +static const struct v4l2_ctrl_ops xcsi2rxss_ctrl_ops = {
> +	.g_volatile_ctrl = xcsi2rxss_g_volatile_ctrl,
> +	.s_ctrl	= xcsi2rxss_s_ctrl
> +};
> +
> +static struct v4l2_ctrl_config xcsi2rxss_ctrls[] = {
> +	{
> +		.ops	= &xcsi2rxss_ctrl_ops,
> +		.id	= V4L2_CID_XILINX_MIPICSISS_ACT_LANES,
> +		.name	= "MIPI CSI2 Rx Subsystem: Active Lanes",
> +		.type	= V4L2_CTRL_TYPE_INTEGER,
> +		.min	= 1,
> +		.max	= 4,
> +		.step	= 1,
> +		.def	= 1,
> +	}, {
> +		.ops	= &xcsi2rxss_ctrl_ops,
> +		.id	= V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER,
> +		.name	= "MIPI CSI2 Rx Subsystem: Frames Received Counter",
> +		.type	= V4L2_CTRL_TYPE_INTEGER,
> +		.min	= 0,
> +		.max	= 0xFFFFFFFF,
> +		.step	= 1,
> +		.def	= 0,
> +		.flags	= V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
> +	}, {
> +		.ops	= &xcsi2rxss_ctrl_ops,
> +		.id	= V4L2_CID_XILINX_MIPICSISS_RESET_COUNTERS,
> +		.name	= "MIPI CSI2 Rx Subsystem: Reset Counters",
> +		.type	= V4L2_CTRL_TYPE_BUTTON,
> +		.min	= 0,
> +		.max	= 1,
> +		.step	= 1,
> +		.def	= 0,
> +		.flags	= V4L2_CTRL_FLAG_WRITE_ONLY,
> +	}
> +};
> +
> +static const struct v4l2_subdev_core_ops xcsi2rxss_core_ops = {
> +	.log_status = xcsi2rxss_log_status,
> +	.subscribe_event = xcsi2rxss_subscribe_event,
> +	.unsubscribe_event = xcsi2rxss_unsubscribe_event
> +};
> +
> +static struct v4l2_subdev_video_ops xcsi2rxss_video_ops = {
> +	.s_stream = xcsi2rxss_s_stream
> +};
> +
> +static struct v4l2_subdev_pad_ops xcsi2rxss_pad_ops = {
> +	.get_fmt = xcsi2rxss_get_format,
> +	.set_fmt = xcsi2rxss_set_format,
> +};
> +
> +static struct v4l2_subdev_ops xcsi2rxss_ops = {
> +	.core = &xcsi2rxss_core_ops,
> +	.video = &xcsi2rxss_video_ops,
> +	.pad = &xcsi2rxss_pad_ops
> +};
> +
> +static const struct v4l2_subdev_internal_ops xcsi2rxss_internal_ops = {
> +	.open = xcsi2rxss_open,
> +	.close = xcsi2rxss_close
> +};
> +
> +/* -----------------------------------------------------------------------------
> + * Power Management
> + */
> +
> +/*
> + * xcsi2rxss_pm_suspend - Function called on Power Suspend
> + * @dev: Pointer to device structure
> + *
> + * On power suspend the CSI-2 Core is disabled if the device isn't
> + * in suspended state and is streaming.
> + *
> + * Return: 0 on success
> + */
> +static int __maybe_unused xcsi2rxss_pm_suspend(struct device *dev)
> +{
> +	struct xcsi2rxss_state *xcsi2rxss = dev_get_drvdata(dev);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	if (!xcsi2rxss->suspended && xcsi2rxss->streaming)
> +		xcsi2rxss_clr(&xcsi2rxss->core,
> +			      XCSI_CCR_OFFSET, XCSI_CCR_COREENB_MASK);

Isn't it needed to store and restore the register values? The registers will be
reset to default When suspending the FPGA.

> +
> +	xcsi2rxss->suspended = true;
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +
> +	return 0;
> +}
> +
> +/*
> + * xcsi2rxss_pm_resume - Function called on Power Resume
> + * @dev: Pointer to device structure
> + *
> + * On power resume the CSI-2 Core is enabled when it is in suspended state
> + * and prior to entering suspended state it was streaming.
> + *
> + * Return: 0 on success
> + */
> +static int __maybe_unused xcsi2rxss_pm_resume(struct device *dev)
> +{
> +	struct xcsi2rxss_state *xcsi2rxss = dev_get_drvdata(dev);
> +
> +	mutex_lock(&xcsi2rxss->lock);
> +
> +	if (xcsi2rxss->suspended && xcsi2rxss->streaming)
> +		xcsi2rxss_set(&xcsi2rxss->core,
> +			      XCSI_CCR_OFFSET, XCSI_CCR_COREENB_MASK);
> +
> +	xcsi2rxss->suspended = false;
> +
> +	mutex_unlock(&xcsi2rxss->lock);
> +	return 0;
> +}
> +
> +/* -----------------------------------------------------------------------------
> + * Platform Device Driver
> + */
> +
> +static int xcsi2rxss_parse_of(struct xcsi2rxss_state *xcsi2rxss)
> +{
> +	struct device_node *node = xcsi2rxss->core.dev->of_node;
> +	struct device_node *ports = NULL;
> +	struct device_node *port = NULL;
> +	unsigned int nports = 0;
> +	struct xcsi2rxss_core *core = &xcsi2rxss->core;
> +	int ret;
> +	bool iic_present;
> +
> +	core->dphy_present = of_property_read_bool(node, "xlnx,dphy-present");
> +	dev_dbg(core->dev, "DPHY present property = %s\n",
> +		core->dphy_present ? "Present" : "Absent");
> +
> +	iic_present = of_property_read_bool(node, "xlnx,iic-present");
> +	dev_dbg(core->dev, "IIC present property = %s\n",
> +		iic_present ? "Present" : "Absent");
> +
> +	if (core->dphy_present) {
> +		if (iic_present)
> +			core->dphy_offset = 0x20000;
> +		else
> +			core->dphy_offset = 0x10000;

Could you please when this information can be found? I couldn't find any
relevant information in the product guide. For example, in the dt binding
example, this goes beyond the specified size of register, 0x20000.

> +	}
> +
> +	ret = of_property_read_u32(node, "xlnx,max-lanes",
> +				   &core->max_num_lanes);
> +	if (ret < 0) {
> +		dev_err(core->dev, "missing xlnx,max-lanes property\n");
> +		return ret;
> +	}
> +
> +	if (core->max_num_lanes > 4 || core->max_num_lanes < 1) {
> +		dev_err(core->dev, "%d max lanes : invalid xlnx,max-lanes property\n",
> +			core->max_num_lanes);
> +		return -EINVAL;
> +	}
> +
> +	ret = of_property_read_u32(node, "xlnx,vc", &core->vc);
> +	if (ret < 0) {
> +		dev_err(core->dev, "missing xlnx,vc property\n");
> +		return ret;
> +	}
> +	if (core->vc > 4) {
> +		dev_err(core->dev, "invalid virtual channel property value.\n");
> +		return -EINVAL;
> +	}
> +
> +	core->enable_active_lanes =
> +		of_property_read_bool(node, "xlnx,en-active-lanes");
> +	dev_dbg(core->dev, "Enable active lanes property = %s\n",
> +		core->enable_active_lanes ? "Present" : "Absent");
> +
> +	ret = of_property_read_string(node, "xlnx,csi-pxl-format",
> +				      &core->pxlformat);
> +	if (ret < 0) {
> +		dev_err(core->dev, "missing xlnx,csi-pxl-format property\n");
> +		return ret;
> +	}
> +
> +	core->datatype = xcsi2rxss_pxlfmtstrtodt(core->pxlformat);
> +	if (core->datatype < MIPI_CSI_DT_YUV_420_8B ||
> +	    core->datatype > MIPI_CSI_DT_RAW_14) {
> +		dev_err(core->dev, "Invalid xlnx,csi-pxl-format string\n");
> +		return -EINVAL;
> +	}
> +
> +	core->vfb = of_property_read_bool(node, "xlnx,vfb");
> +	dev_dbg(core->dev, "Video Format Bridge property = %s\n",
> +		core->vfb ? "Present" : "Absent");
> +
> +	if (core->vfb) {
> +		ret = of_property_read_u32(node, "xlnx,ppc", &core->ppc);
> +		if (ret < 0 || !(core->ppc == 1 || core->ppc == 2 ||
> +				 core->ppc == 4)) {
> +			dev_err(core->dev, "Invalid xlnx,ppc property ret = %d ppc = %d\n",
> +				ret, core->ppc);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	ports = of_get_child_by_name(node, "ports");
> +	if (!ports)
> +		ports = node;
> +
> +	for_each_child_of_node(ports, port) {
> +		int ret;
> +		const struct xvip_video_format *format;
> +		struct device_node *endpoint;
> +		struct v4l2_fwnode_endpoint v4lendpoint;
> +
> +		if (!port->name || of_node_cmp(port->name, "port"))
> +			continue;
> +
> +		/*
> +		 * Currently only a subset of VFB enabled formats present in
> +		 * xvip are supported in the  driver.
> +		 *
> +		 * If the VFB is disabled, the pixels per clock don't matter.
> +		 * The data width is either 32 or 64 bit as selected in design.
> +		 *
> +		 * For e.g. If Data Type is RGB888, VFB is disabled and
> +		 * data width is 32 bits.
> +		 *
> +		 * Clk Cycle  |  Byte 0  |  Byte 1  |  Byte 2  |  Byte 3
> +		 * -----------+----------+----------+----------+----------
> +		 *     1      |     B0   |     G0   |     R0   |     B1
> +		 *     2      |     G1   |     R1   |     B2   |     G2
> +		 *     3      |     R2   |     B3   |     G3   |     R3
> +		 */
> +		format = xvip_of_get_format(port);
> +		if (IS_ERR(format)) {
> +			dev_err(core->dev, "invalid format in DT");
> +			return PTR_ERR(format);
> +		}
> +
> +		if (core->vfb &&
> +		    format->vf_code != XVIP_VF_YUV_422 &&
> +		    format->vf_code != XVIP_VF_RBG &&
> +		    format->vf_code != XVIP_VF_MONO_SENSOR) {
> +			dev_err(core->dev, "Invalid UG934 video format set.\n");
> +			return -EINVAL;
> +		}
> +
> +		/* Get and check the format description */
> +		if (!xcsi2rxss->vip_format) {
> +			xcsi2rxss->vip_format = format;
> +		} else if (xcsi2rxss->vip_format != format) {
> +			dev_err(core->dev, "in/out format mismatch in DT");
> +			return -EINVAL;
> +		}
> +
> +		endpoint = of_get_next_child(port, NULL);
> +		if (!endpoint) {
> +			dev_err(core->dev, "No port at\n");
> +			return -EINVAL;
> +		}
> +
> +		ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
> +						 &v4lendpoint);

You can have a single of_node_put(endpoint); here.

> +		if (ret) {
> +			of_node_put(endpoint);
> +			return ret;
> +		}
> +
> +		of_node_put(endpoint);
> +		dev_dbg(core->dev, "%s : port %d bus type = %d\n",
> +			__func__, nports, v4lendpoint.bus_type);
> +
> +		if (v4lendpoint.bus_type == V4L2_MBUS_CSI2) {
> +			dev_dbg(core->dev, "%s : base.port = %d base.id = %d\n",
> +				__func__, v4lendpoint.base.port,
> +				v4lendpoint.base.id);
> +
> +			dev_dbg(core->dev, "%s : mipi number lanes = %d\n",
> +				__func__,
> +				v4lendpoint.bus.mipi_csi2.num_data_lanes);
> +		} else {
> +			dev_dbg(core->dev, "%s : Not a CSI2 bus\n", __func__);
> +		}
> +
> +		/* Count the number of ports. */
> +		nports++;
> +	}
> +
> +	if (nports != 2) {
> +		dev_err(core->dev, "invalid number of ports %u\n", nports);
> +		return -EINVAL;
> +	}
> +	xcsi2rxss->npads = nports;
> +
> +	/*Register interrupt handler */

Nit. A space.

> +	core->irq = irq_of_parse_and_map(node, 0);
> +
> +	ret = devm_request_irq(core->dev, core->irq, xcsi2rxss_irq_handler,
> +			       IRQF_SHARED, "xilinx-csi2rxss", xcsi2rxss);
> +	if (ret) {
> +		dev_err(core->dev, "Err = %d Interrupt handler reg failed!\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int xcsi2rxss_probe(struct platform_device *pdev)
> +{
> +	struct v4l2_subdev *subdev;
> +	struct xcsi2rxss_state *xcsi2rxss;
> +	struct resource *res;
> +
> +	u32 i;
> +	int ret;
> +	int num_ctrls;
> +
> +	xcsi2rxss = devm_kzalloc(&pdev->dev, sizeof(*xcsi2rxss), GFP_KERNEL);
> +	if (!xcsi2rxss)
> +		return -ENOMEM;
> +
> +	mutex_init(&xcsi2rxss->lock);
> +
> +	xcsi2rxss->core.dev = &pdev->dev;
> +
> +	ret = xcsi2rxss_parse_of(xcsi2rxss);
> +	if (ret < 0)
> +		return ret;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	xcsi2rxss->core.iomem = devm_ioremap_resource(xcsi2rxss->core.dev, res);
> +	if (IS_ERR(xcsi2rxss->core.iomem))
> +		return PTR_ERR(xcsi2rxss->core.iomem);
> +
> +	/*
> +	 * Reset and initialize the core.
> +	 */
> +	xcsi2rxss_reset(&xcsi2rxss->core);
> +
> +	xcsi2rxss->core.events =  (struct xcsi2rxss_event *)&xcsi2rxss_events;

Nit. There are double spaces here.

> +
> +	/* Initialize V4L2 subdevice and media entity */
> +	xcsi2rxss->pads[0].flags = MEDIA_PAD_FL_SOURCE;
> +	xcsi2rxss->pads[1].flags = MEDIA_PAD_FL_SINK;
> +
> +	/* Initialize the default format */
> +	memset(&xcsi2rxss->default_format, 0,
> +	       sizeof(xcsi2rxss->default_format));
> +	xcsi2rxss->default_format.code = xcsi2rxss->vip_format->code;
> +	xcsi2rxss->default_format.field = V4L2_FIELD_NONE;
> +	xcsi2rxss->default_format.colorspace = V4L2_COLORSPACE_SRGB;
> +	xcsi2rxss->default_format.width = XCSI_DEFAULT_WIDTH;
> +	xcsi2rxss->default_format.height = XCSI_DEFAULT_HEIGHT;
> +
> +	xcsi2rxss->formats[0] = xcsi2rxss->default_format;
> +	xcsi2rxss->formats[1] = xcsi2rxss->default_format;
> +
> +	/* Initialize V4L2 subdevice and media entity */
> +	subdev = &xcsi2rxss->subdev;
> +	v4l2_subdev_init(subdev, &xcsi2rxss_ops);
> +
> +	subdev->dev = &pdev->dev;
> +	subdev->internal_ops = &xcsi2rxss_internal_ops;
> +	strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
> +
> +	subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
> +
> +	subdev->entity.ops = &xcsi2rxss_media_ops;
> +
> +	v4l2_set_subdevdata(subdev, xcsi2rxss);
> +
> +	ret = media_entity_pads_init(&subdev->entity, 2, xcsi2rxss->pads);
> +	if (ret < 0)
> +		goto error;
> +
> +	/*
> +	 * In case the Enable Active Lanes config parameter is not set,
> +	 * dynamic lane reconfiguration is not allowed.
> +	 * So V4L2_CID_XILINX_MIPICSISS_ACT_LANES ctrl will not be registered.
> +	 * Accordingly allocate the number of controls
> +	 */
> +	num_ctrls = ARRAY_SIZE(xcsi2rxss_ctrls);
> +
> +	if (!xcsi2rxss->core.enable_active_lanes)
> +		num_ctrls--;
> +
> +	dev_dbg(xcsi2rxss->core.dev, "# of ctrls = %d\n", num_ctrls);
> +
> +	v4l2_ctrl_handler_init(&xcsi2rxss->ctrl_handler, num_ctrls);
> +
> +	for (i = 0; i < ARRAY_SIZE(xcsi2rxss_ctrls); i++) {
> +		struct v4l2_ctrl *ctrl;
> +
> +		if (xcsi2rxss_ctrls[i].id ==
> +			V4L2_CID_XILINX_MIPICSISS_ACT_LANES) {
> +			if (xcsi2rxss->core.enable_active_lanes) {
> +				xcsi2rxss_ctrls[i].max =
> +					xcsi2rxss->core.max_num_lanes;
> +			} else {
> +				/* Don't register control */
> +				dev_dbg(xcsi2rxss->core.dev,
> +					"Skip active lane control\n");
> +				continue;
> +			}

I'd do this without else:
	if (!xcsi2rxss->core.enable_active_lanes) {
		/* Don't register control */
		dev_dbg(xcsi2rxss->core.dev,
			"Skip active lane control\n");
		continue;
	}
	xcsi2rxss_ctrls[i].max = xcsi2rxss->core.max_num_lanes;

> +		}
> +
> +		dev_dbg(xcsi2rxss->core.dev, "%d ctrl = 0x%x\n",
> +			i, xcsi2rxss_ctrls[i].id);
> +		ctrl = v4l2_ctrl_new_custom(&xcsi2rxss->ctrl_handler,
> +					    &xcsi2rxss_ctrls[i], NULL);
> +		if (!ctrl) {
> +			dev_err(xcsi2rxss->core.dev, "Failed for %s ctrl\n",
> +				xcsi2rxss_ctrls[i].name);
> +			goto error;
> +		}
> +	}
> +
> +	dev_dbg(xcsi2rxss->core.dev, "# v4l2 ctrls registered = %d\n", i - 1);
> +
> +	if (xcsi2rxss->ctrl_handler.error) {
> +		dev_err(&pdev->dev, "failed to add controls\n");
> +		ret = xcsi2rxss->ctrl_handler.error;
> +		goto error;
> +	}
> +
> +	subdev->ctrl_handler = &xcsi2rxss->ctrl_handler;
> +
> +	ret = v4l2_ctrl_handler_setup(&xcsi2rxss->ctrl_handler);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to set controls\n");
> +		goto error;
> +	}
> +
> +	platform_set_drvdata(pdev, xcsi2rxss);
> +
> +	dev_info(xcsi2rxss->core.dev, "Xilinx CSI2 Rx Subsystem device found!\n");
> +
> +	ret = v4l2_async_register_subdev(subdev);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to register subdev\n");
> +		goto error;
> +	}
> +
> +	/* default states for streaming and suspend */
> +	xcsi2rxss->streaming = false;
> +	xcsi2rxss->suspended = false;

Are these needed?

> +	return 0;
> +
> +error:
> +	v4l2_ctrl_handler_free(&xcsi2rxss->ctrl_handler);
> +	media_entity_cleanup(&subdev->entity);
> +	mutex_destroy(&xcsi2rxss->lock);
> +
> +	return ret;
> +}
> +
> +static int xcsi2rxss_remove(struct platform_device *pdev)
> +{
> +	struct xcsi2rxss_state *xcsi2rxss = platform_get_drvdata(pdev);
> +	struct v4l2_subdev *subdev = &xcsi2rxss->subdev;
> +
> +	v4l2_async_unregister_subdev(subdev);
> +	v4l2_ctrl_handler_free(&xcsi2rxss->ctrl_handler);
> +	media_entity_cleanup(&subdev->entity);
> +	mutex_destroy(&xcsi2rxss->lock);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(xcsi2rxss_pm_ops,
> +			 xcsi2rxss_pm_suspend, xcsi2rxss_pm_resume);
> +
> +static const struct of_device_id xcsi2rxss_of_id_table[] = {
> +	{ .compatible = "xlnx,mipi-csi2-rx-subsystem-2.0" },
> +	{ .compatible = "xlnx,mipi-csi2-rx-subsystem-3.0" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, xcsi2rxss_of_id_table);
> +
> +static struct platform_driver xcsi2rxss_driver = {
> +	.driver = {
> +		.name		= "xilinx-csi2rxss",
> +		.pm		= &xcsi2rxss_pm_ops,
> +		.of_match_table	= xcsi2rxss_of_id_table,
> +	},
> +	.probe			= xcsi2rxss_probe,
> +	.remove			= xcsi2rxss_remove,
> +};
> +module_platform_driver(xcsi2rxss_driver);
> +MODULE_AUTHOR("Vishal Sagar <vishal.sagar@xilinx.com>");
> +MODULE_DESCRIPTION("Xilinx MIPI CSI2 Rx Subsystem Driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/uapi/linux/xilinx-csi2rxss.h b/include/uapi/linux/xilinx-csi2rxss.h
> new file mode 100644
> index 0000000..973d5b46
> --- /dev/null
> +++ b/include/uapi/linux/xilinx-csi2rxss.h

Would it make sense to create one generic file for Xilinx specific events?

Thanks,
-hyun

> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
> +/*
> + * Events from Xilinx MIPI CSI2 Rx Subsystem exposed to V4L2 application.
> + *
> + * Copyright (C) 2016 - 2018 Xilinx, Inc.
> + * Author: Vishal Sagar <vishal.sagar@xilinx.com>
> + */
> +#ifndef __UAPI_XILINX_CSI2RXSS_H__
> +#define __UAPI_XILINX_CSI2RXSS_H__
> +
> +#include <linux/videodev2.h>
> +
> +/*
> + * Events
> + *
> + * V4L2_EVENT_XLNXCSIRX_SPKT: Short packet received
> + * V4L2_EVENT_XLNXCSIRX_SPKT_OVF: Short packet FIFO overflow
> + * V4L2_EVENT_XLNXCSIRX_SLBF: Stream line buffer full
> + */
> +#define V4L2_EVENT_XLNXCSIRX_CLASS	(V4L2_EVENT_PRIVATE_START | 0x100)
> +#define V4L2_EVENT_XLNXCSIRX_SPKT	(V4L2_EVENT_XLNXCSIRX_CLASS | 0x1)
> +#define V4L2_EVENT_XLNXCSIRX_SPKT_OVF	(V4L2_EVENT_XLNXCSIRX_CLASS | 0x2)
> +#define V4L2_EVENT_XLNXCSIRX_SLBF	(V4L2_EVENT_XLNXCSIRX_CLASS | 0x3)
> +
> +#endif /* __UAPI_XILINX_CSI2RXSS_H__ */
> diff --git a/include/uapi/linux/xilinx-v4l2-controls.h b/include/uapi/linux/xilinx-v4l2-controls.h
> index b6441fe..4ca3b44 100644
> --- a/include/uapi/linux/xilinx-v4l2-controls.h
> +++ b/include/uapi/linux/xilinx-v4l2-controls.h
> @@ -71,4 +71,18 @@
>  /* Noise level */
>  #define V4L2_CID_XILINX_TPG_NOISE_GAIN		(V4L2_CID_XILINX_TPG + 17)
>  
> +/*
> + * Xilinx MIPI CSI2 Rx Subsystem
> + */
> +
> +/* Base ID */
> +#define V4L2_CID_XILINX_MIPICSISS		(V4L2_CID_USER_BASE + 0xc080)
> +
> +/* Active Lanes */
> +#define V4L2_CID_XILINX_MIPICSISS_ACT_LANES	(V4L2_CID_XILINX_MIPICSISS + 1)
> +/* Frames received since streaming is set */
> +#define V4L2_CID_XILINX_MIPICSISS_FRAME_COUNTER	(V4L2_CID_XILINX_MIPICSISS + 2)
> +/* Reset all event counters */
> +#define V4L2_CID_XILINX_MIPICSISS_RESET_COUNTERS (V4L2_CID_XILINX_MIPICSISS + 3)
> +
>  #endif /* __UAPI_XILINX_V4L2_CONTROLS_H__ */
> -- 
> 2.7.4
> 
> 

^ permalink raw reply

* [PATCH] kbuild: add machine size to CHEKCFLAGS
From: Masahiro Yamada @ 2018-05-31  1:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMHZB6GXVPvr1uwbemuxqPPtNzYT7jeVokR6q9tz2mS_=TG6vA@mail.gmail.com>

2018-05-31 8:06 GMT+09:00 Luc Van Oostenryck <luc.vanoostenryck@gmail.com>:
> On Thu, May 31, 2018 at 12:00 AM, Andreas F?rber <afaerber@suse.de> wrote:
>> Hi Luc,
>>
>> The typo in the subject made me curious...
>>
>> Am 30.05.2018 um 22:48 schrieb Luc Van Oostenryck:
>>> By default, sparse assumes a 64bit machine when compiled on x86-64
>>> and 32bit when compiled on anything else.
>>>
>>> This can of course create all sort of problems for the other archs, like
>>> issuing false warnings ('shift too big (32) for type unsigned long'), or
>>> worse, failing to emit legitimate warnings.
>>>
>>> Fix this by adding the -m32/-m64 flag, depending on CONFIG_64BIT,
>>> to CHECKFLAGS in the main Makefile (and so for all archs).
>>> Also, remove the now unneeded -m32/-m64 in arch specific Makefiles.
>>>
>>> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
>>> ---
>>>  Makefile             | 3 +++
>>>  arch/alpha/Makefile  | 2 +-
>>>  arch/arm/Makefile    | 2 +-
>>>  arch/arm64/Makefile  | 2 +-
>>>  arch/ia64/Makefile   | 2 +-
>>>  arch/mips/Makefile   | 3 ---
>>>  arch/parisc/Makefile | 2 +-
>>>  arch/sparc/Makefile  | 2 +-
>>>  arch/x86/Makefile    | 2 +-
>>>  9 files changed, 10 insertions(+), 10 deletions(-)
>>
>> What about the architectures not touched by your patch that previously
>> had no -m32/-m64? (arc, c6x, h8300, hexagon, m68k, microblaze, nds32,
>> nios2, openrisc, powerpc, riscv, s390, sh, unicore32, xtensa)
>
> As explained in the patch, by default sparse uses -m64 if compiled on x86-64
> and 32bit on everything else (well, more recent versions use -m64 if
> compiled on any 64 bit machine). I think that most ppc devs use a ppc
> machine and so ppc was most probably fine (at least ppc64) but I suspect
> that most of these others archs either had never sparse used on them
> or had a lot of wrong warnings. IOW, it was maybe OK but most probably
> incorrect for them and now it is OK.
>
>> You forgot to CC them on this patch.
>
> I didn't thought/knew  it was needed and the CC list is already
> quite long but, if needed, no problem for me.
>
>> Have you really checked that all their toolchains support the -m32/-m64
>> flags you newly introduce for them? Apart from non-biarch architectures,
>> I'm thinking of 31-bit s390 as a corner case where !64 != 32.
>
> Hmm, there is no change to anything I call 'toolchain related', like
> compiler and linker. The only change is sparse (or any other checker)
> receiving now a correct and explicit -m32 or -m64.


Right.  We are talking about sparse.
Nobody needs to test vmlinux or whatever objects.

Except the typo in the subject (I can locally fix it up, though),
this patch looks good to me.






> For s390, as far as I know:
> 1) it has CONFIG_64BIT unconditionally definee (because the old 31bit
>    is no more supported, now everything is s390x only).
> 2) even if the *address space* was only 31 bit, I'm very sure
>    that sizeof(long) and sizeof(void*) was 4 on these machine
>    hence -m32 would have been correct.
>
> Best regards,
> -- Luc
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Masahiro Yamada

^ permalink raw reply

* [xlnx:xlnx_rebase_v4.14 3/940] drivers//dma/xgene-dma.c:459:3: error: implicit declaration of function 'xgene_dma_invalidate_buffer'; did you mean 'xgene_dma_set_src_buffer'?
From: kbuild test robot @ 2018-05-31  1:39 UTC (permalink / raw)
  To: linux-arm-kernel

tree:   https://github.com/Xilinx/linux-xlnx xlnx_rebase_v4.14
head:   7a6053b3d256fa5bc23f28a9d9a23d7a2004c5b7
commit: 20f8898e1f01f307ab6a478e7c06894142195e4b [3/940] Revert "dmaengine: remove DMA_SG as it is dead code in kernel"
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git checkout 20f8898e1f01f307ab6a478e7c06894142195e4b
        # save the attached .config to linux build tree
        make.cross ARCH=arm 

All errors (new ones prefixed by >>):

   drivers//dma/xgene-dma.c: In function 'xgene_dma_prep_cpy_desc':
>> drivers//dma/xgene-dma.c:459:3: error: implicit declaration of function 'xgene_dma_invalidate_buffer'; did you mean 'xgene_dma_set_src_buffer'? [-Werror=implicit-function-declaration]
      xgene_dma_invalidate_buffer(xgene_dma_lookup_ext8(desc2, i));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
      xgene_dma_set_src_buffer
   cc1: some warnings being treated as errors

vim +459 drivers//dma/xgene-dma.c

   422	
   423	static void xgene_dma_prep_cpy_desc(struct xgene_dma_chan *chan,
   424					    struct xgene_dma_desc_sw *desc_sw,
   425					    dma_addr_t dst, dma_addr_t src,
   426					    size_t len)
   427	{
   428		struct xgene_dma_desc_hw *desc1, *desc2;
   429		int i;
   430	
   431		/* Get 1st descriptor */
   432		desc1 = &desc_sw->desc1;
   433		xgene_dma_init_desc(desc1, chan->tx_ring.dst_ring_num);
   434	
   435		/* Set destination address */
   436		desc1->m2 |= cpu_to_le64(XGENE_DMA_DESC_DR_BIT);
   437		desc1->m3 |= cpu_to_le64(dst);
   438	
   439		/* Set 1st source address */
   440		xgene_dma_set_src_buffer(&desc1->m1, &len, &src);
   441	
   442		if (!len)
   443			return;
   444	
   445		/*
   446		 * We need to split this source buffer,
   447		 * and need to use 2nd descriptor
   448		 */
   449		desc2 = &desc_sw->desc2;
   450		desc1->m0 |= cpu_to_le64(XGENE_DMA_DESC_NV_BIT);
   451	
   452		/* Set 2nd to 5th source address */
   453		for (i = 0; i < 4 && len; i++)
   454			xgene_dma_set_src_buffer(xgene_dma_lookup_ext8(desc2, i),
   455						 &len, &src);
   456	
   457		/* Invalidate unused source address field */
   458		for (; i < 4; i++)
 > 459			xgene_dma_invalidate_buffer(xgene_dma_lookup_ext8(desc2, i));
   460	
   461		/* Updated flag that we have prepared 64B descriptor */
   462		desc_sw->flags |= XGENE_DMA_FLAG_64B_DESC;
   463	}
   464	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 63972 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180531/df5d0d6a/attachment-0001.gz>

^ permalink raw reply

* [PATCH] PCI: mediatek: Add system pm support for MT2712
From: Ryder Lee @ 2018-05-31  2:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527647736-19986-1-git-send-email-honghui.zhang@mediatek.com>

On Wed, 2018-05-30 at 10:35 +0800, honghui.zhang at mediatek.com wrote:
> From: Honghui Zhang <honghui.zhang@mediatek.com>
> 
> The MTCMOS of PCIe Host for MT2712 will be off when system suspend, and all
> the internel control register will be reset after system resume. The PCIe
> link should be re-established and the related control register values should
> be re-set after system resume.
> 
> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> CC: Ryder Lee <ryder.lee@mediatek.com>
> ---
>  drivers/pci/host/pcie-mediatek.c | 82 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 82 insertions(+)
> 
> diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> index dabf1086..60f98d92 100644
> --- a/drivers/pci/host/pcie-mediatek.c
> +++ b/drivers/pci/host/pcie-mediatek.c
> @@ -132,12 +132,14 @@ struct mtk_pcie_port;
>  /**
>   * struct mtk_pcie_soc - differentiate between host generations
>   * @need_fix_class_id: whether this host's class ID needed to be fixed or not
> + * @pm_support: whether the host's MTCMOS will be off when suspend
>   * @ops: pointer to configuration access functions
>   * @startup: pointer to controller setting functions
>   * @setup_irq: pointer to initialize IRQ functions
>   */
>  struct mtk_pcie_soc {
>  	bool need_fix_class_id;
> +	bool pm_support;
>  	struct pci_ops *ops;
>  	int (*startup)(struct mtk_pcie_port *port);
>  	int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> @@ -1179,12 +1181,91 @@ static int mtk_pcie_probe(struct platform_device *pdev)
>  	return err;
>  }
>  
> +static int __maybe_unused mtk_pcie_suspend_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev;
> +	struct mtk_pcie *pcie;
> +	struct mtk_pcie_port *port;
> +	const struct mtk_pcie_soc *soc;
> +
> +	pdev = to_platform_device(dev);
> +	pcie = platform_get_drvdata(pdev);

How about this -
struct mtk_pcie *pcie = dev_get_drvdata(dev);

> +	soc = pcie->soc;
> +	if (!soc->pm_support)
> +		return 0;
> +
> +	list_for_each_entry(port, &pcie->ports, list) {
> +		clk_disable_unprepare(port->ahb_ck);
> +		clk_disable_unprepare(port->sys_ck);
> +		phy_power_off(port->phy);
> +	}
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused mtk_pcie_resume_noirq(struct device *dev)
> +{
> +	struct platform_device *pdev;
> +	struct mtk_pcie *pcie;
> +	struct mtk_pcie_port *port;
> +	const struct mtk_pcie_soc *soc;
> +	int ret;
> +
> +	pdev = to_platform_device(dev);
> +	pcie = platform_get_drvdata(pdev);

struct mtk_pcie *pcie = dev_get_drvdata(dev);

> +	soc = pcie->soc;
> +	if (!soc->pm_support)
> +		return 0;
> +
> +	list_for_each_entry(port, &pcie->ports, list) {
> +		ret = phy_power_on(port->phy);
> +		if (ret) {
> +			dev_err(dev, "could not power on phy\n");
> +			return ret;
> +		}
> +		ret = clk_prepare_enable(port->sys_ck);
> +		if (ret) {
> +			dev_err(dev, "enable sys clock error\n");
> +			phy_power_off(port->phy);
> +			return ret;
> +		}
> +
> +		ret = clk_prepare_enable(port->ahb_ck);
> +		if (ret) {
> +			dev_err(dev, "enable ahb clock error\n");
> +			phy_power_off(port->phy);
> +			clk_disable_unprepare(port->sys_ck);
> +			return ret;
> +		}
> +
> +		ret = soc->startup(port);
> +		if (ret) {
> +			dev_err(dev, "pcie linkup failed\n");
> +			phy_power_off(port->phy);
> +			clk_disable_unprepare(port->sys_ck);
> +			clk_disable_unprepare(port->ahb_ck);
> +			return ret;
> +		}
> +
> +		if (IS_ENABLED(CONFIG_PCI_MSI))
> +			mtk_pcie_enable_msi(port);
> +	}
> +
> +	return 0;
> +}
> +

^ permalink raw reply

* [PATCH 1/2] ARM: imx: add standby mode suspend for i.MX6SLL
From: Anson Huang @ 2018-05-31  2:06 UTC (permalink / raw)
  To: linux-arm-kernel

Add standby mode suspend for i.MX6SLL, when
linux kernel suspend, SoC will enter STOP mode
with ARM core power on.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 arch/arm/mach-imx/pm-imx6.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 017539d..d319b20 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -296,7 +296,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 		if (cpu_is_imx6sl())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
 		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-		    cpu_is_imx6ull())
+		    cpu_is_imx6ull() || cpu_is_imx6sll())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/2] ARM: imx: add mem mode suspend for i.MX6SLL
From: Anson Huang @ 2018-05-31  2:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527732369-19740-1-git-send-email-Anson.Huang@nxp.com>

Add mem mode suspend for i.MX6SLL, when linux
kernel suspend, SoC will enter STOP mode,
ARM core will be power gated and MMDC IO
will be set to low power mode.

Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
 arch/arm/mach-imx/pm-imx6.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index d319b20..791e1fd 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -130,6 +130,13 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = {
 	0x330, 0x334, 0x320,        /* SDCKE0, SDCKE1, RESET */
 };
 
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+	0x294, 0x298, 0x29c, 0x2a0, /* DQM0 ~ DQM3 */
+	0x544, 0x54c, 0x554, 0x558, /* GPR_B0DS ~ GPR_B3DS */
+	0x530, 0x540, 0x2ac, 0x52c, /* MODE_CTL, MODE, SDCLK_0, GPR_ADDDS */
+	0x2a4, 0x2a8,		    /* SDCKE0, SDCKE1*/
+};
+
 static const u32 imx6sx_mmdc_io_offset[] __initconst = {
 	0x2ec, 0x2f0, 0x2f4, 0x2f8, /* DQM0 ~ DQM3 */
 	0x60c, 0x610, 0x61c, 0x620, /* GPR_B0DS ~ GPR_B3DS */
@@ -175,6 +182,16 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
 	.mmdc_io_offset = imx6sl_mmdc_io_offset,
 };
 
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+	.mmdc_compat = "fsl,imx6sll-mmdc",
+	.src_compat = "fsl,imx6sll-src",
+	.iomuxc_compat = "fsl,imx6sll-iomuxc",
+	.gpc_compat = "fsl,imx6sll-gpc",
+	.pl310_compat = "arm,pl310-cache",
+	.mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+	.mmdc_io_offset = imx6sll_mmdc_io_offset,
+};
+
 static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
 	.mmdc_compat = "fsl,imx6sx-mmdc",
 	.src_compat = "fsl,imx6sx-src",
@@ -314,7 +331,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
 		if (cpu_is_imx6sl() || cpu_is_imx6sx())
 			val |= BM_CLPCR_BYPASS_PMIC_READY;
 		if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
-		    cpu_is_imx6ull())
+		    cpu_is_imx6ull() || cpu_is_imx6sll())
 			val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
 		else
 			val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -631,7 +648,10 @@ void __init imx6dl_pm_init(void)
 
 void __init imx6sl_pm_init(void)
 {
-	imx6_pm_common_init(&imx6sl_pm_data);
+	if (cpu_is_imx6sl())
+		imx6_pm_common_init(&imx6sl_pm_data);
+	else
+		imx6_pm_common_init(&imx6sll_pm_data);
 }
 
 void __init imx6sx_pm_init(void)
-- 
2.7.4

^ permalink raw reply related

* [PATCH] PCI: mediatek: Add system pm support for MT2712
From: Honghui Zhang @ 2018-05-31  2:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527732336.9842.3.camel@mtkswgap22>

On Thu, 2018-05-31 at 10:05 +0800, Ryder Lee wrote:
> On Wed, 2018-05-30 at 10:35 +0800, honghui.zhang at mediatek.com wrote:
> > From: Honghui Zhang <honghui.zhang@mediatek.com>
> > 
> > The MTCMOS of PCIe Host for MT2712 will be off when system suspend, and all
> > the internel control register will be reset after system resume. The PCIe
> > link should be re-established and the related control register values should
> > be re-set after system resume.
> > 
> > Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> > CC: Ryder Lee <ryder.lee@mediatek.com>
> > ---
> >  drivers/pci/host/pcie-mediatek.c | 82 ++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 82 insertions(+)
> > 
> > diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> > index dabf1086..60f98d92 100644
> > --- a/drivers/pci/host/pcie-mediatek.c
> > +++ b/drivers/pci/host/pcie-mediatek.c
> > @@ -132,12 +132,14 @@ struct mtk_pcie_port;
> >  /**
> >   * struct mtk_pcie_soc - differentiate between host generations
> >   * @need_fix_class_id: whether this host's class ID needed to be fixed or not
> > + * @pm_support: whether the host's MTCMOS will be off when suspend
> >   * @ops: pointer to configuration access functions
> >   * @startup: pointer to controller setting functions
> >   * @setup_irq: pointer to initialize IRQ functions
> >   */
> >  struct mtk_pcie_soc {
> >  	bool need_fix_class_id;
> > +	bool pm_support;
> >  	struct pci_ops *ops;
> >  	int (*startup)(struct mtk_pcie_port *port);
> >  	int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> > @@ -1179,12 +1181,91 @@ static int mtk_pcie_probe(struct platform_device *pdev)
> >  	return err;
> >  }
> >  
> > +static int __maybe_unused mtk_pcie_suspend_noirq(struct device *dev)
> > +{
> > +	struct platform_device *pdev;
> > +	struct mtk_pcie *pcie;
> > +	struct mtk_pcie_port *port;
> > +	const struct mtk_pcie_soc *soc;
> > +
> > +	pdev = to_platform_device(dev);
> > +	pcie = platform_get_drvdata(pdev);
> 
> How about this -
> struct mtk_pcie *pcie = dev_get_drvdata(dev);

Yes, I forgot that, thanks very much for your reminder.

> 
> > +	soc = pcie->soc;
> > +	if (!soc->pm_support)
> > +		return 0;
> > +
> > +	list_for_each_entry(port, &pcie->ports, list) {
> > +		clk_disable_unprepare(port->ahb_ck);
> > +		clk_disable_unprepare(port->sys_ck);
> > +		phy_power_off(port->phy);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int __maybe_unused mtk_pcie_resume_noirq(struct device *dev)
> > +{
> > +	struct platform_device *pdev;
> > +	struct mtk_pcie *pcie;
> > +	struct mtk_pcie_port *port;
> > +	const struct mtk_pcie_soc *soc;
> > +	int ret;
> > +
> > +	pdev = to_platform_device(dev);
> > +	pcie = platform_get_drvdata(pdev);
> 
> struct mtk_pcie *pcie = dev_get_drvdata(dev);

thanks.

> 
> > +	soc = pcie->soc;
> > +	if (!soc->pm_support)
> > +		return 0;
> > +
> > +	list_for_each_entry(port, &pcie->ports, list) {
> > +		ret = phy_power_on(port->phy);
> > +		if (ret) {
> > +			dev_err(dev, "could not power on phy\n");
> > +			return ret;
> > +		}
> > +		ret = clk_prepare_enable(port->sys_ck);
> > +		if (ret) {
> > +			dev_err(dev, "enable sys clock error\n");
> > +			phy_power_off(port->phy);
> > +			return ret;
> > +		}
> > +
> > +		ret = clk_prepare_enable(port->ahb_ck);
> > +		if (ret) {
> > +			dev_err(dev, "enable ahb clock error\n");
> > +			phy_power_off(port->phy);
> > +			clk_disable_unprepare(port->sys_ck);
> > +			return ret;
> > +		}
> > +
> > +		ret = soc->startup(port);
> > +		if (ret) {
> > +			dev_err(dev, "pcie linkup failed\n");
> > +			phy_power_off(port->phy);
> > +			clk_disable_unprepare(port->sys_ck);
> > +			clk_disable_unprepare(port->ahb_ck);
> > +			return ret;
> > +		}
> > +
> > +		if (IS_ENABLED(CONFIG_PCI_MSI))
> > +			mtk_pcie_enable_msi(port);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 
> 

^ permalink raw reply

* [PATCH v4 1/9] drm/mediatek: update dt-bindings for mt2712
From: Rob Herring @ 2018-05-31  2:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527489507-24453-2-git-send-email-stu.hsieh@mediatek.com>

On Mon, May 28, 2018 at 02:38:19PM +0800, Stu Hsieh wrote:
> Update device tree binding documentation for the display subsystem for
> Mediatek MT2712 SoCs.
> 
> Signed-off-by: Stu Hsieh <stu.hsieh@mediatek.com>
> Acked-by: CK Hu <ck.hu@mediatek.com>
> ---
>  Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v4 2/5] clk: imx6: add EPIT clock support
From: Rob Herring @ 2018-05-31  3:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530120327.27681-3-peron.clem@gmail.com>

On Wed, May 30, 2018 at 02:03:24PM +0200, Cl?ment P?ron wrote:
> From: Colin Didier <colin.didier@devialet.com>
> 
> Add EPIT clock support to the i.MX6Q clocking infrastructure.
> 
> Signed-off-by: Colin Didier <colin.didier@devialet.com>
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---
>  drivers/clk/imx/clk-imx6q.c               | 2 ++
>  include/dt-bindings/clock/imx6qdl-clock.h | 4 +++-

Acked-by: Rob Herring <robh@kernel.org>

>  2 files changed, 5 insertions(+), 1 deletion(-)

^ permalink raw reply

* [PATCH v4 3/5] Documentation: DT: add i.MX EPIT timer binding
From: Rob Herring @ 2018-05-31  3:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530120327.27681-4-peron.clem@gmail.com>

On Wed, May 30, 2018 at 02:03:25PM +0200, Cl?ment P?ron wrote:
> From: Cl?ment Peron <clement.peron@devialet.com>

"dt-bindings: timer: ..." is the preferred subject prefix.

> 
> Add devicetree binding document for NXP's i.MX SoC specific
> EPIT timer driver.
> 
> Signed-off-by: Cl?ment Peron <clement.peron@devialet.com>
> ---
>  .../devicetree/bindings/timer/fsl,imxepit.txt | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/fsl,imxepit.txt
> 
> diff --git a/Documentation/devicetree/bindings/timer/fsl,imxepit.txt b/Documentation/devicetree/bindings/timer/fsl,imxepit.txt
> new file mode 100644
> index 000000000000..90112d58af10
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/fsl,imxepit.txt
> @@ -0,0 +1,24 @@
> +Binding for the i.MX EPIT timer
> +
> +This binding uses the common clock binding[1].
> +
> +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt

No need to state this. Listing "clocks" tells us that.

> +
> +Required properties:
> +- compatible: should be "fsl,imx31-epit"

What about imx6q listed below?

> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- interrupts: Should contain EPIT controller interrupt
> +- clocks: list of clock specifiers, must contain an entry for each required
> +  entry in clock-names
> +- clock-names : should include entries "ipg", "per"
> +
> +Example for i.MX6QDL:
> +	epit1: epit at 20d0000 {

timer at ...

> +		compatible = "fsl,imx6q-epit", "fsl,imx31-epit";
> +		reg = <0x020d0000 0x4000>;
> +		interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&clks IMX6QDL_CLK_IPG_PER>,
> +			<&clks IMX6QDL_CLK_EPIT1>;
> +		clock-names = "ipg", "per";
> +	};
> -- 
> 2.17.0
> 

^ permalink raw reply

* [PATCH v3 1/8] dt-bindings: media: rcar-vin: Describe optional ep properties
From: Rob Herring @ 2018-05-31  3:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527606359-19261-2-git-send-email-jacopo+renesas@jmondi.org>

On Tue, May 29, 2018 at 05:05:52PM +0200, Jacopo Mondi wrote:
> Describe the optional endpoint properties for endpoint nodes of port at 0
> and port at 1 of the R-Car VIN driver device tree bindings documentation.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> Acked-by: Niklas S?derlund <niklas.soderlund+renesas@ragnatech.se>
> 
> ---
> v2 -> v3:
> - Do not repeat property description, just reference video-interfaces.txt
> - Indent with spaces, not tabs as the rest of the document
> - Do not remove (yet) the 'bus-width' property from example
> ---
>  Documentation/devicetree/bindings/media/rcar_vin.txt | 10 ++++++++++
>  1 file changed, 10 insertions(+)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 2/8] dt-bindings: media: Document data-enable-active property
From: Rob Herring @ 2018-05-31  3:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527606359-19261-3-git-send-email-jacopo+renesas@jmondi.org>

On Tue, May 29, 2018 at 05:05:53PM +0200, Jacopo Mondi wrote:
> Add 'data-enable-active' property to endpoint node properties list.
> 
> The property allows to specify the polarity of the data-enable signal, which
> when in active state determinates when data lanes have to sampled for valid
> pixel data.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> v3:
> - new patch
> ---
>  Documentation/devicetree/bindings/media/video-interfaces.txt | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 4/8] dt-bindings: media: rcar-vin: Add 'data-enable-active'
From: Rob Herring @ 2018-05-31  3:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527606359-19261-5-git-send-email-jacopo+renesas@jmondi.org>

On Tue, May 29, 2018 at 05:05:55PM +0200, Jacopo Mondi wrote:
> Describe optional endpoint property 'data-enable-active' for R-Car VIN.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> v3:
> - new patch
> ---
> 
>  Documentation/devicetree/bindings/media/rcar_vin.txt | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 6/8] dt-bindings: rcar-vin: Add 'hsync-as-de' custom prop
From: Rob Herring @ 2018-05-31  3:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527606359-19261-7-git-send-email-jacopo+renesas@jmondi.org>

On Tue, May 29, 2018 at 05:05:57PM +0200, Jacopo Mondi wrote:
> Document the boolean custom property 'renesas,hsync-as-de' that indicates
> that the HSYNC signal is internally used as data-enable, when the
> CLKENB signal is not connected.
> 
> As this is a VIN specificity create a custom property specific to the R-Car
> VIN driver.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> v3:
> - new patch
> ---
>  Documentation/devicetree/bindings/media/rcar_vin.txt | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 8/8] ARM: dts: rcar-gen2: Remove unused VIN properties
From: Rob Herring @ 2018-05-31  3:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527606359-19261-9-git-send-email-jacopo+renesas@jmondi.org>

On Tue, May 29, 2018 at 05:05:59PM +0200, Jacopo Mondi wrote:
> The 'bus-width' and 'pclk-sample' properties are not parsed by the VIN
> driver and only confuse users. Remove them in all Gen2 SoC that use
> them.
> 
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> ---
> v3:
> - remove bus-width from dt-bindings example
> ---
>  Documentation/devicetree/bindings/media/rcar_vin.txt | 1 -
>  arch/arm/boot/dts/r8a7790-lager.dts                  | 3 ---
>  arch/arm/boot/dts/r8a7791-koelsch.dts                | 3 ---
>  arch/arm/boot/dts/r8a7791-porter.dts                 | 1 -
>  arch/arm/boot/dts/r8a7793-gose.dts                   | 3 ---
>  arch/arm/boot/dts/r8a7794-alt.dts                    | 1 -
>  arch/arm/boot/dts/r8a7794-silk.dts                   | 1 -
>  7 files changed, 13 deletions(-)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply

* [PATCH v3 0/5] Add sdmmc UHS support to ROC-RK3328-CC board.
From: djw at t-chip.com.cn @ 2018-05-31  3:27 UTC (permalink / raw)
  To: linux-arm-kernel

From: Levin Du <djw@t-chip.com.cn>


Hi all, this is an attemp to add sdmmc UHS support to the
ROC-RK3328-CC board.

This patch series adds a new compatible `rockchip,rk3328-gpio-mute` to
the gpio-syscon driver for the access of the GPIO_MUTE pin in rk3328.

A new gpio controller named `gpio_mute` is defined in
rk3328.dtsi and so that all rk3328 boards has access to it.

The ROC-RK3328-CC board use the new gpio <&gpio_mute 0> in
gpio-regulator to control the signal voltage of the sdmmc.
It is essential for UHS support which requires 1.8V signal voltage.

Many thanks to the Linux people!

Changes in v3:
- Change from general gpio-syscon to specific rk3328-gpio-mute
- Use dedicated "rockchip,rk3328-gpio-mute" driver
- Use <&gpio_mute 0> instead of <&gpio_mute 1> to refer to the GPIO_MUTE pin.

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in doc
- Rename gpio_syscon10 to gpio_mute in rk3328.dtsi
- Rename gpio_syscon10 to gpio_mute in rk3328-roc-cc.dts

Changes in v1:
- New: allow fetching syscon from parent node in gpio-syscon driver
- Refactured for general gpio-syscon usage for Rockchip SoCs.
- Add doc rockchip,gpio-syscon.txt
- Split from V0 and add to rk3328.dtsi for general use.
- Split from V0.
- Split into small patches
- Sort dts properties in sdmmc node

Heiko Stuebner (1):
  gpio: syscon: allow fetching syscon from parent node

Levin Du (4):
  gpio: syscon: rockchip: add GPIO_MUTE support for rk3328
  arm64: dts: rockchip: Add GPIO_MUTE pin support to rk3328
  arm64: dts: rockchip: Add io-domain to roc-rk3328-cc
  arm64: dts: rockchip: Add sdmmc UHS support for roc-rk3328-cc

 .../bindings/gpio/rockchip,rk3328-gpio-mute.txt    | 28 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts     | 34 ++++++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3328.dtsi           |  7 +++++
 drivers/gpio/gpio-syscon.c                         | 33 +++++++++++++++++++++
 4 files changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt

-- 
2.7.4

^ permalink raw reply

* [PATCH v3 2/5] gpio: syscon: rockchip: add GPIO_MUTE support for rk3328
From: djw at t-chip.com.cn @ 2018-05-31  3:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527737273-8387-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

In Rockchip RK3328, the output only GPIO_MUTE pin, originally for codec
mute control, can also be used for general purpose. It is manipulated by
the GRF_SOC_CON10 register.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v3:
- Change from general gpio-syscon to specific rk3328-gpio-mute

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in doc

Changes in v1:
- Refactured for general gpio-syscon usage for Rockchip SoCs.
- Add doc rockchip,gpio-syscon.txt

 .../bindings/gpio/rockchip,rk3328-gpio-mute.txt    | 28 +++++++++++++++++++
 drivers/gpio/gpio-syscon.c                         | 31 ++++++++++++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt

diff --git a/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt b/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
new file mode 100644
index 0000000..10bc632
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/rockchip,rk3328-gpio-mute.txt
@@ -0,0 +1,28 @@
+Rockchip RK3328 GPIO controller dedicated for the GPIO_MUTE pin.
+
+In Rockchip RK3328, the output only GPIO_MUTE pin, originally for codec mute
+control, can also be used for general purpose. It is manipulated by the
+GRF_SOC_CON10 register.
+
+Required properties:
+- compatible: Should contain "rockchip,rk3328-gpio-mute".
+- gpio-controller: Marks the device node as a gpio controller.
+- #gpio-cells: Should be 2. The first cell is the pin number and
+  the second cell is used to specify the gpio polarity:
+    0 = Active high,
+    1 = Active low.
+
+Example:
+
+	grf: syscon at ff100000 {
+		compatible = "rockchip,rk3328-grf", "syscon", "simple-mfd";
+
+		gpio_mute: gpio-mute {
+			compatible = "rockchip,rk3328-gpio-mute";
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+Note: The gpio_mute node should be declared as the child of the GRF (General
+Register File) node. The GPIO_MUTE pin is referred to as <&gpio_mute 0>.
diff --git a/drivers/gpio/gpio-syscon.c b/drivers/gpio/gpio-syscon.c
index 7325b86..49a142a 100644
--- a/drivers/gpio/gpio-syscon.c
+++ b/drivers/gpio/gpio-syscon.c
@@ -135,6 +135,33 @@ static const struct syscon_gpio_data clps711x_mctrl_gpio = {
 	.dat_bit_offset	= 0x40 * 8 + 8,
 };
 
+static void rockchip_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			      int val)
+{
+	struct syscon_gpio_priv *priv = gpiochip_get_data(chip);
+	unsigned int offs;
+	u8 bit;
+	u32 data;
+	int ret;
+
+	offs = priv->dreg_offset + priv->data->dat_bit_offset + offset;
+	bit = offs % SYSCON_REG_BITS;
+	data = (val ? BIT(bit) : 0) | BIT(bit + 16);
+	ret = regmap_write(priv->syscon,
+			   (offs / SYSCON_REG_BITS) * SYSCON_REG_SIZE,
+			   data);
+	if (ret < 0)
+		dev_err(chip->parent, "gpio write failed ret(%d)\n", ret);
+}
+
+static const struct syscon_gpio_data rockchip_rk3328_gpio_mute = {
+	/* RK3328 GPIO_MUTE is an output only pin at GRF_SOC_CON10[1] */
+	.flags		= GPIO_SYSCON_FEAT_OUT,
+	.bit_count	= 1,
+	.dat_bit_offset = 0x0428 * 8 + 1,
+	.set		= rockchip_gpio_set,
+};
+
 #define KEYSTONE_LOCK_BIT BIT(0)
 
 static void keystone_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
@@ -175,6 +202,10 @@ static const struct of_device_id syscon_gpio_ids[] = {
 		.compatible	= "ti,keystone-dsp-gpio",
 		.data		= &keystone_dsp_gpio,
 	},
+	{
+		.compatible	= "rockchip,rk3328-gpio-mute",
+		.data		= &rockchip_rk3328_gpio_mute,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, syscon_gpio_ids);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 3/5] arm64: dts: rockchip: Add GPIO_MUTE pin support to rk3328
From: djw at t-chip.com.cn @ 2018-05-31  3:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527737273-8387-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

Adding a new gpio controller named "gpio_mute" to rk3328, providing
access to the GPIO_MUTE pin, which is manupulated by the GRF_SOC_CON10
register.

The GPIO_MUTE pin is referred to as <&gpio_mute 0>.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v3:
- Use dedicated "rockchip,rk3328-gpio-mute" driver

Changes in v2:
- Rename gpio_syscon10 to gpio_mute in rk3328.dtsi

Changes in v1:
- Split from V0 and add to rk3328.dtsi for general use.

 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index be2bfbc..2ee0fa3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -309,6 +309,13 @@
 			mode-loader = <BOOT_BL_DOWNLOAD>;
 		};
 
+		/* Use <&gpio_mute 0> to refer to GPIO_MUTE pin */
+		gpio_mute: gpio-mute {
+			compatible = "rockchip,rk3328-gpio-mute";
+			gpio-controller;
+			#gpio-cells = <2>;
+			status = "disabled";
+		};
 	};
 
 	uart0: serial at ff110000 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v3 4/5] arm64: dts: rockchip: Add io-domain to roc-rk3328-cc
From: djw at t-chip.com.cn @ 2018-05-31  3:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527737273-8387-1-git-send-email-djw@t-chip.com.cn>

From: Levin Du <djw@t-chip.com.cn>

It is necessary for the io domain setting of the SoC to match
the voltage supplied by the regulators.

Signed-off-by: Levin Du <djw@t-chip.com.cn>

---

Changes in v3: None
Changes in v2: None
Changes in v1:
- Split from V0.

 arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
index 246c317..b983abd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts
@@ -208,6 +208,18 @@
 	};
 };
 
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vcc_io>;
+	vccio2-supply = <&vcc18_emmc>;
+	vccio3-supply = <&vcc_io>;
+	vccio4-supply = <&vcc_18>;
+	vccio5-supply = <&vcc_io>;
+	vccio6-supply = <&vcc_io>;
+	pmuio-supply = <&vcc_io>;
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 3/4] dt-bindings: soc: Add TmFifo binding for Mellanox BlueField SoC
From: Rob Herring @ 2018-05-31  3:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1527279436-14773-3-git-send-email-lsun@mellanox.com>

On Fri, May 25, 2018 at 04:17:15PM -0400, Liming Sun wrote:

Commit msg?

> Reviewed-by: David Woods <dwoods@mellanox.com>
> Signed-off-by: Liming Sun <lsun@mellanox.com>
> ---
>  .../devicetree/bindings/soc/mellanox/tmfifo.txt      | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/mellanox/tmfifo.txt
> 
> diff --git a/Documentation/devicetree/bindings/soc/mellanox/tmfifo.txt b/Documentation/devicetree/bindings/soc/mellanox/tmfifo.txt
> new file mode 100644
> index 0000000..0a362f5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/soc/mellanox/tmfifo.txt
> @@ -0,0 +1,20 @@
> +* Mellanox BlueField SoC TmFifo
> +
> +BlueField TmFifo provides a shared FIFO between the target and the
> +external host machine, which can be accessed via USB or PCIe.

A FIFO for what? I'd like to find a better spot than bindings/soc/
> +
> +Required properties:
> +
> +- compatible:	Should be "mellanox,bf-tmfifo"
> +- reg:		Physical base address and length of Rx/Tx block
> +- interrupts:	The interrupt number of Rx low water mark, Rx high water mark
> +		Tx low water mark, Tx high water mark respectively.
> +
> +Example:
> +
> +tmfifo at 800a20 {
> +	compatible = "mellanox,bf-tmfifo";
> +	reg = <0x00800a20 0x00000018
> +	       0x00800a40 0x00000018>;
> +	interrupts = <41, 42, 43, 44>;
> +};
> -- 
> 1.8.3.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ 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