[PATCH] drm/gma500: Pass GPIO for Intel MID using descriptors

Andy Shevchenko andriy.shevchenko at linux.intel.com
Sun Dec 8 10:20:35 UTC 2019


On Fri, Dec 06, 2019 at 10:43:01AM +0100, Linus Walleij wrote:
> The GMA500 driver is using the legacy GPIO API to fetch
> three optional display control GPIO lines from the SFI
> description used by the Medfield platform.
> 
> Switch this over to use GPIO descriptors and delete the
> custom platform data.
> 
> We create three new static locals in the tc35876x bridge
> code but it is hardly any worse than the I2C client static
> local already there: I tried first to move it to the DRM
> driver state container but there are workarounds for
> probe order in the code so I just stayed off it, as the
> result is unpredictable.
> 
> People wanting to do a more throrugh and proper cleanup
> of the GMA500 driver can work on top of this, I can't
> solve much more since I don't have access to the hardware,
> I can only attempt to tidy up my GPIO corner.

What a nice clean up!
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>

> 
> Cc: Patrik Jakobsson <patrik.r.jakobsson at gmail.com>
> Cc: Daniel Stone <daniels at collabora.com>
> Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
> Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> If someone can test this on the target platform I'd be
> happy.
> ---
>  .../intel-mid/device_libs/platform_tc35876x.c | 26 ++++--
>  drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c    | 88 +++++++------------
>  include/linux/platform_data/tc35876x.h        | 11 ---
>  3 files changed, 51 insertions(+), 74 deletions(-)
>  delete mode 100644 include/linux/platform_data/tc35876x.h
> 
> diff --git a/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c
> index 44d1f884c3d3..139738bbdd36 100644
> --- a/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c
> +++ b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c
> @@ -6,21 +6,31 @@
>   * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy at intel.com>
>   */
>  
> -#include <linux/gpio.h>
> -#include <linux/platform_data/tc35876x.h>
> +#include <linux/gpio/machine.h>
>  #include <asm/intel-mid.h>
>  
> +static struct gpiod_lookup_table tc35876x_gpio_table = {
> +	.dev_id	= "i2c_disp_brig",
> +	.table	= {
> +		GPIO_LOOKUP("0000:00:0c.0", -1, "bridge-reset", GPIO_ACTIVE_HIGH),
> +		GPIO_LOOKUP("0000:00:0c.0", -1, "bl-en", GPIO_ACTIVE_HIGH),
> +		GPIO_LOOKUP("0000:00:0c.0", -1, "vadd", GPIO_ACTIVE_HIGH),
> +		{ },
> +	},
> +};
> +
>  /*tc35876x DSI_LVDS bridge chip and panel platform data*/
>  static void *tc35876x_platform_data(void *data)
>  {
> -	static struct tc35876x_platform_data pdata;
> +	struct gpiod_lookup_table *table = &tc35876x_gpio_table;
> +	struct gpiod_lookup *lookup = table->table;
>  
> -	/* gpio pins set to -1 will not be used by the driver */
> -	pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN");
> -	pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN");
> -	pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3");
> +	lookup[0].chip_hwnum = get_gpio_by_name("LCMB_RXEN");
> +	lookup[1].chip_hwnum = get_gpio_by_name("6S6P_BL_EN");
> +	lookup[2].chip_hwnum = get_gpio_by_name("EN_VREG_LCD_V3P3");
> +	gpiod_add_lookup_table(table);
>  
> -	return &pdata;
> +	return NULL;
>  }
>  
>  static const struct devs_id tc35876x_dev_id __initconst = {
> diff --git a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
> index 7de3ce637c7f..9e8224456ea2 100644
> --- a/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
> +++ b/drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c
> @@ -25,7 +25,7 @@
>  #include <linux/delay.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/platform_data/tc35876x.h>
> +#include <linux/gpio/consumer.h>
>  
>  #include <asm/intel_scu_ipc.h>
>  
> @@ -36,6 +36,11 @@
>  
>  static struct i2c_client *tc35876x_client;
>  static struct i2c_client *cmi_lcd_i2c_client;
> +/* Panel GPIOs */
> +static struct gpio_desc *bridge_reset;
> +static struct gpio_desc *bridge_bl_enable;
> +static struct gpio_desc *backlight_voltage;
> +
>  
>  #define FLD_MASK(start, end)	(((1 << ((start) - (end) + 1)) - 1) << (end))
>  #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
> @@ -316,27 +321,23 @@ static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value)
>  
>  void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)
>  {
> -	struct tc35876x_platform_data *pdata;
> -
>  	if (WARN(!tc35876x_client, "%s called before probe", __func__))
>  		return;
>  
>  	dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);
>  
> -	pdata = dev_get_platdata(&tc35876x_client->dev);
> -
> -	if (pdata->gpio_bridge_reset == -1)
> +	if (!bridge_reset)
>  		return;
>  
>  	if (state) {
> -		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
> +		gpiod_set_value_cansleep(bridge_reset, 0);
>  		mdelay(10);
>  	} else {
>  		/* Pull MIPI Bridge reset pin to Low */
> -		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
> +		gpiod_set_value_cansleep(bridge_reset, 0);
>  		mdelay(20);
>  		/* Pull MIPI Bridge reset pin to High */
> -		gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1);
> +		gpiod_set_value_cansleep(bridge_reset, 1);
>  		mdelay(40);
>  	}
>  }
> @@ -510,25 +511,20 @@ void tc35876x_brightness_control(struct drm_device *dev, int level)
>  
>  void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)
>  {
> -	struct tc35876x_platform_data *pdata;
> -
>  	if (WARN(!tc35876x_client, "%s called before probe", __func__))
>  		return;
>  
>  	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
>  
> -	pdata = dev_get_platdata(&tc35876x_client->dev);
> -
> -	if (pdata->gpio_panel_bl_en != -1)
> -		gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0);
> +	if (bridge_bl_enable)
> +		gpiod_set_value_cansleep(bridge_bl_enable, 0);
>  
> -	if (pdata->gpio_panel_vadd != -1)
> -		gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0);
> +	if (backlight_voltage)
> +		gpiod_set_value_cansleep(backlight_voltage, 0);
>  }
>  
>  void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
>  {
> -	struct tc35876x_platform_data *pdata;
>  	struct drm_psb_private *dev_priv = dev->dev_private;
>  
>  	if (WARN(!tc35876x_client, "%s called before probe", __func__))
> @@ -536,10 +532,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
>  
>  	dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
>  
> -	pdata = dev_get_platdata(&tc35876x_client->dev);
> -
> -	if (pdata->gpio_panel_vadd != -1) {
> -		gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1);
> +	if (backlight_voltage) {
> +		gpiod_set_value_cansleep(backlight_voltage, 1);
>  		msleep(260);
>  	}
>  
> @@ -571,8 +565,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
>  				"i2c write failed (%d)\n", ret);
>  	}
>  
> -	if (pdata->gpio_panel_bl_en != -1)
> -		gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1);
> +	if (bridge_bl_enable)
> +		gpiod_set_value_cansleep(bridge_bl_enable, 1);
>  
>  	tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);
>  }
> @@ -635,8 +629,6 @@ static int tc35876x_get_panel_info(struct drm_device *dev, int pipe,
>  static int tc35876x_bridge_probe(struct i2c_client *client,
>  				const struct i2c_device_id *id)
>  {
> -	struct tc35876x_platform_data *pdata;
> -
>  	dev_info(&client->dev, "%s\n", __func__);
>  
>  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> @@ -645,26 +637,23 @@ static int tc35876x_bridge_probe(struct i2c_client *client,
>  		return -ENODEV;
>  	}
>  
> -	pdata = dev_get_platdata(&client->dev);
> -	if (!pdata) {
> -		dev_err(&client->dev, "%s: no platform data\n", __func__);
> -		return -ENODEV;
> -	}
> +	bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(bridge_reset))
> +		return PTR_ERR(bridge_reset);
> +	if (bridge_reset)
> +		gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset");
>  
> -	if (pdata->gpio_bridge_reset != -1) {
> -		gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset");
> -		gpio_direction_output(pdata->gpio_bridge_reset, 0);
> -	}
> -
> -	if (pdata->gpio_panel_bl_en != -1) {
> -		gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en");
> -		gpio_direction_output(pdata->gpio_panel_bl_en, 0);
> -	}
> +	bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW);
> +	if (IS_ERR(bridge_bl_enable))
> +		return PTR_ERR(bridge_bl_enable);
> +	if (bridge_bl_enable)
> +		gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en");
>  
> -	if (pdata->gpio_panel_vadd != -1) {
> -		gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd");
> -		gpio_direction_output(pdata->gpio_panel_vadd, 0);
> -	}
> +	backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW);
> +	if (IS_ERR(backlight_voltage))
> +		return PTR_ERR(backlight_voltage);
> +	if (backlight_voltage)
> +		gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd");
>  
>  	tc35876x_client = client;
>  
> @@ -673,19 +662,8 @@ static int tc35876x_bridge_probe(struct i2c_client *client,
>  
>  static int tc35876x_bridge_remove(struct i2c_client *client)
>  {
> -	struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev);
> -
>  	dev_dbg(&client->dev, "%s\n", __func__);
>  
> -	if (pdata->gpio_bridge_reset != -1)
> -		gpio_free(pdata->gpio_bridge_reset);
> -
> -	if (pdata->gpio_panel_bl_en != -1)
> -		gpio_free(pdata->gpio_panel_bl_en);
> -
> -	if (pdata->gpio_panel_vadd != -1)
> -		gpio_free(pdata->gpio_panel_vadd);
> -
>  	tc35876x_client = NULL;
>  
>  	return 0;
> diff --git a/include/linux/platform_data/tc35876x.h b/include/linux/platform_data/tc35876x.h
> deleted file mode 100644
> index cd6a51c71e7e..000000000000
> --- a/include/linux/platform_data/tc35876x.h
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -
> -#ifndef _TC35876X_H
> -#define _TC35876X_H
> -
> -struct tc35876x_platform_data {
> -	int gpio_bridge_reset;
> -	int gpio_panel_bl_en;
> -	int gpio_panel_vadd;
> -};
> -
> -#endif /* _TC35876X_H */
> -- 
> 2.23.0
> 

-- 
With Best Regards,
Andy Shevchenko




More information about the dri-devel mailing list