From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Javier Martinez Canillas <javierm@redhat.com>
Cc: linux-kernel@vger.kernel.org,
"Daniel Vetter" <daniel.vetter@ffwll.ch>,
"Geert Uytterhoeven" <geert@linux-m68k.org>,
linux-fbdev@vger.kernel.org, "Sam Ravnborg" <sam@ravnborg.org>,
dri-devel@lists.freedesktop.org,
"Noralf Trønnes" <noralf@tronnes.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Maxime Ripard" <maxime@cerno.tech>,
"Daniel Vetter" <daniel@ffwll.ch>,
"David Airlie" <airlied@linux.ie>,
"Lee Jones" <lee.jones@linaro.org>,
"Liam Girdwood" <lgirdwood@gmail.com>,
"Mark Brown" <broonie@kernel.org>,
"Thierry Reding" <thierry.reding@gmail.com>,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
linux-pwm@vger.kernel.org
Subject: Re: [PATCH v2 2/4] drm/tiny: Add driver for Solomon SSD130X OLED displays
Date: Fri, 4 Feb 2022 16:26:56 +0200 [thread overview]
Message-ID: <Yf03sCSuQwHKvgA9@smile.fi.intel.com> (raw)
In-Reply-To: <20220204134347.1187749-3-javierm@redhat.com>
On Fri, Feb 04, 2022 at 02:43:45PM +0100, Javier Martinez Canillas wrote:
> Add a DRM driver for SSD1305, SSD1306, SSD1307 and SSD1309 Solomon OLED
> controllers that can be programmed via an I2C interface. This is a port
> of the ssd1307fb driver that already supports these devices.
>
> A Device Tree binding is not added because the DRM driver is compatible
> with the existing binding for the ssd1307fb driver.
...
> +/*
> + * DRM driver for Solomon SSD130X OLED displays
> + *
> + * Copyright 2022 Red Hat Inc.
> + *
> + * Based on drivers/video/fbdev/ssd1307fb.c
> + * Copyright 2012 Free Electrons
> + *
No need for this blank line.
> + */
...
> +struct ssd130x_device {
> + struct drm_device drm;
> + struct drm_simple_display_pipe pipe;
> + struct drm_display_mode mode;
> + struct drm_connector connector;
> + struct i2c_client *client;
Can we logically separate hw protocol vs hw interface from day 1, please?
This will allow to add SPI support for this panel much easier.
Technically I would like to see here
struct device *dev;
and probably (I haven't looked into design)
struct ssd130x_ops *ops;
or something alike.
> + const struct ssd130x_deviceinfo *device_info;
> +
> + unsigned area_color_enable : 1;
> + unsigned com_invdir : 1;
> + unsigned com_lrremap : 1;
> + unsigned com_seq : 1;
> + unsigned lookup_table_set : 1;
> + unsigned low_power : 1;
> + unsigned seg_remap : 1;
> + u32 com_offset;
> + u32 contrast;
> + u32 dclk_div;
> + u32 dclk_frq;
> + u32 height;
> + u8 lookup_table[4];
> + u32 page_offset;
> + u32 col_offset;
> + u32 prechargep1;
> + u32 prechargep2;
> +
> + struct backlight_device *bl_dev;
> + struct pwm_device *pwm;
> + struct gpio_desc *reset;
> + struct regulator *vbat_reg;
> + u32 vcomh;
> + u32 width;
> + /* Cached address ranges */
> + u8 col_start;
> + u8 col_end;
> + u8 page_start;
> + u8 page_end;
> +};
...
> +static inline int ssd130x_write_value(struct i2c_client *client, u8 value)
Not sure inline does anything useful here.
Ditto for the rest similar cases.
...
> +static inline int ssd130x_write_cmd(struct i2c_client *client, int count,
> + /* u8 cmd, u8 value, ... */...)
> +{
> + va_list ap;
> + u8 value;
> + int ret;
> +
> + va_start(ap, count);
> + while (count--) {
> + value = va_arg(ap, int);
> + ret = ssd130x_write_value(client, (u8)value);
> + if (ret)
> + goto out_end;
> + }
I'm wondering if this can be written in a form
do {
...
} while (--count);
In this case it will give a hint that count can't be 0.
> +out_end:
> + va_end(ap);
> +
> + return ret;
> +}
...
> + ssd130x->pwm = pwm_get(dev, NULL);
> + if (IS_ERR(ssd130x->pwm)) {
> + dev_err(dev, "Could not get PWM from device tree!\n");
"device tree" is a bit confusing here if I run this on ACPI.
Maybe something like "firmware description"?
> + return PTR_ERR(ssd130x->pwm);
> + }
...
> + /* Set initial contrast */
> + ret = ssd130x_write_cmd(ssd130x->client, 2, SSD130X_CONTRAST, ssd130x->contrast);
Creating a local variable for client allows to:
- make lines shorter and might even be less LOCs
- allow to convert struct device to client in one place
(as per my above comment)
Ditto for other similar cases.
> + if (ret < 0)
> + return ret;
...
> + for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); ++i) {
i++ should work same way.
> + }
...
> + /* Switch to horizontal addressing mode */
> + ret = ssd130x_write_cmd(ssd130x->client, 2, SSD130X_SET_ADDRESS_MODE,
> + SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
Can it be
return ssd130x_write_cmd(...);
?
...
> + unsigned int line_length = DIV_ROUND_UP(width, 8);
> + unsigned int pages = DIV_ROUND_UP(height, 8);
For power of two there are more efficient roundup()/rounddown()
(or with _ in the names, I don't remember by heart).
...
> + for (k = 0; k < m; k++) {
> + u8 byte = buf[(8 * i + k) * line_length +
> + j / 8];
One line?
> + u8 bit = (byte >> (j % 8)) & 1;
> +
> + data |= bit << k;
> + }
...
> +static int ssd130x_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
> + const struct drm_display_mode *mode)
> +{
> + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev);
> +
> + if (mode->hdisplay != ssd130x->mode.hdisplay &&
> + mode->vdisplay != ssd130x->mode.vdisplay)
> + return MODE_ONE_SIZE;
> + else if (mode->hdisplay != ssd130x->mode.hdisplay)
> + return MODE_ONE_WIDTH;
> + else if (mode->vdisplay != ssd130x->mode.vdisplay)
> + return MODE_ONE_HEIGHT;
'else' in both cases is redundant.
> + return MODE_OK;
> +}
...
> +poweroff:
out_power_off: ?
...
> + if (!fb)
> + return;
Can it happen?
...
> + drm_mode_probed_add(connector, mode);
> + drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay);
> +
> + return 1;
Positive code, what is the meaning of it?
...
> + if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
> + ssd130x->prechargep2 = 2;
You can drop conditionals for the optional properties
ssd130x->prechargep2 = 2;
device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2);
and so on for the similar.
...
> + ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(ssd130x->reset)) {
> + ret = PTR_ERR(ssd130x->reset);
> + dev_err(dev, "Failed to get reset gpio: %d\n", ret);
> + return ret;
Why not
return dev_err_probe()?
Each time you call it for deferred probe, it will spam logs.
> + }
> +
> + ssd130x->vbat_reg = devm_regulator_get_optional(dev, "vbat");
> + if (IS_ERR(ssd130x->vbat_reg)) {
> + ret = PTR_ERR(ssd130x->vbat_reg);
> + if (ret == -ENODEV) {
> + ssd130x->vbat_reg = NULL;
> + } else {
> + dev_err(dev, "Failed to get VBAT regulator: %d\n", ret);
> + return ret;
> + }
Ditto ?
> + }
...
> + if (IS_ERR(ssd130x)) {
> + ret = PTR_ERR(ssd130x);
> + dev_err(dev, "Failed to allocate DRM device: %d\n", ret);
> + return ret;
> + }
Ditto.
...
> + i2c_set_clientdata(client, ssd130x);
Wondering if you can split i2c part from the core part and perhaps use regmap
to access the device.
...
> + if (IS_ERR(bl)) {
> + ret = PTR_ERR(bl);
> + dev_err(dev, "Unable to register backlight device: %d\n", ret);
> + return ret;
return dev_err_probe();
> + }
...
> + ret = drm_dev_register(drm, 0);
> + if (ret) {
> + dev_err(dev, "DRM device register failed: %d\n", ret);
> + return ret;
> + }
Ditto.
...
> + {},
Comma is not needed in terminator entry.
...
> +static struct i2c_driver ssd130x_i2c_driver = {
> + .driver = {
> + .name = DRIVER_NAME,
> + .of_match_table = ssd130x_of_match,
> + },
> + .probe_new = ssd130x_probe,
> + .remove = ssd130x_remove,
> + .shutdown = ssd130x_shutdown,
> +};
> +
Redundant blank line.
> +module_i2c_driver(ssd130x_i2c_driver);
--
With Best Regards,
Andy Shevchenko
WARNING: multiple messages have this Message-ID (diff)
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Javier Martinez Canillas <javierm@redhat.com>
Cc: linux-pwm@vger.kernel.org, linux-fbdev@vger.kernel.org,
"David Airlie" <airlied@linux.ie>,
"Daniel Vetter" <daniel.vetter@ffwll.ch>,
"Mark Brown" <broonie@kernel.org>,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
"Liam Girdwood" <lgirdwood@gmail.com>,
"Noralf Trønnes" <noralf@tronnes.org>,
"Geert Uytterhoeven" <geert@linux-m68k.org>,
"Maxime Ripard" <maxime@cerno.tech>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
"Thierry Reding" <thierry.reding@gmail.com>,
"Lee Jones" <lee.jones@linaro.org>,
"Sam Ravnborg" <sam@ravnborg.org>
Subject: Re: [PATCH v2 2/4] drm/tiny: Add driver for Solomon SSD130X OLED displays
Date: Fri, 4 Feb 2022 16:26:56 +0200 [thread overview]
Message-ID: <Yf03sCSuQwHKvgA9@smile.fi.intel.com> (raw)
In-Reply-To: <20220204134347.1187749-3-javierm@redhat.com>
On Fri, Feb 04, 2022 at 02:43:45PM +0100, Javier Martinez Canillas wrote:
> Add a DRM driver for SSD1305, SSD1306, SSD1307 and SSD1309 Solomon OLED
> controllers that can be programmed via an I2C interface. This is a port
> of the ssd1307fb driver that already supports these devices.
>
> A Device Tree binding is not added because the DRM driver is compatible
> with the existing binding for the ssd1307fb driver.
...
> +/*
> + * DRM driver for Solomon SSD130X OLED displays
> + *
> + * Copyright 2022 Red Hat Inc.
> + *
> + * Based on drivers/video/fbdev/ssd1307fb.c
> + * Copyright 2012 Free Electrons
> + *
No need for this blank line.
> + */
...
> +struct ssd130x_device {
> + struct drm_device drm;
> + struct drm_simple_display_pipe pipe;
> + struct drm_display_mode mode;
> + struct drm_connector connector;
> + struct i2c_client *client;
Can we logically separate hw protocol vs hw interface from day 1, please?
This will allow to add SPI support for this panel much easier.
Technically I would like to see here
struct device *dev;
and probably (I haven't looked into design)
struct ssd130x_ops *ops;
or something alike.
> + const struct ssd130x_deviceinfo *device_info;
> +
> + unsigned area_color_enable : 1;
> + unsigned com_invdir : 1;
> + unsigned com_lrremap : 1;
> + unsigned com_seq : 1;
> + unsigned lookup_table_set : 1;
> + unsigned low_power : 1;
> + unsigned seg_remap : 1;
> + u32 com_offset;
> + u32 contrast;
> + u32 dclk_div;
> + u32 dclk_frq;
> + u32 height;
> + u8 lookup_table[4];
> + u32 page_offset;
> + u32 col_offset;
> + u32 prechargep1;
> + u32 prechargep2;
> +
> + struct backlight_device *bl_dev;
> + struct pwm_device *pwm;
> + struct gpio_desc *reset;
> + struct regulator *vbat_reg;
> + u32 vcomh;
> + u32 width;
> + /* Cached address ranges */
> + u8 col_start;
> + u8 col_end;
> + u8 page_start;
> + u8 page_end;
> +};
...
> +static inline int ssd130x_write_value(struct i2c_client *client, u8 value)
Not sure inline does anything useful here.
Ditto for the rest similar cases.
...
> +static inline int ssd130x_write_cmd(struct i2c_client *client, int count,
> + /* u8 cmd, u8 value, ... */...)
> +{
> + va_list ap;
> + u8 value;
> + int ret;
> +
> + va_start(ap, count);
> + while (count--) {
> + value = va_arg(ap, int);
> + ret = ssd130x_write_value(client, (u8)value);
> + if (ret)
> + goto out_end;
> + }
I'm wondering if this can be written in a form
do {
...
} while (--count);
In this case it will give a hint that count can't be 0.
> +out_end:
> + va_end(ap);
> +
> + return ret;
> +}
...
> + ssd130x->pwm = pwm_get(dev, NULL);
> + if (IS_ERR(ssd130x->pwm)) {
> + dev_err(dev, "Could not get PWM from device tree!\n");
"device tree" is a bit confusing here if I run this on ACPI.
Maybe something like "firmware description"?
> + return PTR_ERR(ssd130x->pwm);
> + }
...
> + /* Set initial contrast */
> + ret = ssd130x_write_cmd(ssd130x->client, 2, SSD130X_CONTRAST, ssd130x->contrast);
Creating a local variable for client allows to:
- make lines shorter and might even be less LOCs
- allow to convert struct device to client in one place
(as per my above comment)
Ditto for other similar cases.
> + if (ret < 0)
> + return ret;
...
> + for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); ++i) {
i++ should work same way.
> + }
...
> + /* Switch to horizontal addressing mode */
> + ret = ssd130x_write_cmd(ssd130x->client, 2, SSD130X_SET_ADDRESS_MODE,
> + SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
Can it be
return ssd130x_write_cmd(...);
?
...
> + unsigned int line_length = DIV_ROUND_UP(width, 8);
> + unsigned int pages = DIV_ROUND_UP(height, 8);
For power of two there are more efficient roundup()/rounddown()
(or with _ in the names, I don't remember by heart).
...
> + for (k = 0; k < m; k++) {
> + u8 byte = buf[(8 * i + k) * line_length +
> + j / 8];
One line?
> + u8 bit = (byte >> (j % 8)) & 1;
> +
> + data |= bit << k;
> + }
...
> +static int ssd130x_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe,
> + const struct drm_display_mode *mode)
> +{
> + struct ssd130x_device *ssd130x = drm_to_ssd130x(pipe->crtc.dev);
> +
> + if (mode->hdisplay != ssd130x->mode.hdisplay &&
> + mode->vdisplay != ssd130x->mode.vdisplay)
> + return MODE_ONE_SIZE;
> + else if (mode->hdisplay != ssd130x->mode.hdisplay)
> + return MODE_ONE_WIDTH;
> + else if (mode->vdisplay != ssd130x->mode.vdisplay)
> + return MODE_ONE_HEIGHT;
'else' in both cases is redundant.
> + return MODE_OK;
> +}
...
> +poweroff:
out_power_off: ?
...
> + if (!fb)
> + return;
Can it happen?
...
> + drm_mode_probed_add(connector, mode);
> + drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay);
> +
> + return 1;
Positive code, what is the meaning of it?
...
> + if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
> + ssd130x->prechargep2 = 2;
You can drop conditionals for the optional properties
ssd130x->prechargep2 = 2;
device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2);
and so on for the similar.
...
> + ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> + if (IS_ERR(ssd130x->reset)) {
> + ret = PTR_ERR(ssd130x->reset);
> + dev_err(dev, "Failed to get reset gpio: %d\n", ret);
> + return ret;
Why not
return dev_err_probe()?
Each time you call it for deferred probe, it will spam logs.
> + }
> +
> + ssd130x->vbat_reg = devm_regulator_get_optional(dev, "vbat");
> + if (IS_ERR(ssd130x->vbat_reg)) {
> + ret = PTR_ERR(ssd130x->vbat_reg);
> + if (ret == -ENODEV) {
> + ssd130x->vbat_reg = NULL;
> + } else {
> + dev_err(dev, "Failed to get VBAT regulator: %d\n", ret);
> + return ret;
> + }
Ditto ?
> + }
...
> + if (IS_ERR(ssd130x)) {
> + ret = PTR_ERR(ssd130x);
> + dev_err(dev, "Failed to allocate DRM device: %d\n", ret);
> + return ret;
> + }
Ditto.
...
> + i2c_set_clientdata(client, ssd130x);
Wondering if you can split i2c part from the core part and perhaps use regmap
to access the device.
...
> + if (IS_ERR(bl)) {
> + ret = PTR_ERR(bl);
> + dev_err(dev, "Unable to register backlight device: %d\n", ret);
> + return ret;
return dev_err_probe();
> + }
...
> + ret = drm_dev_register(drm, 0);
> + if (ret) {
> + dev_err(dev, "DRM device register failed: %d\n", ret);
> + return ret;
> + }
Ditto.
...
> + {},
Comma is not needed in terminator entry.
...
> +static struct i2c_driver ssd130x_i2c_driver = {
> + .driver = {
> + .name = DRIVER_NAME,
> + .of_match_table = ssd130x_of_match,
> + },
> + .probe_new = ssd130x_probe,
> + .remove = ssd130x_remove,
> + .shutdown = ssd130x_shutdown,
> +};
> +
Redundant blank line.
> +module_i2c_driver(ssd130x_i2c_driver);
--
With Best Regards,
Andy Shevchenko
next prev parent reply other threads:[~2022-02-04 14:28 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-04 13:43 [PATCH v2 0/4] drm/tiny: Add driver for Solomon SSD1307 OLED displays Javier Martinez Canillas
2022-02-04 13:43 ` Javier Martinez Canillas
2022-02-04 13:43 ` [PATCH v2 1/4] drm/format-helper: Add drm_fb_{xrgb8888,gray8}_to_mono_reversed() Javier Martinez Canillas
2022-02-04 13:43 ` [PATCH v2 1/4] drm/format-helper: Add drm_fb_{xrgb8888, gray8}_to_mono_reversed() Javier Martinez Canillas
2022-02-04 15:52 ` [PATCH v2 1/4] drm/format-helper: Add drm_fb_{xrgb8888,gray8}_to_mono_reversed() Thomas Zimmermann
2022-02-04 15:52 ` Thomas Zimmermann
2022-02-04 16:00 ` Thomas Zimmermann
2022-02-04 19:31 ` Javier Martinez Canillas
2022-02-04 19:31 ` Javier Martinez Canillas
2022-02-04 20:35 ` Thomas Zimmermann
2022-02-04 20:35 ` Thomas Zimmermann
2022-02-04 21:02 ` Ilia Mirkin
2022-02-04 21:02 ` [PATCH v2 1/4] drm/format-helper: Add drm_fb_{xrgb8888, gray8}_to_mono_reversed() Ilia Mirkin
2022-02-07 12:44 ` Thomas Zimmermann
2022-02-04 13:43 ` [PATCH v2 2/4] drm/tiny: Add driver for Solomon SSD130X OLED displays Javier Martinez Canillas
2022-02-04 13:43 ` Javier Martinez Canillas
2022-02-04 14:26 ` Andy Shevchenko [this message]
2022-02-04 14:26 ` Andy Shevchenko
2022-02-04 19:19 ` Javier Martinez Canillas
2022-02-04 19:19 ` Javier Martinez Canillas
2022-02-05 13:04 ` Andy Shevchenko
2022-02-05 13:04 ` Andy Shevchenko
2022-02-05 17:40 ` Javier Martinez Canillas
2022-02-05 17:40 ` Javier Martinez Canillas
2022-02-04 13:43 ` [PATCH v2 3/4] MAINTAINERS: Add entry for Solomon SSD130X OLED displays DRM driver Javier Martinez Canillas
2022-02-04 13:43 ` Javier Martinez Canillas
2022-02-04 13:57 ` Andy Shevchenko
2022-02-04 13:57 ` Andy Shevchenko
2022-02-04 14:12 ` Javier Martinez Canillas
2022-02-04 14:12 ` Javier Martinez Canillas
2022-02-04 14:28 ` Andy Shevchenko
2022-02-04 14:28 ` Andy Shevchenko
2022-02-04 14:33 ` Javier Martinez Canillas
2022-02-04 14:33 ` Javier Martinez Canillas
2022-02-04 13:43 ` [PATCH v2 4/4] dt-bindings: display: ssd1307fb: Add myself as binding co-maintainer Javier Martinez Canillas
2022-02-04 13:43 ` Javier Martinez Canillas
2022-02-09 22:14 ` Rob Herring
2022-02-09 22:14 ` Rob Herring
2022-02-04 14:31 ` [PATCH v2 0/4] drm/tiny: Add driver for Solomon SSD1307 OLED displays Geert Uytterhoeven
2022-02-04 14:31 ` Geert Uytterhoeven
2022-02-04 14:37 ` Javier Martinez Canillas
2022-02-04 14:37 ` Javier Martinez Canillas
2022-02-08 14:19 ` Geert Uytterhoeven
2022-02-08 14:19 ` Geert Uytterhoeven
2022-02-08 15:10 ` Javier Martinez Canillas
2022-02-08 15:10 ` Javier Martinez Canillas
2022-02-08 15:18 ` Mark Brown
2022-02-08 15:18 ` Mark Brown
2022-02-08 15:32 ` Javier Martinez Canillas
2022-02-08 15:32 ` Javier Martinez Canillas
2022-02-08 15:23 ` Geert Uytterhoeven
2022-02-08 15:23 ` Geert Uytterhoeven
2022-02-08 15:40 ` Javier Martinez Canillas
2022-02-08 15:40 ` Javier Martinez Canillas
2022-02-08 17:19 ` Javier Martinez Canillas
2022-02-08 17:19 ` Javier Martinez Canillas
2022-02-09 13:47 ` Andy Shevchenko
2022-02-09 13:47 ` Andy Shevchenko
2022-02-09 14:27 ` Geert Uytterhoeven
2022-02-09 14:27 ` Geert Uytterhoeven
2022-02-09 14:42 ` Javier Martinez Canillas
2022-02-09 14:42 ` Javier Martinez Canillas
2022-02-09 15:32 ` Andy Shevchenko
2022-02-09 15:32 ` Andy Shevchenko
2022-02-10 8:32 ` Maxime Ripard
2022-02-10 8:32 ` Maxime Ripard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Yf03sCSuQwHKvgA9@smile.fi.intel.com \
--to=andriy.shevchenko@linux.intel.com \
--cc=airlied@linux.ie \
--cc=broonie@kernel.org \
--cc=daniel.vetter@ffwll.ch \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=geert@linux-m68k.org \
--cc=javierm@redhat.com \
--cc=lee.jones@linaro.org \
--cc=lgirdwood@gmail.com \
--cc=linux-fbdev@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=maxime@cerno.tech \
--cc=noralf@tronnes.org \
--cc=sam@ravnborg.org \
--cc=thierry.reding@gmail.com \
--cc=tzimmermann@suse.de \
--cc=u.kleine-koenig@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.