Devicetree
 help / color / mirror / Atom feed
* [PATCH 3/3] ARM: dts: imx6dl-riotboard: fix OTG regulator polarity
From: Alexander Kurz @ 2018-05-26 18:30 UTC (permalink / raw)
  To: Shawn Guo; +Cc: Fabio Estevam, devicetree, Alexander Kurz, linux-arm-kernel
In-Reply-To: <20180526183053.14029-1-akurz@blala.de>

USB OTG power is switched on when the GPIO is pulled low.

Signed-off-by: Alexander Kurz <akurz@blala.de>
---
 arch/arm/boot/dts/imx6dl-riotboard.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts
index a52e05934e3a..ef3b270c15e5 100644
--- a/arch/arm/boot/dts/imx6dl-riotboard.dts
+++ b/arch/arm/boot/dts/imx6dl-riotboard.dts
@@ -70,8 +70,7 @@
 		regulator-name = "usb_otg_vbus";
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
-		gpio = <&gpio3 22 0>;
-		enable-active-high;
+		gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
 	};
 };
 
-- 
2.11.0

^ permalink raw reply related

* Re: [PATCH 9/9] regulator: bd71837: Build BD71837 regulator driver
From: kbuild test robot @ 2018-05-27  2:27 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: kbuild-all, mturquette, sboyd, robh+dt, mark.rutland, lee.jones,
	lgirdwood, broonie, mazziesaccount, linux-clk, devicetree,
	linux-kernel, mikko.mutanen, heikki.haikola
In-Reply-To: <20180524060114.GJ4249@localhost.localdomain>

Hi Matti,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.17-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/Matti-Vaittinen/mfd-regulator-clk-bd71837-ROHM-BD71837-PMIC-driver/20180526-192351
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


Please review and possibly fold the followup patch.

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

^ permalink raw reply

* [RFC PATCH] regulator: bd71837: buck_7_volts[] can be static
From: kbuild test robot @ 2018-05-27  2:27 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: kbuild-all, mturquette, sboyd, robh+dt, mark.rutland, lee.jones,
	lgirdwood, broonie, mazziesaccount, linux-clk, devicetree,
	linux-kernel, mikko.mutanen, heikki.haikola
In-Reply-To: <20180524060114.GJ4249@localhost.localdomain>


Fixes: 9ebaeaf21446 ("regulator: bd71837: Build BD71837 regulator driver")
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---
 bd71837-regulator.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/regulator/bd71837-regulator.c b/drivers/regulator/bd71837-regulator.c
index e6c3fa7..d48b71c 100644
--- a/drivers/regulator/bd71837-regulator.c
+++ b/drivers/regulator/bd71837-regulator.c
@@ -207,7 +207,7 @@ static const struct regulator_linear_range bd71837_buck6_voltage_ranges[] = {
  * 110 = 1.95V
  * 111 = 1.995V
  */
-const unsigned int buck_7_volts[] = {
+static const unsigned int buck_7_volts[] = {
 	1605000, 1695000, 1755000, 1800000, 1845000, 1905000, 1950000, 1995000
 };
 
@@ -232,7 +232,7 @@ static const struct regulator_linear_range bd71837_ldo1_voltage_ranges[] = {
  * LDO2
  * 0.8 or 0.9V
  */
-const unsigned int ldo_2_volts[] = {
+static const unsigned int ldo_2_volts[] = {
 	900000, 800000
 };
 

^ permalink raw reply related

* Re: [PATCH 7/9] clk: bd71837: Build ROHM BD71837 PMIC clock driver
From: kbuild test robot @ 2018-05-27  8:28 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: kbuild-all, mturquette, sboyd, robh+dt, mark.rutland, lee.jones,
	lgirdwood, broonie, mazziesaccount, linux-clk, devicetree,
	linux-kernel, mikko.mutanen, heikki.haikola
In-Reply-To: <20180524055955.GH4249@localhost.localdomain>

Hi Matti,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on ljones-mfd/for-mfd-next]
[also build test WARNING on v4.17-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/Matti-Vaittinen/mfd-regulator-clk-bd71837-ROHM-BD71837-PMIC-driver/20180526-192351
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next


coccinelle warnings: (new ones prefixed by >>)

>> drivers/clk/clk-bd71837.c:145:6-11: No need to set .owner here. The core will do it.

Please review and possibly fold the followup patch.

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

^ permalink raw reply

* [PATCH] clk: bd71837: fix platform_no_drv_owner.cocci warnings
From: kbuild test robot @ 2018-05-27  8:28 UTC (permalink / raw)
  To: Matti Vaittinen
  Cc: kbuild-all, mturquette, sboyd, robh+dt, mark.rutland, lee.jones,
	lgirdwood, broonie, mazziesaccount, linux-clk, devicetree,
	linux-kernel, mikko.mutanen, heikki.haikola
In-Reply-To: <20180524055955.GH4249@localhost.localdomain>

From: kbuild test robot <fengguang.wu@intel.com>

drivers/clk/clk-bd71837.c:145:6-11: No need to set .owner here. The core will do it.

 Remove .owner field if calls are used which set it automatically

Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci

Fixes: 0e03c7b6a3c7 ("clk: bd71837: Build ROHM BD71837 PMIC clock driver")
CC: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
Signed-off-by: kbuild test robot <fengguang.wu@intel.com>
---

 clk-bd71837.c |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/clk/clk-bd71837.c
+++ b/drivers/clk/clk-bd71837.c
@@ -142,7 +142,6 @@ static int bd71837_clk_remove(struct pla
 static struct platform_driver bd71837_clk = {
 	.driver = {
 		   .name = "bd71837-clk",
-		   .owner = THIS_MODULE,
 		   },
 	.probe = bd71837_clk_probe,
 	.remove = bd71837_clk_remove,

^ permalink raw reply

* Re: [PATCH v2 4/4] drm/tinydrm: new driver for ILI9341 display panels
From: kbuild test robot @ 2018-05-27 14:04 UTC (permalink / raw)
  Cc: Mark Rutland, devicetree, limor, David Lechner, linux-kernel,
	dri-devel, Rob Herring, kbuild-all, Nitin Patil
In-Reply-To: <20180525193623.15533-5-david@lechnology.com>

[-- Attachment #1: Type: text/plain, Size: 6331 bytes --]

Hi David,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-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/David-Lechner/drm-tinydrm-new-dirver-for-ILI9341-displays/20180527-182036
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

   drivers/gpu/drm/tinydrm/ili9341.c: In function 'yx240qv29_enable':
>> drivers/gpu/drm/tinydrm/ili9341.c:128:2: error: too many arguments to function 'mipi_dbi_enable_flush'
     mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
     ^~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/tinydrm/ili9341.c:21:0:
   include/drm/tinydrm/mipi-dbi.h:70:6: note: declared here
    void mipi_dbi_enable_flush(struct mipi_dbi *mipi);
         ^~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/tinydrm/ili9341.c: At top level:
>> drivers/gpu/drm/tinydrm/ili9341.c:132:12: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .enable = yx240qv29_enable,
               ^~~~~~~~~~~~~~~~
   drivers/gpu/drm/tinydrm/ili9341.c:132:12: note: (near initialization for 'ili9341_pipe_funcs.enable')
>> drivers/gpu/drm/tinydrm/ili9341.c:135:16: error: 'drm_gem_fb_simple_display_pipe_prepare_fb' undeclared here (not in a function); did you mean 'tinydrm_display_pipe_prepare_fb'?
     .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   tinydrm_display_pipe_prepare_fb
   cc1: some warnings being treated as errors

vim +/mipi_dbi_enable_flush +128 drivers/gpu/drm/tinydrm/ili9341.c

    17	
    18	#include <drm/drm_fb_helper.h>
    19	#include <drm/drm_gem_framebuffer_helper.h>
    20	#include <drm/drm_modeset_helper.h>
  > 21	#include <drm/tinydrm/mipi-dbi.h>
    22	#include <drm/tinydrm/tinydrm-helpers.h>
    23	#include <video/mipi_display.h>
    24	
    25	#define ILI9341_FRMCTR1		0xb1
    26	#define ILI9341_DISCTRL		0xb6
    27	#define ILI9341_ETMOD		0xb7
    28	
    29	#define ILI9341_PWCTRL1		0xc0
    30	#define ILI9341_PWCTRL2		0xc1
    31	#define ILI9341_VMCTRL1		0xc5
    32	#define ILI9341_VMCTRL2		0xc7
    33	#define ILI9341_PWCTRLA		0xcb
    34	#define ILI9341_PWCTRLB		0xcf
    35	
    36	#define ILI9341_PGAMCTRL	0xe0
    37	#define ILI9341_NGAMCTRL	0xe1
    38	#define ILI9341_DTCTRLA		0xe8
    39	#define ILI9341_DTCTRLB		0xea
    40	#define ILI9341_PWRSEQ		0xed
    41	
    42	#define ILI9341_EN3GAM		0xf2
    43	#define ILI9341_PUMPCTRL	0xf7
    44	
    45	#define ILI9341_MADCTL_BGR	BIT(3)
    46	#define ILI9341_MADCTL_MV	BIT(5)
    47	#define ILI9341_MADCTL_MX	BIT(6)
    48	#define ILI9341_MADCTL_MY	BIT(7)
    49	
    50	static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
    51				     struct drm_crtc_state *crtc_state,
    52				     struct drm_plane_state *plane_state)
    53	{
    54		struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
    55		struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
    56		u8 addr_mode;
    57		int ret;
    58	
    59		DRM_DEBUG_KMS("\n");
    60	
    61		ret = mipi_dbi_poweron_conditional_reset(mipi);
    62		if (ret < 0)
    63			return;
    64		if (ret == 1)
    65			goto out_enable;
    66	
    67		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
    68	
    69		mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0xc1, 0x30);
    70		mipi_dbi_command(mipi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
    71		mipi_dbi_command(mipi, ILI9341_DTCTRLA, 0x85, 0x00, 0x78);
    72		mipi_dbi_command(mipi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
    73		mipi_dbi_command(mipi, ILI9341_PUMPCTRL, 0x20);
    74		mipi_dbi_command(mipi, ILI9341_DTCTRLB, 0x00, 0x00);
    75	
    76		/* Power Control */
    77		mipi_dbi_command(mipi, ILI9341_PWCTRL1, 0x23);
    78		mipi_dbi_command(mipi, ILI9341_PWCTRL2, 0x10);
    79		/* VCOM */
    80		mipi_dbi_command(mipi, ILI9341_VMCTRL1, 0x3e, 0x28);
    81		mipi_dbi_command(mipi, ILI9341_VMCTRL2, 0x86);
    82	
    83		/* Memory Access Control */
    84		mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
    85	
    86		/* Frame Rate */
    87		mipi_dbi_command(mipi, ILI9341_FRMCTR1, 0x00, 0x1b);
    88	
    89		/* Gamma */
    90		mipi_dbi_command(mipi, ILI9341_EN3GAM, 0x00);
    91		mipi_dbi_command(mipi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
    92		mipi_dbi_command(mipi, ILI9341_PGAMCTRL,
    93				 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
    94				 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
    95		mipi_dbi_command(mipi, ILI9341_NGAMCTRL,
    96				 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
    97				 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
    98	
    99		/* DDRAM */
   100		mipi_dbi_command(mipi, ILI9341_ETMOD, 0x07);
   101	
   102		/* Display */
   103		mipi_dbi_command(mipi, ILI9341_DISCTRL, 0x08, 0x82, 0x27, 0x00);
   104		mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
   105		msleep(100);
   106	
   107		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
   108		msleep(100);
   109	
   110	out_enable:
   111		switch (mipi->rotation) {
   112		default:
   113			addr_mode = ILI9341_MADCTL_MX;
   114			break;
   115		case 90:
   116			addr_mode = ILI9341_MADCTL_MV;
   117			break;
   118		case 180:
   119			addr_mode = ILI9341_MADCTL_MY;
   120			break;
   121		case 270:
   122			addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
   123				    ILI9341_MADCTL_MX;
   124			break;
   125		}
   126		addr_mode |= ILI9341_MADCTL_BGR;
   127		mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
 > 128		mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
   129	}
   130	
   131	static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = {
 > 132		.enable = yx240qv29_enable,
   133		.disable = mipi_dbi_pipe_disable,
   134		.update = tinydrm_display_pipe_update,
 > 135		.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
   136	};
   137	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 62956 bytes --]

[-- Attachment #3: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v2 4/4] drm/tinydrm: new driver for ILI9341 display panels
From: kbuild test robot @ 2018-05-27 14:04 UTC (permalink / raw)
  Cc: kbuild-all, dri-devel, devicetree, Mark Rutland, limor,
	David Lechner, linux-kernel, Rob Herring, Nitin Patil
In-Reply-To: <20180525193623.15533-5-david@lechnology.com>

[-- Attachment #1: Type: text/plain, Size: 5568 bytes --]

Hi David,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-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/David-Lechner/drm-tinydrm-new-dirver-for-ILI9341-displays/20180527-182036
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   drivers/gpu//drm/tinydrm/ili9341.c: In function 'yx240qv29_enable':
   drivers/gpu//drm/tinydrm/ili9341.c:128:2: error: too many arguments to function 'mipi_dbi_enable_flush'
     mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
     ^~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/gpu//drm/tinydrm/ili9341.c:21:
   include/drm/tinydrm/mipi-dbi.h:70:6: note: declared here
    void mipi_dbi_enable_flush(struct mipi_dbi *mipi);
         ^~~~~~~~~~~~~~~~~~~~~
   drivers/gpu//drm/tinydrm/ili9341.c: At top level:
>> drivers/gpu//drm/tinydrm/ili9341.c:132:12: error: initialization of 'void (*)(struct drm_simple_display_pipe *, struct drm_crtc_state *)' from incompatible pointer type 'void (*)(struct drm_simple_display_pipe *, struct drm_crtc_state *, struct drm_plane_state *)' [-Werror=incompatible-pointer-types]
     .enable = yx240qv29_enable,
               ^~~~~~~~~~~~~~~~
   drivers/gpu//drm/tinydrm/ili9341.c:132:12: note: (near initialization for 'ili9341_pipe_funcs.enable')
   drivers/gpu//drm/tinydrm/ili9341.c:135:16: error: 'drm_gem_fb_simple_display_pipe_prepare_fb' undeclared here (not in a function); did you mean 'tinydrm_display_pipe_prepare_fb'?
     .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   tinydrm_display_pipe_prepare_fb
   cc1: some warnings being treated as errors

vim +132 drivers/gpu//drm/tinydrm/ili9341.c

    49	
    50	static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
    51				     struct drm_crtc_state *crtc_state,
    52				     struct drm_plane_state *plane_state)
    53	{
    54		struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
    55		struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
    56		u8 addr_mode;
    57		int ret;
    58	
    59		DRM_DEBUG_KMS("\n");
    60	
    61		ret = mipi_dbi_poweron_conditional_reset(mipi);
    62		if (ret < 0)
    63			return;
    64		if (ret == 1)
    65			goto out_enable;
    66	
    67		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
    68	
    69		mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0xc1, 0x30);
    70		mipi_dbi_command(mipi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
    71		mipi_dbi_command(mipi, ILI9341_DTCTRLA, 0x85, 0x00, 0x78);
    72		mipi_dbi_command(mipi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
    73		mipi_dbi_command(mipi, ILI9341_PUMPCTRL, 0x20);
    74		mipi_dbi_command(mipi, ILI9341_DTCTRLB, 0x00, 0x00);
    75	
    76		/* Power Control */
    77		mipi_dbi_command(mipi, ILI9341_PWCTRL1, 0x23);
    78		mipi_dbi_command(mipi, ILI9341_PWCTRL2, 0x10);
    79		/* VCOM */
    80		mipi_dbi_command(mipi, ILI9341_VMCTRL1, 0x3e, 0x28);
    81		mipi_dbi_command(mipi, ILI9341_VMCTRL2, 0x86);
    82	
    83		/* Memory Access Control */
    84		mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
    85	
    86		/* Frame Rate */
    87		mipi_dbi_command(mipi, ILI9341_FRMCTR1, 0x00, 0x1b);
    88	
    89		/* Gamma */
    90		mipi_dbi_command(mipi, ILI9341_EN3GAM, 0x00);
    91		mipi_dbi_command(mipi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
    92		mipi_dbi_command(mipi, ILI9341_PGAMCTRL,
    93				 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
    94				 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
    95		mipi_dbi_command(mipi, ILI9341_NGAMCTRL,
    96				 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
    97				 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
    98	
    99		/* DDRAM */
   100		mipi_dbi_command(mipi, ILI9341_ETMOD, 0x07);
   101	
   102		/* Display */
   103		mipi_dbi_command(mipi, ILI9341_DISCTRL, 0x08, 0x82, 0x27, 0x00);
   104		mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
   105		msleep(100);
   106	
   107		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
   108		msleep(100);
   109	
   110	out_enable:
   111		switch (mipi->rotation) {
   112		default:
   113			addr_mode = ILI9341_MADCTL_MX;
   114			break;
   115		case 90:
   116			addr_mode = ILI9341_MADCTL_MV;
   117			break;
   118		case 180:
   119			addr_mode = ILI9341_MADCTL_MY;
   120			break;
   121		case 270:
   122			addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
   123				    ILI9341_MADCTL_MX;
   124			break;
   125		}
   126		addr_mode |= ILI9341_MADCTL_BGR;
   127		mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
 > 128		mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
   129	}
   130	
   131	static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = {
 > 132		.enable = yx240qv29_enable,
   133		.disable = mipi_dbi_pipe_disable,
   134		.update = tinydrm_display_pipe_update,
   135		.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
   136	};
   137	

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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 49884 bytes --]

^ permalink raw reply

* Re: [PATCH v2 4/4] drm/tinydrm: new driver for ILI9341 display panels
From: kbuild test robot @ 2018-05-27 14:50 UTC (permalink / raw)
  Cc: Mark Rutland, devicetree, limor, David Lechner, linux-kernel,
	dri-devel, Rob Herring, kbuild-all, Nitin Patil
In-Reply-To: <20180525193623.15533-5-david@lechnology.com>

Hi David,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.17-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/David-Lechner/drm-tinydrm-new-dirver-for-ILI9341-displays/20180527-182036
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   drivers/gpu/drm/tinydrm/ili9341.c:128:30: sparse: too many arguments for function mipi_dbi_enable_flush
>> drivers/gpu/drm/tinydrm/ili9341.c:132:19: sparse: incorrect type in initializer (different argument counts) @@    expected void ( *enable )( ... ) @@    got void ( *enable )( ... ) @@
   drivers/gpu/drm/tinydrm/ili9341.c:132:19:    expected void ( *enable )( ... )
   drivers/gpu/drm/tinydrm/ili9341.c:132:19:    got void ( *<noident> )( ... )
   drivers/gpu/drm/tinydrm/ili9341.c:135:23: sparse: undefined identifier 'drm_gem_fb_simple_display_pipe_prepare_fb'
   drivers/gpu/drm/tinydrm/ili9341.c: In function 'yx240qv29_enable':
   drivers/gpu/drm/tinydrm/ili9341.c:128:2: error: too many arguments to function 'mipi_dbi_enable_flush'
     mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
     ^~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/tinydrm/ili9341.c:21:0:
   include/drm/tinydrm/mipi-dbi.h:70:6: note: declared here
    void mipi_dbi_enable_flush(struct mipi_dbi *mipi);
         ^~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/tinydrm/ili9341.c: At top level:
   drivers/gpu/drm/tinydrm/ili9341.c:132:12: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .enable = yx240qv29_enable,
               ^~~~~~~~~~~~~~~~
   drivers/gpu/drm/tinydrm/ili9341.c:132:12: note: (near initialization for 'ili9341_pipe_funcs.enable')
   drivers/gpu/drm/tinydrm/ili9341.c:135:16: error: 'drm_gem_fb_simple_display_pipe_prepare_fb' undeclared here (not in a function); did you mean 'tinydrm_display_pipe_prepare_fb'?
     .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   tinydrm_display_pipe_prepare_fb
   cc1: some warnings being treated as errors

vim +132 drivers/gpu/drm/tinydrm/ili9341.c

    49	
    50	static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
    51				     struct drm_crtc_state *crtc_state,
    52				     struct drm_plane_state *plane_state)
    53	{
    54		struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
    55		struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
    56		u8 addr_mode;
    57		int ret;
    58	
    59		DRM_DEBUG_KMS("\n");
    60	
    61		ret = mipi_dbi_poweron_conditional_reset(mipi);
    62		if (ret < 0)
    63			return;
    64		if (ret == 1)
    65			goto out_enable;
    66	
    67		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
    68	
    69		mipi_dbi_command(mipi, ILI9341_PWCTRLB, 0x00, 0xc1, 0x30);
    70		mipi_dbi_command(mipi, ILI9341_PWRSEQ, 0x64, 0x03, 0x12, 0x81);
    71		mipi_dbi_command(mipi, ILI9341_DTCTRLA, 0x85, 0x00, 0x78);
    72		mipi_dbi_command(mipi, ILI9341_PWCTRLA, 0x39, 0x2c, 0x00, 0x34, 0x02);
    73		mipi_dbi_command(mipi, ILI9341_PUMPCTRL, 0x20);
    74		mipi_dbi_command(mipi, ILI9341_DTCTRLB, 0x00, 0x00);
    75	
    76		/* Power Control */
    77		mipi_dbi_command(mipi, ILI9341_PWCTRL1, 0x23);
    78		mipi_dbi_command(mipi, ILI9341_PWCTRL2, 0x10);
    79		/* VCOM */
    80		mipi_dbi_command(mipi, ILI9341_VMCTRL1, 0x3e, 0x28);
    81		mipi_dbi_command(mipi, ILI9341_VMCTRL2, 0x86);
    82	
    83		/* Memory Access Control */
    84		mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
    85	
    86		/* Frame Rate */
    87		mipi_dbi_command(mipi, ILI9341_FRMCTR1, 0x00, 0x1b);
    88	
    89		/* Gamma */
    90		mipi_dbi_command(mipi, ILI9341_EN3GAM, 0x00);
    91		mipi_dbi_command(mipi, MIPI_DCS_SET_GAMMA_CURVE, 0x01);
    92		mipi_dbi_command(mipi, ILI9341_PGAMCTRL,
    93				 0x0f, 0x31, 0x2b, 0x0c, 0x0e, 0x08, 0x4e, 0xf1,
    94				 0x37, 0x07, 0x10, 0x03, 0x0e, 0x09, 0x00);
    95		mipi_dbi_command(mipi, ILI9341_NGAMCTRL,
    96				 0x00, 0x0e, 0x14, 0x03, 0x11, 0x07, 0x31, 0xc1,
    97				 0x48, 0x08, 0x0f, 0x0c, 0x31, 0x36, 0x0f);
    98	
    99		/* DDRAM */
   100		mipi_dbi_command(mipi, ILI9341_ETMOD, 0x07);
   101	
   102		/* Display */
   103		mipi_dbi_command(mipi, ILI9341_DISCTRL, 0x08, 0x82, 0x27, 0x00);
   104		mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
   105		msleep(100);
   106	
   107		mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
   108		msleep(100);
   109	
   110	out_enable:
   111		switch (mipi->rotation) {
   112		default:
   113			addr_mode = ILI9341_MADCTL_MX;
   114			break;
   115		case 90:
   116			addr_mode = ILI9341_MADCTL_MV;
   117			break;
   118		case 180:
   119			addr_mode = ILI9341_MADCTL_MY;
   120			break;
   121		case 270:
   122			addr_mode = ILI9341_MADCTL_MV | ILI9341_MADCTL_MY |
   123				    ILI9341_MADCTL_MX;
   124			break;
   125		}
   126		addr_mode |= ILI9341_MADCTL_BGR;
   127		mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
 > 128		mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
   129	}
   130	
   131	static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = {
 > 132		.enable = yx240qv29_enable,
   133		.disable = mipi_dbi_pipe_disable,
   134		.update = tinydrm_display_pipe_update,
   135		.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
   136	};
   137	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH 1/3] ARM: dts: imx6 wandboard and riotboard: remove regulators bus node
From: Fabio Estevam @ 2018-05-27 16:40 UTC (permalink / raw)
  To: Alexander Kurz
  Cc: Fabio Estevam,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Shawn Guo,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20180526183053.14029-2-akurz@blala.de>

Hi Alexander,

[It would be better to split this patch in two: one for wandboard and
another one for riotboard]

On Sat, May 26, 2018 at 3:30 PM, Alexander Kurz <akurz@blala.de> wrote:

> +
> +       reg_2p5v: fixedregulator@0 {

This causes dtc warnings with W=1 as you are passing a unit address
without a corresponding reg property.

You can rewrite this as:

reg_2p5v: regulator-2p5v {

Please follow this convention in the entire series.

Thanks

^ permalink raw reply

* [PATCH 00/13] Bluetooth: Add RTL8723BS support
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree

Hi All,

Here is a series of patches adding support for RTL8723BS' bluetooth
component through serdev enumration.

This builds on the great work done on this by Martin Blumenstingl
which makes the btrtl.c code also support firmware+config loading
for the RTL8723BS, as well as Jeremy's Cline work to add ACPI
enumeration support on top of this.

I've tested this series on several Intel boards with a RTL8723BS
chip. As such this series only hooks up ACPI enumerated devices.

Adding support for devicetree enumeration using the bindings already
defined for this by Martin should be trivial for someone who has
the necessary hardware to develop this.

Regards,

Hans

^ permalink raw reply

* [PATCH 01/13] dt-bindings: net: bluetooth: add support for Realtek Bluetooth chips
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

This adds the documentation for Bluetooth functionality of the Realtek
RTL8723BS and RTL8723DS.
Both are SDIO wifi chips with an additional Bluetooth module which is
connected via UART to the host.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 .../bindings/net/realtek-bluetooth.txt        | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/realtek-bluetooth.txt

diff --git a/Documentation/devicetree/bindings/net/realtek-bluetooth.txt b/Documentation/devicetree/bindings/net/realtek-bluetooth.txt
new file mode 100644
index 000000000000..1491329c4cd1
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/realtek-bluetooth.txt
@@ -0,0 +1,41 @@
+Realtek Bluetooth Chips
+-----------------------
+
+This documents the binding structure and common properties for serial
+attached Realtek devices.
+
+Serial attached Realtek devices shall be a child node of the host UART
+device the slave device is attached to. See ../serial/slave-device.txt
+for more information
+
+Required properties:
+- compatible: should contain one of the following:
+    * "realtek,rtl8723bs-bluetooth"
+    * "realtek,rtl8723ds-bluetooth"
+
+Optional properties:
+- realtek,config-data: Bluetooth chipset configuration data which is
+			needed for communication (it typically contains
+			board specific settings like the baudrate and
+			whether flow-control is used).
+			This is an array of u8 values.
+- enable-gpios: GPIO specifier, used to enable/disable the BT module
+- reset-gpios: GPIO specifier, used to reset the BT module
+
+
+Example:
+
+&uart {
+	...
+
+	bluetooth {
+		compatible = "realtek,rtl8723bs-bluetooth";
+		enable-gpios = <&gpio 20 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+		realtek,config-data = /bits/ 8 <
+			0x55 0xab 0x23 0x87 0x29 0x00 0xf4 0x00 0x01 0x01 0xf6 0x00
+			0x02 0x81 0x00 0xfa 0x00 0x02 0x12 0x80 0x0c 0x00 0x10 0x02
+			0x80 0x92 0x04 0x50 0xc5 0xea 0x19 0xe1 0x1b 0xfd 0xaf 0x5f
+			0x01 0xa4 0x0b 0xd9 0x00 0x01 0x0f 0xe4 0x00 0x01 0x08>;
+	};
+};
-- 
2.17.0

^ permalink raw reply related

* [PATCH 02/13] Bluetooth: btrtl: add MODULE_FIRMWARE declarations
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

This makes the firmware names show up in modinfo.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btrtl.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index 437f080deaab..c08f63e3bc14 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -528,3 +528,12 @@ MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
 MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("rtl_bt/rtl8723a_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8821a_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8822b_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8822b_config.bin");
-- 
2.17.0

^ permalink raw reply related

* [PATCH 03/13] Bluetooth: btrtl: split the device initialization into smaller parts
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

This prepares the btrtl code so it can be used to initialize Bluetooth
modules connected via UART (these are found for example on the RTL8723BS
and RTL8723DS SDIO chips, which come with an embedded UART Bluetooth
module).

The Realtek "rtl8723bs_bt" and "rtl8723ds_bt" userspace Bluetooth UART
initialization tools (rtk_hciattach) use the following sequence:
1) send H5 sync pattern (already supported by hci_h5)
2) get LMP version (already supported by btrtl)
3) get ROM version (already supported by btrtl)
4) load the firmware and config for the current chipset (already
   supported by btrtl)
5) read UART settings from the config blob (currently not supported)
6) send UART settings via a vendor command to the device (which changes
   the baudrate of the device and enables or disables flow control
   depending on the config)
7) change the baudrate and flow control settings on the host
8) send the firmware and config blob to the device (already supported by
   btrtl)

The main reason why the initialization has to be split is step #7. This
requires changes to the underlying "bus", which should be kept outside
of the "generic" btrtl driver.
The idea for this split is borrowed from the btbcm driver but adjusted
where needed (the btrtl driver for example needs two blobs: firmware and
config, while the btbcm only needs one).

This also prepares the code for step #5 (parsing the config blob) by
centralizing the code which loads the firmware and config blobs and
storing the result in the new struct btrtl_device_info.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btrtl.c | 278 +++++++++++++++++++++++---------------
 drivers/bluetooth/btrtl.h |  21 +++
 2 files changed, 193 insertions(+), 106 deletions(-)

diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index c08f63e3bc14..d7b44338cc8a 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -47,48 +47,96 @@ struct id_table {
 	__u16 lmp_subver;
 	__u16 hci_rev;
 	bool config_needed;
+	bool has_rom_version;
 	char *fw_name;
 	char *cfg_name;
 };
 
+struct btrtl_device_info {
+	const struct id_table *ic_info;
+	u8 rom_version;
+	u8 *fw_data;
+	int fw_len;
+	u8 *cfg_data;
+	int cfg_len;
+};
+
 static const struct id_table ic_id_table[] = {
+	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8723A, 0x0,
+	  .config_needed = false,
+	  .has_rom_version = false,
+	  .fw_name = "rtl_bt/rtl8723a_fw.bin",
+	  .cfg_name = NULL },
+
+	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_3499, 0x0,
+	  .config_needed = false,
+	  .has_rom_version = false,
+	  .fw_name = "rtl_bt/rtl8723a_fw.bin",
+	  .cfg_name = NULL },
+
 	/* 8723B */
 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xb),
 	  .config_needed = false,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8723b_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8723b_config.bin" },
 
 	/* 8723D */
 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xd),
 	  .config_needed = true,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8723d_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8723d_config.bin" },
 
 	/* 8821A */
 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xa),
 	  .config_needed = false,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8821a_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8821a_config.bin" },
 
 	/* 8821C */
 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xc),
 	  .config_needed = false,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8821c_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8821c_config.bin" },
 
 	/* 8761A */
 	{ IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0,
 	  .config_needed = false,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8761a_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8761a_config.bin" },
 
 	/* 8822B */
 	{ IC_INFO(RTL_ROM_LMP_8822B, 0xb),
 	  .config_needed = true,
+	  .has_rom_version = true,
 	  .fw_name  = "rtl_bt/rtl8822b_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8822b_config.bin" },
 	};
 
+static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
+		if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
+		    (ic_id_table[i].lmp_subver != lmp_subver))
+			continue;
+		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
+		    (ic_id_table[i].hci_rev != hci_rev))
+			continue;
+
+		break;
+	}
+	if (i >= ARRAY_SIZE(ic_id_table))
+		return NULL;
+
+	return &ic_id_table[i];
+}
+
 static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
 {
 	struct rtl_rom_version_evt *rom_version;
@@ -118,16 +166,16 @@ static int rtl_read_rom_version(struct hci_dev *hdev, u8 *version)
 	return 0;
 }
 
-static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
-				const struct firmware *fw,
+static int rtlbt_parse_firmware(struct hci_dev *hdev,
+				struct btrtl_device_info *btrtl_dev,
 				unsigned char **_buf)
 {
 	const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 };
 	struct rtl_epatch_header *epatch_info;
 	unsigned char *buf;
-	int i, ret, len;
+	int i, len;
 	size_t min_size;
-	u8 opcode, length, data, rom_version = 0;
+	u8 opcode, length, data;
 	int project_id = -1;
 	const unsigned char *fwptr, *chip_id_base;
 	const unsigned char *patch_length_base, *patch_offset_base;
@@ -146,15 +194,11 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
 		{ RTL_ROM_LMP_8821A, 10 },	/* 8821C */
 	};
 
-	ret = rtl_read_rom_version(hdev, &rom_version);
-	if (ret)
-		return ret;
-
 	min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
-	if (fw->size < min_size)
+	if (btrtl_dev->fw_len < min_size)
 		return -EINVAL;
 
-	fwptr = fw->data + fw->size - sizeof(extension_sig);
+	fwptr = btrtl_dev->fw_data + btrtl_dev->fw_len - sizeof(extension_sig);
 	if (memcmp(fwptr, extension_sig, sizeof(extension_sig)) != 0) {
 		BT_ERR("%s: extension section signature mismatch", hdev->name);
 		return -EINVAL;
@@ -166,7 +210,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
 	 * Once we have that, we double-check that that project_id is suitable
 	 * for the hardware we are working with.
 	 */
-	while (fwptr >= fw->data + (sizeof(struct rtl_epatch_header) + 3)) {
+	while (fwptr >= btrtl_dev->fw_data + (sizeof(*epatch_info) + 3)) {
 		opcode = *--fwptr;
 		length = *--fwptr;
 		data = *--fwptr;
@@ -206,13 +250,14 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
 		return -EINVAL;
 	}
 
-	if (lmp_subver != project_id_to_lmp_subver[i].lmp_subver) {
+	if (btrtl_dev->ic_info->lmp_subver != project_id_to_lmp_subver[i].lmp_subver) {
 		BT_ERR("%s: firmware is for %x but this is a %x", hdev->name,
-		       project_id_to_lmp_subver[i].lmp_subver, lmp_subver);
+		       project_id_to_lmp_subver[i].lmp_subver,
+		       btrtl_dev->ic_info->lmp_subver);
 		return -EINVAL;
 	}
 
-	epatch_info = (struct rtl_epatch_header *)fw->data;
+	epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data;
 	if (memcmp(epatch_info->signature, RTL_EPATCH_SIGNATURE, 8) != 0) {
 		BT_ERR("%s: bad EPATCH signature", hdev->name);
 		return -EINVAL;
@@ -229,16 +274,16 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
 	 * Find the right patch for this chip.
 	 */
 	min_size += 8 * num_patches;
-	if (fw->size < min_size)
+	if (btrtl_dev->fw_len < min_size)
 		return -EINVAL;
 
-	chip_id_base = fw->data + sizeof(struct rtl_epatch_header);
+	chip_id_base = btrtl_dev->fw_data + sizeof(struct rtl_epatch_header);
 	patch_length_base = chip_id_base + (sizeof(u16) * num_patches);
 	patch_offset_base = patch_length_base + (sizeof(u16) * num_patches);
 	for (i = 0; i < num_patches; i++) {
 		u16 chip_id = get_unaligned_le16(chip_id_base +
 						 (i * sizeof(u16)));
-		if (chip_id == rom_version + 1) {
+		if (chip_id == btrtl_dev->rom_version + 1) {
 			patch_length = get_unaligned_le16(patch_length_base +
 							  (i * sizeof(u16)));
 			patch_offset = get_unaligned_le32(patch_offset_base +
@@ -249,20 +294,21 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,
 
 	if (!patch_offset) {
 		BT_ERR("%s: didn't find patch for chip id %d",
-		       hdev->name, rom_version);
+		       hdev->name, btrtl_dev->rom_version);
 		return -EINVAL;
 	}
 
 	BT_DBG("length=%x offset=%x index %d", patch_length, patch_offset, i);
 	min_size = patch_offset + patch_length;
-	if (fw->size < min_size)
+	if (btrtl_dev->fw_len < min_size)
 		return -EINVAL;
 
 	/* Copy the firmware into a new buffer and write the version at
 	 * the end.
 	 */
 	len = patch_length;
-	buf = kmemdup(fw->data + patch_offset, patch_length, GFP_KERNEL);
+	buf = kmemdup(btrtl_dev->fw_data + patch_offset, patch_length,
+		      GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
@@ -324,7 +370,7 @@ static int rtl_download_firmware(struct hci_dev *hdev,
 	return ret;
 }
 
-static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
+static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)
 {
 	const struct firmware *fw;
 	int ret;
@@ -343,96 +389,37 @@ static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
 	return ret;
 }
 
-static int btrtl_setup_rtl8723a(struct hci_dev *hdev)
+static int btrtl_setup_rtl8723a(struct hci_dev *hdev,
+				struct btrtl_device_info *btrtl_dev)
 {
-	const struct firmware *fw;
-	int ret;
-
-	bt_dev_info(hdev, "rtl: loading rtl_bt/rtl8723a_fw.bin");
-	ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev);
-	if (ret < 0) {
-		BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
-		return ret;
-	}
-
-	if (fw->size < 8) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (btrtl_dev->fw_len < 8)
+		return -EINVAL;
 
 	/* Check that the firmware doesn't have the epatch signature
 	 * (which is only for RTL8723B and newer).
 	 */
-	if (!memcmp(fw->data, RTL_EPATCH_SIGNATURE, 8)) {
+	if (!memcmp(btrtl_dev->fw_data, RTL_EPATCH_SIGNATURE, 8)) {
 		BT_ERR("%s: unexpected EPATCH signature!", hdev->name);
-		ret = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
-	ret = rtl_download_firmware(hdev, fw->data, fw->size);
-
-out:
-	release_firmware(fw);
-	return ret;
+	return rtl_download_firmware(hdev, btrtl_dev->fw_data,
+				     btrtl_dev->fw_len);
 }
 
-static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 hci_rev,
-				u16 lmp_subver)
+static int btrtl_setup_rtl8723b(struct hci_dev *hdev,
+				struct btrtl_device_info *btrtl_dev)
 {
 	unsigned char *fw_data = NULL;
-	const struct firmware *fw;
 	int ret;
-	int cfg_sz;
-	u8 *cfg_buff = NULL;
 	u8 *tbuff;
-	char *cfg_name = NULL;
-	char *fw_name = NULL;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(ic_id_table); i++) {
-		if ((ic_id_table[i].match_flags & IC_MATCH_FL_LMPSUBV) &&
-		    (ic_id_table[i].lmp_subver != lmp_subver))
-			continue;
-		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
-		    (ic_id_table[i].hci_rev != hci_rev))
-			continue;
-
-		break;
-	}
-
-	if (i >= ARRAY_SIZE(ic_id_table)) {
-		BT_ERR("%s: unknown IC info, lmp subver %04x, hci rev %04x",
-		       hdev->name, lmp_subver, hci_rev);
-		return -EINVAL;
-	}
-
-	cfg_name = ic_id_table[i].cfg_name;
-
-	if (cfg_name) {
-		cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff);
-		if (cfg_sz < 0) {
-			cfg_sz = 0;
-			if (ic_id_table[i].config_needed)
-				BT_ERR("Necessary config file %s not found\n",
-				       cfg_name);
-		}
-	} else
-		cfg_sz = 0;
-
-	fw_name = ic_id_table[i].fw_name;
-	bt_dev_info(hdev, "rtl: loading %s", fw_name);
-	ret = request_firmware(&fw, fw_name, &hdev->dev);
-	if (ret < 0) {
-		BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
-		goto err_req_fw;
-	}
 
-	ret = rtlbt_parse_firmware(hdev, lmp_subver, fw, &fw_data);
+	ret = rtlbt_parse_firmware(hdev, btrtl_dev, &fw_data);
 	if (ret < 0)
 		goto out;
 
-	if (cfg_sz) {
-		tbuff = kzalloc(ret + cfg_sz, GFP_KERNEL);
+	if (btrtl_dev->cfg_len > 0) {
+		tbuff = kzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL);
 		if (!tbuff) {
 			ret = -ENOMEM;
 			goto out;
@@ -441,22 +428,18 @@ static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 hci_rev,
 		memcpy(tbuff, fw_data, ret);
 		kfree(fw_data);
 
-		memcpy(tbuff + ret, cfg_buff, cfg_sz);
-		ret += cfg_sz;
+		memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len);
+		ret += btrtl_dev->cfg_len;
 
 		fw_data = tbuff;
 	}
 
-	bt_dev_info(hdev, "cfg_sz %d, total size %d", cfg_sz, ret);
+	bt_dev_info(hdev, "cfg_sz %d, total size %d", btrtl_dev->cfg_len, ret);
 
 	ret = rtl_download_firmware(hdev, fw_data, ret);
 
 out:
-	release_firmware(fw);
 	kfree(fw_data);
-err_req_fw:
-	if (cfg_sz)
-		kfree(cfg_buff);
 	return ret;
 }
 
@@ -482,15 +465,33 @@ static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
 	return skb;
 }
 
-int btrtl_setup_realtek(struct hci_dev *hdev)
+void btrtl_free(struct btrtl_device_info *btrtl_dev)
+{
+	kfree(btrtl_dev->fw_data);
+	kfree(btrtl_dev->cfg_data);
+	kfree(btrtl_dev);
+}
+EXPORT_SYMBOL_GPL(btrtl_free);
+
+struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
 {
+	struct btrtl_device_info *btrtl_dev;
 	struct sk_buff *skb;
 	struct hci_rp_read_local_version *resp;
 	u16 hci_rev, lmp_subver;
+	int ret;
+
+	btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
+	if (!btrtl_dev) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
 
 	skb = btrtl_read_local_version(hdev);
-	if (IS_ERR(skb))
-		return -PTR_ERR(skb);
+	if (IS_ERR(skb)) {
+		ret = PTR_ERR(skb);
+		goto err_free;
+	}
 
 	resp = (struct hci_rp_read_local_version *)skb->data;
 	bt_dev_info(hdev, "rtl: examining hci_ver=%02x hci_rev=%04x "
@@ -502,26 +503,91 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
 	lmp_subver = le16_to_cpu(resp->lmp_subver);
 	kfree_skb(skb);
 
+	btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev);
+	if (!btrtl_dev->ic_info) {
+		bt_dev_err(hdev, "rtl: unknown IC info, lmp subver %04x, hci "
+			   "rev %04x", lmp_subver, hci_rev);
+		ret = -EINVAL;
+		goto err_free;
+	}
+
+	if (btrtl_dev->ic_info->has_rom_version) {
+		ret = rtl_read_rom_version(hdev, &btrtl_dev->rom_version);
+		if (ret)
+			goto err_free;
+	}
+
+	btrtl_dev->fw_len = rtl_load_file(hdev, btrtl_dev->ic_info->fw_name,
+					  &btrtl_dev->fw_data);
+	if (btrtl_dev->fw_len < 0) {
+		bt_dev_err(hdev, "firmware file %s not found\n",
+			   btrtl_dev->ic_info->fw_name);
+		ret = btrtl_dev->fw_len;
+		goto err_free;
+	}
+
+	if (btrtl_dev->ic_info->cfg_name) {
+		btrtl_dev->cfg_len = rtl_load_file(hdev,
+						   btrtl_dev->ic_info->cfg_name,
+						   &btrtl_dev->cfg_data);
+		if (btrtl_dev->ic_info->config_needed && btrtl_dev->cfg_len <= 0) {
+			bt_dev_err(hdev,
+				   "mandatory config file %s not found\n",
+				   btrtl_dev->ic_info->cfg_name);
+			ret = btrtl_dev->cfg_len;
+			goto err_free;
+		}
+	}
+
+	return btrtl_dev;
+
+err_free:
+	btrtl_free(btrtl_dev);
+err_alloc:
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_GPL(btrtl_initialize);
+
+int btrtl_download_firmware(struct hci_dev *hdev,
+			    struct btrtl_device_info *btrtl_dev)
+{
 	/* Match a set of subver values that correspond to stock firmware,
 	 * which is not compatible with standard btusb.
 	 * If matched, upload an alternative firmware that does conform to
 	 * standard btusb. Once that firmware is uploaded, the subver changes
 	 * to a different value.
 	 */
-	switch (lmp_subver) {
+	switch (btrtl_dev->ic_info->lmp_subver) {
 	case RTL_ROM_LMP_8723A:
 	case RTL_ROM_LMP_3499:
-		return btrtl_setup_rtl8723a(hdev);
+		return btrtl_setup_rtl8723a(hdev, btrtl_dev);
 	case RTL_ROM_LMP_8723B:
 	case RTL_ROM_LMP_8821A:
 	case RTL_ROM_LMP_8761A:
 	case RTL_ROM_LMP_8822B:
-		return btrtl_setup_rtl8723b(hdev, hci_rev, lmp_subver);
+		return btrtl_setup_rtl8723b(hdev, btrtl_dev);
 	default:
 		bt_dev_info(hdev, "rtl: assuming no firmware upload needed");
 		return 0;
 	}
 }
+EXPORT_SYMBOL_GPL(btrtl_download_firmware);
+
+int btrtl_setup_realtek(struct hci_dev *hdev)
+{
+	struct btrtl_device_info *btrtl_dev;
+	int ret;
+
+	btrtl_dev = btrtl_initialize(hdev);
+	if (IS_ERR(btrtl_dev))
+		return PTR_ERR(btrtl_dev);
+
+	ret = btrtl_download_firmware(hdev, btrtl_dev);
+
+	btrtl_free(btrtl_dev);
+
+	return ret;
+}
 EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
 
 MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h
index 38ffe4890cd1..21c28dcbe5e0 100644
--- a/drivers/bluetooth/btrtl.h
+++ b/drivers/bluetooth/btrtl.h
@@ -17,6 +17,8 @@
 
 #define RTL_FRAG_LEN 252
 
+struct btrtl_device_info;
+
 struct rtl_download_cmd {
 	__u8 index;
 	__u8 data[RTL_FRAG_LEN];
@@ -40,10 +42,29 @@ struct rtl_epatch_header {
 
 #if IS_ENABLED(CONFIG_BT_RTL)
 
+struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev);
+void btrtl_free(struct btrtl_device_info *btrtl_dev);
+int btrtl_download_firmware(struct hci_dev *hdev,
+			    struct btrtl_device_info *btrtl_dev);
 int btrtl_setup_realtek(struct hci_dev *hdev);
 
 #else
 
+static inline struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void btrtl_free(struct btrtl_device_info *btrtl_dev)
+{
+}
+
+static inline int btrtl_download_firmware(struct hci_dev *hdev,
+					  struct btrtl_device_info *btrtl_dev)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline int btrtl_setup_realtek(struct hci_dev *hdev)
 {
 	return -EOPNOTSUPP;
-- 
2.17.0

^ permalink raw reply related

* [PATCH 04/13] Bluetooth: btrtl: add support for retrieving the UART settings
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

The UART settings are embedded in the config blob. This has to be parsed
to successfully initialize the Bluetooth part of the RTL8723BS (which is
an SDIO chip, but the Bluetooth part is connected via UART).

The Realtek "rtl8723bs_bt" and "rtl8723ds_bt" userspace Bluetooth UART
initialization tools (rtk_hciattach) use the following sequence:
- send H5 sync pattern (already supported by hci_h5)
- get LMP version (already supported by btrtl)
- get ROM version (already supported by btrtl)
- load the firmware and config for the current chipset (already
  supported by btrtl)
- read UART settings from the config blob (part of this patch)
- send UART settings via a vendor command to the device (which changes
  the baudrate of the device and enables or disables flow control
  depending on the config)
- change the baudrate and flow control settings on the host
- send the firmware and config blob to the device (already supported by
  btrtl)

Sending the last firmware and config blob download command
(rtl_download_cmd) fails if the UART settings are not updated
beforehand. This is presumably because the device applies the config
right after the firmware and config blob download - which means that at
this point the host is using different UART settings than the device
(which will obviously result in non-working communication).

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btrtl.c | 112 ++++++++++++++++++++++++++++++++++++++
 drivers/bluetooth/btrtl.h |  25 +++++++++
 2 files changed, 137 insertions(+)

diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index d7b44338cc8a..bc56ef7fcac3 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -34,6 +34,7 @@
 #define RTL_ROM_LMP_8821A	0x8821
 #define RTL_ROM_LMP_8761A	0x8761
 #define RTL_ROM_LMP_8822B	0x8822
+#define RTL_CONFIG_MAGIC	0x8723ab55
 
 #define IC_MATCH_FL_LMPSUBV	(1 << 0)
 #define IC_MATCH_FL_HCIREV	(1 << 1)
@@ -590,6 +591,117 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
 }
 EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
 
+unsigned int btrtl_convert_baudrate(u32 device_baudrate)
+{
+	switch (device_baudrate) {
+	case 0x0252a00a:
+		return 230400;
+
+	case 0x05f75004:
+		return 921600;
+
+	case 0x00005004:
+		return 1000000;
+
+	case 0x04928002:
+	case 0x01128002:
+		return 1500000;
+
+	case 0x00005002:
+		return 2000000;
+
+	case 0x0000b001:
+		return 2500000;
+
+	case 0x04928001:
+		return 3000000;
+
+	case 0x052a6001:
+		return 3500000;
+
+	case 0x00005001:
+		return 4000000;
+
+	case 0x0252c014:
+	default:
+		return 115200;
+	}
+}
+
+int btrtl_get_uart_settings(struct hci_dev *hdev,
+			    struct btrtl_device_info *btrtl_dev,
+			    unsigned int *controller_baudrate,
+			    u32 *device_baudrate, bool *flow_control)
+{
+	struct rtl_vendor_config *config;
+	struct rtl_vendor_config_entry *entry;
+	int i, total_data_len;
+	bool found = false;
+
+	total_data_len = btrtl_dev->cfg_len - sizeof(*config);
+	if (total_data_len <= 0) {
+		bt_dev_warn(hdev, "rtl: no config loaded");
+		return -EINVAL;
+	}
+
+	config = (struct rtl_vendor_config *)btrtl_dev->cfg_data;
+	if (le32_to_cpu(config->signature) != RTL_CONFIG_MAGIC) {
+		bt_dev_err(hdev, "rtl: invalid config magic");
+		return -EINVAL;
+	}
+
+	if (total_data_len < le16_to_cpu(config->total_len)) {
+		bt_dev_err(hdev, "rtl: config is too short");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < total_data_len; ) {
+		entry = ((void *)config->entry) + i;
+
+		switch (le16_to_cpu(entry->offset)) {
+		case 0xc:
+			if (entry->len < sizeof(*device_baudrate)) {
+				bt_dev_err(hdev,
+					   "rtl: invalid UART config entry");
+				return -EINVAL;
+			}
+
+			*device_baudrate = get_unaligned_le32(entry->data);
+			*controller_baudrate = btrtl_convert_baudrate(
+							*device_baudrate);
+
+			if (entry->len >= 13)
+				*flow_control = !!(entry->data[12] & BIT(2));
+			else
+				*flow_control = false;
+
+			found = true;
+			break;
+
+		default:
+			bt_dev_dbg(hdev,
+				   "rtl: skipping config entry 0x%x (len %u)",
+				   le16_to_cpu(entry->offset), entry->len);
+			break;
+		};
+
+		i += sizeof(*entry) + entry->len;
+	}
+
+	if (!found) {
+		bt_dev_err(hdev, "rtl: no UART config entry found");
+		return -ENOENT;
+	}
+
+	bt_dev_dbg(hdev, "rtl: device baudrate = 0x%08x", *device_baudrate);
+	bt_dev_dbg(hdev, "rtl: controller baudrate = %u",
+		   *controller_baudrate);
+	bt_dev_dbg(hdev, "rtl: flow control %d", *flow_control);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
+
 MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
 MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
 MODULE_VERSION(VERSION);
diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h
index 21c28dcbe5e0..2e7856fa5ac7 100644
--- a/drivers/bluetooth/btrtl.h
+++ b/drivers/bluetooth/btrtl.h
@@ -40,6 +40,18 @@ struct rtl_epatch_header {
 	__le16 num_patches;
 } __packed;
 
+struct rtl_vendor_config_entry {
+	__le16 offset;
+	__u8 len;
+	__u8 data[0];
+} __packed;
+
+struct rtl_vendor_config {
+	__le32 signature;
+	__le16 total_len;
+	struct rtl_vendor_config_entry entry[0];
+} __packed;
+
 #if IS_ENABLED(CONFIG_BT_RTL)
 
 struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev);
@@ -47,6 +59,10 @@ void btrtl_free(struct btrtl_device_info *btrtl_dev);
 int btrtl_download_firmware(struct hci_dev *hdev,
 			    struct btrtl_device_info *btrtl_dev);
 int btrtl_setup_realtek(struct hci_dev *hdev);
+int btrtl_get_uart_settings(struct hci_dev *hdev,
+			    struct btrtl_device_info *btrtl_dev,
+			    unsigned int *controller_baudrate,
+			    u32 *device_baudrate, bool *flow_control);
 
 #else
 
@@ -70,4 +86,13 @@ static inline int btrtl_setup_realtek(struct hci_dev *hdev)
 	return -EOPNOTSUPP;
 }
 
+static inline int btrtl_get_uart_settings(struct hci_dev *hdev,
+					  struct btrtl_device_info *btrtl_dev,
+					  unsigned int *controller_baudrate,
+					  u32 *device_baudrate,
+					  bool *flow_control)
+{
+	return -ENOENT;
+}
+
 #endif
-- 
2.17.0

^ permalink raw reply related

* [PATCH 05/13] Bluetooth: btrtl: add support for the RTL8723BS and RTL8723DS chips
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

The Realtek RTL8723BS and RTL8723DS chipsets are SDIO wifi chips. They
also contain a Bluetooth module which is connected via UART to the host.

Realtek's userspace initialization tool (rtk_hciattach) differentiates
these two via the HCI version and revision returned by the
HCI_OP_READ_LOCAL_VERSION command.
Additionally we apply these checks only the for UART devices. Everything
else is assumed to be a "RTL8723B" which was originally supported by the
driver (communicating via USB).

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btrtl.c | 50 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index bc56ef7fcac3..134eac0c8fe7 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -38,6 +38,8 @@
 
 #define IC_MATCH_FL_LMPSUBV	(1 << 0)
 #define IC_MATCH_FL_HCIREV	(1 << 1)
+#define IC_MATCH_FL_HCIVER	(1 << 2)
+#define IC_MATCH_FL_HCIBUS	(1 << 3)
 #define IC_INFO(lmps, hcir) \
 	.match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
 	.lmp_subver = (lmps), \
@@ -47,6 +49,8 @@ struct id_table {
 	__u16 match_flags;
 	__u16 lmp_subver;
 	__u16 hci_rev;
+	__u8 hci_ver;
+	__u8 hci_bus;
 	bool config_needed;
 	bool has_rom_version;
 	char *fw_name;
@@ -75,6 +79,18 @@ static const struct id_table ic_id_table[] = {
 	  .fw_name = "rtl_bt/rtl8723a_fw.bin",
 	  .cfg_name = NULL },
 
+	/* 8723BS */
+	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV | \
+			 IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
+	  .lmp_subver = RTL_ROM_LMP_8723B,
+	  .hci_rev = 0xb,
+	  .hci_ver = 6,
+	  .hci_bus = HCI_UART,
+	  .config_needed = true,
+	  .has_rom_version = true,
+	  .fw_name  = "rtl_bt/rtl8723bs_fw.bin",
+	  .cfg_name = "rtl_bt/rtl8723bs_config.bin" },
+
 	/* 8723B */
 	{ IC_INFO(RTL_ROM_LMP_8723B, 0xb),
 	  .config_needed = false,
@@ -89,6 +105,18 @@ static const struct id_table ic_id_table[] = {
 	  .fw_name  = "rtl_bt/rtl8723d_fw.bin",
 	  .cfg_name = "rtl_bt/rtl8723d_config.bin" },
 
+	/* 8723DS */
+	{ .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV | \
+			 IC_MATCH_FL_HCIVER | IC_MATCH_FL_HCIBUS,
+	  .lmp_subver = RTL_ROM_LMP_8723B,
+	  .hci_rev = 0xd,
+	  .hci_ver = 8,
+	  .hci_bus = HCI_UART,
+	  .config_needed = true,
+	  .has_rom_version = true,
+	  .fw_name  = "rtl_bt/rtl8723ds_fw.bin",
+	  .cfg_name = "rtl_bt/rtl8723ds_config.bin" },
+
 	/* 8821A */
 	{ IC_INFO(RTL_ROM_LMP_8821A, 0xa),
 	  .config_needed = false,
@@ -118,7 +146,8 @@ static const struct id_table ic_id_table[] = {
 	  .cfg_name = "rtl_bt/rtl8822b_config.bin" },
 	};
 
-static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev)
+static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
+					     u8 hci_ver, u8 hci_bus)
 {
 	int i;
 
@@ -129,6 +158,12 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev)
 		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIREV) &&
 		    (ic_id_table[i].hci_rev != hci_rev))
 			continue;
+		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIVER) &&
+		    (ic_id_table[i].hci_ver != hci_ver))
+			continue;
+		if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
+		    (ic_id_table[i].hci_bus != hci_bus))
+			continue;
 
 		break;
 	}
@@ -480,6 +515,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
 	struct sk_buff *skb;
 	struct hci_rp_read_local_version *resp;
 	u16 hci_rev, lmp_subver;
+	u8 hci_ver;
 	int ret;
 
 	btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
@@ -500,14 +536,18 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
 		    resp->hci_ver, resp->hci_rev,
 		    resp->lmp_ver, resp->lmp_subver);
 
+	hci_ver = resp->hci_ver;
 	hci_rev = le16_to_cpu(resp->hci_rev);
 	lmp_subver = le16_to_cpu(resp->lmp_subver);
 	kfree_skb(skb);
 
-	btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev);
+	btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
+					    hdev->bus);
+
 	if (!btrtl_dev->ic_info) {
 		bt_dev_err(hdev, "rtl: unknown IC info, lmp subver %04x, hci "
-			   "rev %04x", lmp_subver, hci_rev);
+			   "rev %04x, hci ver %04x", lmp_subver, hci_rev,
+			   hci_ver);
 		ret = -EINVAL;
 		goto err_free;
 	}
@@ -709,6 +749,10 @@ MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("rtl_bt/rtl8723a_fw.bin");
 MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
 MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
+MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
 MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
 MODULE_FIRMWARE("rtl_bt/rtl8761a_config.bin");
 MODULE_FIRMWARE("rtl_bt/rtl8821a_fw.bin");
-- 
2.17.0

^ permalink raw reply related

* [PATCH 06/13] Bluetooth: btrtl: load the config blob from devicetree when available
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

Some Realtek bluetooth devices need a "config" blob. The btrtl driver
currently only allows loading this config blob via the request_firmware
mechanism.

The UART Bluetooth chips use this config blob to specify the baudrate,
whether flow control is used and some other unknown bits. This means
that the config blob is board-specific - thus loading it via
request_firmware means that the rootfs is tied to a specific board.

The UART Bluetooth chips are implemented through serdev. This means
there is also a devicetree node which describes the Bluetooth chip.
Thus we can also load the blob from the devicetree node to keep the
filesystem independent of any board configuration data. In the future
this could be extended to support ACPI as well (in case that's needed).

Parse the devicetree node if it exists and obtain the config blob from
there. Otherwise fall back to using the "old" request_firmware
mechanism.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jeremy Cline <jeremy@jcline.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/btrtl.c | 43 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
index 134eac0c8fe7..4962a7a2d9c1 100644
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 #include <asm/unaligned.h>
+#include <linux/of.h>
 #include <linux/usb.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -509,6 +510,41 @@ void btrtl_free(struct btrtl_device_info *btrtl_dev)
 }
 EXPORT_SYMBOL_GPL(btrtl_free);
 
+static int rtl_load_config_from_dt(struct hci_dev *hdev,
+				   struct btrtl_device_info *btrtl_dev)
+{
+	struct device_node *np = hdev->dev.parent->of_node;
+	int ret, config_len;
+
+	if (!of_device_is_available(np))
+		return -ENOENT;
+
+	if (!of_find_property(np, "realtek,config-data", NULL))
+		return -ENOENT;
+
+	config_len = of_property_count_u8_elems(np, "realtek,config-data");
+	if (config_len <= 0)
+		return -ENOENT;
+
+	btrtl_dev->cfg_data = kzalloc(config_len, GFP_KERNEL);
+	if (!btrtl_dev->cfg_data)
+		return -ENOMEM;
+
+	ret = of_property_read_u8_array(np, "realtek,config-data",
+					btrtl_dev->cfg_data, config_len);
+	if (ret) {
+		kfree(btrtl_dev->cfg_data);
+		return ret;
+	}
+
+	btrtl_dev->cfg_len = config_len;
+
+	bt_dev_dbg(hdev, "rtl: using config data with len %d from DT",
+		   config_len);
+
+	return 0;
+}
+
 struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
 {
 	struct btrtl_device_info *btrtl_dev;
@@ -567,13 +603,16 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev)
 		goto err_free;
 	}
 
-	if (btrtl_dev->ic_info->cfg_name) {
+	/* try loading the config blob from device-tree first: */
+	ret = rtl_load_config_from_dt(hdev, btrtl_dev);
+	/* fall back to loading the config via request_firmware: */
+	if (ret && btrtl_dev->ic_info->cfg_name) {
 		btrtl_dev->cfg_len = rtl_load_file(hdev,
 						   btrtl_dev->ic_info->cfg_name,
 						   &btrtl_dev->cfg_data);
 		if (btrtl_dev->ic_info->config_needed && btrtl_dev->cfg_len <= 0) {
 			bt_dev_err(hdev,
-				   "mandatory config file %s not found\n",
+				   "mandatory config blob not found in %s or DT\n",
 				   btrtl_dev->ic_info->cfg_name);
 			ret = btrtl_dev->cfg_len;
 			goto err_free;
-- 
2.17.0

^ permalink raw reply related

* [PATCH 07/13] Bluetooth: hci_uart: Restore hci_dev->flush callback on open()
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

For reasons explained in detail in commit 3611f4d2a5e0 ("hci_ldisc:
fix null pointer deref") the hci_uart_close() functions sets
hci_dev->flush to NULL.

But the device may be re-opened after a close, this commit restores the
hci_dev->flush callback on open().

Note this commit also moves the nearly empty defition of hci_uart_open()
a bit down in the file to avoid the need for forward declaring
hci_uart_flush().

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_ldisc.c  | 20 +++++++++++---------
 drivers/bluetooth/hci_serdev.c | 19 +++++++++++--------
 2 files changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index b6a71705b7d6..8da0f53b5912 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -229,15 +229,6 @@ int hci_uart_init_ready(struct hci_uart *hu)
 }
 
 /* ------- Interface to HCI layer ------ */
-/* Initialize device */
-static int hci_uart_open(struct hci_dev *hdev)
-{
-	BT_DBG("%s %p", hdev->name, hdev);
-
-	/* Nothing to do for UART driver */
-	return 0;
-}
-
 /* Reset device */
 static int hci_uart_flush(struct hci_dev *hdev)
 {
@@ -264,6 +255,17 @@ static int hci_uart_flush(struct hci_dev *hdev)
 	return 0;
 }
 
+/* Initialize device */
+static int hci_uart_open(struct hci_dev *hdev)
+{
+	BT_DBG("%s %p", hdev->name, hdev);
+
+	/* Undo clearing this from hci_uart_close() */
+	hdev->flush = hci_uart_flush;
+
+	return 0;
+}
+
 /* Close device */
 static int hci_uart_close(struct hci_dev *hdev)
 {
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index e0e6461b9200..da6eb5bcfa6f 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -101,14 +101,6 @@ static void hci_uart_write_work(struct work_struct *work)
 
 /* ------- Interface to HCI layer ------ */
 
-/* Initialize device */
-static int hci_uart_open(struct hci_dev *hdev)
-{
-	BT_DBG("%s %p", hdev->name, hdev);
-
-	return 0;
-}
-
 /* Reset device */
 static int hci_uart_flush(struct hci_dev *hdev)
 {
@@ -129,6 +121,17 @@ static int hci_uart_flush(struct hci_dev *hdev)
 	return 0;
 }
 
+/* Initialize device */
+static int hci_uart_open(struct hci_dev *hdev)
+{
+	BT_DBG("%s %p", hdev->name, hdev);
+
+	/* Undo clearing this from hci_uart_close() */
+	hdev->flush = hci_uart_flush;
+
+	return 0;
+}
+
 /* Close device */
 static int hci_uart_close(struct hci_dev *hdev)
 {
-- 
2.17.0

^ permalink raw reply related

* [PATCH 08/13] Bluetooth: hci_serdev: Move serdev_device_close/open into common hci_serdev code
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

Make hci_uart_register_device() and hci_uart_unregister_device() call
serdev_device_close()/open() themselves instead of relying on the various
hci_uart drivers to do this for them.

Besides reducing code complexity, this also ensures correct error checking
of serdev_device_open(), which was missing in a few drivers.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_bcm.c    | 10 +---------
 drivers/bluetooth/hci_ll.c     |  3 ---
 drivers/bluetooth/hci_nokia.c  |  3 ---
 drivers/bluetooth/hci_serdev.c |  9 ++++++++-
 4 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index f06f0f1132fb..ddbd8c6a0ceb 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -380,10 +380,6 @@ static int bcm_open(struct hci_uart *hu)
 	mutex_lock(&bcm_device_lock);
 
 	if (hu->serdev) {
-		err = serdev_device_open(hu->serdev);
-		if (err)
-			goto err_free;
-
 		bcm->dev = serdev_device_get_drvdata(hu->serdev);
 		goto out;
 	}
@@ -420,13 +416,10 @@ static int bcm_open(struct hci_uart *hu)
 	return 0;
 
 err_unset_hu:
-	if (hu->serdev)
-		serdev_device_close(hu->serdev);
 #ifdef CONFIG_PM
-	else
+	if (!hu->serdev)
 		bcm->dev->hu = NULL;
 #endif
-err_free:
 	mutex_unlock(&bcm_device_lock);
 	hu->priv = NULL;
 	kfree(bcm);
@@ -445,7 +438,6 @@ static int bcm_close(struct hci_uart *hu)
 	mutex_lock(&bcm_device_lock);
 
 	if (hu->serdev) {
-		serdev_device_close(hu->serdev);
 		bdev = serdev_device_get_drvdata(hu->serdev);
 	} else if (bcm_device_exists(bcm->dev)) {
 		bdev = bcm->dev;
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 27e414b4e3a2..3e767f245ed5 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -141,7 +141,6 @@ static int ll_open(struct hci_uart *hu)
 
 	if (hu->serdev) {
 		struct ll_device *lldev = serdev_device_get_drvdata(hu->serdev);
-		serdev_device_open(hu->serdev);
 		if (!IS_ERR(lldev->ext_clk))
 			clk_prepare_enable(lldev->ext_clk);
 	}
@@ -179,8 +178,6 @@ static int ll_close(struct hci_uart *hu)
 		gpiod_set_value_cansleep(lldev->enable_gpio, 0);
 
 		clk_disable_unprepare(lldev->ext_clk);
-
-		serdev_device_close(hu->serdev);
 	}
 
 	hu->priv = NULL;
diff --git a/drivers/bluetooth/hci_nokia.c b/drivers/bluetooth/hci_nokia.c
index 3539fd03f47e..14d159e2042d 100644
--- a/drivers/bluetooth/hci_nokia.c
+++ b/drivers/bluetooth/hci_nokia.c
@@ -477,8 +477,6 @@ static int nokia_open(struct hci_uart *hu)
 
 	dev_dbg(dev, "protocol open");
 
-	serdev_device_open(hu->serdev);
-
 	pm_runtime_enable(dev);
 
 	return 0;
@@ -513,7 +511,6 @@ static int nokia_close(struct hci_uart *hu)
 	gpiod_set_value(btdev->wakeup_bt, 0);
 
 	pm_runtime_disable(&btdev->serdev->dev);
-	serdev_device_close(btdev->serdev);
 
 	return 0;
 }
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index da6eb5bcfa6f..ce024142f5d3 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -285,10 +285,14 @@ int hci_uart_register_device(struct hci_uart *hu,
 
 	serdev_device_set_client_ops(hu->serdev, &hci_serdev_client_ops);
 
-	err = p->open(hu);
+	err = serdev_device_open(hu->serdev);
 	if (err)
 		return err;
 
+	err = p->open(hu);
+	if (err)
+		goto err_open;
+
 	hu->proto = p;
 	set_bit(HCI_UART_PROTO_READY, &hu->flags);
 
@@ -354,6 +358,8 @@ int hci_uart_register_device(struct hci_uart *hu,
 err_alloc:
 	clear_bit(HCI_UART_PROTO_READY, &hu->flags);
 	p->close(hu);
+err_open:
+	serdev_device_close(hu->serdev);
 	return err;
 }
 EXPORT_SYMBOL_GPL(hci_uart_register_device);
@@ -368,5 +374,6 @@ void hci_uart_unregister_device(struct hci_uart *hu)
 	cancel_work_sync(&hu->write_work);
 
 	hu->proto->close(hu);
+	serdev_device_close(hu->serdev);
 }
 EXPORT_SYMBOL_GPL(hci_uart_unregister_device);
-- 
2.17.0

^ permalink raw reply related

* [PATCH 09/13] Bluetooth: hci_serdev: Fix HCI_UART_INIT_PENDING not working
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

Init hci_uart->init_ready so that hci_uart_init_ready() works properly.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_ldisc.c  | 2 +-
 drivers/bluetooth/hci_serdev.c | 1 +
 drivers/bluetooth/hci_uart.h   | 1 +
 3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 8da0f53b5912..1b240022dc19 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -195,7 +195,7 @@ static void hci_uart_write_work(struct work_struct *work)
 	clear_bit(HCI_UART_SENDING, &hu->tx_state);
 }
 
-static void hci_uart_init_work(struct work_struct *work)
+void hci_uart_init_work(struct work_struct *work)
 {
 	struct hci_uart *hu = container_of(work, struct hci_uart, init_ready);
 	int err;
diff --git a/drivers/bluetooth/hci_serdev.c b/drivers/bluetooth/hci_serdev.c
index ce024142f5d3..cf1ade833fcd 100644
--- a/drivers/bluetooth/hci_serdev.c
+++ b/drivers/bluetooth/hci_serdev.c
@@ -309,6 +309,7 @@ int hci_uart_register_device(struct hci_uart *hu,
 	hdev->bus = HCI_UART;
 	hci_set_drvdata(hdev, hu);
 
+	INIT_WORK(&hu->init_ready, hci_uart_init_work);
 	INIT_WORK(&hu->write_work, hci_uart_write_work);
 	percpu_init_rwsem(&hu->proto_lock);
 
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 66e8c68e4607..00cab2fd7a1b 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -116,6 +116,7 @@ void hci_uart_unregister_device(struct hci_uart *hu);
 
 int hci_uart_tx_wakeup(struct hci_uart *hu);
 int hci_uart_init_ready(struct hci_uart *hu);
+void hci_uart_init_work(struct work_struct *work);
 void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed);
 void hci_uart_set_flow_control(struct hci_uart *hu, bool enable);
 void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed,
-- 
2.17.0

^ permalink raw reply related

* [PATCH 10/13] Bluetooth: hci_h5: Add support for serdev enumerated devices
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

Add basic support for serdev enumerated devices, note sine this does
not (yet) declare any of / ACPI ids to bind to atm this is a nop.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_h5.c | 51 +++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 6a8d0d06aba7..11bfe28edb86 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -23,6 +23,7 @@
 
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/serdev.h>
 #include <linux/skbuff.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -65,6 +66,9 @@ enum {
 };
 
 struct h5 {
+	/* Must be the first member, hci_serdev.c expects this. */
+	struct hci_uart		serdev_hu;
+
 	struct sk_buff_head	unack;		/* Unack'ed packets queue */
 	struct sk_buff_head	rel;		/* Reliable packets queue */
 	struct sk_buff_head	unrel;		/* Unreliable packets queue */
@@ -193,9 +197,13 @@ static int h5_open(struct hci_uart *hu)
 
 	BT_DBG("hu %p", hu);
 
-	h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
-	if (!h5)
-		return -ENOMEM;
+	if (hu->serdev) {
+		h5 = serdev_device_get_drvdata(hu->serdev);
+	} else {
+		h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
+		if (!h5)
+			return -ENOMEM;
+	}
 
 	hu->priv = h5;
 	h5->hu = hu;
@@ -229,7 +237,8 @@ static int h5_close(struct hci_uart *hu)
 	skb_queue_purge(&h5->rel);
 	skb_queue_purge(&h5->unrel);
 
-	kfree(h5);
+	if (!hu->serdev)
+		kfree(h5);
 
 	return 0;
 }
@@ -750,12 +759,46 @@ static const struct hci_uart_proto h5p = {
 	.flush		= h5_flush,
 };
 
+static int h5_serdev_probe(struct serdev_device *serdev)
+{
+	struct h5 *h5;
+
+	h5 = devm_kzalloc(&serdev->dev, sizeof(*h5), GFP_KERNEL);
+	if (!h5)
+		return -ENOMEM;
+
+	set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.flags);
+
+	h5->hu = &h5->serdev_hu;
+	h5->serdev_hu.serdev = serdev;
+	serdev_device_set_drvdata(serdev, h5);
+
+	return hci_uart_register_device(&h5->serdev_hu, &h5p);
+}
+
+static void h5_serdev_remove(struct serdev_device *serdev)
+{
+	struct h5 *h5 = serdev_device_get_drvdata(serdev);
+
+	hci_uart_unregister_device(&h5->serdev_hu);
+}
+
+static struct serdev_device_driver h5_serdev_driver = {
+	.probe = h5_serdev_probe,
+	.remove = h5_serdev_remove,
+	.driver = {
+		.name = "hci_uart_h5",
+	},
+};
+
 int __init h5_init(void)
 {
+	serdev_device_driver_register(&h5_serdev_driver);
 	return hci_uart_register_proto(&h5p);
 }
 
 int __exit h5_deinit(void)
 {
+	serdev_device_driver_unregister(&h5_serdev_driver);
 	return hci_uart_unregister_proto(&h5p);
 }
-- 
2.17.0

^ permalink raw reply related

* [PATCH 11/13] Bluetooth: hci_h5: Add vendor setup, open, and close callbacks
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Jeremy Cline <jeremy@jcline.org>

Allow vendor-specific setup, open, and close functions to be defined.

Signed-off-by: Jeremy Cline <jeremy@jcline.org>
[hdegoede@redhat.com: Port from bt3wire.c to hci_h5.c]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_h5.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index 11bfe28edb86..db0d531d7813 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -21,8 +21,10 @@
  *
  */
 
-#include <linux/kernel.h>
+#include <linux/acpi.h>
 #include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/of_device.h>
 #include <linux/serdev.h>
 #include <linux/skbuff.h>
 
@@ -99,6 +101,14 @@ struct h5 {
 		H5_SLEEPING,
 		H5_WAKING_UP,
 	} sleep;
+
+	const struct h5_vnd *vnd;
+};
+
+struct h5_vnd {
+	int (*setup)(struct h5 *h5);
+	void (*open)(struct h5 *h5);
+	void (*close)(struct h5 *h5);
 };
 
 static void h5_reset_rx(struct h5 *h5);
@@ -218,6 +228,9 @@ static int h5_open(struct hci_uart *hu)
 
 	h5->tx_win = H5_TX_WIN_MAX;
 
+	if (h5->vnd && h5->vnd->open)
+		h5->vnd->open(h5);
+
 	set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags);
 
 	/* Send initial sync request */
@@ -237,12 +250,25 @@ static int h5_close(struct hci_uart *hu)
 	skb_queue_purge(&h5->rel);
 	skb_queue_purge(&h5->unrel);
 
+	if (h5->vnd && h5->vnd->close)
+		h5->vnd->close(h5);
+
 	if (!hu->serdev)
 		kfree(h5);
 
 	return 0;
 }
 
+static int h5_setup(struct hci_uart *hu)
+{
+	struct h5 *h5 = hu->priv;
+
+	if (h5->vnd && h5->vnd->setup)
+		return h5->vnd->setup(h5);
+
+	return 0;
+}
+
 static void h5_pkt_cull(struct h5 *h5)
 {
 	struct sk_buff *skb, *tmp;
@@ -753,6 +779,7 @@ static const struct hci_uart_proto h5p = {
 	.name		= "Three-wire (H5)",
 	.open		= h5_open,
 	.close		= h5_close,
+	.setup		= h5_setup,
 	.recv		= h5_recv,
 	.enqueue	= h5_enqueue,
 	.dequeue	= h5_dequeue,
@@ -773,6 +800,11 @@ static int h5_serdev_probe(struct serdev_device *serdev)
 	h5->serdev_hu.serdev = serdev;
 	serdev_device_set_drvdata(serdev, h5);
 
+	if (has_acpi_companion(&serdev->dev))
+		h5->vnd = acpi_device_get_match_data(&serdev->dev);
+	else
+		h5->vnd = of_device_get_match_data(&serdev->dev);
+
 	return hci_uart_register_device(&h5->serdev_hu, &h5p);
 }
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH 12/13] Bluetooth: hci_h5: Add support for the RTL8723BS
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

From: Jeremy Cline <jeremy@jcline.org>

Implement support for the RTL8723BS chip.

Signed-off-by: Jeremy Cline <jeremy@jcline.org>
[hdegoede@redhat.com: Port from bt3wire.c to hci_h5.c, drop broken GPIO code]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_h5.c | 69 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index db0d531d7813..d81f950cea27 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -31,6 +31,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
+#include "btrtl.h"
 #include "hci_uart.h"
 
 #define HCI_3WIRE_ACK_PKT	0
@@ -815,11 +816,79 @@ static void h5_serdev_remove(struct serdev_device *serdev)
 	hci_uart_unregister_device(&h5->serdev_hu);
 }
 
+static int h5_btrtl_setup(struct h5 *h5)
+{
+	struct btrtl_device_info *btrtl_dev;
+	struct sk_buff *skb;
+	__le32 baudrate_data;
+	u32 device_baudrate;
+	unsigned int controller_baudrate;
+	bool flow_control;
+	int err;
+
+	btrtl_dev = btrtl_initialize(h5->hu->hdev);
+	if (IS_ERR(btrtl_dev))
+		return PTR_ERR(btrtl_dev);
+
+	err = btrtl_get_uart_settings(h5->hu->hdev, btrtl_dev,
+				      &controller_baudrate, &device_baudrate,
+				      &flow_control);
+	if (err)
+		goto out_free;
+
+	baudrate_data = cpu_to_le32(device_baudrate);
+	skb = __hci_cmd_sync(h5->hu->hdev, 0xfc17, sizeof(baudrate_data),
+			     &baudrate_data, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		bt_dev_err(h5->hu->hdev, "set baud rate command failed");
+		err = PTR_ERR(skb);
+		goto out_free;
+	} else {
+		kfree_skb(skb);
+	}
+	/* Give the device some time to set up the new baudrate. */
+	msleep(10);
+
+	serdev_device_set_baudrate(h5->hu->serdev, controller_baudrate);
+	serdev_device_set_flow_control(h5->hu->serdev, flow_control);
+
+	err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev);
+	/* Give the device some time before the hci-core sends it a reset */
+	msleep(10);
+
+out_free:
+	btrtl_free(btrtl_dev);
+
+	return err;
+}
+
+static void h5_btrtl_open(struct h5 *h5)
+{
+	/* Devices always start with these fixed parameters */
+	serdev_device_set_flow_control(h5->hu->serdev, false);
+	serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN);
+	serdev_device_set_baudrate(h5->hu->serdev, 115200);
+}
+
+static struct h5_vnd rtl_vnd = {
+	.setup		= h5_btrtl_setup,
+	.open		= h5_btrtl_open,
+};
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id h5_acpi_match[] = {
+	{ "OBDA8723", (kernel_ulong_t)&rtl_vnd },
+	{ },
+};
+MODULE_DEVICE_TABLE(acpi, h5_acpi_match);
+#endif
+
 static struct serdev_device_driver h5_serdev_driver = {
 	.probe = h5_serdev_probe,
 	.remove = h5_serdev_remove,
 	.driver = {
 		.name = "hci_uart_h5",
+		.acpi_match_table = ACPI_PTR(h5_acpi_match),
 	},
 };
 
-- 
2.17.0

^ permalink raw reply related

* [PATCH 13/13] Bluetooth: hci_h5: Add support for enable and device-wake GPIOs
From: Hans de Goede @ 2018-05-27 19:04 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Martin Blumenstingl
  Cc: Hans de Goede, robh, Jeremy Cline, linux-bluetooth, linux-serial,
	linux-acpi, devicetree
In-Reply-To: <20180527190457.2632-1-hdegoede@redhat.com>

Add support for the enable and device-wake GPIOs used on ACPI enumerated
RTL8723BS devices.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/bluetooth/hci_h5.c | 47 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index d81f950cea27..177eabd00d49 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -23,6 +23,7 @@
 
 #include <linux/acpi.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 #include <linux/kernel.h>
 #include <linux/of_device.h>
 #include <linux/serdev.h>
@@ -104,12 +105,16 @@ struct h5 {
 	} sleep;
 
 	const struct h5_vnd *vnd;
+
+	struct gpio_desc *enable_gpio;
+	struct gpio_desc *device_wake_gpio;
 };
 
 struct h5_vnd {
 	int (*setup)(struct h5 *h5);
 	void (*open)(struct h5 *h5);
 	void (*close)(struct h5 *h5);
+	const struct acpi_gpio_mapping *acpi_gpios;
 };
 
 static void h5_reset_rx(struct h5 *h5);
@@ -801,10 +806,25 @@ static int h5_serdev_probe(struct serdev_device *serdev)
 	h5->serdev_hu.serdev = serdev;
 	serdev_device_set_drvdata(serdev, h5);
 
-	if (has_acpi_companion(&serdev->dev))
+	if (has_acpi_companion(&serdev->dev)) {
 		h5->vnd = acpi_device_get_match_data(&serdev->dev);
-	else
+		if (h5->vnd && h5->vnd->acpi_gpios)
+			devm_acpi_dev_add_driver_gpios(&serdev->dev,
+						       h5->vnd->acpi_gpios);
+	} else {
 		h5->vnd = of_device_get_match_data(&serdev->dev);
+	}
+
+	h5->enable_gpio = devm_gpiod_get_optional(&serdev->dev, "enable",
+						  GPIOD_OUT_LOW);
+	if (IS_ERR(h5->enable_gpio))
+		return PTR_ERR(h5->enable_gpio);
+
+	h5->device_wake_gpio = devm_gpiod_get_optional(&serdev->dev,
+						       "device-wake",
+						       GPIOD_OUT_LOW);
+	if (IS_ERR(h5->device_wake_gpio))
+		return PTR_ERR(h5->device_wake_gpio);
 
 	return hci_uart_register_device(&h5->serdev_hu, &h5p);
 }
@@ -868,11 +888,34 @@ static void h5_btrtl_open(struct h5 *h5)
 	serdev_device_set_flow_control(h5->hu->serdev, false);
 	serdev_device_set_parity(h5->hu->serdev, SERDEV_PARITY_EVEN);
 	serdev_device_set_baudrate(h5->hu->serdev, 115200);
+
+	/* The controller needs up to 500ms to wakeup */
+	gpiod_set_value_cansleep(h5->enable_gpio, 1);
+	gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
+	msleep(500);
 }
 
+static void h5_btrtl_close(struct h5 *h5)
+{
+	gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
+	gpiod_set_value_cansleep(h5->enable_gpio, 0);
+}
+
+static const struct acpi_gpio_params btrtl_device_wake_gpios = { 0, 0, false };
+static const struct acpi_gpio_params btrtl_enable_gpios = { 1, 0, false };
+static const struct acpi_gpio_params btrtl_host_wake_gpios = { 2, 0, false };
+static const struct acpi_gpio_mapping acpi_btrtl_gpios[] = {
+	{ "device-wake-gpios", &btrtl_device_wake_gpios, 1 },
+	{ "enable-gpios", &btrtl_enable_gpios, 1 },
+	{ "host-wake-gpios", &btrtl_host_wake_gpios, 1 },
+	{},
+};
+
 static struct h5_vnd rtl_vnd = {
 	.setup		= h5_btrtl_setup,
 	.open		= h5_btrtl_open,
+	.close		= h5_btrtl_close,
+	.acpi_gpios	= acpi_btrtl_gpios,
 };
 
 #ifdef CONFIG_ACPI
-- 
2.17.0

^ permalink raw reply related

* [PATCH v2 0/6] mtd: rawnand: add NVIDIA Tegra NAND flash support
From: Stefan Agner @ 2018-05-27 21:54 UTC (permalink / raw)
  To: boris.brezillon, dwmw2, computersforpeace, marek.vasut, robh+dt,
	mark.rutland, thierry.reding, mturquette, sboyd
  Cc: dev, miquel.raynal, richard, marcel, krzk, digetx,
	benjamin.lindqvist, jonathanh, pdeschrijver, pgaikwad, mirza.krak,
	linux-mtd, linux-tegra, devicetree, linux-kernel, linux-clk,
	Stefan Agner

This picks up an older patchset written by Lucas Stach which
adds raw NAND flash support for Tegra 2.
http://lists.infradead.org/pipermail/linux-mtd/2015-November/063031.html

The driver has been reworked to implement the ->exec_op callback.
Some smaller changes and bug fixes have been applied too, but I did
not keep track of them. Since the original patchset has been posted
some years back already, I guess review needs to be done from scratch
anyway.

This second revision is a rather major overhaul again. There are some
open issues:
- Driver specific DMA enabled (read/write)_page_raw are non functional
  (I am not sure why, or if this is maybe even not possible at all...)
- OOB layout discrepancy
  When using HW BCH support, the location of the ECC bytes changes
  depending on whether extra OOB bytes (tag data) are transmitted or
  not... Writing/Reading should always be with tag enabled or always
  without. I am not sure how to solve this correctly, maybe disallow
  using OOB data with HW ECC completely?

--
Stefan

Changes since v1:
- Split controller and NAND chip structure
- Add BCH support
- Allow to select algorithm and strength using device tree
- Improve HW ECC error reporting and use DEC_STATUS_BUF only
- Use SPDX license identifier
- Use per algorithm mtd_ooblayout_ops
- Use setup_data_interface callback for NAND timing configuration

Lucas Stach (4):
  mtd: rawnand: tegra: add devicetree binding
  clk: tegra20: init NDFLASH clock to sensible rate
  ARM: tegra: add Tegra20 NAND flash controller node
  ARM: tegra: enable NAND flash on Colibri T20

Stefan Agner (2):
  mtd: rawnand: add Reed-Solomon error correction algorithm
  mtd: rawnand: add NVIDIA Tegra NAND Flash controller driver

 .../bindings/mtd/nvidia,tegra20-nand.txt      |  62 ++
 MAINTAINERS                                   |   7 +
 arch/arm/boot/dts/tegra20-colibri-512.dtsi    |  16 +
 arch/arm/boot/dts/tegra20.dtsi                |  13 +
 drivers/clk/tegra/clk-tegra20.c               |   1 +
 drivers/mtd/nand/raw/Kconfig                  |   6 +
 drivers/mtd/nand/raw/Makefile                 |   1 +
 drivers/mtd/nand/raw/nand_base.c              |   1 +
 drivers/mtd/nand/raw/tegra_nand.c             | 999 ++++++++++++++++++
 include/linux/mtd/rawnand.h                   |   1 +
 10 files changed, 1107 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/nvidia,tegra20-nand.txt
 create mode 100644 drivers/mtd/nand/raw/tegra_nand.c

-- 
2.17.0

^ permalink raw reply

* [PATCH v2 1/6] mtd: rawnand: add Reed-Solomon error correction algorithm
From: Stefan Agner @ 2018-05-27 21:54 UTC (permalink / raw)
  To: boris.brezillon, dwmw2, computersforpeace, marek.vasut, robh+dt,
	mark.rutland, thierry.reding, mturquette, sboyd
  Cc: dev, miquel.raynal, richard, marcel, krzk, digetx,
	benjamin.lindqvist, jonathanh, pdeschrijver, pgaikwad, mirza.krak,
	linux-mtd, linux-tegra, devicetree, linux-kernel, linux-clk,
	Stefan Agner

Add Reed-Solomon (RS) to the enumeration of ECC algorithms.

Signed-off-by: Stefan Agner <stefan@agner.ch>
---
 drivers/mtd/nand/raw/nand_base.c | 1 +
 include/linux/mtd/rawnand.h      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index f28c3a555861..9eb5678dd6d0 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5744,6 +5744,7 @@ static int of_get_nand_ecc_mode(struct device_node *np)
 static const char * const nand_ecc_algos[] = {
 	[NAND_ECC_HAMMING]	= "hamming",
 	[NAND_ECC_BCH]		= "bch",
+	[NAND_ECC_RS]		= "rs",
 };
 
 static int of_get_nand_ecc_algo(struct device_node *np)
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 5dad59b31244..6a82da8c44ce 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -114,6 +114,7 @@ enum nand_ecc_algo {
 	NAND_ECC_UNKNOWN,
 	NAND_ECC_HAMMING,
 	NAND_ECC_BCH,
+	NAND_ECC_RS,
 };
 
 /*
-- 
2.17.0

^ permalink raw reply related


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