Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function

2017-04-13 Thread Christoph Hellwig
On Thu, Apr 13, 2017 at 11:06:16PM -0600, Logan Gunthorpe wrote:
> Or maybe I'll just send a patch for that
> separately seeing it doesn't depend on anything and is pretty simple. I
> can do that next week.

Yes, please just send that patch linux-nvme, we should be able to get
it into 4.12.


Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe


On 13/04/17 10:59 PM, Christoph Hellwig wrote:
> On Thu, Apr 13, 2017 at 04:05:15PM -0600, Logan Gunthorpe wrote:
>> This is a straight forward conversion in two places. Should kmap fail,
>> the code will return an INVALD_DATA error in the completion.
> 
> It really should be using nvmet_copy_from_sgl to make things safer,
> as we don't want to rely on any particular SG list layout.  In fact
> I'm pretty sure I did the conversion at some point, but it must never
> have made it upstream.

Ha, I did the conversion too a couple times for my RFC series. I can
change this patch to do that. Or maybe I'll just send a patch for that
separately seeing it doesn't depend on anything and is pretty simple. I
can do that next week.

Thanks,

Logan


Re: [PATCH 02/22] nvmet: Make use of the new sg_map helper function

2017-04-13 Thread Christoph Hellwig
On Thu, Apr 13, 2017 at 04:05:15PM -0600, Logan Gunthorpe wrote:
> This is a straight forward conversion in two places. Should kmap fail,
> the code will return an INVALD_DATA error in the completion.

It really should be using nvmet_copy_from_sgl to make things safer,
as we don't want to rely on any particular SG list layout.  In fact
I'm pretty sure I did the conversion at some point, but it must never
have made it upstream.


cron job: media_tree daily build: WARNINGS

2017-04-13 Thread Hans Verkuil
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.

Results of the daily build of media_tree:

date:   Fri Apr 14 05:00:15 CEST 2017
media-tree git hash:4aed35ca73f6d9cfd5f7089ba5d04f5fb8623080
media_build git hash:   8a44f033b9899e3193da85b1d3369a9dbfcc9eab
v4l-utils git hash: e748123b973e899cd6f0c08272a165661bd8386f
gcc version:i686-linux-gcc (GCC) 6.2.0
sparse version: v0.5.0-3553-g78b2ea6
smatch version: v0.5.0-3553-g78b2ea6
host hardware:  x86_64
host os:4.9.0-164

linux-git-arm-at91: OK
linux-git-arm-davinci: OK
linux-git-arm-multi: OK
linux-git-arm-pxa: OK
linux-git-blackfin-bf561: OK
linux-git-i686: OK
linux-git-m32r: OK
linux-git-mips: OK
linux-git-powerpc64: OK
linux-git-sh: OK
linux-git-x86_64: OK
linux-2.6.36.4-i686: OK
linux-2.6.37.6-i686: OK
linux-2.6.38.8-i686: OK
linux-2.6.39.4-i686: OK
linux-3.0.60-i686: OK
linux-3.1.10-i686: OK
linux-3.2.37-i686: OK
linux-3.3.8-i686: OK
linux-3.4.27-i686: OK
linux-3.5.7-i686: OK
linux-3.6.11-i686: OK
linux-3.7.4-i686: OK
linux-3.8-i686: OK
linux-3.9.2-i686: OK
linux-3.10.1-i686: WARNINGS
linux-3.11.1-i686: OK
linux-3.12.67-i686: OK
linux-3.13.11-i686: WARNINGS
linux-3.14.9-i686: WARNINGS
linux-3.15.2-i686: WARNINGS
linux-3.16.7-i686: WARNINGS
linux-3.17.8-i686: WARNINGS
linux-3.18.7-i686: WARNINGS
linux-3.19-i686: WARNINGS
linux-4.0.9-i686: WARNINGS
linux-4.1.33-i686: WARNINGS
linux-4.2.8-i686: WARNINGS
linux-4.3.6-i686: WARNINGS
linux-4.4.22-i686: WARNINGS
linux-4.5.7-i686: WARNINGS
linux-4.6.7-i686: WARNINGS
linux-4.7.5-i686: WARNINGS
linux-4.8-i686: OK
linux-4.9-i686: OK
linux-4.10.1-i686: OK
linux-4.11-rc1-i686: OK
linux-2.6.36.4-x86_64: OK
linux-2.6.37.6-x86_64: OK
linux-2.6.38.8-x86_64: OK
linux-2.6.39.4-x86_64: OK
linux-3.0.60-x86_64: OK
linux-3.1.10-x86_64: OK
linux-3.2.37-x86_64: OK
linux-3.3.8-x86_64: OK
linux-3.4.27-x86_64: OK
linux-3.5.7-x86_64: OK
linux-3.6.11-x86_64: OK
linux-3.7.4-x86_64: OK
linux-3.8-x86_64: OK
linux-3.9.2-x86_64: OK
linux-3.10.1-x86_64: WARNINGS
linux-3.11.1-x86_64: OK
linux-3.12.67-x86_64: OK
linux-3.13.11-x86_64: WARNINGS
linux-3.14.9-x86_64: WARNINGS
linux-3.15.2-x86_64: WARNINGS
linux-3.16.7-x86_64: WARNINGS
linux-3.17.8-x86_64: WARNINGS
linux-3.18.7-x86_64: WARNINGS
linux-3.19-x86_64: WARNINGS
linux-4.0.9-x86_64: WARNINGS
linux-4.1.33-x86_64: WARNINGS
linux-4.2.8-x86_64: WARNINGS
linux-4.3.6-x86_64: WARNINGS
linux-4.4.22-x86_64: WARNINGS
linux-4.5.7-x86_64: WARNINGS
linux-4.6.7-x86_64: WARNINGS
linux-4.7.5-x86_64: WARNINGS
linux-4.8-x86_64: WARNINGS
linux-4.9-x86_64: WARNINGS
linux-4.10.1-x86_64: WARNINGS
linux-4.11-rc1-x86_64: OK
apps: WARNINGS
spec-git: OK
sparse: WARNINGS

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Friday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Friday.tar.bz2

The Media Infrastructure API from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/index.html


[PATCH v2 15/15] [media] cxd2880 : Update MAINTAINERS file for CXD2880 driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This is MAINTAINERS file update about the driver for
the Sony CXD2880 DVB-T2/T tuner + demodulator.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 MAINTAINERS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fdd5350fe261..62543a76d6bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8042,6 +8042,15 @@ T:   git git://linuxtv.org/media_tree.git
 S: Supported
 F: drivers/media/dvb-frontends/cxd2841er*
 
+MEDIA DRIVERS FOR CXD2880
+M: Yasunari Takiguchi 
+L: linux-media@vger.kernel.org
+W: http://linuxtv.org/
+T: git git://linuxtv.org/media_tree.git
+S: Supported
+F: drivers/media/dvb-frontends/cxd2880/*
+F: drivers/media/spi/cxd2880*
+
 MEDIA DRIVERS FOR HORUS3A
 M: Sergey Kozlov 
 M: Abylay Ospan 
-- 
2.11.0



[PATCH v2 14/15] [media] cxd2880: Add all Kconfig files for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This is the Kconfig files of driver for
the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/Kconfig |  2 ++
 drivers/media/dvb-frontends/cxd2880/Kconfig |  6 ++
 drivers/media/spi/Kconfig   | 14 ++
 3 files changed, 22 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/Kconfig

diff --git a/drivers/media/dvb-frontends/Kconfig 
b/drivers/media/dvb-frontends/Kconfig
index e8c6554a47aa..3a3a7129a150 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -518,6 +518,8 @@ config DVB_GP8PSK_FE
depends on DVB_CORE
default DVB_USB_GP8PSK
 
+source "drivers/media/dvb-frontends/cxd2880/Kconfig"
+
 comment "DVB-C (cable) frontends"
depends on DVB_CORE
 
diff --git a/drivers/media/dvb-frontends/cxd2880/Kconfig 
b/drivers/media/dvb-frontends/cxd2880/Kconfig
new file mode 100644
index ..36b8b6f7c4f7
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/Kconfig
@@ -0,0 +1,6 @@
+config DVB_CXD2880
+   tristate "Sony CXD2880 DVB-T2/T tuner + demodulator"
+   depends on DVB_CORE && SPI
+   default m if !MEDIA_SUBDRV_AUTOSELECT
+   help
+ Say Y when you want to support this frontend.
\ No newline at end of file
diff --git a/drivers/media/spi/Kconfig b/drivers/media/spi/Kconfig
index a21f5a39a440..b07ac86fc53c 100644
--- a/drivers/media/spi/Kconfig
+++ b/drivers/media/spi/Kconfig
@@ -12,3 +12,17 @@ config VIDEO_GS1662
 endmenu
 
 endif
+
+if SPI
+menu "Media SPI Adapters"
+
+config CXD2880_SPI_DRV
+   tristate "Sony CXD2880 SPI support"
+   depends on DVB_CORE && SPI
+   default m if !MEDIA_SUBDRV_AUTOSELECT
+   help
+ Choose if you would like to have SPI interface support for Sony 
CXD2880.
+
+endmenu
+
+endif
-- 
2.11.0



[PATCH v2 13/15] [media] cxd2880: Add all Makefile files for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This is the Makefile files of driver
for the Sony CXD2880 DVB-T2/T tuner + demodulator.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/Makefile |  1 +
 drivers/media/dvb-frontends/cxd2880/Makefile | 21 +
 drivers/media/spi/Makefile   |  5 +
 3 files changed, 27 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/Makefile

diff --git a/drivers/media/dvb-frontends/Makefile 
b/drivers/media/dvb-frontends/Makefile
index 3fccaf34ef52..d298c7954699 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -126,3 +126,4 @@ obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
 obj-$(CONFIG_DVB_HELENE) += helene.o
 obj-$(CONFIG_DVB_ZD1301_DEMOD) += zd1301_demod.o
+obj-$(CONFIG_DVB_CXD2880) += cxd2880/
diff --git a/drivers/media/dvb-frontends/cxd2880/Makefile 
b/drivers/media/dvb-frontends/cxd2880/Makefile
new file mode 100644
index ..2672c4a3d65c
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/Makefile
@@ -0,0 +1,21 @@
+cxd2880-objs := cxd2880_common.o \
+   cxd2880_devio_spi.o \
+   cxd2880_integ.o \
+   cxd2880_integ_dvbt2.o \
+   cxd2880_integ_dvbt.o \
+   cxd2880_io.o \
+   cxd2880_spi_device.o \
+   cxd2880_stopwatch_port.o \
+   cxd2880_tnrdmd.o \
+   cxd2880_tnrdmd_dvbt2.o \
+   cxd2880_tnrdmd_dvbt2_mon.o \
+   cxd2880_tnrdmd_dvbt.o \
+   cxd2880_tnrdmd_dvbt_mon.o\
+   cxd2880_tnrdmd_mon.o\
+   cxd2880_math.o \
+   cxd2880_top.o
+
+obj-$(CONFIG_DVB_CXD2880) += cxd2880.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/spi/Makefile b/drivers/media/spi/Makefile
index ea64013d16cc..40e0f88d9f6c 100644
--- a/drivers/media/spi/Makefile
+++ b/drivers/media/spi/Makefile
@@ -1 +1,6 @@
 obj-$(CONFIG_VIDEO_GS1662) += gs1662.o
+obj-$(CONFIG_CXD2880_SPI_DRV) += cxd2880-spi.o
+
+ccflags-y += -Idrivers/media/dvb-core
+ccflags-y += -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends/cxd2880
\ No newline at end of file
-- 
2.11.0



[PATCH v2 12/15] [media] cxd2880: Add DVB-T2 monitor and integration layer functions

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Provide monitor and integration layer functions (DVB-T2)
for the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c|  311 +++
 .../dvb-frontends/cxd2880/cxd2880_integ_dvbt2.h|   64 +
 .../cxd2880/cxd2880_tnrdmd_dvbt2_mon.c | 2523 
 .../cxd2880/cxd2880_tnrdmd_dvbt2_mon.h |  170 ++
 4 files changed, 3068 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.h
 create mode 100644 
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c
 create mode 100644 
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c
new file mode 100644
index ..1d60b9c236d8
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c
@@ -0,0 +1,311 @@
+/*
+ * cxd2880_integ_dvbt2.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration layer functions for DVB-T2
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "cxd2880_tnrdmd_dvbt2.h"
+#include "cxd2880_tnrdmd_dvbt2_mon.h"
+#include "cxd2880_integ_dvbt2.h"
+
+static enum cxd2880_ret dvbt2_wait_demod_lock(struct cxd2880_tnrdmd *tnr_dmd,
+ enum cxd2880_dvbt2_profile
+ profile);
+
+static enum cxd2880_ret dvbt2_wait_l1_post_lock(struct cxd2880_tnrdmd 
*tnr_dmd);
+
+enum cxd2880_ret cxd2880_integ_dvbt2_tune(struct cxd2880_tnrdmd *tnr_dmd,
+ struct cxd2880_dvbt2_tune_param
+ *tune_param)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+   if ((!tnr_dmd) || (!tune_param))
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+   (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+   return CXD2880_RESULT_ERROR_SW_STATE;
+
+   cxd2880_atomic_set(_dmd->cancel, 0);
+
+   if ((tune_param->bandwidth != CXD2880_DTV_BW_1_7_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ)) {
+   return CXD2880_RESULT_ERROR_NOSUPPORT;
+   }
+
+   if ((tune_param->profile != CXD2880_DVBT2_PROFILE_BASE) &&
+   (tune_param->profile != CXD2880_DVBT2_PROFILE_LITE))
+   return CXD2880_RESULT_ERROR_ARG;
+
+   ret = cxd2880_tnrdmd_dvbt2_tune1(tnr_dmd, tune_param);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   CXD2880_SLEEP(CXD2880_TNRDMD_WAIT_AGC_STABLE);
+
+   ret = cxd2880_tnrdmd_dvbt2_tune2(tnr_dmd, tune_param);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   ret = dvbt2_wait_demod_lock(tnr_dmd, tune_param->profile);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   ret = cxd2880_tnrdmd_dvbt2_diver_fef_setting(tnr_dmd);
+   if (ret == CXD2880_RESULT_ERROR_HW_STATE)
+   

[PATCH v2 11/15] [media] cxd2880: Add DVB-T2 control functions for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Provide definitions, interfaces and functions needed for DVB-T2
of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../media/dvb-frontends/cxd2880/cxd2880_dvbt2.h|  402 ++
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c   | 1309 
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h   |   82 ++
 3 files changed, 1793 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h
new file mode 100644
index ..1870398cba9d
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h
@@ -0,0 +1,402 @@
+/*
+ * cxd2880_dvbt2.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * DVB-T2 related definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#ifndef CXD2880_DVBT2_H
+#define CXD2880_DVBT2_H
+
+#include "cxd2880_common.h"
+
+enum cxd2880_dvbt2_profile {
+   CXD2880_DVBT2_PROFILE_BASE,
+   CXD2880_DVBT2_PROFILE_LITE,
+   CXD2880_DVBT2_PROFILE_ANY
+};
+
+enum cxd2880_dvbt2_version {
+   CXD2880_DVBT2_V111,
+   CXD2880_DVBT2_V121,
+   CXD2880_DVBT2_V131
+};
+
+enum cxd2880_dvbt2_s1 {
+   CXD2880_DVBT2_S1_BASE_SISO = 0x00,
+   CXD2880_DVBT2_S1_BASE_MISO = 0x01,
+   CXD2880_DVBT2_S1_NON_DVBT2 = 0x02,
+   CXD2880_DVBT2_S1_LITE_SISO = 0x03,
+   CXD2880_DVBT2_S1_LITE_MISO = 0x04,
+   CXD2880_DVBT2_S1_RSVD3 = 0x05,
+   CXD2880_DVBT2_S1_RSVD4 = 0x06,
+   CXD2880_DVBT2_S1_RSVD5 = 0x07,
+   CXD2880_DVBT2_S1_UNKNOWN = 0xFF
+};
+
+enum cxd2880_dvbt2_base_s2 {
+   CXD2880_DVBT2_BASE_S2_M2K_G_ANY = 0x00,
+   CXD2880_DVBT2_BASE_S2_M8K_G_DVBT = 0x01,
+   CXD2880_DVBT2_BASE_S2_M4K_G_ANY = 0x02,
+   CXD2880_DVBT2_BASE_S2_M1K_G_ANY = 0x03,
+   CXD2880_DVBT2_BASE_S2_M16K_G_ANY = 0x04,
+   CXD2880_DVBT2_BASE_S2_M32K_G_DVBT = 0x05,
+   CXD2880_DVBT2_BASE_S2_M8K_G_DVBT2 = 0x06,
+   CXD2880_DVBT2_BASE_S2_M32K_G_DVBT2 = 0x07,
+   CXD2880_DVBT2_BASE_S2_UNKNOWN = 0xFF
+};
+
+enum cxd2880_dvbt2_lite_s2 {
+   CXD2880_DVBT2_LITE_S2_M2K_G_ANY = 0x00,
+   CXD2880_DVBT2_LITE_S2_M8K_G_DVBT = 0x01,
+   CXD2880_DVBT2_LITE_S2_M4K_G_ANY = 0x02,
+   CXD2880_DVBT2_LITE_S2_M16K_G_DVBT2 = 0x03,
+   CXD2880_DVBT2_LITE_S2_M16K_G_DVBT = 0x04,
+   CXD2880_DVBT2_LITE_S2_RSVD1 = 0x05,
+   CXD2880_DVBT2_LITE_S2_M8K_G_DVBT2 = 0x06,
+   CXD2880_DVBT2_LITE_S2_RSVD2 = 0x07,
+   CXD2880_DVBT2_LITE_S2_UNKNOWN = 0xFF
+};
+
+enum cxd2880_dvbt2_guard {
+   CXD2880_DVBT2_G1_32 = 0x00,
+   CXD2880_DVBT2_G1_16 = 0x01,
+   CXD2880_DVBT2_G1_8 = 0x02,
+   CXD2880_DVBT2_G1_4 = 0x03,
+   CXD2880_DVBT2_G1_128 = 0x04,
+   CXD2880_DVBT2_G19_128 = 0x05,
+   CXD2880_DVBT2_G19_256 = 0x06,
+   CXD2880_DVBT2_G_RSVD1 = 0x07,
+   CXD2880_DVBT2_G_UNKNOWN = 0xFF
+};
+
+enum cxd2880_dvbt2_mode {
+   CXD2880_DVBT2_M2K = 0x00,
+   CXD2880_DVBT2_M8K = 0x01,
+   CXD2880_DVBT2_M4K = 0x02,
+   CXD2880_DVBT2_M1K = 0x03,
+   CXD2880_DVBT2_M16K = 0x04,
+   CXD2880_DVBT2_M32K = 0x05,
+   CXD2880_DVBT2_M_RSVD1 = 0x06,
+   CXD2880_DVBT2_M_RSVD2 = 0x07
+};
+
+enum cxd2880_dvbt2_bw {
+   CXD2880_DVBT2_BW_8 = 0x00,
+   

[PATCH v2 10/15] [media] cxd2880: Add DVB-T monitor and integration layer functions

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Provide monitor and integration layer functions (DVB-T)
for the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../dvb-frontends/cxd2880/cxd2880_integ_dvbt.c |  197 
 .../dvb-frontends/cxd2880/cxd2880_integ_dvbt.h |   58 +
 .../cxd2880/cxd2880_tnrdmd_dvbt_mon.c  | 1190 
 .../cxd2880/cxd2880_tnrdmd_dvbt_mon.h  |  106 ++
 4 files changed, 1551 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.h
 create mode 100644 
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c
 create mode 100644 
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c
new file mode 100644
index ..43b7da69fc6d
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c
@@ -0,0 +1,197 @@
+/*
+ * cxd2880_integ_dvbt.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration layer functions for DVB-T
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "cxd2880_tnrdmd_dvbt.h"
+#include "cxd2880_integ_dvbt.h"
+
+static enum cxd2880_ret dvbt_wait_demod_lock(struct cxd2880_tnrdmd *tnr_dmd);
+
+enum cxd2880_ret cxd2880_integ_dvbt_tune(struct cxd2880_tnrdmd *tnr_dmd,
+struct cxd2880_dvbt_tune_param
+*tune_param)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+
+   if ((!tnr_dmd) || (!tune_param))
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if ((tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) &&
+   (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE))
+   return CXD2880_RESULT_ERROR_SW_STATE;
+
+   cxd2880_atomic_set(_dmd->cancel, 0);
+
+   if ((tune_param->bandwidth != CXD2880_DTV_BW_5_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_6_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_7_MHZ) &&
+   (tune_param->bandwidth != CXD2880_DTV_BW_8_MHZ)) {
+   return CXD2880_RESULT_ERROR_NOSUPPORT;
+   }
+
+   ret = cxd2880_tnrdmd_dvbt_tune1(tnr_dmd, tune_param);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   CXD2880_SLEEP(CXD2880_TNRDMD_WAIT_AGC_STABLE);
+
+   ret = cxd2880_tnrdmd_dvbt_tune2(tnr_dmd, tune_param);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   ret = dvbt_wait_demod_lock(tnr_dmd);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   return ret;
+}
+
+enum cxd2880_ret cxd2880_integ_dvbt_wait_ts_lock(struct cxd2880_tnrdmd 
*tnr_dmd)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+   enum cxd2880_tnrdmd_lock_result lock =
+   CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
+   struct cxd2880_stopwatch timer;
+   u8 continue_wait = 1;
+   u32 elapsed = 0;
+
+   if (!tnr_dmd)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
+   return CXD2880_RESULT_ERROR_SW_STATE;
+
+   ret = 

[PATCH v2 09/15] [media] cxd2880: Add DVB-T control functions the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Provide definitions, interfaces and functions needed for DVB-T
of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h |   91 ++
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c| 1072 
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h|   62 ++
 3 files changed, 1225 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h
new file mode 100644
index ..345c094760d2
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h
@@ -0,0 +1,91 @@
+/*
+ * cxd2880_dvbt.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * DVB-T related definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#ifndef CXD2880_DVBT_H
+#define CXD2880_DVBT_H
+
+#include "cxd2880_common.h"
+
+enum cxd2880_dvbt_constellation {
+   CXD2880_DVBT_CONSTELLATION_QPSK,
+   CXD2880_DVBT_CONSTELLATION_16QAM,
+   CXD2880_DVBT_CONSTELLATION_64QAM,
+   CXD2880_DVBT_CONSTELLATION_RESERVED_3
+};
+
+enum cxd2880_dvbt_hierarchy {
+   CXD2880_DVBT_HIERARCHY_NON,
+   CXD2880_DVBT_HIERARCHY_1,
+   CXD2880_DVBT_HIERARCHY_2,
+   CXD2880_DVBT_HIERARCHY_4
+};
+
+enum cxd2880_dvbt_coderate {
+   CXD2880_DVBT_CODERATE_1_2,
+   CXD2880_DVBT_CODERATE_2_3,
+   CXD2880_DVBT_CODERATE_3_4,
+   CXD2880_DVBT_CODERATE_5_6,
+   CXD2880_DVBT_CODERATE_7_8,
+   CXD2880_DVBT_CODERATE_RESERVED_5,
+   CXD2880_DVBT_CODERATE_RESERVED_6,
+   CXD2880_DVBT_CODERATE_RESERVED_7
+};
+
+enum cxd2880_dvbt_guard {
+   CXD2880_DVBT_GUARD_1_32,
+   CXD2880_DVBT_GUARD_1_16,
+   CXD2880_DVBT_GUARD_1_8,
+   CXD2880_DVBT_GUARD_1_4
+};
+
+enum cxd2880_dvbt_mode {
+   CXD2880_DVBT_MODE_2K,
+   CXD2880_DVBT_MODE_8K,
+   CXD2880_DVBT_MODE_RESERVED_2,
+   CXD2880_DVBT_MODE_RESERVED_3
+};
+
+enum cxd2880_dvbt_profile {
+   CXD2880_DVBT_PROFILE_HP = 0,
+   CXD2880_DVBT_PROFILE_LP
+};
+
+struct cxd2880_dvbt_tpsinfo {
+   enum cxd2880_dvbt_constellation constellation;
+   enum cxd2880_dvbt_hierarchy hierarchy;
+   enum cxd2880_dvbt_coderate rate_hp;
+   enum cxd2880_dvbt_coderate rate_lp;
+   enum cxd2880_dvbt_guard guard;
+   enum cxd2880_dvbt_mode mode;
+   u8 fnum;
+   u8 length_indicator;
+   u16 cell_id;
+   u8 cell_id_ok;
+   u8 reserved_even;
+   u8 reserved_odd;
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c
new file mode 100644
index ..f36cf533ec17
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c
@@ -0,0 +1,1072 @@
+/*
+ * cxd2880_tnrdmd_dvbt.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * control functions for DVB-T
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * 

[PATCH v2 08/15] [media] cxd2880: Add top level of the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This provides the main dvb frontend operation functions
for the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/cxd2880/cxd2880_top.c | 1550 +
 1 file changed, 1550 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_top.c

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
new file mode 100644
index ..66d78fb93a13
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c
@@ -0,0 +1,1550 @@
+/*
+ * cxd2880_top.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include 
+
+#include "dvb_frontend.h"
+
+#include "cxd2880.h"
+#include "cxd2880_tnrdmd_mon.h"
+#include "cxd2880_tnrdmd_dvbt2_mon.h"
+#include "cxd2880_tnrdmd_dvbt_mon.h"
+#include "cxd2880_integ_dvbt2.h"
+#include "cxd2880_integ_dvbt.h"
+#include "cxd2880_devio_spi.h"
+#include "cxd2880_spi_device.h"
+#include "cxd2880_tnrdmd_driver_version.h"
+
+struct cxd2880_priv {
+   struct cxd2880_tnrdmd tnrdmd;
+   struct spi_device *spi;
+   struct cxd2880_io regio;
+   struct cxd2880_spi_device spi_device;
+   struct cxd2880_spi cxd2880_spi;
+   struct cxd2880_dvbt_tune_param dvbt_tune_param;
+   struct cxd2880_dvbt2_tune_param dvbt2_tune_param;
+   struct mutex *spi_mutex; /* For SPI access exclusive control */
+};
+
+/*
+ * return value conversion table
+ */
+static int return_tbl[] = {
+   0, /* CXD2880_RESULT_OK */
+   -EINVAL,   /* CXD2880_RESULT_ERROR_ARG*/
+   -EIO,  /* CXD2880_RESULT_ERROR_IO */
+   -EPERM,/* CXD2880_RESULT_ERROR_SW_STATE */
+   -EBUSY,/* CXD2880_RESULT_ERROR_HW_STATE */
+   -ETIME,/* CXD2880_RESULT_ERROR_TIMEOUT */
+   -EAGAIN,   /* CXD2880_RESULT_ERROR_UNLOCK */
+   -ERANGE,   /* CXD2880_RESULT_ERROR_RANGE */
+   -EOPNOTSUPP,   /* CXD2880_RESULT_ERROR_NOSUPPORT */
+   -ECANCELED,/* CXD2880_RESULT_ERROR_CANCEL */
+   -EPERM,/* CXD2880_RESULT_ERROR_OTHER */
+   -EOVERFLOW,/* CXD2880_RESULT_ERROR_OVERFLOW */
+   0, /* CXD2880_RESULT_OK_CONFIRM */
+};
+
+static enum cxd2880_ret cxd2880_pre_bit_err_t(
+   struct cxd2880_tnrdmd *tnrdmd, u32 *pre_bit_err,
+   u32 *pre_bit_count)
+{
+   u8 rdata[2];
+
+   if ((!tnrdmd) || (!pre_bit_err) || (!pre_bit_count))
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnrdmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (tnrdmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
+   return CXD2880_RESULT_ERROR_SW_STATE;
+
+   if (tnrdmd->sys != CXD2880_DTV_SYS_DVBT)
+   return CXD2880_RESULT_ERROR_SW_STATE;
+
+   if (slvt_freeze_reg(tnrdmd) != CXD2880_RESULT_OK)
+   return CXD2880_RESULT_ERROR_IO;
+
+   if (tnrdmd->io->write_reg(tnrdmd->io, CXD2880_IO_TGT_DMD,
+   0x00, 0x10) != CXD2880_RESULT_OK) {
+   slvt_unfreeze_reg(tnrdmd);
+   return CXD2880_RESULT_ERROR_IO;
+   }
+
+   if (tnrdmd->io->read_regs(tnrdmd->io, CXD2880_IO_TGT_DMD,
+   0x39, rdata, 1) != CXD2880_RESULT_OK) {
+   slvt_unfreeze_reg(tnrdmd);
+   return CXD2880_RESULT_ERROR_IO;
+   }

[PATCH v2 07/15] [media] cxd2880: Add integration layer for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

These functions monitor the driver and watch for task completion.
This is part of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../media/dvb-frontends/cxd2880/cxd2880_integ.c| 99 ++
 .../media/dvb-frontends/cxd2880/cxd2880_integ.h| 44 ++
 2 files changed, 143 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
new file mode 100644
index ..5ad6685e2a1d
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c
@@ -0,0 +1,99 @@
+/*
+ * cxd2880_integ.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration layer common functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "cxd2880_tnrdmd.h"
+#include "cxd2880_tnrdmd_mon.h"
+#include "cxd2880_integ.h"
+
+enum cxd2880_ret cxd2880_integ_init(struct cxd2880_tnrdmd *tnr_dmd)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+   struct cxd2880_stopwatch timer;
+   u32 elapsed_time = 0;
+   u8 cpu_task_completed = 0;
+
+   if (!tnr_dmd)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   ret = cxd2880_tnrdmd_init1(tnr_dmd);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   ret = cxd2880_stopwatch_start();
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   while (1) {
+   ret = cxd2880_stopwatch_elapsed(, _time);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   ret =
+   cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
+_task_completed);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   if (cpu_task_completed)
+   break;
+
+   if (elapsed_time > CXD2880_TNRDMD_WAIT_INIT_TIMEOUT)
+   return CXD2880_RESULT_ERROR_TIMEOUT;
+   ret =
+   cxd2880_stopwatch_sleep(,
+   CXD2880_TNRDMD_WAIT_INIT_INTVL);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+   }
+
+   ret = cxd2880_tnrdmd_init2(tnr_dmd);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_integ_cancel(struct cxd2880_tnrdmd *tnr_dmd)
+{
+   if (!tnr_dmd)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   cxd2880_atomic_set(_dmd->cancel, 1);
+
+   return CXD2880_RESULT_OK;
+}
+
+enum cxd2880_ret cxd2880_integ_check_cancellation(struct cxd2880_tnrdmd
+ *tnr_dmd)
+{
+   if (!tnr_dmd)
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (cxd2880_atomic_read(_dmd->cancel) != 0)
+   return CXD2880_RESULT_ERROR_CANCEL;
+
+   return CXD2880_RESULT_OK;
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
new file mode 100644
index ..9cfc52dbf9d4
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h
@@ -0,0 +1,44 @@
+/*
+ * cxd2880_integ.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * integration 

[PATCH v2 06/15] [media] cxd2880: Add tuner part of the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This part of the driver has the main routines to handle
the tuner and demodulator functionality.  The tnrdmd_mon.* files
have monitor functions for the driver.
This is part of the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h  |   50 +
 .../media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c   | 3925 
 .../media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h   |  395 ++
 .../cxd2880/cxd2880_tnrdmd_driver_version.h|   29 +
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c |  207 ++
 .../dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h |   52 +
 6 files changed, 4658 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h
 create mode 100644 
drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
new file mode 100644
index ..7de098d556fe
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h
@@ -0,0 +1,50 @@
+/*
+ * cxd2880_dtv.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * DTV related definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#ifndef CXD2880_DTV_H
+#define CXD2880_DTV_H
+
+enum cxd2880_dtv_sys {
+   CXD2880_DTV_SYS_UNKNOWN,
+   CXD2880_DTV_SYS_DVBT,
+   CXD2880_DTV_SYS_DVBT2,
+   CXD2880_DTV_SYS_ISDBT,
+   CXD2880_DTV_SYS_ISDBTSB,
+   CXD2880_DTV_SYS_ISDBTMM_A,
+   CXD2880_DTV_SYS_ISDBTMM_B,
+   CXD2880_DTV_SYS_ANY
+};
+
+enum cxd2880_dtv_bandwidth {
+   CXD2880_DTV_BW_UNKNOWN = 0,
+   CXD2880_DTV_BW_1_7_MHZ = 1,
+   CXD2880_DTV_BW_5_MHZ = 5,
+   CXD2880_DTV_BW_6_MHZ = 6,
+   CXD2880_DTV_BW_7_MHZ = 7,
+   CXD2880_DTV_BW_8_MHZ = 8
+};
+
+#endif
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
new file mode 100644
index ..286384ae0124
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c
@@ -0,0 +1,3925 @@
+/*
+ * cxd2880_tnrdmd.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common control functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, 

[PATCH v2 05/15] [media] cxd2880: Add spi device IO routines

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Add functions for initializing, reading and writing to the SPI
device for the Sony CXD2880 DVB-T2/T tuner + demodulator.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../dvb-frontends/cxd2880/cxd2880_devio_spi.c  | 147 +
 .../dvb-frontends/cxd2880/cxd2880_devio_spi.h  |  40 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h  |  51 +++
 .../dvb-frontends/cxd2880/cxd2880_spi_device.c | 130 ++
 .../dvb-frontends/cxd2880/cxd2880_spi_device.h |  45 +++
 5 files changed, 413 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
new file mode 100644
index ..516efade6bf5
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c
@@ -0,0 +1,147 @@
+/*
+ * cxd2880_devio_spi.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * I/O interface via SPI
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "cxd2880_devio_spi.h"
+#include "cxd2880_stdlib.h"
+
+#define BURST_WRITE_MAX 128
+
+static enum cxd2880_ret cxd2880_io_spi_read_reg(struct cxd2880_io *io,
+   enum cxd2880_io_tgt tgt,
+   u8 sub_address, u8 *data,
+   u32 size)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+   struct cxd2880_spi *spi = NULL;
+   u8 send_data[6];
+   u8 *read_data_top = data;
+
+   if ((!io) || (!io->if_object) || (!data))
+   return CXD2880_RESULT_ERROR_ARG;
+
+   if (sub_address + size > 0x100)
+   return CXD2880_RESULT_ERROR_RANGE;
+
+   spi = (struct cxd2880_spi *)(io->if_object);
+
+   if (tgt == CXD2880_IO_TGT_SYS)
+   send_data[0] = 0x0B;
+   else
+   send_data[0] = 0x0A;
+
+   send_data[3] = 0;
+   send_data[4] = 0;
+   send_data[5] = 0;
+
+   while (size > 0) {
+   send_data[1] = sub_address;
+   if (size > 255)
+   send_data[2] = 255;
+   else
+   send_data[2] = (u8)size;
+
+   ret =
+   spi->write_read(spi, send_data, sizeof(send_data),
+   read_data_top, send_data[2]);
+   if (ret != CXD2880_RESULT_OK)
+   return ret;
+
+   sub_address += send_data[2];
+   read_data_top += send_data[2];
+   size -= send_data[2];
+   }
+
+   return ret;
+}
+
+static enum cxd2880_ret cxd2880_io_spi_write_reg(struct cxd2880_io *io,
+enum cxd2880_io_tgt tgt,
+u8 sub_address,
+const u8 *data, u32 size)
+{
+   enum cxd2880_ret ret = CXD2880_RESULT_OK;
+   struct cxd2880_spi *spi = NULL;
+   u8 send_data[BURST_WRITE_MAX + 4];
+   const u8 *write_data_top = data;
+
+   if ((!io) || (!io->if_object) || (!data))
+ 

[PATCH v2 04/15] [media] cxd2880: Add math functions for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Provide some math support functions (fixed-point log functions)
for the Sony CXD2880 DVB-T2/T tuner + demodulator driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c | 89 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h | 40 ++
 2 files changed, 129 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
new file mode 100644
index ..434c827898ff
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
@@ -0,0 +1,89 @@
+/*
+ * cxd2880_math.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * mathmatics functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "cxd2880_math.h"
+
+#define MAX_BIT_PRECISION5
+#define FRAC_BITMASK   0x1F
+#define LOG2_10_100X332
+#define LOG2_E_100X  144
+
+static const u8 log2_look_up[] = {
+   0, 4,
+   9, 13,
+   17, 21,
+   25, 29,
+   32, 36,
+   39, 43,
+   46, 49,
+   52, 55,
+   58, 61,
+   64, 67,
+   70, 73,
+   75, 78,
+   81, 83,
+   86, 88,
+   91, 93,
+   95, 98
+};
+
+u32 cxd2880_math_log2(u32 x)
+{
+   u8 count = 0;
+   u8 index = 0;
+   u32 xval = x;
+
+   for (x >>= 1; x > 0; x >>= 1)
+   count++;
+
+   x = count * 100;
+
+   if (count > 0) {
+   if (count <= MAX_BIT_PRECISION) {
+   index =
+   (u8)(xval << (MAX_BIT_PRECISION - count)) &
+   FRAC_BITMASK;
+   x += log2_look_up[index];
+   } else {
+   index =
+   (u8)(xval >> (count - MAX_BIT_PRECISION)) &
+   FRAC_BITMASK;
+   x += log2_look_up[index];
+   }
+   }
+
+   return x;
+}
+
+u32 cxd2880_math_log10(u32 x)
+{
+   return ((100 * cxd2880_math_log2(x) + LOG2_10_100X / 2) / LOG2_10_100X);
+}
+
+u32 cxd2880_math_log(u32 x)
+{
+   return ((100 * cxd2880_math_log2(x) + LOG2_E_100X / 2) / LOG2_E_100X);
+}
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
new file mode 100644
index ..94211835a4ad
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
@@ -0,0 +1,40 @@
+/*
+ * cxd2880_math.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * mathmatics definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ 

[PATCH v2 03/15] [media] cxd2880: Add common files for the driver

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

These are common files for the driver for the
Sony CXD2880 DVB-T2/T tuner + demodulator.
These contains helper functions for the driver.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/dvb-frontends/cxd2880/cxd2880.h  | 46 
 .../media/dvb-frontends/cxd2880/cxd2880_common.c   | 84 +
 .../media/dvb-frontends/cxd2880/cxd2880_common.h   | 86 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c   | 68 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h   | 62 
 .../media/dvb-frontends/cxd2880/cxd2880_stdlib.h   | 35 +
 .../dvb-frontends/cxd2880/cxd2880_stopwatch_port.c | 71 ++
 7 files changed, 452 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c

diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880.h 
b/drivers/media/dvb-frontends/cxd2880/cxd2880.h
new file mode 100644
index ..281f9a784eb5
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880.h
@@ -0,0 +1,46 @@
+/*
+ * cxd2880.h
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver public definitions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#ifndef CXD2880_H
+#define CXD2880_H
+
+struct cxd2880_config {
+   struct spi_device *spi;
+   struct mutex *spi_mutex; /* For SPI access exclusive control */
+};
+
+#if IS_REACHABLE(CONFIG_DVB_CXD2880)
+extern struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
+   struct cxd2880_config *cfg);
+#else
+static inline struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe,
+   struct cxd2880_config *cfg)
+{
+   pr_warn("%s: driver disabled by Kconfig\n", __func__);
+   return NULL;
+}
+#endif /* CONFIG_DVB_CXD2880 */
+
+#endif /* CXD2880_H */
diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c 
b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
new file mode 100644
index ..850f3a76b2c7
--- /dev/null
+++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
@@ -0,0 +1,84 @@
+/*
+ * cxd2880_common.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * common functions
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 

[PATCH v2 02/15] [media] cxd2880-spi: Add support for CXD2008 SPI interface

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This is the SPI adapter part of the driver for the
Sony CXD2880 DVB-T2/T tuner + demodulator.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 drivers/media/spi/cxd2880-spi.c | 728 
 1 file changed, 728 insertions(+)
 create mode 100644 drivers/media/spi/cxd2880-spi.c

diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c
new file mode 100644
index ..82e122349055
--- /dev/null
+++ b/drivers/media/spi/cxd2880-spi.c
@@ -0,0 +1,728 @@
+/*
+ * cxd2880-spi.c
+ * Sony CXD2880 DVB-T2/T tuner + demodulator driver
+ * SPI adapter
+ *
+ * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include 
+
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_frontend.h"
+#include "cxd2880.h"
+
+#define CXD2880_MAX_FILTER_SIZE 32
+#define BURST_WRITE_MAX 128
+#define MAX_TRANS_PACKET 300
+
+struct cxd2880_ts_buf_info {
+   u8 read_ready;
+   u8 almost_full;
+   u8 almost_empty;
+   u8 overflow;
+   u8 underflow;
+   u16 packet_num;
+};
+
+struct cxd2880_pid_config {
+   u8 is_enable;
+   u16 pid;
+};
+
+struct cxd2880_pid_filter_config {
+   u8 is_negative;
+   struct cxd2880_pid_config pid_config[CXD2880_MAX_FILTER_SIZE];
+};
+
+struct cxd2880_dvb_spi {
+   struct dvb_frontend dvb_fe;
+   struct dvb_adapter adapter;
+   struct dvb_demux demux;
+   struct dmxdev dmxdev;
+   struct dmx_frontend dmx_fe;
+   struct task_struct *cxd2880_ts_read_thread;
+   struct spi_device *spi;
+   struct mutex spi_mutex; /* For SPI access exclusive control */
+   int feed_count;
+   int all_pid_feed_count;
+   u8 *ts_buf;
+   struct cxd2880_pid_filter_config filter_config;
+};
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static int cxd2880_write_spi(struct spi_device *spi, u8 *data, u32 size)
+{
+   struct spi_message msg;
+   struct spi_transfer tx;
+   int ret = 0;
+
+   if ((!spi) || (!data)) {
+   pr_err("%s: invalid arg\n", __func__);
+   return -EINVAL;
+   }
+
+   memset(, 0, sizeof(tx));
+   tx.tx_buf = data;
+   tx.len = size;
+
+   spi_message_init();
+   spi_message_add_tail(, );
+   ret = spi_sync(spi, );
+
+   return ret;
+}
+
+static int cxd2880_write_reg(struct spi_device *spi,
+   u8 subAddress, const u8 *data, u32 size)
+{
+   u8 send_data[BURST_WRITE_MAX + 4];
+   const u8 *write_data_top = NULL;
+   int ret = 0;
+
+   if ((!spi) || (!data)) {
+   pr_err("%s: invalid arg\n", __func__);
+   return -EINVAL;
+   }
+   if (size > BURST_WRITE_MAX) {
+   pr_err("%s: data size > WRITE_MAX\n", __func__);
+   return -EINVAL;
+   }
+
+   if (subAddress + size > 0x100) {
+   pr_err("%s: out of range\n", __func__);
+   return -EINVAL;
+   }
+
+   send_data[0] = 0x0E;
+   write_data_top = data;
+
+   while (size > 0) {
+   send_data[1] = subAddress;
+   if (size > 255)
+   send_data[2] = 255;
+   else
+   send_data[2] = (u8)size;
+
+   memcpy(_data[3], write_data_top, send_data[2]);
+
+   ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3);
+   if (ret) {
+   dev_err(>dev, "%s: write spi failed %d\n",
+   __func__, ret);
+  

[PATCH v2 01/15] [dt-bindings] [media] Add document file for CXD2880 SPI I/F

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

This is the document file for Sony CXD2880 DVB-T2/T tuner + demodulator.
It contains the description of the SPI adapter binding.

Signed-off-by: Yasunari Takiguchi 
Signed-off-by: Masayuki Yamamoto 
Signed-off-by: Hideki Nozawa 
Signed-off-by: Kota Yonezawa 
Signed-off-by: Toshihiko Matsumoto 
Signed-off-by: Satoshi Watanabe 
---
 .../devicetree/bindings/media/spi/sony-cxd2880.txt | 14 ++
 1 file changed, 14 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt

diff --git a/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt 
b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
new file mode 100644
index ..fc5aa263abe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
@@ -0,0 +1,14 @@
+Sony CXD2880 DVB-T2/T tuner + demodulator driver SPI adapter
+
+Required properties:
+- compatible: Should be "sony,cxd2880".
+- reg: SPI chip select number for the device.
+- spi-max-frequency: Maximum bus speed, should be set to <5500> (55MHz).
+
+Example:
+
+cxd2880@0 {
+   compatible = "sony,cxd2880";
+   reg = <0>; /* CE0 */
+   spi-max-frequency = <5500>; /* 55MHz */
+};
-- 
2.11.0



[PATCH v2 0/15] [dt-bindings] [media] Add document file and driver for Sony CXD2880 DVB-T2/T tuner + demodulator

2017-04-13 Thread Yasunari.Takiguchi
From: Yasunari Takiguchi 

Hi,

This is the patch series (version 2) of Sony CXD2880 DVB-T2/T tuner + 
demodulator driver.
The driver supports DVB-API and interfaces through SPI.

We have tested the driver on Raspberry Pi 3 and got picture and sound from a 
media player.

Thanks,
Takiguchi
---
 Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt|   14 
++
 drivers/media/spi/cxd2880-spi.c | 728 

 drivers/media/dvb-frontends/cxd2880/cxd2880.h   |   46 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_common.c|   84 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_common.h|   86 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c|   68 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h|   62 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h|   35 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c|   71 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c  |   89 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h  |   40 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c |  147 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h |   40 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h   |   51 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c|  130 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h|   45 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_dtv.h   |   50 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c| 3925 

 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.h|  395 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_driver_version.h |   29 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.c|  207 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_mon.h|   52 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.c |   99 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ.h |   44 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_top.c   | 1550 

 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt.h  |   91 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.c   | 1072 
+
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt.h   |   62 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.c|  197 ++
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt.h|   58 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.c   | 1190 
+
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt_mon.h   |  106 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_dvbt2.h |  402 
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c  | 1309 
++
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.h  |   82 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.c   |  311 +++
 drivers/media/dvb-frontends/cxd2880/cxd2880_integ_dvbt2.h   |   64 +
 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.c  | 2523 

 drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2_mon.h  |  170 ++
 drivers/media/dvb-frontends/Makefile|1 +
 drivers/media/dvb-frontends/cxd2880/Makefile|   21 
+
 drivers/media/spi/Makefile  |5 
+
 drivers/media/dvb-frontends/Kconfig |2 ++
 drivers/media/dvb-frontends/cxd2880/Kconfig |6 
++
 drivers/media/spi/Kconfig   |   14 
++
 MAINTAINERS |9 
+

 46 files changed, 15782 insertions(+)

 create mode 100644 Documentation/devicetree/bindings/media/spi/sony-cxd2880.txt
 create mode 100644 drivers/media/spi/cxd2880-spi.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_common.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_io.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stdlib.h
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_stopwatch_port.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.c
 create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_math.h
 create mode 100644 

[PATCH 15/22] scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers

2017-04-13 Thread Logan Gunthorpe
These two drivers appear to duplicate the functionality of
sg_copy_buffer. So we clean them up to use the common code.

This helps us remove a couple of instances that would otherwise be
slightly tricky sg_map usages.

Signed-off-by: Logan Gunthorpe 
---
 drivers/scsi/csiostor/csio_scsi.c | 54 +++
 drivers/scsi/libfc/fc_libfc.c | 49 ---
 2 files changed, 14 insertions(+), 89 deletions(-)

diff --git a/drivers/scsi/csiostor/csio_scsi.c 
b/drivers/scsi/csiostor/csio_scsi.c
index a1ff75f..bd9d062 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1489,60 +1489,14 @@ static inline uint32_t
 csio_scsi_copy_to_sgl(struct csio_hw *hw, struct csio_ioreq *req)
 {
struct scsi_cmnd *scmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
-   struct scatterlist *sg;
-   uint32_t bytes_left;
-   uint32_t bytes_copy;
-   uint32_t buf_off = 0;
-   uint32_t start_off = 0;
-   uint32_t sg_off = 0;
-   void *sg_addr;
-   void *buf_addr;
struct csio_dma_buf *dma_buf;
+   size_t copied;
 
-   bytes_left = scsi_bufflen(scmnd);
-   sg = scsi_sglist(scmnd);
dma_buf = (struct csio_dma_buf *)csio_list_next(>gen_list);
+   copied = sg_copy_from_buffer(scsi_sglist(scmnd), scsi_sg_count(scmnd),
+dma_buf->vaddr, scsi_bufflen(scmnd));
 
-   /* Copy data from driver buffer to SGs of SCSI CMD */
-   while (bytes_left > 0 && sg && dma_buf) {
-   if (buf_off >= dma_buf->len) {
-   buf_off = 0;
-   dma_buf = (struct csio_dma_buf *)
-   csio_list_next(dma_buf);
-   continue;
-   }
-
-   if (start_off >= sg->length) {
-   start_off -= sg->length;
-   sg = sg_next(sg);
-   continue;
-   }
-
-   buf_addr = dma_buf->vaddr + buf_off;
-   sg_off = sg->offset + start_off;
-   bytes_copy = min((dma_buf->len - buf_off),
-   sg->length - start_off);
-   bytes_copy = min((uint32_t)(PAGE_SIZE - (sg_off & ~PAGE_MASK)),
-bytes_copy);
-
-   sg_addr = kmap_atomic(sg_page(sg) + (sg_off >> PAGE_SHIFT));
-   if (!sg_addr) {
-   csio_err(hw, "failed to kmap sg:%p of ioreq:%p\n",
-   sg, req);
-   break;
-   }
-
-   csio_dbg(hw, "copy_to_sgl:sg_addr %p sg_off %d buf %p len %d\n",
-   sg_addr, sg_off, buf_addr, bytes_copy);
-   memcpy(sg_addr + (sg_off & ~PAGE_MASK), buf_addr, bytes_copy);
-   kunmap_atomic(sg_addr);
-
-   start_off +=  bytes_copy;
-   buf_off += bytes_copy;
-   bytes_left -= bytes_copy;
-   }
-
-   if (bytes_left > 0)
+   if (copied != scsi_bufflen(scmnd))
return DID_ERROR;
else
return DID_OK;
diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c
index d623d08..ce0805a 100644
--- a/drivers/scsi/libfc/fc_libfc.c
+++ b/drivers/scsi/libfc/fc_libfc.c
@@ -113,45 +113,16 @@ u32 fc_copy_buffer_to_sglist(void *buf, size_t len,
 u32 *nents, size_t *offset,
 u32 *crc)
 {
-   size_t remaining = len;
-   u32 copy_len = 0;
-
-   while (remaining > 0 && sg) {
-   size_t off, sg_bytes;
-   void *page_addr;
-
-   if (*offset >= sg->length) {
-   /*
-* Check for end and drop resources
-* from the last iteration.
-*/
-   if (!(*nents))
-   break;
-   --(*nents);
-   *offset -= sg->length;
-   sg = sg_next(sg);
-   continue;
-   }
-   sg_bytes = min(remaining, sg->length - *offset);
-
-   /*
-* The scatterlist item may be bigger than PAGE_SIZE,
-* but we are limited to mapping PAGE_SIZE at a time.
-*/
-   off = *offset + sg->offset;
-   sg_bytes = min(sg_bytes,
-  (size_t)(PAGE_SIZE - (off & ~PAGE_MASK)));
-   page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT));
-   if (crc)
-   *crc = crc32(*crc, buf, sg_bytes);
-   memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes);
-   kunmap_atomic(page_addr);
-   buf += sg_bytes;
-   *offset += sg_bytes;
-   remaining -= sg_bytes;
-   

[PATCH 07/22] crypto: shash, caam: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Very straightforward conversion to the new function in two crypto
drivers.

Signed-off-by: Logan Gunthorpe 
---
 crypto/shash.c| 9 ++---
 drivers/crypto/caam/caamalg.c | 8 +++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/crypto/shash.c b/crypto/shash.c
index 5e31c8d..2b7de94 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -283,10 +283,13 @@ int shash_ahash_digest(struct ahash_request *req, struct 
shash_desc *desc)
if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
void *data;
 
-   data = kmap_atomic(sg_page(sg));
-   err = crypto_shash_digest(desc, data + offset, nbytes,
+   data = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(data))
+   return PTR_ERR(data);
+
+   err = crypto_shash_digest(desc, data, nbytes,
  req->result);
-   kunmap_atomic(data);
+   sg_unmap(sg, data, SG_KMAP_ATOMIC);
crypto_yield(desc->flags);
} else
err = crypto_shash_init(desc) ?:
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 9bc80eb..76b97de 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -89,7 +89,6 @@ static void dbg_dump_sg(const char *level, const char 
*prefix_str,
struct scatterlist *sg, size_t tlen, bool ascii)
 {
struct scatterlist *it;
-   void *it_page;
size_t len;
void *buf;
 
@@ -98,19 +97,18 @@ static void dbg_dump_sg(const char *level, const char 
*prefix_str,
 * make sure the scatterlist's page
 * has a valid virtual memory mapping
 */
-   it_page = kmap_atomic(sg_page(it));
-   if (unlikely(!it_page)) {
+   buf = sg_map(it, SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
printk(KERN_ERR "dbg_dump_sg: kmap failed\n");
return;
}
 
-   buf = it_page + it->offset;
len = min_t(size_t, tlen, it->length);
print_hex_dump(level, prefix_str, prefix_type, rowsize,
   groupsize, buf, len, ascii);
tlen -= len;
 
-   kunmap_atomic(it_page);
+   sg_unmap(it, buf, SG_KMAP_ATOMIC);
}
 }
 #endif
-- 
2.1.4



[PATCH 10/22] staging: unisys: visorbus: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion to the new function.

Signed-off-by: Logan Gunthorpe 
---
 drivers/staging/unisys/visorhba/visorhba_main.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c 
b/drivers/staging/unisys/visorhba/visorhba_main.c
index 0ce92c8..2d8c8bc 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -842,7 +842,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct 
scsi_cmnd *scsicmd)
struct scatterlist *sg;
unsigned int i;
char *this_page;
-   char *this_page_orig;
int bufind = 0;
struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
@@ -869,11 +868,14 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct 
scsi_cmnd *scsicmd)
 
sg = scsi_sglist(scsicmd);
for (i = 0; i < scsi_sg_count(scsicmd); i++) {
-   this_page_orig = kmap_atomic(sg_page(sg + i));
-   this_page = (void *)((unsigned long)this_page_orig |
-sg[i].offset);
+   this_page = sg_map(sg + i, SG_KMAP_ATOMIC);
+   if (IS_ERR(this_page)) {
+   scsicmd->result = DID_ERROR << 16;
+   return;
+   }
+
memcpy(this_page, buf + bufind, sg[i].length);
-   kunmap_atomic(this_page_orig);
+   sg_unmap(sg + i, this_page, SG_KMAP_ATOMIC);
}
} else {
devdata = (struct visorhba_devdata *)scsidev->host->hostdata;
-- 
2.1.4



[PATCH 03/22] libiscsi: Make use of new the sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Convert the kmap and kmap_atomic uses to the sg_map function. We now
store the flags for the kmap instead of a boolean to indicate
atomicitiy. We also propogate a possible kmap error down and create
a new ISCSI_TCP_INTERNAL_ERR error type for this.

Signed-off-by: Logan Gunthorpe 
---
 drivers/scsi/cxgbi/libcxgbi.c |  5 +
 drivers/scsi/libiscsi_tcp.c   | 32 
 include/scsi/libiscsi_tcp.h   |  3 ++-
 3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index bd7d39e..e38d0c1 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -1556,6 +1556,11 @@ static inline int read_pdu_skb(struct iscsi_conn *conn,
 */
iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu or skb.");
return -EFAULT;
+   case ISCSI_TCP_INTERNAL_ERR:
+   pr_info("skb 0x%p, off %u, %d, TCP_INTERNAL_ERR.\n",
+   skb, offset, offloaded);
+   iscsi_conn_printk(KERN_ERR, conn, "Internal error.");
+   return -EFAULT;
case ISCSI_TCP_SEGMENT_DONE:
log_debug(1 << CXGBI_DBG_PDU_RX,
"skb 0x%p, off %u, %d, TCP_SEG_DONE, rc %d.\n",
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index 63a1d69..a2427699 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -133,25 +133,23 @@ static void iscsi_tcp_segment_map(struct iscsi_segment 
*segment, int recv)
if (page_count(sg_page(sg)) >= 1 && !recv)
return;
 
-   if (recv) {
-   segment->atomic_mapped = true;
-   segment->sg_mapped = kmap_atomic(sg_page(sg));
-   } else {
-   segment->atomic_mapped = false;
-   /* the xmit path can sleep with the page mapped so use kmap */
-   segment->sg_mapped = kmap(sg_page(sg));
+   /* the xmit path can sleep with the page mapped so don't use atomic */
+   segment->sg_map_flags = recv ? SG_KMAP_ATOMIC : SG_KMAP;
+   segment->sg_mapped = sg_map(sg, segment->sg_map_flags);
+
+   if (IS_ERR(segment->sg_mapped)) {
+   segment->sg_mapped = NULL;
+   return;
}
 
-   segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
+   segment->data = segment->sg_mapped + segment->sg_offset;
 }
 
 void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
 {
if (segment->sg_mapped) {
-   if (segment->atomic_mapped)
-   kunmap_atomic(segment->sg_mapped);
-   else
-   kunmap(sg_page(segment->sg));
+   sg_unmap(segment->sg, segment->sg_mapped,
+ segment->sg_map_flags);
segment->sg_mapped = NULL;
segment->data = NULL;
}
@@ -304,6 +302,9 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn,
break;
}
 
+   if (segment->data)
+   return -EFAULT;
+
copy = min(len - copied, segment->size - segment->copied);
ISCSI_DBG_TCP(tcp_conn->iscsi_conn, "copying %d\n", copy);
memcpy(segment->data + segment->copied, ptr + copied, copy);
@@ -927,6 +928,13 @@ int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct 
sk_buff *skb,
  avail);
rc = iscsi_tcp_segment_recv(tcp_conn, segment, ptr, avail);
BUG_ON(rc == 0);
+   if (rc < 0) {
+   ISCSI_DBG_TCP(conn, "memory fault. Consumed %d\n",
+ consumed);
+   *status = ISCSI_TCP_INTERNAL_ERR;
+   goto skb_done;
+   }
+
consumed += rc;
 
if (segment->total_copied >= segment->total_size) {
diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h
index 30520d5..58c79af 100644
--- a/include/scsi/libiscsi_tcp.h
+++ b/include/scsi/libiscsi_tcp.h
@@ -47,7 +47,7 @@ struct iscsi_segment {
struct scatterlist  *sg;
void*sg_mapped;
unsigned intsg_offset;
-   boolatomic_mapped;
+   int sg_map_flags;
 
iscsi_segment_done_fn_t *done;
 };
@@ -92,6 +92,7 @@ enum {
ISCSI_TCP_SKB_DONE, /* skb is out of data */
ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */
ISCSI_TCP_SUSPENDED,/* conn is suspended */
+   ISCSI_TCP_INTERNAL_ERR, /* an internal error occurred */
 };
 
 extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn);
-- 
2.1.4



[PATCH 12/22] scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call sites

2017-04-13 Thread Logan Gunthorpe
Very straightforward conversion of three scsi drivers.

Signed-off-by: Logan Gunthorpe 
---
 drivers/scsi/ipr.c  | 27 ++-
 drivers/scsi/isci/request.c | 42 +-
 drivers/scsi/pmcraid.c  | 19 ---
 3 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b29afaf..f98f251 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3853,7 +3853,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist 
*sglist)
 static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
 u8 *buffer, u32 len)
 {
-   int bsize_elem, i, result = 0;
+   int bsize_elem, i;
struct scatterlist *scatterlist;
void *kaddr;
 
@@ -3863,32 +3863,33 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist 
*sglist,
scatterlist = sglist->scatterlist;
 
for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
-   struct page *page = sg_page([i]);
+   kaddr = sg_map([i], SG_KMAP);
+   if (IS_ERR(kaddr)) {
+   ipr_trace;
+   return PTR_ERR(kaddr);
+   }
 
-   kaddr = kmap(page);
memcpy(kaddr, buffer, bsize_elem);
-   kunmap(page);
+   sg_unmap([i], kaddr, SG_KMAP);
 
scatterlist[i].length = bsize_elem;
-
-   if (result != 0) {
-   ipr_trace;
-   return result;
-   }
}
 
if (len % bsize_elem) {
-   struct page *page = sg_page([i]);
+   kaddr = sg_map([i], SG_KMAP);
+   if (IS_ERR(kaddr)) {
+   ipr_trace;
+   return PTR_ERR(kaddr);
+   }
 
-   kaddr = kmap(page);
memcpy(kaddr, buffer, len % bsize_elem);
-   kunmap(page);
+   sg_unmap([i], kaddr, SG_KMAP);
 
scatterlist[i].length = len % bsize_elem;
}
 
sglist->buffer_len = len;
-   return result;
+   return 0;
 }
 
 /**
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 47f66e9..66d6596 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -1424,12 +1424,14 @@ sci_stp_request_pio_data_in_copy_data_buffer(struct 
isci_stp_request *stp_req,
sg = task->scatter;
 
while (total_len > 0) {
-   struct page *page = sg_page(sg);
-
copy_len = min_t(int, total_len, sg_dma_len(sg));
-   kaddr = kmap_atomic(page);
-   memcpy(kaddr + sg->offset, src_addr, copy_len);
-   kunmap_atomic(kaddr);
+   kaddr = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(kaddr))
+   return SCI_FAILURE;
+
+   memcpy(kaddr, src_addr, copy_len);
+   sg_unmap(sg, kaddr, SG_KMAP_ATOMIC);
+
total_len -= copy_len;
src_addr += copy_len;
sg = sg_next(sg);
@@ -1771,14 +1773,16 @@ sci_io_request_frame_handler(struct isci_request *ireq,
case SCI_REQ_SMP_WAIT_RESP: {
struct sas_task *task = isci_request_access_task(ireq);
struct scatterlist *sg = >smp_task.smp_resp;
-   void *frame_header, *kaddr;
+   void *frame_header;
u8 *rsp;
 
sci_unsolicited_frame_control_get_header(>uf_control,
 frame_index,
 _header);
-   kaddr = kmap_atomic(sg_page(sg));
-   rsp = kaddr + sg->offset;
+   rsp = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(rsp))
+   return SCI_FAILURE;
+
sci_swab32_cpy(rsp, frame_header, 1);
 
if (rsp[0] == SMP_RESPONSE) {
@@ -1814,7 +1818,7 @@ sci_io_request_frame_handler(struct isci_request *ireq,
ireq->sci_status = 
SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
sci_change_state(>sm, SCI_REQ_COMPLETED);
}
-   kunmap_atomic(kaddr);
+   sg_unmap(sg, rsp, SG_KMAP_ATOMIC);
 
sci_controller_release_frame(ihost, frame_index);
 
@@ -2919,15 +2923,18 @@ static void isci_request_io_request_complete(struct 
isci_host *ihost,
case SAS_PROTOCOL_SMP: {
struct scatterlist *sg = >smp_task.smp_req;
struct smp_req *smp_req;
-   void *kaddr;
 
dma_unmap_sg(>pdev->dev, sg, 1, DMA_TO_DEVICE);
 
/* need to swab it back in case the command buffer is re-used */
-   

[PATCH 04/22] target: Make use of the new sg_map function at 16 call sites

2017-04-13 Thread Logan Gunthorpe
Fairly straightforward conversions in all spots. In a couple of cases
any error gets propogated up should sg_map fail. In other
cases a warning is issued if the kmap fails seeing there's no
clear error path. This should not be an issue until someone tries to
use unmappable memory in the sgl with this driver.

Signed-off-by: Logan Gunthorpe 
---
 drivers/target/iscsi/iscsi_target.c|  27 +---
 drivers/target/target_core_rd.c|   3 +-
 drivers/target/target_core_sbc.c   | 122 +++--
 drivers/target/target_core_transport.c |  18 +++--
 drivers/target/target_core_user.c  |  43 
 include/target/target_core_backend.h   |   4 +-
 6 files changed, 149 insertions(+), 68 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c 
b/drivers/target/iscsi/iscsi_target.c
index a918024..e3e0d8f 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -579,7 +579,7 @@ iscsit_xmit_nondatain_pdu(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
 }
 
 static int iscsit_map_iovec(struct iscsi_cmd *, struct kvec *, u32, u32);
-static void iscsit_unmap_iovec(struct iscsi_cmd *);
+static void iscsit_unmap_iovec(struct iscsi_cmd *, struct kvec *);
 static u32 iscsit_do_crypto_hash_sg(struct ahash_request *, struct iscsi_cmd *,
u32, u32, u32, u8 *);
 static int
@@ -646,7 +646,7 @@ iscsit_xmit_datain_pdu(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
 
ret = iscsit_fe_sendpage_sg(cmd, conn);
 
-   iscsit_unmap_iovec(cmd);
+   iscsit_unmap_iovec(cmd, >iov_data[1]);
 
if (ret < 0) {
iscsit_tx_thread_wait_for_tcp(conn);
@@ -925,7 +925,10 @@ static int iscsit_map_iovec(
while (data_length) {
u32 cur_len = min_t(u32, data_length, sg->length - page_off);
 
-   iov[i].iov_base = kmap(sg_page(sg)) + sg->offset + page_off;
+   iov[i].iov_base = sg_map_offset(sg, page_off, SG_KMAP);
+   if (IS_ERR(iov[i].iov_base))
+   goto map_err;
+
iov[i].iov_len = cur_len;
 
data_length -= cur_len;
@@ -937,17 +940,25 @@ static int iscsit_map_iovec(
cmd->kmapped_nents = i;
 
return i;
+
+map_err:
+   cmd->kmapped_nents = i - 1;
+   iscsit_unmap_iovec(cmd, iov);
+   return -1;
 }
 
-static void iscsit_unmap_iovec(struct iscsi_cmd *cmd)
+static void iscsit_unmap_iovec(struct iscsi_cmd *cmd, struct kvec *iov)
 {
u32 i;
struct scatterlist *sg;
+   unsigned int page_off = cmd->first_data_sg_off;
 
sg = cmd->first_data_sg;
 
-   for (i = 0; i < cmd->kmapped_nents; i++)
-   kunmap(sg_page([i]));
+   for (i = 0; i < cmd->kmapped_nents; i++) {
+   sg_unmap_offset([i], iov[i].iov_base, page_off, SG_KMAP);
+   page_off = 0;
+   }
 }
 
 static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn)
@@ -1610,7 +1621,7 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct 
iscsi_cmd *cmd,
 
rx_got = rx_data(conn, >iov_data[0], iov_count, rx_size);
 
-   iscsit_unmap_iovec(cmd);
+   iscsit_unmap_iovec(cmd, iov);
 
if (rx_got != rx_size)
return -1;
@@ -2626,7 +2637,7 @@ static int iscsit_handle_immediate_data(
 
rx_got = rx_data(conn, >iov_data[0], iov_count, rx_size);
 
-   iscsit_unmap_iovec(cmd);
+   iscsit_unmap_iovec(cmd, cmd->iov_data);
 
if (rx_got != rx_size) {
iscsit_rx_thread_wait_for_tcp(conn);
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index ddc216c..22c5ad5 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -431,7 +431,8 @@ static sense_reason_t rd_do_prot_rw(struct se_cmd *cmd, 
bool is_read)
cmd->t_prot_sg, 0);
 
if (!rc)
-   sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg, prot_offset);
+   rc = sbc_dif_copy_prot(cmd, sectors, is_read, prot_sg,
+  prot_offset);
 
return rc;
 }
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index c194063..67cb420 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -420,17 +420,17 @@ static sense_reason_t xdreadwrite_callback(struct se_cmd 
*cmd, bool success,
 
offset = 0;
for_each_sg(cmd->t_bidi_data_sg, sg, cmd->t_bidi_data_nents, count) {
-   addr = kmap_atomic(sg_page(sg));
-   if (!addr) {
+   addr = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(addr)) {
ret = TCM_OUT_OF_RESOURCES;
goto out;
}
 
for (i = 0; i < sg->length; i++)
-   *(addr + sg->offset + i) ^= *(buf + offset + i);
+   

[PATCH 18/22] mmc: spi: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
We use the sg_map helper but it's slightly more complicated
as we only check for the error when the mapping actually gets used.
Such that if the mapping failed but wasn't needed then no
error occurs.

Signed-off-by: Logan Gunthorpe 
---
 drivers/mmc/host/mmc_spi.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index e77d79c..82f786d 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -676,9 +676,15 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct 
spi_transfer *t,
struct scratch  *scratch = host->data;
u32 pattern;
 
-   if (host->mmc->use_spi_crc)
+   if (host->mmc->use_spi_crc) {
+   if (IS_ERR(t->tx_buf))
+   return PTR_ERR(t->tx_buf);
+
scratch->crc_val = cpu_to_be16(
crc_itu_t(0, t->tx_buf, t->len));
+   t->tx_buf += t->len;
+   }
+
if (host->dma_dev)
dma_sync_single_for_device(host->dma_dev,
host->data_dma, sizeof(*scratch),
@@ -743,7 +749,6 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct 
spi_transfer *t,
return status;
}
 
-   t->tx_buf += t->len;
if (host->dma_dev)
t->tx_dma += t->len;
 
@@ -809,6 +814,11 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct 
spi_transfer *t,
}
leftover = status << 1;
 
+   if (bitshift || host->mmc->use_spi_crc) {
+   if (IS_ERR(t->rx_buf))
+   return PTR_ERR(t->rx_buf);
+   }
+
if (host->dma_dev) {
dma_sync_single_for_device(host->dma_dev,
host->data_dma, sizeof(*scratch),
@@ -860,9 +870,10 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct 
spi_transfer *t,
scratch->crc_val, crc, t->len);
return -EILSEQ;
}
+
+   t->rx_buf += t->len;
}
 
-   t->rx_buf += t->len;
if (host->dma_dev)
t->rx_dma += t->len;
 
@@ -936,11 +947,11 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct 
mmc_command *cmd,
}
 
/* allow pio too; we don't allow highmem */
-   kmap_addr = kmap(sg_page(sg));
+   kmap_addr = sg_map(sg, SG_KMAP);
if (direction == DMA_TO_DEVICE)
-   t->tx_buf = kmap_addr + sg->offset;
+   t->tx_buf = kmap_addr;
else
-   t->rx_buf = kmap_addr + sg->offset;
+   t->rx_buf = kmap_addr;
 
/* transfer each block, and update request status */
while (length) {
@@ -970,7 +981,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct 
mmc_command *cmd,
/* discard mappings */
if (direction == DMA_FROM_DEVICE)
flush_kernel_dcache_page(sg_page(sg));
-   kunmap(sg_page(sg));
+   if (!IS_ERR(kmap_addr))
+   sg_unmap(sg, kmap_addr, SG_KMAP);
if (dma_dev)
dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
-- 
2.1.4



[PATCH 16/22] xen-blkfront: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion to the new helper, except due to
the lack of error path, we have to warn if unmapable memory
is ever present in the sgl.

Signed-off-by: Logan Gunthorpe 
---
 drivers/block/xen-blkfront.c | 33 +++--
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 5067a0a..7dcf41d 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -807,8 +807,19 @@ static int blkif_queue_rw_req(struct request *req, struct 
blkfront_ring_info *ri
BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
if (setup.need_copy) {
-   setup.bvec_off = sg->offset;
-   setup.bvec_data = kmap_atomic(sg_page(sg));
+   setup.bvec_off = 0;
+   setup.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(setup.bvec_data)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there is a
+* questionable error path out of here,
+* we WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return 1;
+   }
}
 
gnttab_foreach_grant_in_range(sg_page(sg),
@@ -818,7 +829,7 @@ static int blkif_queue_rw_req(struct request *req, struct 
blkfront_ring_info *ri
  );
 
if (setup.need_copy)
-   kunmap_atomic(setup.bvec_data);
+   sg_unmap(sg, setup.bvec_data, SG_KMAP_ATOMIC);
}
if (setup.segments)
kunmap_atomic(setup.segments);
@@ -1468,8 +1479,18 @@ static bool blkif_completion(unsigned long *id,
for_each_sg(s->sg, sg, num_sg, i) {
BUG_ON(sg->offset + sg->length > PAGE_SIZE);
 
-   data.bvec_offset = sg->offset;
-   data.bvec_data = kmap_atomic(sg_page(sg));
+   data.bvec_offset = 0;
+   data.bvec_data = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(data.bvec_data)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there is no
+* clear error path, we WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return 1;
+   }
 
gnttab_foreach_grant_in_range(sg_page(sg),
  sg->offset,
@@ -1477,7 +1498,7 @@ static bool blkif_completion(unsigned long *id,
  blkif_copy_from_grant,
  );
 
-   kunmap_atomic(data.bvec_data);
+   sg_unmap(sg, data.bvec_data, SG_KMAP_ATOMIC);
}
}
/* Add the persistent grant into the list of free grants */
-- 
2.1.4



[PATCH 22/22] memstick: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion, but we have to WARN if unmappable
memory finds its way into the sgl.

Signed-off-by: Logan Gunthorpe 
---
 drivers/memstick/host/jmb38x_ms.c | 23 ++-
 drivers/memstick/host/tifm_ms.c   | 22 +-
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/drivers/memstick/host/jmb38x_ms.c 
b/drivers/memstick/host/jmb38x_ms.c
index 48db922..256cf41 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -303,7 +303,6 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host 
*host)
unsigned int off;
unsigned int t_size, p_cnt;
unsigned char *buf;
-   struct page *pg;
unsigned long flags = 0;
 
if (host->req->long_data) {
@@ -318,14 +317,26 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host 
*host)
unsigned int uninitialized_var(p_off);
 
if (host->req->long_data) {
-   pg = nth_page(sg_page(>req->sg),
- off >> PAGE_SHIFT);
p_off = offset_in_page(off);
p_cnt = PAGE_SIZE - p_off;
p_cnt = min(p_cnt, length);
 
local_irq_save(flags);
-   buf = kmap_atomic(pg) + p_off;
+   buf = sg_map_offset(>req->sg,
+off - host->req->sg.offset,
+SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   break;
+   }
+
} else {
buf = host->req->data + host->block_pos;
p_cnt = host->req->data_len - host->block_pos;
@@ -341,7 +352,9 @@ static int jmb38x_ms_transfer_data(struct jmb38x_ms_host 
*host)
 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
 
if (host->req->long_data) {
-   kunmap_atomic(buf - p_off);
+   sg_unmap_offset(>req->sg, buf,
+off - host->req->sg.offset,
+SG_KMAP_ATOMIC);
local_irq_restore(flags);
}
 
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index 7bafa72..c0bc40e 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -186,7 +186,6 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms 
*host)
unsigned int off;
unsigned int t_size, p_cnt;
unsigned char *buf;
-   struct page *pg;
unsigned long flags = 0;
 
if (host->req->long_data) {
@@ -203,14 +202,25 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms 
*host)
unsigned int uninitialized_var(p_off);
 
if (host->req->long_data) {
-   pg = nth_page(sg_page(>req->sg),
- off >> PAGE_SHIFT);
p_off = offset_in_page(off);
p_cnt = PAGE_SIZE - p_off;
p_cnt = min(p_cnt, length);
 
local_irq_save(flags);
-   buf = kmap_atomic(pg) + p_off;
+   buf = sg_map_offset(>req->sg,
+off - host->req->sg.offset,
+SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   break;
+   }
} else {
buf = host->req->data + host->block_pos;
p_cnt = host->req->data_len - host->block_pos;
@@ -221,7 +231,9 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms 
*host)
 : tifm_ms_read_data(host, buf, p_cnt);
 
if 

[PATCH 19/22] mmc: tmio: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion to sg_map helper. A couple paths will
WARN if the memory does not end up being mappable.

Signed-off-by: Logan Gunthorpe 
---
 drivers/mmc/host/tmio_mmc.h | 12 ++--
 drivers/mmc/host/tmio_mmc_dma.c |  5 +
 drivers/mmc/host/tmio_mmc_pio.c | 24 
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 2b349d4..ba68c9fed 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -198,17 +198,25 @@ void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, 
u32 i);
 void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
 irqreturn_t tmio_mmc_irq(int irq, void *devid);
 
+/* Note: this function may return PTR_ERR and must be checked! */
 static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
 unsigned long *flags)
 {
+   void *ret;
+
local_irq_save(*flags);
-   return kmap_atomic(sg_page(sg)) + sg->offset;
+   ret = sg_map(sg, SG_KMAP_ATOMIC);
+
+   if (IS_ERR(ret))
+   local_irq_restore(*flags);
+
+   return ret;
 }
 
 static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
  unsigned long *flags, void *virt)
 {
-   kunmap_atomic(virt - sg->offset);
+   sg_unmap(sg, virt, SG_KMAP_ATOMIC);
local_irq_restore(*flags);
 }
 
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
index fa8a936..07531f7 100644
--- a/drivers/mmc/host/tmio_mmc_dma.c
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -149,6 +149,11 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host 
*host)
if (!aligned) {
unsigned long flags;
void *sg_vaddr = tmio_mmc_kmap_atomic(sg, );
+   if (IS_ERR(sg_vaddr)) {
+   ret = PTR_ERR(sg_vaddr);
+   goto pio;
+   }
+
sg_init_one(>bounce_sg, host->bounce_buf, sg->length);
memcpy(host->bounce_buf, sg_vaddr, host->bounce_sg.length);
tmio_mmc_kunmap_atomic(sg, , sg_vaddr);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 6b789a7..d6fdbf6 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -479,6 +479,18 @@ static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
}
 
sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, );
+   if (IS_ERR(sg_virt)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return;
+   }
+
buf = (unsigned short *)(sg_virt + host->sg_off);
 
count = host->sg_ptr->length - host->sg_off;
@@ -506,6 +518,18 @@ static void tmio_mmc_check_bounce_buffer(struct 
tmio_mmc_host *host)
if (host->sg_ptr == >bounce_sg) {
unsigned long flags;
void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, );
+   if (IS_ERR(sg_vaddr)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return;
+   }
+
memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length);
tmio_mmc_kunmap_atomic(host->sg_orig, , sg_vaddr);
}
-- 
2.1.4



[PATCH 08/22] crypto: chcr: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
The get_page in this area looks *highly* suspect due to there being no
corresponding put_page. However, I've left that as is to avoid breaking
things.

I've also removed the KMAP_ATOMIC_ARGS check as it appears to be dead
code that dates back to when it was first committed...

Signed-off-by: Logan Gunthorpe 
---
 drivers/crypto/chelsio/chcr_algo.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/chelsio/chcr_algo.c 
b/drivers/crypto/chelsio/chcr_algo.c
index 41bc7f4..a993d1d 100644
--- a/drivers/crypto/chelsio/chcr_algo.c
+++ b/drivers/crypto/chelsio/chcr_algo.c
@@ -1489,22 +1489,21 @@ static struct sk_buff *create_authenc_wr(struct 
aead_request *req,
return ERR_PTR(-EINVAL);
 }
 
-static void aes_gcm_empty_pld_pad(struct scatterlist *sg,
- unsigned short offset)
+static int aes_gcm_empty_pld_pad(struct scatterlist *sg,
+unsigned short offset)
 {
-   struct page *spage;
unsigned char *addr;
 
-   spage = sg_page(sg);
-   get_page(spage); /* so that it is not freed by NIC */
-#ifdef KMAP_ATOMIC_ARGS
-   addr = kmap_atomic(spage, KM_SOFTIRQ0);
-#else
-   addr = kmap_atomic(spage);
-#endif
-   memset(addr + sg->offset, 0, offset + 1);
+   get_page(sg_page(sg)); /* so that it is not freed by NIC */
+
+   addr = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(addr))
+   return PTR_ERR(addr);
+
+   memset(addr, 0, offset + 1);
+   sg_unmap(sg, addr, SG_KMAP_ATOMIC);
 
-   kunmap_atomic(addr);
+   return 0;
 }
 
 static int set_msg_len(u8 *block, unsigned int msglen, int csize)
@@ -1940,7 +1939,10 @@ static struct sk_buff *create_gcm_wr(struct aead_request 
*req,
if (req->cryptlen) {
write_sg_to_skb(skb, , src, req->cryptlen);
} else {
-   aes_gcm_empty_pld_pad(req->dst, authsize - 1);
+   err = aes_gcm_empty_pld_pad(req->dst, authsize - 1);
+   if (err)
+   goto dstmap_fail;
+
write_sg_to_skb(skb, , reqctx->dst, crypt_len);
 
}
-- 
2.1.4



[PATCH 05/22] drm/i915: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
This is a single straightforward conversion from kmap to sg_map.

Signed-off-by: Logan Gunthorpe 
---
 drivers/gpu/drm/i915/i915_gem.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 67b1fc5..1b1b91a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2188,6 +2188,15 @@ static void __i915_gem_object_reset_page_iter(struct 
drm_i915_gem_object *obj)
radix_tree_delete(>mm.get_page.radix, iter.index);
 }
 
+static void i915_gem_object_unmap(const struct drm_i915_gem_object *obj,
+ void *ptr)
+{
+   if (is_vmalloc_addr(ptr))
+   vunmap(ptr);
+   else
+   sg_unmap(obj->mm.pages->sgl, ptr, SG_KMAP);
+}
+
 void __i915_gem_object_put_pages(struct drm_i915_gem_object *obj,
 enum i915_mm_subclass subclass)
 {
@@ -2215,10 +2224,7 @@ void __i915_gem_object_put_pages(struct 
drm_i915_gem_object *obj,
void *ptr;
 
ptr = ptr_mask_bits(obj->mm.mapping);
-   if (is_vmalloc_addr(ptr))
-   vunmap(ptr);
-   else
-   kunmap(kmap_to_page(ptr));
+   i915_gem_object_unmap(obj, ptr);
 
obj->mm.mapping = NULL;
}
@@ -2475,8 +2481,11 @@ static void *i915_gem_object_map(const struct 
drm_i915_gem_object *obj,
void *addr;
 
/* A single page can always be kmapped */
-   if (n_pages == 1 && type == I915_MAP_WB)
-   return kmap(sg_page(sgt->sgl));
+   if (n_pages == 1 && type == I915_MAP_WB) {
+   addr = sg_map(sgt->sgl, SG_KMAP);
+   if (IS_ERR(addr))
+   return NULL;
+   }
 
if (n_pages > ARRAY_SIZE(stack_pages)) {
/* Too big for stack -- allocate temporary array instead */
@@ -2543,11 +2552,7 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object 
*obj,
goto err_unpin;
}
 
-   if (is_vmalloc_addr(ptr))
-   vunmap(ptr);
-   else
-   kunmap(kmap_to_page(ptr));
-
+   i915_gem_object_unmap(obj, ptr);
ptr = obj->mm.mapping = NULL;
}
 
-- 
2.1.4



[PATCH 01/22] scatterlist: Introduce sg_map helper functions

2017-04-13 Thread Logan Gunthorpe
This patch introduces functions which kmap the pages inside an sgl. Two
variants are provided: one if an offset is required and one if the
offset is zero. These functions replace a common pattern of
kmap(sg_page(sg)) that is used in about 50 places within the kernel.

The motivation for this work is to eventually safely support sgls that
contain io memory. In order for that to work, any access to the contents
of an iomem SGL will need to be done with iomemcpy or hit some warning.
(The exact details of how this will work have yet to be worked out.)
Having all the kmaps in one place is just a first step in that
direction. Additionally, seeing this helps cut down the users of sg_page,
it should make any effort to go to struct-page-less DMAs a little
easier (should that idea ever swing back into favour again).

A flags option is added to select between a regular or atomic mapping so
these functions can replace kmap(sg_page or kmap_atomic(sg_page.
Future work may expand this to have flags for using page_address or
vmap. Much further in the future, there may be a flag to allocate memory
and copy the data from/to iomem.

We also add the semantic that sg_map can fail to create a mapping,
despite the fact that the current code this is replacing is assumed to
never fail and the current version of these functions cannot fail. This
is to support iomem which either have to fail to create the mapping or
allocate memory as a bounce buffer which itself can fail.

Also, in terms of cleanup, a few of the existing kmap(sg_page) users
play things a bit loose in terms of whether they apply sg->offset
so using these helper functions should help avoid such issues.

Signed-off-by: Logan Gunthorpe 
---
 drivers/dma-buf/dma-buf.c   |  3 ++
 include/linux/scatterlist.h | 97 +
 2 files changed, 100 insertions(+)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 0007b79..b95934b 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -37,6 +37,9 @@
 
 #include 
 
+/* Prevent the highmem.h macro from aliasing ops->kunmap_atomic */
+#undef kunmap_atomic
+
 static inline int is_dma_buf_file(struct file *);
 
 struct dma_buf_list {
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index cb3c8fe..acd4d73 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -5,6 +5,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 struct scatterlist {
@@ -126,6 +127,102 @@ static inline struct page *sg_page(struct scatterlist *sg)
return (struct page *)((sg)->page_link & ~0x3);
 }
 
+#define SG_KMAP(1 << 0)/* create a mapping with kmap */
+#define SG_KMAP_ATOMIC (1 << 1)/* create a mapping with kmap_atomic */
+
+/**
+ * sg_map_offset - kmap a page inside an sgl
+ * @sg:SG entry
+ * @offset:Offset into entry
+ * @flags: Flags for creating the mapping
+ *
+ * Description:
+ *   Use this function to map a page in the scatterlist at the specified
+ *   offset. sg->offset is already added for you. Note: the semantics of
+ *   this function are that it may fail. Thus, its output should be checked
+ *   with IS_ERR and PTR_ERR. Otherwise, a pointer to the specified offset
+ *   in the mapped page is returned.
+ *
+ *   Flags can be any of:
+ * * SG_KMAP- Use kmap to create the mapping
+ * * SG_KMAP_ATOMIC - Use kmap_atomic to map the page atommically.
+ *Thus, the rules of that function apply: the cpu
+ *may not sleep until it is unmaped.
+ *
+ *   Also, consider carefully whether this function is appropriate. It is
+ *   largely not recommended for new code and if the sgl came from another
+ *   subsystem and you don't know what kind of memory might be in the list
+ *   then you definitely should not call it. Non-mappable memory may be in
+ *   the sgl and thus this function may fail unexpectedly.
+ **/
+static inline void *sg_map_offset(struct scatterlist *sg, size_t offset,
+  int flags)
+{
+   struct page *pg;
+   unsigned int pg_off;
+
+   offset += sg->offset;
+   pg = nth_page(sg_page(sg), offset >> PAGE_SHIFT);
+   pg_off = offset_in_page(offset);
+
+   if (flags & SG_KMAP_ATOMIC)
+   return kmap_atomic(pg) + pg_off;
+   else
+   return kmap(pg) + pg_off;
+}
+
+/**
+ * sg_unkmap_offset - unmap a page that was mapped with sg_map_offset
+ * @sg:SG entry
+ * @addr:  address returned by sg_map_offset
+ * @offset:Offset into entry (same as specified for sg_map_offset)
+ * @flags: Flags, which are the same specified for sg_map_offset
+ *
+ * Description:
+ *   Unmap the page that was mapped with sg_map_offset
+ *
+ **/
+static inline void sg_unmap_offset(struct scatterlist *sg, void *addr,
+   size_t offset, int flags)
+{
+   

[PATCH 02/22] nvmet: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
This is a straight forward conversion in two places. Should kmap fail,
the code will return an INVALD_DATA error in the completion.

Signed-off-by: Logan Gunthorpe 
---
 drivers/nvme/target/fabrics-cmd.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/target/fabrics-cmd.c 
b/drivers/nvme/target/fabrics-cmd.c
index 8bd022af..f62a634 100644
--- a/drivers/nvme/target/fabrics-cmd.c
+++ b/drivers/nvme/target/fabrics-cmd.c
@@ -122,7 +122,11 @@ static void nvmet_execute_admin_connect(struct nvmet_req 
*req)
struct nvmet_ctrl *ctrl = NULL;
u16 status = 0;
 
-   d = kmap(sg_page(req->sg)) + req->sg->offset;
+   d = sg_map(req->sg, SG_KMAP);
+   if (IS_ERR(d)) {
+   status = NVME_SC_SGL_INVALID_DATA;
+   goto out;
+   }
 
/* zero out initial completion result, assign values as needed */
req->rsp->result.u32 = 0;
@@ -158,7 +162,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req 
*req)
req->rsp->result.u16 = cpu_to_le16(ctrl->cntlid);
 
 out:
-   kunmap(sg_page(req->sg));
+   sg_unmap(req->sg, d, SG_KMAP);
nvmet_req_complete(req, status);
 }
 
@@ -170,7 +174,11 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
u16 qid = le16_to_cpu(c->qid);
u16 status = 0;
 
-   d = kmap(sg_page(req->sg)) + req->sg->offset;
+   d = sg_map(req->sg, SG_KMAP);
+   if (IS_ERR(d)) {
+   status = NVME_SC_SGL_INVALID_DATA;
+   goto out;
+   }
 
/* zero out initial completion result, assign values as needed */
req->rsp->result.u32 = 0;
@@ -205,7 +213,7 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
pr_info("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid);
 
 out:
-   kunmap(sg_page(req->sg));
+   sg_unmap(req->sg, d, SG_KMAP);
nvmet_req_complete(req, status);
return;
 
-- 
2.1.4



[PATCH 11/22] RDS: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion except there's no error path, so we WARN if
the sg_map fails.

Signed-off-by: Logan Gunthorpe 
---
 net/rds/ib_recv.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index e10624a..7f8fa99 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -801,9 +801,20 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off);
BUG_ON(to_copy & 7); /* Must be 64bit aligned. */
 
-   addr = kmap_atomic(sg_page(>f_sg));
+   addr = sg_map(>f_sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(addr)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return;
+   }
 
-   src = addr + frag->f_sg.offset + frag_off;
+   src = addr + frag_off;
dst = (void *)map->m_page_addrs[map_page] + map_off;
for (k = 0; k < to_copy; k += 8) {
/* Record ports that became uncongested, ie
@@ -811,7 +822,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn,
uncongested |= ~(*src) & *dst;
*dst++ = *src++;
}
-   kunmap_atomic(addr);
+   sg_unmap(>f_sg, addr, SG_KMAP_ATOMIC);
 
copied += to_copy;
 
-- 
2.1.4



[PATCH 00/22] Introduce common scatterlist map function

2017-04-13 Thread Logan Gunthorpe
Hi Everyone,

As part of my effort to enable P2P DMA transactions with PCI cards,
we've identified the need to be able to safely put IO memory into
scatterlists (and eventually other spots). This probably involves a
conversion from struct page to pfn_t but that migration is a ways off
and those decisions are yet to be made.

As an initial step in that direction, I've started cleaning up some of the
scatterlist code by trying to carve out a better defined layer between it
and it's users. The longer term goal would be to remove sg_page or replace
it with something that can potentially fail.

This patchset is the first step in that effort. I've introduced
a common function to map scatterlist memory and converted all the common
kmap(sg_page()) cases. This removes about 66 sg_page calls (of ~331).

Seeing this is a fairly large cleanup set that touches a wide swath of
the kernel I have limited the people I've sent this to. I'd suggest we look
toward merging the first patch and then I can send the individual subsystem
patches on to their respective maintainers and get them merged
independantly. (This is to avoid the conflicts I created with my last
cleanup set... Sorry) Though, I'm certainly open to other suggestions to get
it merged.

The patchset is based on v4.11-rc6 and can be found in the sg_map
branch from this git tree:

https://github.com/sbates130272/linux-p2pmem.git

Thanks,

Logan


Logan Gunthorpe (22):
  scatterlist: Introduce sg_map helper functions
  nvmet: Make use of the new sg_map helper function
  libiscsi: Make use of new the sg_map helper function
  target: Make use of the new sg_map function at 16 call sites
  drm/i915: Make use of the new sg_map helper function
  crypto: hifn_795x: Make use of the new sg_map helper function
  crypto: shash, caam: Make use of the new sg_map helper function
  crypto: chcr: Make use of the new sg_map helper function
  dm-crypt: Make use of the new sg_map helper in 4 call sites
  staging: unisys: visorbus: Make use of the new sg_map helper function
  RDS: Make use of the new sg_map helper function
  scsi: ipr, pmcraid, isci: Make use of the new sg_map helper in 4 call
sites
  scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper
function
  scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper
function
  scsi: libfc, csiostor: Change to sg_copy_buffer in two drivers
  xen-blkfront: Make use of the new sg_map helper function
  mmc: sdhci: Make use of the new sg_map helper function
  mmc: spi: Make use of the new sg_map helper function
  mmc: tmio: Make use of the new sg_map helper function
  mmc: sdricoh_cs: Make use of the new sg_map helper function
  mmc: tifm_sd: Make use of the new sg_map helper function
  memstick: Make use of the new sg_map helper function

 crypto/shash.c  |   9 +-
 drivers/block/xen-blkfront.c|  33 +--
 drivers/crypto/caam/caamalg.c   |   8 +-
 drivers/crypto/chelsio/chcr_algo.c  |  28 +++---
 drivers/crypto/hifn_795x.c  |  32 ---
 drivers/dma-buf/dma-buf.c   |   3 +
 drivers/gpu/drm/i915/i915_gem.c |  27 +++---
 drivers/md/dm-crypt.c   |  38 +---
 drivers/memstick/host/jmb38x_ms.c   |  23 -
 drivers/memstick/host/tifm_ms.c |  22 -
 drivers/mmc/host/mmc_spi.c  |  26 +++--
 drivers/mmc/host/sdhci.c|  35 ++-
 drivers/mmc/host/sdricoh_cs.c   |  14 ++-
 drivers/mmc/host/tifm_sd.c  |  88 +
 drivers/mmc/host/tmio_mmc.h |  12 ++-
 drivers/mmc/host/tmio_mmc_dma.c |   5 +
 drivers/mmc/host/tmio_mmc_pio.c |  24 +
 drivers/nvme/target/fabrics-cmd.c   |  16 +++-
 drivers/scsi/arcmsr/arcmsr_hba.c|  16 +++-
 drivers/scsi/csiostor/csio_scsi.c   |  54 +--
 drivers/scsi/cxgbi/libcxgbi.c   |   5 +
 drivers/scsi/gdth.c |   9 +-
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c  |  14 ++-
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c  |  13 ++-
 drivers/scsi/ipr.c  |  27 +++---
 drivers/scsi/ips.c  |   8 +-
 drivers/scsi/isci/request.c |  42 
 drivers/scsi/libfc/fc_libfc.c   |  49 ++
 drivers/scsi/libiscsi_tcp.c |  32 ---
 drivers/scsi/megaraid.c |   9 +-
 drivers/scsi/mvsas/mv_sas.c |  10 +-
 drivers/scsi/pmcraid.c  |  19 ++--
 drivers/staging/unisys/visorhba/visorhba_main.c |  12 ++-
 drivers/target/iscsi/iscsi_target.c |  27 --
 drivers/target/target_core_rd.c |   3 +-
 drivers/target/target_core_sbc.c| 122 +---
 

[PATCH 17/22] mmc: sdhci: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Straightforward conversion, except due to the lack of error path we
have to WARN if the memory in the SGL is not mappable.

Signed-off-by: Logan Gunthorpe 
---
 drivers/mmc/host/sdhci.c | 35 ++-
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 63bc33a..af0c107 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -497,15 +497,34 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host,
return sg_count;
 }
 
+/*
+ * Note this function may return PTR_ERR and must be checked.
+ */
 static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
 {
+   void *ret;
+
local_irq_save(*flags);
-   return kmap_atomic(sg_page(sg)) + sg->offset;
+
+   ret = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(ret)) {
+   /*
+* This should really never happen unless the code is changed
+* to use memory that is not mappable in the sg. Seeing there
+* doesn't seem to be any error path out of here, we can only
+* WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   local_irq_restore(*flags);
+   }
+
+   return ret;
 }
 
-static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
+static void sdhci_kunmap_atomic(struct scatterlist *sg, void *buffer,
+   unsigned long *flags)
 {
-   kunmap_atomic(buffer);
+   sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
local_irq_restore(*flags);
 }
 
@@ -568,8 +587,11 @@ static void sdhci_adma_table_pre(struct sdhci_host *host,
if (offset) {
if (data->flags & MMC_DATA_WRITE) {
buffer = sdhci_kmap_atomic(sg, );
+   if (IS_ERR(buffer))
+   return;
+
memcpy(align, buffer, offset);
-   sdhci_kunmap_atomic(buffer, );
+   sdhci_kunmap_atomic(sg, buffer, );
}
 
/* tran, valid */
@@ -646,8 +668,11 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
   (sg_dma_address(sg) & 
SDHCI_ADMA2_MASK);
 
buffer = sdhci_kmap_atomic(sg, );
+   if (IS_ERR(buffer))
+   return;
+
memcpy(buffer, align, size);
-   sdhci_kunmap_atomic(buffer, );
+   sdhci_kunmap_atomic(sg, buffer, );
 
align += SDHCI_ADMA2_ALIGN;
}
-- 
2.1.4



[PATCH 21/22] mmc: tifm_sd: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
This conversion is a bit complicated. We modiy the read_fifo,
write_fifo and copy_page functions to take a scatterlist instead of a
page. Thus we can use sg_map instead of kmap_atomic. There's a bit of
accounting that needed to be done for the offset for this to work.
(Seeing sg_map takes care of the offset but it's already added and
used earlier in the code.

There's also no error path, so if unmappable memory finds its way into
the sgl we can only WARN.

Signed-off-by: Logan Gunthorpe 
---
 drivers/mmc/host/tifm_sd.c | 88 +++---
 1 file changed, 67 insertions(+), 21 deletions(-)

diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 93c4b40..75b0d74 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -111,14 +111,26 @@ struct tifm_sd {
 };
 
 /* for some reason, host won't respond correctly to readw/writew */
-static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
+static void tifm_sd_read_fifo(struct tifm_sd *host, struct scatterlist *sg,
  unsigned int off, unsigned int cnt)
 {
struct tifm_dev *sock = host->dev;
unsigned char *buf;
unsigned int pos = 0, val;
 
-   buf = kmap_atomic(pg) + off;
+   buf = sg_map_offset(sg, off - sg->offset, SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return;
+   }
+
if (host->cmd_flags & DATA_CARRY) {
buf[pos++] = host->bounce_buf_data[0];
host->cmd_flags &= ~DATA_CARRY;
@@ -134,17 +146,29 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, 
struct page *pg,
}
buf[pos++] = (val >> 8) & 0xff;
}
-   kunmap_atomic(buf - off);
+   sg_unmap_offset(sg, buf, off - sg->offset, SG_KMAP_ATOMIC);
 }
 
-static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
+static void tifm_sd_write_fifo(struct tifm_sd *host, struct scatterlist *sg,
   unsigned int off, unsigned int cnt)
 {
struct tifm_dev *sock = host->dev;
unsigned char *buf;
unsigned int pos = 0, val;
 
-   buf = kmap_atomic(pg) + off;
+   buf = sg_map_offset(sg, off - sg->offset, SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
+   /*
+* This should really never happen unless
+* the code is changed to use memory that is
+* not mappable in the sg. Seeing there doesn't
+* seem to be any error path out of here,
+* we can only WARN.
+*/
+   WARN(1, "Non-mappable memory used in sg!");
+   return;
+   }
+
if (host->cmd_flags & DATA_CARRY) {
val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00);
writel(val, sock->addr + SOCK_MMCSD_DATA);
@@ -161,7 +185,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct 
page *pg,
val |= (buf[pos++] << 8) & 0xff00;
writel(val, sock->addr + SOCK_MMCSD_DATA);
}
-   kunmap_atomic(buf - off);
+   sg_unmap_offset(sg, buf, off - sg->offset, SG_KMAP_ATOMIC);
 }
 
 static void tifm_sd_transfer_data(struct tifm_sd *host)
@@ -170,7 +194,6 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
struct scatterlist *sg = r_data->sg;
unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2;
unsigned int p_off, p_cnt;
-   struct page *pg;
 
if (host->sg_pos == host->sg_len)
return;
@@ -192,33 +215,57 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
}
off = sg[host->sg_pos].offset + host->block_pos;
 
-   pg = nth_page(sg_page([host->sg_pos]), off >> PAGE_SHIFT);
p_off = offset_in_page(off);
p_cnt = PAGE_SIZE - p_off;
p_cnt = min(p_cnt, cnt);
p_cnt = min(p_cnt, t_size);
 
if (r_data->flags & MMC_DATA_READ)
-   tifm_sd_read_fifo(host, pg, p_off, p_cnt);
+   tifm_sd_read_fifo(host, [host->sg_pos], p_off,
+ p_cnt);
else if (r_data->flags & MMC_DATA_WRITE)
-   tifm_sd_write_fifo(host, pg, p_off, p_cnt);
+   tifm_sd_write_fifo(host, [host->sg_pos], p_off,
+  p_cnt);
 
t_size -= p_cnt;
host->block_pos += p_cnt;
}
 }
 
-static void tifm_sd_copy_page(struct page 

[PATCH 13/22] scsi: hisi_sas, mvsas, gdth: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Very straightforward conversion of three scsi drivers.

Signed-off-by: Logan Gunthorpe 
---
 drivers/scsi/gdth.c|  9 +++--
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 14 +-
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 13 +
 drivers/scsi/mvsas/mv_sas.c| 10 +-
 4 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index d020a13..82c9fba 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2301,10 +2301,15 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, 
Scsi_Cmnd *scp,
 return;
 }
 local_irq_save(flags);
-address = kmap_atomic(sg_page(sl)) + sl->offset;
+address = sg_map(sl, SG_KMAP_ATOMIC);
+if (IS_ERR(address)) {
+scp->result = DID_ERROR << 16;
+return;
+   }
+
 memcpy(address, buffer, cpnow);
 flush_dcache_page(sg_page(sl));
-kunmap_atomic(address);
+sg_unmap(sl, address, SG_KMAP_ATOMIC);
 local_irq_restore(flags);
 if (cpsum == cpcount)
 break;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 854fbea..30408f8 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -1377,18 +1377,22 @@ static int slot_complete_v1_hw(struct hisi_hba 
*hisi_hba,
void *to;
struct scatterlist *sg_resp = >smp_task.smp_resp;
 
-   ts->stat = SAM_STAT_GOOD;
-   to = kmap_atomic(sg_page(sg_resp));
+   to = sg_map(sg_resp, SG_KMAP_ATOMIC);
+   if (IS_ERR(to)) {
+   dev_err(dev, "slot complete: error mapping memory");
+   ts->stat = SAS_SG_ERR;
+   break;
+   }
 
+   ts->stat = SAM_STAT_GOOD;
dma_unmap_sg(dev, >smp_task.smp_resp, 1,
 DMA_FROM_DEVICE);
dma_unmap_sg(dev, >smp_task.smp_req, 1,
 DMA_TO_DEVICE);
-   memcpy(to + sg_resp->offset,
-  slot->status_buffer +
+   memcpy(to, slot->status_buffer +
   sizeof(struct hisi_sas_err_record),
   sg_dma_len(sg_resp));
-   kunmap_atomic(to);
+   sg_unmap(sg_resp, to, SG_KMAP_ATOMIC);
break;
}
case SAS_PROTOCOL_SATA:
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 1b21445..0907947 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1796,18 +1796,23 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct 
hisi_sas_slot *slot,
struct scatterlist *sg_resp = >smp_task.smp_resp;
void *to;
 
+   to = sg_map(sg_resp, SG_KMAP_ATOMIC);
+   if (IS_ERR(to)) {
+   dev_err(dev, "slot complete: error mapping memory");
+   ts->stat = SAS_SG_ERR;
+   break;
+   }
+
ts->stat = SAM_STAT_GOOD;
-   to = kmap_atomic(sg_page(sg_resp));
 
dma_unmap_sg(dev, >smp_task.smp_resp, 1,
 DMA_FROM_DEVICE);
dma_unmap_sg(dev, >smp_task.smp_req, 1,
 DMA_TO_DEVICE);
-   memcpy(to + sg_resp->offset,
-  slot->status_buffer +
+   memcpy(to, slot->status_buffer +
   sizeof(struct hisi_sas_err_record),
   sg_dma_len(sg_resp));
-   kunmap_atomic(to);
+   sg_unmap(sg_resp, to, SG_KMAP_ATOMIC);
break;
}
case SAS_PROTOCOL_SATA:
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index c7cc803..374d0e0 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1798,11 +1798,11 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 
rx_desc, u32 flags)
case SAS_PROTOCOL_SMP: {
struct scatterlist *sg_resp = >smp_task.smp_resp;
tstat->stat = SAM_STAT_GOOD;
-   to = kmap_atomic(sg_page(sg_resp));
-   memcpy(to + sg_resp->offset,
-   slot->response + sizeof(struct mvs_err_info),
-   sg_dma_len(sg_resp));
-   kunmap_atomic(to);
+   to = sg_map(sg_resp, SG_KMAP_ATOMIC);
+   memcpy(to,
+  slot->response + sizeof(struct mvs_err_info),
+  sg_dma_len(sg_resp));
+   sg_unmap(sg_resp, to, SG_KMAP_ATOMIC);
  

[PATCH 20/22] mmc: sdricoh_cs: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
This is a straightforward conversion to the new function.

Signed-off-by: Logan Gunthorpe 
---
 drivers/mmc/host/sdricoh_cs.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c
index 5ff26ab..7eeed23 100644
--- a/drivers/mmc/host/sdricoh_cs.c
+++ b/drivers/mmc/host/sdricoh_cs.c
@@ -319,16 +319,20 @@ static void sdricoh_request(struct mmc_host *mmc, struct 
mmc_request *mrq)
for (i = 0; i < data->blocks; i++) {
size_t len = data->blksz;
u8 *buf;
-   struct page *page;
int result;
-   page = sg_page(data->sg);
 
-   buf = kmap(page) + data->sg->offset + (len * i);
+   buf = sg_map_offset(data->sg, (len * i), SG_KMAP);
+   if (IS_ERR(buf)) {
+   cmd->error = PTR_ERR(buf);
+   break;
+   }
+
result =
sdricoh_blockio(host,
data->flags & MMC_DATA_READ, buf, len);
-   kunmap(page);
-   flush_dcache_page(page);
+   sg_unmap_offset(data->sg, buf, (len * i), SG_KMAP);
+
+   flush_dcache_page(sg_page(data->sg));
if (result) {
dev_err(dev, "sdricoh_request: cmd %i "
"block transfer failed\n", cmd->opcode);
-- 
2.1.4



[PATCH 09/22] dm-crypt: Make use of the new sg_map helper in 4 call sites

2017-04-13 Thread Logan Gunthorpe
Very straightforward conversion to the new function in all four spots.

Signed-off-by: Logan Gunthorpe 
---
 drivers/md/dm-crypt.c | 38 +-
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 389a363..6bd0ffc 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -589,9 +589,12 @@ static int crypt_iv_lmk_gen(struct crypt_config *cc, u8 
*iv,
int r = 0;
 
if (bio_data_dir(dmreq->ctx->bio_in) == WRITE) {
-   src = kmap_atomic(sg_page(>sg_in));
-   r = crypt_iv_lmk_one(cc, iv, dmreq, src + dmreq->sg_in.offset);
-   kunmap_atomic(src);
+   src = sg_map(>sg_in, SG_KMAP_ATOMIC);
+   if (IS_ERR(src))
+   return PTR_ERR(src);
+
+   r = crypt_iv_lmk_one(cc, iv, dmreq, src);
+   sg_unmap(>sg_in, src, SG_KMAP_ATOMIC);
} else
memset(iv, 0, cc->iv_size);
 
@@ -607,14 +610,17 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 
*iv,
if (bio_data_dir(dmreq->ctx->bio_in) == WRITE)
return 0;
 
-   dst = kmap_atomic(sg_page(>sg_out));
-   r = crypt_iv_lmk_one(cc, iv, dmreq, dst + dmreq->sg_out.offset);
+   dst = sg_map(>sg_out, SG_KMAP_ATOMIC);
+   if (IS_ERR(dst))
+   return PTR_ERR(dst);
+
+   r = crypt_iv_lmk_one(cc, iv, dmreq, dst);
 
/* Tweak the first block of plaintext sector */
if (!r)
-   crypto_xor(dst + dmreq->sg_out.offset, iv, cc->iv_size);
+   crypto_xor(dst, iv, cc->iv_size);
 
-   kunmap_atomic(dst);
+   sg_unmap(>sg_out, dst, SG_KMAP_ATOMIC);
return r;
 }
 
@@ -731,9 +737,12 @@ static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 
*iv,
 
/* Remove whitening from ciphertext */
if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) {
-   src = kmap_atomic(sg_page(>sg_in));
-   r = crypt_iv_tcw_whitening(cc, dmreq, src + 
dmreq->sg_in.offset);
-   kunmap_atomic(src);
+   src = sg_map(>sg_in, SG_KMAP_ATOMIC);
+   if (IS_ERR(src))
+   return PTR_ERR(src);
+
+   r = crypt_iv_tcw_whitening(cc, dmreq, src);
+   sg_unmap(>sg_in, src, SG_KMAP_ATOMIC);
}
 
/* Calculate IV */
@@ -755,9 +764,12 @@ static int crypt_iv_tcw_post(struct crypt_config *cc, u8 
*iv,
return 0;
 
/* Apply whitening on ciphertext */
-   dst = kmap_atomic(sg_page(>sg_out));
-   r = crypt_iv_tcw_whitening(cc, dmreq, dst + dmreq->sg_out.offset);
-   kunmap_atomic(dst);
+   dst = sg_map(>sg_out, SG_KMAP_ATOMIC);
+   if (IS_ERR(dst))
+   return PTR_ERR(dst);
+
+   r = crypt_iv_tcw_whitening(cc, dmreq, dst);
+   sg_unmap(>sg_out, dst, SG_KMAP_ATOMIC);
 
return r;
 }
-- 
2.1.4



[PATCH 14/22] scsi: arcmsr, ips, megaraid: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Very straightforward conversion of three scsi drivers

Signed-off-by: Logan Gunthorpe 
---
 drivers/scsi/arcmsr/arcmsr_hba.c | 16 
 drivers/scsi/ips.c   |  8 
 drivers/scsi/megaraid.c  |  9 +++--
 3 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index af032c4..3cd485c 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -2306,7 +2306,10 @@ static int arcmsr_iop_message_xfer(struct 
AdapterControlBlock *acb,
 
use_sg = scsi_sg_count(cmd);
sg = scsi_sglist(cmd);
-   buffer = kmap_atomic(sg_page(sg)) + sg->offset;
+   buffer = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(buffer))
+   return ARCMSR_MESSAGE_FAIL;
+
if (use_sg > 1) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
@@ -2539,7 +2542,7 @@ static int arcmsr_iop_message_xfer(struct 
AdapterControlBlock *acb,
 message_out:
if (use_sg) {
struct scatterlist *sg = scsi_sglist(cmd);
-   kunmap_atomic(buffer - sg->offset);
+   sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
}
return retvalue;
 }
@@ -2590,11 +2593,16 @@ static void arcmsr_handle_virtual_command(struct 
AdapterControlBlock *acb,
strncpy([32], "R001", 4); /* Product Revision */
 
sg = scsi_sglist(cmd);
-   buffer = kmap_atomic(sg_page(sg)) + sg->offset;
+   buffer = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(buffer)) {
+   cmd->result = (DID_ERROR << 16);
+   cmd->scsi_done(cmd);
+   return;
+   }
 
memcpy(buffer, inqdata, sizeof(inqdata));
sg = scsi_sglist(cmd);
-   kunmap_atomic(buffer - sg->offset);
+   sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
 
cmd->scsi_done(cmd);
}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 3419e1b..a44291d 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1506,14 +1506,14 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
 /* kmap_atomic() ensures addressability of the user buffer.*/
 /* local_irq_save() protects the KM_IRQ0 address slot. */
 local_irq_save(flags);
-buffer = kmap_atomic(sg_page(sg)) + sg->offset;
-if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
+buffer = sg_map(sg, SG_KMAP_ATOMIC);
+if (!IS_ERR(buffer) && buffer[0] == 'C' && buffer[1] == 'O' &&
 buffer[2] == 'P' && buffer[3] == 'P') {
-kunmap_atomic(buffer - sg->offset);
+sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
 local_irq_restore(flags);
 return 1;
 }
-kunmap_atomic(buffer - sg->offset);
+sg_unmap(sg, buffer, SG_KMAP_ATOMIC);
 local_irq_restore(flags);
}
return 0;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 3c63c29..0b66e50 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -663,10 +663,15 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int 
*busy)
struct scatterlist *sg;
 
sg = scsi_sglist(cmd);
-   buf = kmap_atomic(sg_page(sg)) + sg->offset;
+   buf = sg_map(sg, SG_KMAP_ATOMIC);
+   if (IS_ERR(buf)) {
+cmd->result = (DID_ERROR << 16);
+   cmd->scsi_done(cmd);
+   return NULL;
+   }
 
memset(buf, 0, cmd->cmnd[4]);
-   kunmap_atomic(buf - sg->offset);
+   sg_unmap(sg, buf, SG_KMAP_ATOMIC);
 
cmd->result = (DID_OK << 16);
cmd->scsi_done(cmd);
-- 
2.1.4



[PATCH 06/22] crypto: hifn_795x: Make use of the new sg_map helper function

2017-04-13 Thread Logan Gunthorpe
Conversion of a couple kmap_atomic instances to the sg_map helper
function.

However, it looks like there was a bug in the original code: the source
scatter lists offset (t->offset) was passed to ablkcipher_get which
added it to the destination address. This doesn't make a lot of
sense, but t->offset is likely always zero anyway. So, this patch cleans
that brokeness up.

Also, a change to the error path: if ablkcipher_get failed, everything
seemed to proceed as if it hadn't. Setting 'error' should hopefully
clear that up.

Signed-off-by: Logan Gunthorpe 
---
 drivers/crypto/hifn_795x.c | 32 +---
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index e09d405..8e2c6a9 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1619,7 +1619,7 @@ static int hifn_start_device(struct hifn_device *dev)
return 0;
 }
 
-static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int 
offset,
+static int ablkcipher_get(void *saddr, unsigned int *srestp,
struct scatterlist *dst, unsigned int size, unsigned int 
*nbytesp)
 {
unsigned int srest = *srestp, nbytes = *nbytesp, copy;
@@ -1632,15 +1632,17 @@ static int ablkcipher_get(void *saddr, unsigned int 
*srestp, unsigned int offset
while (size) {
copy = min3(srest, dst->length, size);
 
-   daddr = kmap_atomic(sg_page(dst));
-   memcpy(daddr + dst->offset + offset, saddr, copy);
-   kunmap_atomic(daddr);
+   daddr = sg_map(dst, SG_KMAP_ATOMIC);
+   if (IS_ERR(daddr))
+   return PTR_ERR(daddr);
+
+   memcpy(daddr, saddr, copy);
+   sg_unmap(dst, daddr, SG_KMAP_ATOMIC);
 
nbytes -= copy;
size -= copy;
srest -= copy;
saddr += copy;
-   offset = 0;
 
pr_debug("%s: copy: %u, size: %u, srest: %u, nbytes: %u.\n",
 __func__, copy, size, srest, nbytes);
@@ -1671,11 +1673,12 @@ static inline void hifn_complete_sa(struct hifn_device 
*dev, int i)
 
 static void hifn_process_ready(struct ablkcipher_request *req, int error)
 {
+   int err;
struct hifn_request_context *rctx = ablkcipher_request_ctx(req);
 
if (rctx->walk.flags & ASYNC_FLAGS_MISALIGNED) {
unsigned int nbytes = req->nbytes;
-   int idx = 0, err;
+   int idx = 0;
struct scatterlist *dst, *t;
void *saddr;
 
@@ -1695,17 +1698,24 @@ static void hifn_process_ready(struct 
ablkcipher_request *req, int error)
continue;
}
 
-   saddr = kmap_atomic(sg_page(t));
+   saddr = sg_map(t, SG_KMAP_ATOMIC);
+   if (IS_ERR(saddr)) {
+   if (!error)
+   error = PTR_ERR(saddr);
+   break;
+   }
+
+   err = ablkcipher_get(saddr, >length,
+dst, nbytes, );
+   sg_unmap(t, saddr, SG_KMAP_ATOMIC);
 
-   err = ablkcipher_get(saddr, >length, t->offset,
-   dst, nbytes, );
if (err < 0) {
-   kunmap_atomic(saddr);
+   if (!error)
+   error = err;
break;
}
 
idx += err;
-   kunmap_atomic(saddr);
}
 
hifn_cipher_walk_exit(>walk);
-- 
2.1.4



Re: [PATCH 14/14] atomisp: remove UDS kernel code

2017-04-13 Thread kbuild test robot
Hi Alan,

[auto build test ERROR on next-20170412]
[cannot apply to linuxtv-media/master v4.9-rc8 v4.9-rc7 v4.9-rc6 v4.11-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Alan-Cox/staging-atomisp-use-local-variable-to-reduce-number-of-references/20170413-112312
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

>> make[7]: *** No rule to make target 
>> 'drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/uds/uds_1.0/ia_css_uds.host.o',
>>  needed by 'drivers/staging/media/atomisp/pci/atomisp2/atomisp.o'.
   make[7]: *** No rule to make target 
'drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds.host.o',
 needed by 'drivers/staging/media/atomisp/pci/atomisp2/atomisp.o'.
   make[7]: Target '__build' not remade because of errors.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 40/40] media: imx: set and propagate empty field, colorimetry params

2017-04-13 Thread Steve Longerbeam



On 04/13/2017 03:09 AM, Philipp Zabel wrote:

Hi Steve,

thanks for cleaning this up. Apart from the comments below, this looks
good to me.

On Wed, 2017-04-12 at 17:45 -0700, Steve Longerbeam wrote:

This patch adds a call to imx_media_fill_empty_mbus_fields() in the
*_try_fmt() functions at the sink pads, to set empty field order and
colorimetry parameters.

If the field order is set to ANY, choose the currently set field order
at the sink pad. If the colorspace is set to DEFAULT, choose the
current colorspace at the sink pad.  If any of xfer_func, ycbcr_enc
or quantization are set to DEFAULT, either choose the current sink pad
setting, or the default setting for the new colorspace, if non-DEFAULT
colorspace was given.

Colorimetry is also propagated from sink to source pads anywhere
this has not already been done. The exception is ic-prpencvf at the
source pad, since the Image Converter outputs fixed quantization and
Y`CbCr encoding.

Signed-off-by: Steve Longerbeam 
---
 drivers/staging/media/imx/imx-ic-prp.c  |  5 ++-
 drivers/staging/media/imx/imx-ic-prpencvf.c | 25 +++---
 drivers/staging/media/imx/imx-media-csi.c   | 12 +--
 drivers/staging/media/imx/imx-media-utils.c | 53 +
 drivers/staging/media/imx/imx-media-vdic.c  |  7 ++--
 drivers/staging/media/imx/imx-media.h   |  3 +-
 6 files changed, 95 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/media/imx/imx-ic-prp.c 
b/drivers/staging/media/imx/imx-ic-prp.c
index b4d4e48..8baa0d5 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -180,6 +180,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
goto out;
}

+   fmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
+


Should this be changed to infmt for consistency?


sure, will do.




switch (sdformat->pad) {
case PRP_SINK_PAD:
v4l_bound_align_image(>format.width, MIN_W, MAX_W,
@@ -193,11 +195,12 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
cc = imx_media_find_ipu_format(code, CS_SEL_ANY);
sdformat->format.code = cc->codes[0];
}
+
+   imx_media_fill_empty_mbus_fields(>format, fmt);
break;
case PRP_SRC_PAD_PRPENC:
case PRP_SRC_PAD_PRPVF:
/* Output pads mirror input pad */
-   fmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
sdformat->format = *fmt;
break;
}
diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
b/drivers/staging/media/imx/imx-ic-prpencvf.c
index 860b406..cdfb51a 100644
--- a/drivers/staging/media/imx/imx-ic-prpencvf.c
+++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
@@ -772,6 +772,8 @@ static void prp_try_fmt(struct prp_priv *priv,
struct v4l2_subdev_format *sdformat,
const struct imx_media_pixfmt **cc)
 {
+   struct v4l2_mbus_framefmt *infmt;
+
*cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY);
if (!*cc) {
u32 code;
@@ -781,11 +783,9 @@ static void prp_try_fmt(struct prp_priv *priv,
sdformat->format.code = (*cc)->codes[0];
}

-   if (sdformat->pad == PRPENCVF_SRC_PAD) {
-   struct v4l2_mbus_framefmt *infmt =
-   __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD,
- sdformat->which);
+   infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which);

+   if (sdformat->pad == PRPENCVF_SRC_PAD) {
if (sdformat->format.field != V4L2_FIELD_NONE)
sdformat->format.field = infmt->field;

@@ -804,12 +804,29 @@ static void prp_try_fmt(struct prp_priv *priv,
  >format.height,
  infmt->height / 4, MAX_H_SRC,
  H_ALIGN_SRC, S_ALIGN);
+
+   /*
+* The Image Converter produces fixed quantization
+* (full range for RGB, limited range for YUV), and
+* uses a fixed Y`CbCr encoding (V4L2_YCBCR_ENC_601).
+* For colorspace and transfer func, just propagate
+* from the sink.
+*/
+   sdformat->format.quantization =
+   ((*cc)->cs != IPUV3_COLORSPACE_YUV) ?
+   V4L2_QUANTIZATION_FULL_RANGE :
+   V4L2_QUANTIZATION_LIM_RANGE;
+   sdformat->format.ycbcr_enc = V4L2_YCBCR_ENC_601;


Support for V4L2_YCBCR_ENC_709 and quantization options could be added
to the IPUv3 core code, so this limitation could be relaxed later.


Yes, I was going to mention that too. We can add coefficient tables
to ipu-ic for all the encodings enumerated in enum 

[RFC v3.1 05/14] vb2: Anticipate queue specific DMA attributes for USERPTR buffers

2017-04-13 Thread Sakari Ailus
The DMA attributes were available for the memop implementation for MMAP
buffers but not for USERPTR buffers. Do the same for USERPTR. This patch
makes no functional changes.

Signed-off-by: Sakari Ailus 
---
since RFC v1:

- Add missing q->dma_attrs argument to call_ptr_memop(vb, get_userptr...

 drivers/media/v4l2-core/videobuf2-core.c   | 2 +-
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 ++-
 drivers/media/v4l2-core/videobuf2-dma-sg.c | 3 ++-
 drivers/media/v4l2-core/videobuf2-vmalloc.c| 3 ++-
 include/media/videobuf2-core.h | 3 ++-
 5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index e866115..c659b64 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1025,7 +1025,7 @@ static int __prepare_userptr(struct vb2_buffer *vb, const 
void *pb)
mem_priv = call_ptr_memop(vb, get_userptr,
q->alloc_devs[plane] ? : q->dev,
planes[plane].m.userptr,
-   planes[plane].length, dma_dir);
+   planes[plane].length, dma_dir, q->dma_attrs);
if (IS_ERR(mem_priv)) {
dprintk(1, "failed acquiring userspace memory for plane 
%d\n",
plane);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index d29a07f..30082a4 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -475,7 +475,8 @@ static inline dma_addr_t vb2_dc_pfn_to_dma(struct device 
*dev, unsigned long pfn
 #endif
 
 static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
-   unsigned long size, enum dma_data_direction dma_dir)
+   unsigned long size, enum dma_data_direction dma_dir,
+   unsigned long attrs)
 {
struct vb2_dc_buf *buf;
struct frame_vector *vec;
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 29fde1a..102ddb2 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -220,7 +220,8 @@ static void vb2_dma_sg_finish(void *buf_priv)
 
 static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
unsigned long size,
-   enum dma_data_direction dma_dir)
+   enum dma_data_direction dma_dir,
+   unsigned long dma_attrs)
 {
struct vb2_dma_sg_buf *buf;
struct sg_table *sgt;
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c 
b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index f83253a..a4914fc 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -73,7 +73,8 @@ static void vb2_vmalloc_put(void *buf_priv)
 
 static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr,
 unsigned long size,
-enum dma_data_direction dma_dir)
+enum dma_data_direction dma_dir,
+unsigned long dma_attrs)
 {
struct vb2_vmalloc_buf *buf;
struct frame_vector *vec;
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index cb97c22..4172f6e 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -122,7 +122,8 @@ struct vb2_mem_ops {
 
void*(*get_userptr)(struct device *dev, unsigned long vaddr,
unsigned long size,
-   enum dma_data_direction dma_dir);
+   enum dma_data_direction dma_dir,
+   unsigned long dma_attrs);
void(*put_userptr)(void *buf_priv);
 
void(*prepare)(void *buf_priv);
-- 
2.7.4



Re: [PATCH v6 17/39] platform: add video-multiplexer subdevice driver

2017-04-13 Thread Philipp Zabel
Hi Sakari,

thank you for the review.

On Tue, 2017-04-04 at 15:47 +0300, Sakari Ailus wrote:
> Hi Steve, Philipp and Pavel,
> 
> On Mon, Mar 27, 2017 at 05:40:34PM -0700, Steve Longerbeam wrote:
> > From: Philipp Zabel 
> > 
> > This driver can handle SoC internal and external video bus multiplexers,
> > controlled either by register bit fields or by a GPIO. The subdevice
> > passes through frame interval and mbus configuration of the active input
> > to the output side.
> 
> The MUX framework is already in linux-next. Could you use that instead of
> adding new driver + bindings that are not compliant with the MUX framework?
> I don't think it'd be much of a change in terms of code, using the MUX
> framework appears quite simple.

It is not quite clear to me how to design the DT bindings for this. Just
splitting the video-multiplexer driver from the mux-mmio / mux-gpio
would make it necessary to keep the video-multiplexer node to describe
the of-graph bindings. But then we have two different nodes in the DT
that describe the same hardware:

mux: mux {
compatible = "mux-gpio";
mux-gpios = < 0>, < 1>;
#mux-control-cells = <0>;
}

video-multiplexer {
compatible = "video-multiplexer"
mux-controls = <>;

ports {
/* ... */
}
}

It would feel more natural to have the ports in the mux node, but then
how would the video-multiplexer driver be instanciated, and how would it
get to the of-graph nodes?

> In general the driver looks pretty good, especially regarding the user space
> API implementation which is important for use with other drivers.
> 
> I have some more detailed comments below.
> 
> > 
> > Signed-off-by: Sascha Hauer 
> > Signed-off-by: Philipp Zabel 
> > 
> > - fixed a cut error in vidsw_remove(): v4l2_async_register_subdev()
> >   should be unregister.
> > 
> > - added media_entity_cleanup() to vidsw_remove().
> > 
> > - added missing MODULE_DEVICE_TABLE().
> >   Suggested-by: Javier Martinez Canillas 
> > 
> > - there was a line left over from a previous iteration that negated
> >   the new way of determining the pad count just before it which
> >   has been removed (num_pads = of_get_child_count(np)).
> > 
> > - removed [gs]_frame_interval ops. timeperframe is not used anywhwere
> >   in this subdev, and currently it has no control over frame rate.
> > 
> > - add link_validate to media_entity_operations.
> > 
> > - moved devicetree binding doc to a separate commit.
> > 
> > - Philipp Zabel has developed a set of patches that allow adding
> >   to the subdev async notifier waiting list using a chaining method
> >   from the async registered callbacks (v4l2_of_subdev_registered()
> >   and the prep patches for that). For now, I've removed the use of
> >   v4l2_of_subdev_registered() for the vidmux driver's registered
> >   callback. This doesn't affect the functionality of this driver,
> >   but allows for it to be merged now, before adding the chaining
> >   support.
> > 
> > Signed-off-by: Steve Longerbeam 
> > ---
> >  drivers/media/platform/Kconfig |   8 +
> >  drivers/media/platform/Makefile|   2 +
> >  drivers/media/platform/video-multiplexer.c | 451 
> > +
> >  3 files changed, 461 insertions(+)
> >  create mode 100644 drivers/media/platform/video-multiplexer.c
> > 
> > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> > index ab0bb48..c9b8d9c 100644
> > --- a/drivers/media/platform/Kconfig
> > +++ b/drivers/media/platform/Kconfig
> > @@ -74,6 +74,14 @@ config VIDEO_M32R_AR_M64278
> >   To compile this driver as a module, choose M here: the
> >   module will be called arv.
> >  
> > +config VIDEO_MULTIPLEXER
> > +   tristate "Video Multiplexer"
> > +   depends on VIDEO_V4L2_SUBDEV_API && MEDIA_CONTROLLER
> > +   help
> > + This driver provides support for SoC internal N:1 video bus
> > + multiplexers controlled by register bitfields as well as external
> > + 2:1 video multiplexers controlled by a single GPIO.
> > +
> >  config VIDEO_OMAP3
> > tristate "OMAP 3 Camera support"
> > depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3
> > diff --git a/drivers/media/platform/Makefile 
> > b/drivers/media/platform/Makefile
> > index 8959f6e..d418add 100644
> > --- a/drivers/media/platform/Makefile
> > +++ b/drivers/media/platform/Makefile
> > @@ -27,6 +27,8 @@ obj-$(CONFIG_VIDEO_SH_VEU)+= sh_veu.o
> >  
> >  obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE)+= m2m-deinterlace.o
> >  
> > +obj-$(CONFIG_VIDEO_MULTIPLEXER)+= video-multiplexer.o
> > +
> >  obj-$(CONFIG_VIDEO_S3C_CAMIF)  += s3c-camif/
> >  obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/
> 

[GIT PULL FOR v4.12] Voice coil lens controls, use them for ad5820

2017-04-13 Thread Sakari Ailus
Hi Mauro,

This pull request adds a control class for voice coil lens controls and
makes use of the new control for ad5820.

Please pull.


The following changes since commit 0538bee6fdec9b79910c1c9835e79be75d0e1bdf:

  [media] MAINTAINERS: update atmel-isi.c path (2017-04-10 08:13:08 -0300)

are available in the git repository at:

  https://linuxtv.org/git/sailus/media_tree.git lens

for you to fetch changes up to 117e4713db7b4ac1211a21e9964926966d0867eb:

  ad5820: Use VOICE_COIL_CURRENT control (2017-04-13 14:14:37 +0300)


Sakari Ailus (2):
  v4l: Add camera voice coil lens control class, current control
  ad5820: Use VOICE_COIL_CURRENT control

 Documentation/media/uapi/v4l/extended-controls.rst | 28 ++
 drivers/media/i2c/ad5820.c | 27 -
 include/uapi/linux/v4l2-controls.h |  8 +++
 3 files changed, 57 insertions(+), 6 deletions(-)

-- 
Kind regards,

Sakari Ailus
e-mail: sakari.ai...@iki.fi XMPP: sai...@retiisi.org.uk


Re: [PATCH 12/14] atomisp: remove fixedbds kernel code

2017-04-13 Thread kbuild test robot
Hi Alan,

[auto build test ERROR on next-20170412]
[cannot apply to linuxtv-media/master v4.9-rc8 v4.9-rc7 v4.9-rc6 v4.11-rc6]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Alan-Cox/staging-atomisp-use-local-variable-to-reduce-number-of-references/20170413-112312
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=i386 

All errors (new ones prefixed by >>):

>> make[7]: *** No rule to make target 
>> 'drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/fixedbds/fixedbds_1.0/ia_css_fixedbds.host.o',
>>  needed by 'drivers/staging/media/atomisp/pci/atomisp2/atomisp.o'.
   make[7]: Target '__build' not remade because of errors.

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


Re: [PATCH 40/40] media: imx: set and propagate empty field, colorimetry params

2017-04-13 Thread Philipp Zabel
Hi Steve,

thanks for cleaning this up. Apart from the comments below, this looks
good to me.

On Wed, 2017-04-12 at 17:45 -0700, Steve Longerbeam wrote:
> This patch adds a call to imx_media_fill_empty_mbus_fields() in the
> *_try_fmt() functions at the sink pads, to set empty field order and
> colorimetry parameters.
> 
> If the field order is set to ANY, choose the currently set field order
> at the sink pad. If the colorspace is set to DEFAULT, choose the
> current colorspace at the sink pad.  If any of xfer_func, ycbcr_enc
> or quantization are set to DEFAULT, either choose the current sink pad
> setting, or the default setting for the new colorspace, if non-DEFAULT
> colorspace was given.
> 
> Colorimetry is also propagated from sink to source pads anywhere
> this has not already been done. The exception is ic-prpencvf at the
> source pad, since the Image Converter outputs fixed quantization and
> Y`CbCr encoding.
> 
> Signed-off-by: Steve Longerbeam 
> ---
>  drivers/staging/media/imx/imx-ic-prp.c  |  5 ++-
>  drivers/staging/media/imx/imx-ic-prpencvf.c | 25 +++---
>  drivers/staging/media/imx/imx-media-csi.c   | 12 +--
>  drivers/staging/media/imx/imx-media-utils.c | 53 
> +
>  drivers/staging/media/imx/imx-media-vdic.c  |  7 ++--
>  drivers/staging/media/imx/imx-media.h   |  3 +-
>  6 files changed, 95 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/staging/media/imx/imx-ic-prp.c 
> b/drivers/staging/media/imx/imx-ic-prp.c
> index b4d4e48..8baa0d5 100644
> --- a/drivers/staging/media/imx/imx-ic-prp.c
> +++ b/drivers/staging/media/imx/imx-ic-prp.c
> @@ -180,6 +180,8 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
>   goto out;
>   }
>  
> + fmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
> +

Should this be changed to infmt for consistency?

>   switch (sdformat->pad) {
>   case PRP_SINK_PAD:
>   v4l_bound_align_image(>format.width, MIN_W, MAX_W,
> @@ -193,11 +195,12 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
>   cc = imx_media_find_ipu_format(code, CS_SEL_ANY);
>   sdformat->format.code = cc->codes[0];
>   }
> +
> + imx_media_fill_empty_mbus_fields(>format, fmt);
>   break;
>   case PRP_SRC_PAD_PRPENC:
>   case PRP_SRC_PAD_PRPVF:
>   /* Output pads mirror input pad */
> - fmt = __prp_get_fmt(priv, cfg, PRP_SINK_PAD, sdformat->which);
>   sdformat->format = *fmt;
>   break;
>   }
> diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c 
> b/drivers/staging/media/imx/imx-ic-prpencvf.c
> index 860b406..cdfb51a 100644
> --- a/drivers/staging/media/imx/imx-ic-prpencvf.c
> +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c
> @@ -772,6 +772,8 @@ static void prp_try_fmt(struct prp_priv *priv,
>   struct v4l2_subdev_format *sdformat,
>   const struct imx_media_pixfmt **cc)
>  {
> + struct v4l2_mbus_framefmt *infmt;
> +
>   *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_ANY);
>   if (!*cc) {
>   u32 code;
> @@ -781,11 +783,9 @@ static void prp_try_fmt(struct prp_priv *priv,
>   sdformat->format.code = (*cc)->codes[0];
>   }
>  
> - if (sdformat->pad == PRPENCVF_SRC_PAD) {
> - struct v4l2_mbus_framefmt *infmt =
> - __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD,
> -   sdformat->which);
> + infmt = __prp_get_fmt(priv, cfg, PRPENCVF_SINK_PAD, sdformat->which);
>  
> + if (sdformat->pad == PRPENCVF_SRC_PAD) {
>   if (sdformat->format.field != V4L2_FIELD_NONE)
>   sdformat->format.field = infmt->field;
>  
> @@ -804,12 +804,29 @@ static void prp_try_fmt(struct prp_priv *priv,
> >format.height,
> infmt->height / 4, MAX_H_SRC,
> H_ALIGN_SRC, S_ALIGN);
> +
> + /*
> +  * The Image Converter produces fixed quantization
> +  * (full range for RGB, limited range for YUV), and
> +  * uses a fixed Y`CbCr encoding (V4L2_YCBCR_ENC_601).
> +  * For colorspace and transfer func, just propagate
> +  * from the sink.
> +  */
> + sdformat->format.quantization =
> + ((*cc)->cs != IPUV3_COLORSPACE_YUV) ?
> + V4L2_QUANTIZATION_FULL_RANGE :
> + V4L2_QUANTIZATION_LIM_RANGE;
> + sdformat->format.ycbcr_enc = V4L2_YCBCR_ENC_601;

Support for V4L2_YCBCR_ENC_709 and quantization options could be added
to the IPUv3 core code, so this limitation could be relaxed later.

> + sdformat->format.colorspace = infmt->colorspace;
> + 

Re: [PATCH] [media] imx: csi: retain current field order and colorimetry setting as default

2017-04-13 Thread Philipp Zabel
On Wed, 2017-04-12 at 09:03 +0200, Hans Verkuil wrote:
[...]
> >> Do you have a git tree with this patch? It is really hard to review without
> >> having the full imx-media-csi.c source.
> > 
> > The patch applies on top of
> > 
> >   https://github.com/slongerbeam/mediatree.git imx-media-staging-md-v14
> > 
> > I have uploaded a branch
> > 
> >   git://git.pengutronix.de/git/pza/linux imx-media-staging-md-v14+color
> > 
> > with the patch applied on top.
> > 
> >> I think one problem is that it is not clearly defined how subdevs and 
> >> colorspace
> >> information should work.
> 
> Ah, having the full source helped.
> 
> Ignore my previous review, it was incorrect.

Ok.

> I'll have to think about this some more. I'll get back to this, but it may 
> take some
> time since my vacation starts tomorrow. The spec is simply unclear about how 
> to handle
> this so we have to come up with some guidelines.

Yes, please. Until then, have a nice vacation.

regards
Philipp



[bug report] [media] vp702x: comment dead code

2017-04-13 Thread Dan Carpenter
Hello Mauro Carvalho Chehab,

The patch 269d91f53fe3: "[media] vp702x: comment dead code" from Apr
29, 2015, leads to the following static checker warning:

drivers/media/usb/dvb-usb/dvb-usb-remote.c:128 
legacy_dvb_usb_read_remote_control()
error: uninitialized symbol 'state'.

drivers/media/usb/dvb-usb/dvb-usb-remote.c
   108  static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
   109  {
   110  struct dvb_usb_device *d =
   111  container_of(work, struct dvb_usb_device, 
rc_query_work.work);
   112  u32 event;
   113  int state;
   114  
   115  /* TODO: need a lock here.  We can simply skip checking for the 
remote control
   116 if we're busy. */
   117  
   118  /* when the parameter has been set to 1 via sysfs while the 
driver was running */
   119  if (dvb_usb_disable_rc_polling)
   120  return;
   121  
   122  if (d->props.rc.legacy.rc_query(d,,)) {
   ^
This sometimes returns zero without doing anything like in
vp702x_rc_query().

   123  err("error while querying for an remote control 
event.");
   124  goto schedule;
   125  }
   126  
   127  
   128  switch (state) {
   129  case REMOTE_NO_KEY_PRESSED:
   130  break;
   131  case REMOTE_KEY_PRESSED:
   132  deb_rc("key pressed\n");
   133  d->last_event = event;
   134  case REMOTE_KEY_REPEAT:
   135  deb_rc("key repeated\n");
   136  input_event(d->input_dev, EV_KEY, event, 1);
   137  input_sync(d->input_dev);
   138  input_event(d->input_dev, EV_KEY, 
d->last_event, 0);
   139  input_sync(d->input_dev);
   140  break;
   141  default:
   142  break;
   143  }

regards,
dan carpenter


Re: [RFC PATCH 3/3] encoder-tpd12s015: keep the ls_oe_gpio on while the phys_addr is valid

2017-04-13 Thread Tomi Valkeinen
On 13/04/17 12:12, Hans Verkuil wrote:

>> Is there anything else CEC needs to access or control (besides the CEC
>> IP itself)?
> 
> The CEC framework needs to be informed about the physical address contained
> in the EDID (part of the CEA-861 block). And when the HPD goes down it needs
> to be informed as well (same call, but with CEC_PHYS_ADDR_INVALID as 
> argument).

Ah, hmm... And currently that's (kind of) handled in
hdmi_power_off_full() by setting CEC_PHYS_ADDR_INVALID? That's not the
same thing as HPD off, though, but maybe it's enough (for now).

 Tomi



signature.asc
Description: OpenPGP digital signature


Re: [RFC PATCH 3/3] encoder-tpd12s015: keep the ls_oe_gpio on while the phys_addr is valid

2017-04-13 Thread Hans Verkuil
On 04/13/2017 10:43 AM, Tomi Valkeinen wrote:
> On 12/04/17 17:04, Hans Verkuil wrote:
> 
>>> So is some other driver supporting this already? Or is the omap4 the
>>> first platform you're trying this on?
>>
>> No, there are quite a few CEC drivers by now, but typically the CEC block is
>> a totally independent IP block with its own power, irq, etc. The omap4 is by 
>> far
>> the most complex one to set up with various GPIO pins, interrupts, 
>> regulators,
>> etc. to deal with.
>>
>> Normally it takes about 2 days to make a new CEC driver, but the omap4 is 
>> much
>> more work :-(
> 
> Ok.
> 
> I mentioned the omapdrm restructuring that we've planned to do, I think
> after that this will be easier to implement in a nice way.
> 
> For now, I think more or less what you have now is an acceptable
> solution. We can hack the tpd12s015 to keep the level shifter always
> enabled, and, afaics, everything else can be handled inside the hdmi4
> driver, right?

Right.

> Generally speaking, what are the "dependencies" for CEC? It needs to
> access EDID? Does CEC care about HPD? Does it care if the cable is
> connected or not? For Panda, the level shifter of tpd12s015 is obviously
> one hard dendency.
> 
> Is there anything else CEC needs to access or control (besides the CEC
> IP itself)?

The CEC framework needs to be informed about the physical address contained
in the EDID (part of the CEA-861 block). And when the HPD goes down it needs
to be informed as well (same call, but with CEC_PHYS_ADDR_INVALID as argument).

And it needs to stay powered up even if the HPD is down.

That's all.

Regards,

Hans


Re: [RFC PATCH 3/3] encoder-tpd12s015: keep the ls_oe_gpio on while the phys_addr is valid

2017-04-13 Thread Tomi Valkeinen
On 12/04/17 17:04, Hans Verkuil wrote:

>> So is some other driver supporting this already? Or is the omap4 the
>> first platform you're trying this on?
> 
> No, there are quite a few CEC drivers by now, but typically the CEC block is
> a totally independent IP block with its own power, irq, etc. The omap4 is by 
> far
> the most complex one to set up with various GPIO pins, interrupts, regulators,
> etc. to deal with.
> 
> Normally it takes about 2 days to make a new CEC driver, but the omap4 is much
> more work :-(

Ok.

I mentioned the omapdrm restructuring that we've planned to do, I think
after that this will be easier to implement in a nice way.

For now, I think more or less what you have now is an acceptable
solution. We can hack the tpd12s015 to keep the level shifter always
enabled, and, afaics, everything else can be handled inside the hdmi4
driver, right?

Generally speaking, what are the "dependencies" for CEC? It needs to
access EDID? Does CEC care about HPD? Does it care if the cable is
connected or not? For Panda, the level shifter of tpd12s015 is obviously
one hard dendency.

Is there anything else CEC needs to access or control (besides the CEC
IP itself)?

 Tomi



signature.asc
Description: OpenPGP digital signature


[PATCH v2] [media] mceusb: TX -EPIPE (urb status = -32) lockup fix

2017-04-13 Thread A Sun

fix previous v1 patch error; incorrect location of "ir->pipe_in = pipe;"
caused null pointer dereference

Bug:

Once IR blasting or mceusb device commands fail with mce_async_callback() TX 
-EPIPE error, all subsequent TX to device then fail with the same error.
...
[  249.986174] mceusb 1-1.2:1.0: requesting 38000 HZ carrier
[  249.986210] mceusb 1-1.2:1.0: send request called (size=0x4)
[  249.986256] mceusb 1-1.2:1.0: send request complete (res=0)
[  249.986403] mceusb 1-1.2:1.0: Error: request urb status = -32 (TX HALT)
[  249.999885] mceusb 1-1.2:1.0: send request called (size=0x3)
[  249.29] mceusb 1-1.2:1.0: send request complete (res=0)
[  250.13] mceusb 1-1.2:1.0: Error: request urb status = -32 (TX HALT)
[  250.019830] mceusb 1-1.2:1.0: send request called (size=0x21)
[  250.019868] mceusb 1-1.2:1.0: send request complete (res=0)
[  250.020007] mceusb 1-1.2:1.0: Error: request urb status = -32 (TX HALT)
...

Fix:

Message pertains to TX usb halt (stall) condition requiring usb_clear_halt() 
call in non-interrupt context to recover.
Add USB TX halt error handling similar to the RX halt handling case from an 
earlier patch proposal.
Reorder some mceusb code to accommodate TX halt error handling.

This patch depends on the earlier proposed patch set:
  [PATCH 1/3] [media] mceusb: RX -EPIPE (urb status = -32) lockup failure fix
  [PATCH 2/3] [media] mceusb: sporadic RX truncation corruption fix
  [PATCH 3/3] [media] mceusb: fix inaccurate debug buffer dumps and misleading

Tested with:

Linux raspberrypi 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l 
GNU/Linux
mceusb 1-1.2:1.0: Registered SMK eHome Infrared Transceiver with mce emulator 
interface version 1
mceusb 1-1.2:1.0: 2 tx ports (0x1 cabled) and 2 rx sensors (0x1 active)

Fault simulation/injection is by executing the following USB operation in a 
mceusb instrumented driver, prior to TX I/O.
retval = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
USB_REQ_SET_FEATURE, USB_RECIP_ENDPOINT,
USB_ENDPOINT_HALT, usb_pipeendpoint(ir->pipe_out),
NULL, 0, USB_CTRL_SET_TIMEOUT);
dev_dbg(ir->dev, "set halt retval, %d", retval);

After setting halt state for the TX endpoint, perform an lirc "irsend" to 
generate TX traffic to device.
After the TX HALT, the patch restores subsequent TX to working state.
...
[  508.009638] mceusb 1-1.2:1.0: send request called (size=0x3)
[  508.009697] mceusb 1-1.2:1.0: send request complete (res=0)
[  508.009847] mce_async_callback()
[  508.009864] mceusb 1-1.2:1.0: Error: request urb status = -32 (TX HALT)
[  508.009890] mceusb 1-1.2:1.0: kevent 0 scheduled
[  508.021552] mceusb 1-1.2:1.0: send request called (size=0x21)
[  508.021598] mceusb 1-1.2:1.0: send request complete (res=0)
[  508.021963] mce_async_callback()
[  508.021981] mceusb 1-1.2:1.0: tx data: 84 b0 0c 8c 0c 84 8c 0c 8c 0c 84 8c 
0c 8c 0c 84 98 0c 98 0c 84 98 0c 8c 0c 84 8c 0c 8c 0c 81 8c 80 (length=33)
[  508.021997] mceusb 1-1.2:1.0: Raw IR data, 0 pulse/space samples
[  508.066627] mceusb 1-1.2:1.0: send request called (size=0x3)
[  508.09] mceusb 1-1.2:1.0: send request complete (res=0)
[  508.066841] mce_async_callback()
[  508.066858] mceusb 1-1.2:1.0: tx data: 9f 08 03 (length=3)
...

Open issue(s):

Testing with Pinnacle mceusb device reveals device specific (non USB 2.0 
standard) misbehavior with respect to USB TX halt.

Linux raspberrypi 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l 
GNU/Linux
mceusb 1-1.2:1.0: Registered Pinnacle Systems PCTV Remote USB with mce emulator 
interface version 1
mceusb 1-1.2:1.0: 2 tx ports (0x1 cabled) and 2 rx sensors (0x1 active)

The Pinnacle device failed Linux usbtest module (modded to bind to the 
Pinnacle) test 13 with bogus halt status and -110 (-ETIMEDOUT) errors.

[ 4558.114664] usbcore: deregistering interface driver mceusb
[14956.572207] usbtest 1-1.2:1.0: mce ir device
[14956.572234] usbtest 1-1.2:1.0: full-speed {control bulk-out} tests
[14956.572363] usbcore: registered new interface driver usbtest
[15241.341143] usbtest 1-1.2:1.0: TEST 1:  write 512 bytes 1000 times
[15456.690845] usbtest 1-1.2:1.0: TEST 13:  set/clear 1000 halts
[15456.691362] usbtest 1-1.2:1.0: ep 02 bogus status: 0001 != 0
[15456.691381] usbtest 1-1.2:1.0: halts failed, iterations left 999

[37432.646344] usbcore: deregistering interface driver mceusb
[37468.447929] usbtest 1-1.2:1.0: mce ir device
[37468.447956] usbtest 1-1.2:1.0: full-speed {control bulk-out} tests
[37468.448079] usbcore: registered new interface driver usbtest
[37519.150810] usbtest 1-1.2:1.0: TEST 1:  write 512 bytes 1000 times
[37537.853493] usbtest 1-1.2:1.0: TEST 13:  set/clear 1000 halts
[37547.866871] usb 1-1.2: verify_not_halted failed, iterations left 0, status 
-110 (not 0)
[37547.866901] usbtest 1-1.2:1.0: halts failed, iterations left 999

With mceusb, upon executing usb_clear_halt() on this Pinnacle mceusb USB TX 
end-point, regardless of its halt/stall state, TX 

[RFC v3 08/14] vb2: dma-contig: Don't warn on failure in obtaining scatterlist

2017-04-13 Thread Sakari Ailus
vb2_dc_get_base_sgt() which obtains the scatterlist already prints
information on why the scatterlist could not be obtained.

Also, remove the useless warning of a failed kmalloc().

Signed-off-by: Sakari Ailus 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index ddbbcf0..22636cd 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -370,10 +370,8 @@ static struct sg_table *vb2_dc_get_base_sgt(struct 
vb2_dc_buf *buf)
struct sg_table *sgt;
 
sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
-   if (!sgt) {
-   dev_err(buf->dev, "failed to alloc sg table\n");
+   if (!sgt)
return NULL;
-   }
 
ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
buf->size, buf->attrs);
@@ -400,7 +398,7 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, 
unsigned long flags)
if (!buf->dma_sgt)
buf->dma_sgt = vb2_dc_get_base_sgt(buf);
 
-   if (WARN_ON(!buf->dma_sgt))
+   if (!buf->dma_sgt)
return NULL;
 
dbuf = dma_buf_export(_info);
-- 
2.7.4



[RFC v3 02/14] vb2: Move buffer cache synchronisation to prepare from queue

2017-04-13 Thread Sakari Ailus
The buffer cache should be synchronised in buffer preparation, not when
the buffer is queued to the device. Fix this.

Mmap buffers do not need cache synchronisation since they are always
coherent.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 8df680d..8bf3369 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1227,23 +1227,19 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, 
const void *pb)
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
-   unsigned int plane;
 
vb->state = VB2_BUF_STATE_ACTIVE;
atomic_inc(>owned_by_drv_count);
 
trace_vb2_buf_queue(q, vb);
 
-   /* sync buffers */
-   for (plane = 0; plane < vb->num_planes; ++plane)
-   call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
-
call_void_vb_qop(vb, buf_queue, vb);
 }
 
 static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
 {
struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
int ret;
 
if (q->error) {
@@ -1268,11 +1264,19 @@ static int __buf_prepare(struct vb2_buffer *vb, const 
void *pb)
ret = -EINVAL;
}
 
-   if (ret)
+   if (ret) {
dprintk(1, "buffer preparation failed: %d\n", ret);
-   vb->state = ret ? VB2_BUF_STATE_DEQUEUED : VB2_BUF_STATE_PREPARED;
+   vb->state = VB2_BUF_STATE_DEQUEUED;
+   return ret;
+   }
 
-   return ret;
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
+
+   vb->state = VB2_BUF_STATE_PREPARED;
+
+   return 0;
 }
 
 int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb)
-- 
2.7.4



[RFC v3 00/14] vb2: Handle user cache hints, allow drivers to choose cache coherency

2017-04-13 Thread Sakari Ailus
Hello,

This is a rebased and partially reworked version of the vb2 cache hints
support patch series posted by Laurent more three months ago. The patches
have been modified as needed by the upstream changes. There are a number
of other changes as well. Since then, patch ccc66e73 ("ARM: 8508/2:
videobuf2-dc: Let drivers specify DMA attrs") that supposedly added DMA
attribute support for videobuf2-dma-contig has been merged. For dma-contig
memory type, this patchset addresses issues in that patch instead of
providing support for the feature from scratch. It also adds support for
USERPTR buffer type and makes necessary changes to dma-sg memory type as
well. Details below.

I'm still posting this patchset as RFC as the dma-sg patch hasn't been
tested apart from compiling it. Otherwise the subject line would have
PATCH instead of RFC. Testing especially on a device using dma-sg would be
beneficial.


The videobuf2 memory managers use the DMA mapping API to handle cache
synchronization on systems that require them transparently for drivers. As
cache operations are expensive, system performances can be impacted. Cache
synchronization can't be skipped altogether if we want to retain correct
behaviour, but optimizations are possible in cases related to buffer sharing
between multiple devices without CPU access to the memory.

The first optimization covers cases where the memory never needs to be
accessed by the CPU (neither in kernelspace nor in userspace). In those cases,
as no CPU memory mappings exist, cache synchronization can be skipped. The
situation could be detected in the kernel as we have enough information to
determine whether CPU mappings for kernelspace or userspace exist (in the
first case because drivers should request them explicitly, in the second case
because the mmap() handler hasn't been invoked). This optimization is not
implemented currently but should at least be prototyped as it could improve
performances automatically in a large number of cases.

The second class of optimizations cover cases where the memory sometimes needs
to be accessed by the CPU. In those cases memory mapping must be created and
cache handled, but cache synchronization could be skipped for buffer that are
not touched by the CPU.

By default the following cache synchronization operations need to be performed
related to the buffer management ioctls. For simplicity means of QBUF below
apply to buf VIDIOC_QBUF and VIDIOC_PREPARE_BUF.

| QBUF  | DQBUF

CAPTURE | Invalidate| Invalidate (*)
OUTPUT  | Clean | -

(*) for systems using speculative pre-fetching only

The following cases can be optimized.

1. CAPTURE, the CPU has not written to the buffer before QBUF

   Cache invalidation can be skipped at QBUF time, but becomes required at
   DQBUF time on all systems, regardless of whether they use speculative
   prefetching.

2. CAPTURE, the CPU will not read from the buffer after DQBUF

   Cache invalidation can be skipped at DQBUF time.

3. CAPTURE, combination of (1) and (2)

   Cache invalidation can be skipped at both QBUF and DQBUF time.

4. OUTPUT, the CPU has not written to the buffer before QBUF

   Cache clean can be skipped at QBUF time.


The kernel can't detect thoses situations automatically and thus requires
hints from userspace to decide whether cache synchronization can be skipped.
It should be noted that those hints might not be honoured. In particular, if
userspace hints that it hasn't touched the buffer with the CPU, drivers might
need to perform memory accesses themselves (adding JPEG or MPEG headers to
buffers is a common case where CPU access could be needed in the kernel), in
which case the userspace hints will be ignored.

Getting the hints wrong will result in data corruption. Userspace applications
are allowed to shoot themselves in the foot, but driver are responsible for
deciding whether data corruption can pose a risk to the system in general. For
instance if the device could be made to crash, or behave in a way that would
jeopardize system security, reliability or performances, when fed with invalid
data, cache synchronization shall not be skipped solely due to possibly
incorrect userspace hints.

The V4L2 API defines two flags, V4L2_BUF_FLAG_NO_CACHE_INVALIDATE and
V4L2_BUF_FLAG_NO_CACHE_SYNC, that can be used to provide cache-related hints
to the kernel. However, no kernel has ever implemented support for those flags
that are thus most likely unused.

A single flag is enough to cover all the optimization cases described above,
provided we keep track of the flag being set at QBUF time to force cache
invalidation at DQBUF time for case (1) if the  flag isn't set at DQBUF time.
This patch series thus cleans up the userspace API and merges both flags into
a single one.

One potential issue with case (1) is that cache invalidation at DQBUF time for
CAPTURE buffers isn't fully under the control of 

[RFC v3 14/14] vb2: Improve struct vb2_mem_ops documentation; alloc and put are for MMAP

2017-04-13 Thread Sakari Ailus
The alloc() and put() ops are for MMAP buffers only. Document it.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 include/media/videobuf2-core.h | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 08f1d0e..dd67ae6 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -46,16 +46,16 @@ struct vb2_threadio_data;
 
 /**
  * struct vb2_mem_ops - memory handling/memory allocator operations
- * @alloc: allocate video memory and, optionally, allocator private data,
- * return ERR_PTR() on failure or a pointer to allocator private,
- * per-buffer data on success; the returned private structure
- * will then be passed as @buf_priv argument to other ops in this
- * structure. Additional gfp_flags to use when allocating the
- * are also passed to this operation. These flags are from the
- * gfp_flags field of vb2_queue.
- * @put:   inform the allocator that the buffer will no longer be used;
- * usually will result in the allocator freeing the buffer (if
- * no other users of this buffer are present); the @buf_priv
+ * @alloc: allocate video memory for an MMAP buffer and, optionally,
+ * allocator private data, return ERR_PTR() on failure or a pointer
+ * to allocator private, per-buffer data on success; the returned
+ * private structure will then be passed as @buf_priv argument to
+ * other ops in this structure. Additional gfp_flags to use when
+ * allocating the memory are also passed to this operation. These
+ * flags are from the gfp_flags field of vb2_queue.
+ * @put:   inform the allocator that the MMAP buffer will no longer be
+ * used; usually will result in the allocator freeing the buffer
+ * (if no other users of this buffer are present); the @buf_priv
  * argument is the allocator private per-buffer structure
  * previously returned from the alloc callback.
  * @get_dmabuf: acquire userspace memory for a hardware operation; used for
-- 
2.7.4



[RFC v3 10/14] vb2: dma-contig: Fix DMA attribute and cache management

2017-04-13 Thread Sakari Ailus
Patch ccc66e73 ("ARM: 8508/2: videobuf2-dc: Let drivers specify DMA
attrs") added support for driver specific DMA attributes to
videobuf2-dma-contig but it had several issues in it.

In particular,

- cache operations were only performed on USERPTR buffers,

- DMA attributes were set only for MMAP buffers and

- it did not provide begin_cpu_access() and end_cpu_access() dma_buf_ops
  callbacks for cache syncronisation on exported MMAP buffers.

This patch corrects these issues.

Also arrange the header files alphabetically.

Fixes: ccc66e73 ("ARM: 8508/2: videobuf2-dc: Let drivers specify DMA attrs")
Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 90 --
 1 file changed, 69 insertions(+), 21 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 8ea9ab9..6a707d3 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -11,12 +11,12 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -116,12 +116,13 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   /* DMABUF exporter will flush the cache for us */
-   if (!buf->vec)
-   return;
-
-   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
-  buf->dma_dir);
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
+  buf->dma_dir);
 }
 
 static void vb2_dc_finish(void *buf_priv)
@@ -129,11 +130,13 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   /* DMABUF exporter will flush the cache for us */
-   if (!buf->vec)
-   return;
-
-   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents,
+   buf->dma_dir);
 }
 
 /*/
@@ -172,9 +175,9 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long 
attrs,
 
buf->attrs = attrs;
buf->cookie = dma_alloc_attrs(dev, size, >dma_addr,
-   GFP_KERNEL | gfp_flags, buf->attrs);
+ GFP_KERNEL | gfp_flags, buf->attrs);
if (!buf->cookie) {
-   dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
+   dev_err(dev, "dma_alloc_attrs of size %ld failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
@@ -187,6 +190,14 @@ static void *vb2_dc_alloc(struct device *dev, unsigned 
long attrs,
buf->size = size;
buf->dma_dir = dma_dir;
 
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
+   if (!buf->dma_sgt) {
+   dma_free_attrs(dev, size, buf->cookie, buf->dma_addr,
+  buf->attrs);
+   put_device(dev);
+   return ERR_PTR(-ENOMEM);
+   }
+
buf->handler.refcount = >refcount;
buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
@@ -359,6 +370,40 @@ static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, 
unsigned long pgnum)
return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL;
 }
 
+static int vb2_dc_dmabuf_ops_begin_cpu_access(struct dma_buf *dbuf,
+ enum dma_data_direction direction)
+{
+   struct vb2_dc_buf *buf = dbuf->priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents,
+   buf->dma_dir);
+
+   return 0;
+}
+
+static int vb2_dc_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf,
+   enum dma_data_direction direction)
+{
+   struct vb2_dc_buf *buf = dbuf->priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   

[RFC v3 12/14] vb2: dma-sg: Let drivers decide DMA attrs of MMAP and USERPTR bufs

2017-04-13 Thread Sakari Ailus
The desirable DMA attributes are not generic for all devices using
Videobuf2 scatter-gather DMA ops. Let the drivers decide.

As a result, also the DMA-BUF exporter must provide ops for synchronising
the cache. This adds begin_cpu_access and end_cpu_access ops to
vb2_dc_dmabuf_ops.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/videobuf2-dma-sg.c | 81 +++---
 1 file changed, 62 insertions(+), 19 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 102ddb2..5662f00 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -38,6 +38,7 @@ struct vb2_dma_sg_buf {
struct frame_vector *vec;
int offset;
enum dma_data_direction dma_dir;
+   unsigned long   dma_attrs;
struct sg_table sg_table;
/*
 * This will point to sg_table when used with the MMAP or USERPTR
@@ -114,6 +115,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned 
long dma_attrs,
 
buf->vaddr = NULL;
buf->dma_dir = dma_dir;
+   buf->dma_attrs = dma_attrs;
buf->offset = 0;
buf->size = size;
/* size is already page aligned */
@@ -143,7 +145,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned 
long dma_attrs,
 * prepare() memop is called.
 */
sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
- buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
+ buf->dma_dir, dma_attrs);
if (!sgt->nents)
goto fail_map;
 
@@ -181,7 +183,7 @@ static void vb2_dma_sg_put(void *buf_priv)
dprintk(1, "%s: Freeing buffer of %d pages\n", __func__,
buf->num_pages);
dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
-  buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
+  buf->dma_dir, buf->dma_attrs);
if (buf->vaddr)
vm_unmap_ram(buf->vaddr, buf->num_pages);
sg_free_table(buf->dma_sgt);
@@ -198,12 +200,13 @@ static void vb2_dma_sg_prepare(void *buf_priv)
struct vb2_dma_sg_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   /* DMABUF exporter will flush the cache for us */
-   if (buf->db_attach)
-   return;
-
-   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
-  buf->dma_dir);
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   if (buf->dma_attrs & DMA_ATTR_NON_CONSISTENT)
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
+  buf->dma_dir);
 }
 
 static void vb2_dma_sg_finish(void *buf_priv)
@@ -211,11 +214,13 @@ static void vb2_dma_sg_finish(void *buf_priv)
struct vb2_dma_sg_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   /* DMABUF exporter will flush the cache for us */
-   if (buf->db_attach)
-   return;
-
-   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   /*
+* DMABUF exporter will flush the cache for us; only USERPTR
+* and MMAP buffers with non-coherent memory will be flushed.
+*/
+   if (buf->dma_attrs & DMA_ATTR_NON_CONSISTENT)
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents,
+   buf->dma_dir);
 }
 
 static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
@@ -237,6 +242,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, 
unsigned long vaddr,
buf->vaddr = NULL;
buf->dev = dev;
buf->dma_dir = dma_dir;
+   buf->dma_attrs = dma_attrs;
buf->offset = vaddr & ~PAGE_MASK;
buf->size = size;
buf->dma_sgt = >sg_table;
@@ -260,7 +266,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, 
unsigned long vaddr,
 * prepare() memop is called.
 */
sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
- buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC);
+ buf->dma_dir, dma_attrs);
if (!sgt->nents)
goto userptr_fail_map;
 
@@ -288,7 +294,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
dprintk(1, "%s: Releasing userspace buffer of %d pages\n",
   __func__, buf->num_pages);
dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir,
-  DMA_ATTR_SKIP_CPU_SYNC);
+  buf->dma_attrs);
if 

[RFC v3 11/14] vb2: dma-contig: Add WARN_ON_ONCE() to check for potential bugs

2017-04-13 Thread Sakari Ailus
The scatterlist should always be present when the cache would need to be
flushed. Each buffer type has its own means to provide that. Add
WARN_ON_ONCE() to check the scatterist exists.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 6a707d3..2847fbf 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -120,7 +120,7 @@ static void vb2_dc_prepare(void *buf_priv)
 * DMABUF exporter will flush the cache for us; only USERPTR
 * and MMAP buffers with non-coherent memory will be flushed.
 */
-   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT && !WARN_ON_ONCE(!sgt))
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
   buf->dma_dir);
 }
@@ -134,7 +134,7 @@ static void vb2_dc_finish(void *buf_priv)
 * DMABUF exporter will flush the cache for us; only USERPTR
 * and MMAP buffers with non-coherent memory will be flushed.
 */
-   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT && !WARN_ON_ONCE(!sgt))
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents,
buf->dma_dir);
 }
@@ -380,7 +380,7 @@ static int vb2_dc_dmabuf_ops_begin_cpu_access(struct 
dma_buf *dbuf,
 * DMABUF exporter will flush the cache for us; only USERPTR
 * and MMAP buffers with non-coherent memory will be flushed.
 */
-   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT && !WARN_ON_ONCE(!sgt))
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents,
buf->dma_dir);
 
@@ -397,7 +397,7 @@ static int vb2_dc_dmabuf_ops_end_cpu_access(struct dma_buf 
*dbuf,
 * DMABUF exporter will flush the cache for us; only USERPTR
 * and MMAP buffers with non-coherent memory will be flushed.
 */
-   if (buf->attrs & DMA_ATTR_NON_CONSISTENT)
+   if (buf->attrs & DMA_ATTR_NON_CONSISTENT && !WARN_ON_ONCE(!sgt))
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents,
   buf->dma_dir);
 
-- 
2.7.4



[RFC v3 06/14] vb2: dma-contig: Assign DMA attrs for a buffer unconditionally

2017-04-13 Thread Sakari Ailus
attrs used to be a pointer and the caller of vb2_dc_alloc() could
optionally provide it, or NULL. This was when struct dma_attrs was used
to describe DMA attributes rather than an unsigned long value. There is no
longer a need to maintain the condition, assign the value unconditionally.
There is no functional difference because the memory was initialised to
zero anyway.

Fixes: 00085f1e ("dma-mapping: use unsigned long for dma_attrs")
Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 30082a4..a8a46a8 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -149,8 +149,7 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long 
attrs,
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   if (attrs)
-   buf->attrs = attrs;
+   buf->attrs = attrs;
buf->cookie = dma_alloc_attrs(dev, size, >dma_addr,
GFP_KERNEL | gfp_flags, buf->attrs);
if (!buf->cookie) {
-- 
2.7.4



[RFC v3 05/14] vb2: Anticipate queue specific DMA attributes for USERPTR buffers

2017-04-13 Thread Sakari Ailus
The DMA attributes were available for the memop implementation for MMAP
buffers but not for USERPTR buffers. Do the same for USERPTR. This patch
makes no functional changes.

Signed-off-by: Sakari Ailus 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 ++-
 drivers/media/v4l2-core/videobuf2-dma-sg.c | 3 ++-
 drivers/media/v4l2-core/videobuf2-vmalloc.c| 3 ++-
 include/media/videobuf2-core.h | 3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index d29a07f..30082a4 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -475,7 +475,8 @@ static inline dma_addr_t vb2_dc_pfn_to_dma(struct device 
*dev, unsigned long pfn
 #endif
 
 static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr,
-   unsigned long size, enum dma_data_direction dma_dir)
+   unsigned long size, enum dma_data_direction dma_dir,
+   unsigned long attrs)
 {
struct vb2_dc_buf *buf;
struct frame_vector *vec;
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c 
b/drivers/media/v4l2-core/videobuf2-dma-sg.c
index 29fde1a..102ddb2 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c
@@ -220,7 +220,8 @@ static void vb2_dma_sg_finish(void *buf_priv)
 
 static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr,
unsigned long size,
-   enum dma_data_direction dma_dir)
+   enum dma_data_direction dma_dir,
+   unsigned long dma_attrs)
 {
struct vb2_dma_sg_buf *buf;
struct sg_table *sgt;
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c 
b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index f83253a..a4914fc 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -73,7 +73,8 @@ static void vb2_vmalloc_put(void *buf_priv)
 
 static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr,
 unsigned long size,
-enum dma_data_direction dma_dir)
+enum dma_data_direction dma_dir,
+unsigned long dma_attrs)
 {
struct vb2_vmalloc_buf *buf;
struct frame_vector *vec;
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index cb97c22..4172f6e 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -122,7 +122,8 @@ struct vb2_mem_ops {
 
void*(*get_userptr)(struct device *dev, unsigned long vaddr,
unsigned long size,
-   enum dma_data_direction dma_dir);
+   enum dma_data_direction dma_dir,
+   unsigned long dma_attrs);
void(*put_userptr)(void *buf_priv);
 
void(*prepare)(void *buf_priv);
-- 
2.7.4



[RFC v3 07/14] vb2: dma-contig: Remove redundant sgt_base field

2017-04-13 Thread Sakari Ailus
The struct vb2_dc_buf contains two struct sg_table fields: sgt_base and
dma_sgt. The former is used by DMA-BUF buffers whereas the latter is used
by USERPTR.

Unify the two, leaving dma_sgt.

MMAP buffers do not need cache flushing since they have been allocated
using dma_alloc_coherent().

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a8a46a8..ddbbcf0 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -31,12 +31,13 @@ struct vb2_dc_buf {
unsigned long   attrs;
enum dma_data_direction dma_dir;
struct sg_table *dma_sgt;
-   struct frame_vector *vec;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
refcount_t  refcount;
-   struct sg_table *sgt_base;
+
+   /* USERPTR related */
+   struct frame_vector *vec;
 
/* DMABUF related */
struct dma_buf_attachment   *db_attach;
@@ -96,7 +97,7 @@ static void vb2_dc_prepare(void *buf_priv)
struct sg_table *sgt = buf->dma_sgt;
 
/* DMABUF exporter will flush the cache for us */
-   if (!sgt || buf->db_attach)
+   if (!buf->vec)
return;
 
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
@@ -109,7 +110,7 @@ static void vb2_dc_finish(void *buf_priv)
struct sg_table *sgt = buf->dma_sgt;
 
/* DMABUF exporter will flush the cache for us */
-   if (!sgt || buf->db_attach)
+   if (!buf->vec)
return;
 
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
@@ -126,9 +127,9 @@ static void vb2_dc_put(void *buf_priv)
if (!refcount_dec_and_test(>refcount))
return;
 
-   if (buf->sgt_base) {
-   sg_free_table(buf->sgt_base);
-   kfree(buf->sgt_base);
+   if (buf->dma_sgt) {
+   sg_free_table(buf->dma_sgt);
+   kfree(buf->dma_sgt);
}
dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr,
   buf->attrs);
@@ -239,13 +240,13 @@ static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, 
struct device *dev,
/* Copy the buf->base_sgt scatter list to the attachment, as we can't
 * map the same scatter list to multiple attachments at the same time.
 */
-   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   ret = sg_alloc_table(sgt, buf->dma_sgt->orig_nents, GFP_KERNEL);
if (ret) {
kfree(attach);
return -ENOMEM;
}
 
-   rd = buf->sgt_base->sgl;
+   rd = buf->dma_sgt->sgl;
wr = sgt->sgl;
for (i = 0; i < sgt->orig_nents; ++i) {
sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
@@ -396,10 +397,10 @@ static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, 
unsigned long flags)
exp_info.flags = flags;
exp_info.priv = buf;
 
-   if (!buf->sgt_base)
-   buf->sgt_base = vb2_dc_get_base_sgt(buf);
+   if (!buf->dma_sgt)
+   buf->dma_sgt = vb2_dc_get_base_sgt(buf);
 
-   if (WARN_ON(!buf->sgt_base))
+   if (WARN_ON(!buf->dma_sgt))
return NULL;
 
dbuf = dma_buf_export(_info);
-- 
2.7.4



[RFC v3 09/14] vb2: dma-contig: Move vb2_dc_get_base_sgt() up

2017-04-13 Thread Sakari Ailus
Just move the function up. It'll be soon needed earlier than previously.

Signed-off-by: Sakari Ailus 
Reviewed-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c | 40 +-
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 22636cd..8ea9ab9 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -63,6 +63,26 @@ static unsigned long vb2_dc_get_contiguous_size(struct 
sg_table *sgt)
return size;
 }
 
+static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
+{
+   int ret;
+   struct sg_table *sgt;
+
+   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+   if (!sgt)
+   return NULL;
+
+   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
+   buf->size, buf->attrs);
+   if (ret < 0) {
+   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
+   kfree(sgt);
+   return NULL;
+   }
+
+   return sgt;
+}
+
 /*/
 /* callbacks for all buffers */
 /*/
@@ -364,26 +384,6 @@ static struct dma_buf_ops vb2_dc_dmabuf_ops = {
.release = vb2_dc_dmabuf_ops_release,
 };
 
-static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
-{
-   int ret;
-   struct sg_table *sgt;
-
-   sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
-   if (!sgt)
-   return NULL;
-
-   ret = dma_get_sgtable_attrs(buf->dev, sgt, buf->cookie, buf->dma_addr,
-   buf->size, buf->attrs);
-   if (ret < 0) {
-   dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
-   kfree(sgt);
-   return NULL;
-   }
-
-   return sgt;
-}
-
 static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags)
 {
struct vb2_dc_buf *buf = buf_priv;
-- 
2.7.4



[RFC v3 13/14] vb2: Don't sync cache for a buffer if so requested

2017-04-13 Thread Sakari Ailus
From: Samu Onkalo 

The user may request to the driver (vb2) to skip the cache maintenance
operations in case the buffer does not need cache synchronisation, e.g. in
cases where the buffer is passed between hardware blocks without it being
touched by the CPU.

Also document that the prepare and finish vb2_mem_ops might not get called
every time the buffer ownership changes between the kernel and the user
space.

Signed-off-by: Samu Onkalo 
Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c | 101 +--
 drivers/media/v4l2-core/videobuf2-v4l2.c |  14 -
 include/media/videobuf2-core.h   |  23 ---
 3 files changed, 97 insertions(+), 41 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index e866115..7f21acd 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -189,6 +189,28 @@ static void __vb2_queue_cancel(struct vb2_queue *q);
 static void __enqueue_in_driver(struct vb2_buffer *vb);
 
 /**
+ * __mem_prepare_planes() - call finish mem op for all planes of the buffer
+ */
+static void __mem_prepare_planes(struct vb2_buffer *vb)
+{
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_void_memop(vb, prepare, vb->planes[plane].mem_priv);
+}
+
+/**
+ * __mem_finish_planes() - call finish mem op for all planes of the buffer
+ */
+static void __mem_finish_planes(struct vb2_buffer *vb)
+{
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_void_memop(vb, finish, vb->planes[plane].mem_priv);
+}
+
+/**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
  */
 static int __vb2_buf_mem_alloc(struct vb2_buffer *vb)
@@ -953,20 +975,29 @@ EXPORT_SYMBOL_GPL(vb2_discard_done);
 /**
  * __prepare_mmap() - prepare an MMAP buffer
  */
-static int __prepare_mmap(struct vb2_buffer *vb, const void *pb)
+static int __prepare_mmap(struct vb2_buffer *vb, const void *pb,
+ bool no_cache_sync)
 {
-   int ret = 0;
+   int ret;
 
-   if (pb)
+   if (pb) {
ret = call_bufop(vb->vb2_queue, fill_vb2_buffer,
 vb, pb, vb->planes);
-   return ret ? ret : call_vb_qop(vb, buf_prepare, vb);
+   if (ret)
+   return ret;
+   }
+
+   if (!no_cache_sync)
+   __mem_prepare_planes(vb);
+
+   return call_vb_qop(vb, buf_prepare, vb);
 }
 
 /**
  * __prepare_userptr() - prepare a USERPTR buffer
  */
-static int __prepare_userptr(struct vb2_buffer *vb, const void *pb)
+static int __prepare_userptr(struct vb2_buffer *vb, const void *pb,
+bool no_cache_sync)
 {
struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
@@ -1057,6 +1088,11 @@ static int __prepare_userptr(struct vb2_buffer *vb, 
const void *pb)
dprintk(1, "buffer initialization failed\n");
goto err;
}
+
+   /* This is new buffer memory --- always synchronise cache. */
+   __mem_prepare_planes(vb);
+   } else if (!no_cache_sync) {
+   __mem_prepare_planes(vb);
}
 
ret = call_vb_qop(vb, buf_prepare, vb);
@@ -1084,7 +1120,8 @@ static int __prepare_userptr(struct vb2_buffer *vb, const 
void *pb)
 /**
  * __prepare_dmabuf() - prepare a DMABUF buffer
  */
-static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
+static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb,
+   bool no_cache_sync)
 {
struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
@@ -1199,6 +1236,11 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const 
void *pb)
dprintk(1, "buffer initialization failed\n");
goto err;
}
+
+   /* This is new buffer memory --- always synchronise cache. */
+   __mem_prepare_planes(vb);
+   } else if (!no_cache_sync) {
+   __mem_prepare_planes(vb);
}
 
ret = call_vb_qop(vb, buf_prepare, vb);
@@ -1231,10 +1273,10 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
call_void_vb_qop(vb, buf_queue, vb);
 }
 
-static int __buf_prepare(struct vb2_buffer *vb, const void *pb)
+static int __buf_prepare(struct vb2_buffer *vb, const void *pb,
+bool no_cache_sync)
 {
struct vb2_queue *q = vb->vb2_queue;
-   unsigned int plane;
int ret;
 
if (q->error) {
@@ -1246,13 +1288,13 @@ static int __buf_prepare(struct vb2_buffer *vb, const 
void *pb)
 
switch (q->memory) {
case 

[RFC v3 03/14] vb2: Move cache synchronisation from buffer done to dqbuf handler

2017-04-13 Thread Sakari Ailus
The cache synchronisation may be a time consuming operation and thus not
best performed in an interrupt which is a typical context for
vb2_buffer_done() calls. This may consume up to tens of ms on some
machines, depending on the buffer size.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 8bf3369..e866115 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -889,7 +889,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags;
-   unsigned int plane;
 
if (WARN_ON(vb->state != VB2_BUF_STATE_ACTIVE))
return;
@@ -910,10 +909,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, "done processing on buffer %d, state: %d\n",
vb->index, state);
 
-   /* sync buffers */
-   for (plane = 0; plane < vb->num_planes; ++plane)
-   call_void_memop(vb, finish, vb->planes[plane].mem_priv);
-
spin_lock_irqsave(>done_lock, flags);
if (state == VB2_BUF_STATE_QUEUED ||
state == VB2_BUF_STATE_REQUEUEING) {
@@ -1573,6 +1568,10 @@ static void __vb2_dqbuf(struct vb2_buffer *vb)
 
vb->state = VB2_BUF_STATE_DEQUEUED;
 
+   /* sync buffers */
+   for (i = 0; i < vb->num_planes; ++i)
+   call_void_memop(vb, finish, vb->planes[i].mem_priv);
+
/* unmap DMABUF buffer */
if (q->memory == VB2_MEMORY_DMABUF)
for (i = 0; i < vb->num_planes; ++i) {
-- 
2.7.4



[RFC v3 01/14] vb2: Rename confusingly named internal buffer preparation functions

2017-04-13 Thread Sakari Ailus
Rename __qbuf_*() functions which are specific to a buffer type as
__prepare_*() which matches with what they do. The naming was there for
historical reasons; the purpose of the functions was changed without
renaming them.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
Reviewed-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/videobuf2-core.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 94afbbf9..8df680d 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -956,9 +956,9 @@ void vb2_discard_done(struct vb2_queue *q)
 EXPORT_SYMBOL_GPL(vb2_discard_done);
 
 /**
- * __qbuf_mmap() - handle qbuf of an MMAP buffer
+ * __prepare_mmap() - prepare an MMAP buffer
  */
-static int __qbuf_mmap(struct vb2_buffer *vb, const void *pb)
+static int __prepare_mmap(struct vb2_buffer *vb, const void *pb)
 {
int ret = 0;
 
@@ -969,9 +969,9 @@ static int __qbuf_mmap(struct vb2_buffer *vb, const void 
*pb)
 }
 
 /**
- * __qbuf_userptr() - handle qbuf of a USERPTR buffer
+ * __prepare_userptr() - prepare a USERPTR buffer
  */
-static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb)
+static int __prepare_userptr(struct vb2_buffer *vb, const void *pb)
 {
struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
@@ -1087,9 +1087,9 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const 
void *pb)
 }
 
 /**
- * __qbuf_dmabuf() - handle qbuf of a DMABUF buffer
+ * __prepare_dmabuf() - prepare a DMABUF buffer
  */
-static int __qbuf_dmabuf(struct vb2_buffer *vb, const void *pb)
+static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb)
 {
struct vb2_plane planes[VB2_MAX_PLANES];
struct vb2_queue *q = vb->vb2_queue;
@@ -1255,13 +1255,13 @@ static int __buf_prepare(struct vb2_buffer *vb, const 
void *pb)
 
switch (q->memory) {
case VB2_MEMORY_MMAP:
-   ret = __qbuf_mmap(vb, pb);
+   ret = __prepare_mmap(vb, pb);
break;
case VB2_MEMORY_USERPTR:
-   ret = __qbuf_userptr(vb, pb);
+   ret = __prepare_userptr(vb, pb);
break;
case VB2_MEMORY_DMABUF:
-   ret = __qbuf_dmabuf(vb, pb);
+   ret = __prepare_dmabuf(vb, pb);
break;
default:
WARN(1, "Invalid queue type\n");
-- 
2.7.4



[RFC v3 04/14] v4l: Unify cache management hint buffer flags

2017-04-13 Thread Sakari Ailus
The V4L2_BUF_FLAG_NO_CACHE_INVALIDATE and V4L2_BUF_FLAG_NO_CACHE_CLEAN
buffer flags are currently not used by the kernel. Replace the definitions
by a single V4L2_BUF_FLAG_NO_CACHE_SYNC flag to be used by further
patches.

Different cache architectures should not be visible to the user space
which can make no meaningful use of the differences anyway. In case a
device can make use of non-coherent memory accesses, the necessary cache
operations depend on the CPU architecture and the buffer type, not the
requests of the user. The cache operation itself may be skipped on the
user's request which was the purpose of the two flags.

On ARM the invalidate and clean are separate operations whereas on
x86(-64) the two are a single operation (flush). Whether the hardware uses
the buffer for reading (V4L2_BUF_TYPE_*_OUTPUT*) or writing
(V4L2_BUF_TYPE_*CAPTURE*) already defines the required cache operation
(clean and invalidate, respectively). No user input is required.

Signed-off-by: Sakari Ailus 
Acked-by: Hans Verkuil 
---
 Documentation/media/uapi/v4l/buffer.rst| 24 --
 .../media/uapi/v4l/vidioc-prepare-buf.rst  |  5 ++---
 include/trace/events/v4l2.h|  3 +--
 include/uapi/linux/videodev2.h |  7 +--
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/Documentation/media/uapi/v4l/buffer.rst 
b/Documentation/media/uapi/v4l/buffer.rst
index ac58966..601c3e9 100644
--- a/Documentation/media/uapi/v4l/buffer.rst
+++ b/Documentation/media/uapi/v4l/buffer.rst
@@ -437,23 +437,17 @@ Buffer Flags
:ref:`VIDIOC_PREPARE_BUF `,
:ref:`VIDIOC_QBUF` or
:ref:`VIDIOC_DQBUF ` ioctl is called.
-* .. _`V4L2-BUF-FLAG-NO-CACHE-INVALIDATE`:
+* .. _`V4L2-BUF-FLAG-NO-CACHE-SYNC`:
 
-  - ``V4L2_BUF_FLAG_NO_CACHE_INVALIDATE``
+  - ``V4L2_BUF_FLAG_NO_CACHE_SYNC``
   - 0x0800
-  - Caches do not have to be invalidated for this buffer. Typically
-   applications shall use this flag if the data captured in the
-   buffer is not going to be touched by the CPU, instead the buffer
-   will, probably, be passed on to a DMA-capable hardware unit for
-   further processing or output.
-* .. _`V4L2-BUF-FLAG-NO-CACHE-CLEAN`:
-
-  - ``V4L2_BUF_FLAG_NO_CACHE_CLEAN``
-  - 0x1000
-  - Caches do not have to be cleaned for this buffer. Typically
-   applications shall use this flag for output buffers if the data in
-   this buffer has not been created by the CPU but by some
-   DMA-capable unit, in which case caches have not been used.
+  - Do not perform CPU cache synchronisation operations when the buffer is
+   queued or dequeued. The user is responsible for the correct use of
+   this flag. It should be only used when the buffer is not accessed
+   using the CPU, e.g. the buffer is written to by a hardware block and
+   then read by another one, in which case the flag should be set in both
+   :ref:`VIDIOC_QBUF` and :ref:`VIDIOC_DQBUF` ioctls. The flag has no
+   effect on some devices / architectures.
 * .. _`V4L2-BUF-FLAG-LAST`:
 
   - ``V4L2_BUF_FLAG_LAST``
diff --git a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst 
b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst
index bdcfd9f..80aeb7e 100644
--- a/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst
+++ b/Documentation/media/uapi/v4l/vidioc-prepare-buf.rst
@@ -36,9 +36,8 @@ pass ownership of the buffer to the driver before actually 
enqueuing it,
 using the :ref:`VIDIOC_QBUF` ioctl, and to prepare it for future I/O. Such
 preparations may include cache invalidation or cleaning. Performing them
 in advance saves time during the actual I/O. In case such cache
-operations are not required, the application can use one of
-``V4L2_BUF_FLAG_NO_CACHE_INVALIDATE`` and
-``V4L2_BUF_FLAG_NO_CACHE_CLEAN`` flags to skip the respective step.
+operations are not required, the application can use the
+``V4L2_BUF_FLAG_NO_CACHE_SYNC`` flag to skip the cache synchronization step.
 
 The struct :c:type:`v4l2_buffer` structure is specified in
 :ref:`buffer`.
diff --git a/include/trace/events/v4l2.h b/include/trace/events/v4l2.h
index ee7754c..fb9ad7b 100644
--- a/include/trace/events/v4l2.h
+++ b/include/trace/events/v4l2.h
@@ -80,8 +80,7 @@ SHOW_FIELD
{ V4L2_BUF_FLAG_ERROR,   "ERROR" },   \
{ V4L2_BUF_FLAG_TIMECODE,"TIMECODE" },\
{ V4L2_BUF_FLAG_PREPARED,"PREPARED" },\
-   { V4L2_BUF_FLAG_NO_CACHE_INVALIDATE, "NO_CACHE_INVALIDATE" }, \
-   { V4L2_BUF_FLAG_NO_CACHE_CLEAN,  "NO_CACHE_CLEAN" },  \
+   { V4L2_BUF_FLAG_NO_CACHE_SYNC,   "NO_CACHE_SYNC" },   \
{ V4L2_BUF_FLAG_TIMESTAMP_MASK,  "TIMESTAMP_MASK" },  \
{ 

[PATCH 1/3] dt-bindings: mt8173: Fix mdp device tree

2017-04-13 Thread Minghsiu Tsai
If the mdp_* nodes are under an mdp sub-node, their corresponding
platform device does not automatically get its iommu assigned properly.

Fix this by moving the mdp component nodes up a level such that they are
siblings of mdp and all other SoC subsystems.  This also simplifies the
device tree.

Signed-off-by: Daniel Kurtz 
Signed-off-by: Minghsiu Tsai 

---
 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt 
b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index 4182063..0d03e3a 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -2,7 +2,7 @@
 
 Media Data Path is used for scaling and color space conversion.
 
-Required properties (controller (parent) node):
+Required properties (controller node):
 - compatible: "mediatek,mt8173-mdp"
 - mediatek,vpu: the node of video processor unit, see
   Documentation/devicetree/bindings/media/mediatek-vpu.txt for details.
@@ -32,21 +32,16 @@ Required properties (DMA function blocks, child node):
   for details.
 
 Example:
-mdp {
-   compatible = "mediatek,mt8173-mdp";
-   #address-cells = <2>;
-   #size-cells = <2>;
-   ranges;
-   mediatek,vpu = <>;
-
mdp_rdma0: rdma@14001000 {
compatible = "mediatek,mt8173-mdp-rdma";
+"mediatek,mt8173-mdp";
reg = <0 0x14001000 0 0x1000>;
clocks = < CLK_MM_MDP_RDMA0>,
 < CLK_MM_MUTEX_32K>;
power-domains = < MT8173_POWER_DOMAIN_MM>;
iommus = < M4U_PORT_MDP_RDMA0>;
mediatek,larb = <>;
+   mediatek,vpu = <>;
};
 
mdp_rdma1: rdma@14002000 {
@@ -106,4 +101,3 @@ mdp {
iommus = < M4U_PORT_MDP_WROT1>;
mediatek,larb = <>;
};
-};
-- 
1.9.1



[PATCH 0/3] Fix mdp device tree

2017-04-13 Thread Minghsiu Tsai
Fix this by moving the mdp component nodes up a level such that they are
siblings of mdp and all other SoC subsystems.  This also simplifies the
device tree.

Daniel Kurtz (2):
  arm64: dts: mt8173: Fix mdp device tree
  media: mtk-mdp: Fix mdp device tree

Minghsiu Tsai (1):
  dt-bindings: mt8173: Fix mdp device tree

 .../devicetree/bindings/media/mediatek-mdp.txt |  12 +-
 arch/arm64/boot/dts/mediatek/mt8173.dtsi   | 126 ++---
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c  |   2 +-
 3 files changed, 64 insertions(+), 76 deletions(-)

-- 
1.9.1



[PATCH 2/3] arm64: dts: mt8173: Fix mdp device tree

2017-04-13 Thread Minghsiu Tsai
From: Daniel Kurtz 

If the mdp_* nodes are under an mdp sub-node, their corresponding
platform device does not automatically get its iommu assigned properly.

Fix this by moving the mdp component nodes up a level such that they are
siblings of mdp and all other SoC subsystems.  This also simplifies the
device tree.

Signed-off-by: Daniel Kurtz 
Signed-off-by: Minghsiu Tsai 

---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 126 +++
 1 file changed, 60 insertions(+), 66 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi 
b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 6922252..d28a363 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -792,80 +792,74 @@
#clock-cells = <1>;
};
 
-   mdp {
-   compatible = "mediatek,mt8173-mdp";
-   #address-cells = <2>;
-   #size-cells = <2>;
-   ranges;
+   mdp_rdma0: rdma@14001000 {
+   compatible = "mediatek,mt8173-mdp-rdma",
+"mediatek,mt8173-mdp";
+   reg = <0 0x14001000 0 0x1000>;
+   clocks = < CLK_MM_MDP_RDMA0>,
+< CLK_MM_MUTEX_32K>;
+   power-domains = < MT8173_POWER_DOMAIN_MM>;
+   iommus = < M4U_PORT_MDP_RDMA0>;
+   mediatek,larb = <>;
mediatek,vpu = <>;
+   };
 
-   mdp_rdma0: rdma@14001000 {
-   compatible = "mediatek,mt8173-mdp-rdma";
-   reg = <0 0x14001000 0 0x1000>;
-   clocks = < CLK_MM_MDP_RDMA0>,
-< CLK_MM_MUTEX_32K>;
-   power-domains = < 
MT8173_POWER_DOMAIN_MM>;
-   iommus = < M4U_PORT_MDP_RDMA0>;
-   mediatek,larb = <>;
-   };
-
-   mdp_rdma1: rdma@14002000 {
-   compatible = "mediatek,mt8173-mdp-rdma";
-   reg = <0 0x14002000 0 0x1000>;
-   clocks = < CLK_MM_MDP_RDMA1>,
-< CLK_MM_MUTEX_32K>;
-   power-domains = < 
MT8173_POWER_DOMAIN_MM>;
-   iommus = < M4U_PORT_MDP_RDMA1>;
-   mediatek,larb = <>;
-   };
+   mdp_rdma1: rdma@14002000 {
+   compatible = "mediatek,mt8173-mdp-rdma";
+   reg = <0 0x14002000 0 0x1000>;
+   clocks = < CLK_MM_MDP_RDMA1>,
+< CLK_MM_MUTEX_32K>;
+   power-domains = < MT8173_POWER_DOMAIN_MM>;
+   iommus = < M4U_PORT_MDP_RDMA1>;
+   mediatek,larb = <>;
+   };
 
-   mdp_rsz0: rsz@14003000 {
-   compatible = "mediatek,mt8173-mdp-rsz";
-   reg = <0 0x14003000 0 0x1000>;
-   clocks = < CLK_MM_MDP_RSZ0>;
-   power-domains = < 
MT8173_POWER_DOMAIN_MM>;
-   };
+   mdp_rsz0: rsz@14003000 {
+   compatible = "mediatek,mt8173-mdp-rsz";
+   reg = <0 0x14003000 0 0x1000>;
+   clocks = < CLK_MM_MDP_RSZ0>;
+   power-domains = < MT8173_POWER_DOMAIN_MM>;
+   };
 
-   mdp_rsz1: rsz@14004000 {
-   compatible = "mediatek,mt8173-mdp-rsz";
-   reg = <0 0x14004000 0 0x1000>;
-   clocks = < CLK_MM_MDP_RSZ1>;
-   power-domains = < 
MT8173_POWER_DOMAIN_MM>;
-   };
+   mdp_rsz1: rsz@14004000 {
+   compatible = "mediatek,mt8173-mdp-rsz";
+   reg = <0 0x14004000 0 0x1000>;
+   clocks = < CLK_MM_MDP_RSZ1>;
+   power-domains = < MT8173_POWER_DOMAIN_MM>;
+   };
 
-   mdp_rsz2: rsz@14005000 {
-   compatible = "mediatek,mt8173-mdp-rsz";
-   reg = <0 0x14005000 0 0x1000>;
-   clocks = < CLK_MM_MDP_RSZ2>;
-   power-domains = < 
MT8173_POWER_DOMAIN_MM>;
-   };
+   mdp_rsz2: rsz@14005000 {
+   compatible = "mediatek,mt8173-mdp-rsz";
+   reg = <0 0x14005000 0 0x1000>;
+  

[PATCH 3/3] media: mtk-mdp: Fix mdp device tree

2017-04-13 Thread Minghsiu Tsai
From: Daniel Kurtz 

If the mdp_* nodes are under an mdp sub-node, their corresponding
platform device does not automatically get its iommu assigned properly.

Fix this by moving the mdp component nodes up a level such that they are
siblings of mdp and all other SoC subsystems.  This also simplifies the
device tree.

Signed-off-by: Daniel Kurtz 
Signed-off-by: Minghsiu Tsai 

---
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c 
b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 9e4eb7d..a5ad586 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -118,7 +118,7 @@ static int mtk_mdp_probe(struct platform_device *pdev)
mutex_init(>vpulock);
 
/* Iterate over sibling MDP function blocks */
-   for_each_child_of_node(dev->of_node, node) {
+   for_each_child_of_node(dev->of_node->parent, node) {
const struct of_device_id *of_id;
enum mtk_mdp_comp_type comp_type;
int comp_id;
-- 
1.9.1



Re: [PATCH] [media] mtk-mdp: Fix g_/s_selection capture/compose logic

2017-04-13 Thread 李務誠
Reviewed-by: Wu-Cheng Li 

On Thu, Apr 13, 2017 at 12:18 PM, Minghsiu Tsai
 wrote:
> From: Daniel Kurtz 
>
> Experiments show that the:
>  (1) mtk-mdp uses the _MPLANE form of CAPTURE/OUTPUT
>  (2) CAPTURE types use CROP targets, and OUTPUT types use COMPOSE targets
>
> Signed-off-by: Daniel Kurtz 
> Signed-off-by: Minghsiu Tsai 
>
> ---
>  drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c 
> b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> index 13afe48..8ab7ca0 100644
> --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c
> @@ -837,12 +837,12 @@ static int mtk_mdp_m2m_g_selection(struct file *file, 
> void *fh,
> struct mtk_mdp_ctx *ctx = fh_to_ctx(fh);
> bool valid = false;
>
> -   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> -   if (mtk_mdp_is_target_compose(s->target))
> -   valid = true;
> -   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> +   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> if (mtk_mdp_is_target_crop(s->target))
> valid = true;
> +   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> +   if (mtk_mdp_is_target_compose(s->target))
> +   valid = true;
> }
> if (!valid) {
> mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> @@ -907,12 +907,12 @@ static int mtk_mdp_m2m_s_selection(struct file *file, 
> void *fh,
> int ret;
> bool valid = false;
>
> -   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
> -   if (s->target == V4L2_SEL_TGT_COMPOSE)
> -   valid = true;
> -   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
> +   if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
> if (s->target == V4L2_SEL_TGT_CROP)
> valid = true;
> +   } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> +   if (s->target == V4L2_SEL_TGT_COMPOSE)
> +   valid = true;
> }
> if (!valid) {
> mtk_mdp_dbg(1, "[%d] invalid type:%d,%u", ctx->id, s->type,
> @@ -925,7 +925,7 @@ static int mtk_mdp_m2m_s_selection(struct file *file, 
> void *fh,
> if (ret)
> return ret;
>
> -   if (mtk_mdp_is_target_crop(s->target))
> +   if (mtk_mdp_is_target_compose(s->target))
> frame = >s_frame;
> else
> frame = >d_frame;
> --
> 1.9.1
>