History

drm/gma500: Pass GPIO for Intel MID using descriptors

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.

Linus Walleij committed 6 years ago

Commit cd6a1ca1 parent 2840f1f3 files · +51 −74Browse files

Unified · Split

3 files
  1. arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c +18 −8
  2. drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c +33 −55
  3. include/linux/platform_data/tc35876x.h +0 −11
arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c+18−8
@@ -6,21 +6,31 @@ · 5 unmodified lines
66 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
77 */
88
9−#include <linux/gpio.h>
10−#include <linux/platform_data/tc35876x.h>
9+#include <linux/gpio/machine.h>
1110 #include <asm/intel-mid.h>
1211
12+static struct gpiod_lookup_table tc35876x_gpio_table = {
13+ .dev_id = "i2c_disp_brig",
14+ .table = {
15+ GPIO_LOOKUP("0000:00:0c.0", -1, "bridge-reset", GPIO_ACTIVE_HIGH),
16+ GPIO_LOOKUP("0000:00:0c.0", -1, "bl-en", GPIO_ACTIVE_HIGH),
17+ GPIO_LOOKUP("0000:00:0c.0", -1, "vadd", GPIO_ACTIVE_HIGH),
18+ { },
19+ },
20+};
21+
1322 /*tc35876x DSI_LVDS bridge chip and panel platform data*/
1423 static void *tc35876x_platform_data(void *data)
1524 {
16− static struct tc35876x_platform_data pdata;
25+ struct gpiod_lookup_table *table = &tc35876x_gpio_table;
26+ struct gpiod_lookup *lookup = table->table;
1727
18− /* gpio pins set to -1 will not be used by the driver */
19− pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN");
20− pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN");
21− pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3");
28+ lookup[0].chip_hwnum = get_gpio_by_name("LCMB_RXEN");
29+ lookup[1].chip_hwnum = get_gpio_by_name("6S6P_BL_EN");
30+ lookup[2].chip_hwnum = get_gpio_by_name("EN_VREG_LCD_V3P3");
31+ gpiod_add_lookup_table(table);
2232
23− return &pdata;
33+ return NULL;
2434 }
2535
2636 static const struct devs_id tc35876x_dev_id __initconst = {
drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c+33−55
@@ -25,7 +25,7 @@ · 24 unmodified lines
2525 #include <linux/delay.h>
2626 #include <linux/kernel.h>
2727 #include <linux/module.h>
28−#include <linux/platform_data/tc35876x.h>
28+#include <linux/gpio/consumer.h>
2929
3030 #include <asm/intel_scu_ipc.h>
3131
@@ -36,6 +36,11 @@ · 4 unmodified lines
3636
3737 static struct i2c_client *tc35876x_client;
3838 static struct i2c_client *cmi_lcd_i2c_client;
39+/* Panel GPIOs */
40+static struct gpio_desc *bridge_reset;
41+static struct gpio_desc *bridge_bl_enable;
42+static struct gpio_desc *backlight_voltage;
43+
3944
4045 #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
4146 #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) · 274 unmodified lines
316321
317322 void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)
318323 {
319− struct tc35876x_platform_data *pdata;
320−
321324 if (WARN(!tc35876x_client, "%s called before probe", __func__))
322325 return;
323326
324327 dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);
325328
326− pdata = dev_get_platdata(&tc35876x_client->dev);
327−
328− if (pdata->gpio_bridge_reset == -1)
329+ if (!bridge_reset)
329330 return;
330331
331332 if (state) {
332− gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
333+ gpiod_set_value_cansleep(bridge_reset, 0);
333334 mdelay(10);
334335 } else {
335336 /* Pull MIPI Bridge reset pin to Low */
336− gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);
337+ gpiod_set_value_cansleep(bridge_reset, 0);
337338 mdelay(20);
338339 /* Pull MIPI Bridge reset pin to High */
339− gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1);
340+ gpiod_set_value_cansleep(bridge_reset, 1);
340341 mdelay(40);
341342 }
342343 }
@@ -510,25 +511,20 @@ void tc35876x_brightness_control(struct drm_device *dev, int level) · 167 unmodified lines
510511
511512 void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)
512513 {
513− struct tc35876x_platform_data *pdata;
514−
515514 if (WARN(!tc35876x_client, "%s called before probe", __func__))
516515 return;
517516
518517 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
519518
520− pdata = dev_get_platdata(&tc35876x_client->dev);
521−
522− if (pdata->gpio_panel_bl_en != -1)
523− gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0);
519+ if (bridge_bl_enable)
520+ gpiod_set_value_cansleep(bridge_bl_enable, 0);
524521
525− if (pdata->gpio_panel_vadd != -1)
526− gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0);
522+ if (backlight_voltage)
523+ gpiod_set_value_cansleep(backlight_voltage, 0);
527524 }
528525
529526 void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
530527 {
531− struct tc35876x_platform_data *pdata;
532528 struct drm_psb_private *dev_priv = dev->dev_private;
533529
534530 if (WARN(!tc35876x_client, "%s called before probe", __func__))
@@ -536,10 +532,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) · 1 unmodified line
536532
537533 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
538534
539− pdata = dev_get_platdata(&tc35876x_client->dev);
540−
541− if (pdata->gpio_panel_vadd != -1) {
542− gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1);
535+ if (backlight_voltage) {
536+ gpiod_set_value_cansleep(backlight_voltage, 1);
543537 msleep(260);
544538 }
545539
@@ -571,8 +565,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) · 25 unmodified lines
571565 "i2c write failed (%d)\n", ret);
572566 }
573567
574− if (pdata->gpio_panel_bl_en != -1)
575− gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1);
568+ if (bridge_bl_enable)
569+ gpiod_set_value_cansleep(bridge_bl_enable, 1);
576570
577571 tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);
578572 }
@@ -635,8 +629,6 @@ static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, · 56 unmodified lines
635629 static int tc35876x_bridge_probe(struct i2c_client *client,
636630 const struct i2c_device_id *id)
637631 {
638− struct tc35876x_platform_data *pdata;
639−
640632 dev_info(&client->dev, "%s\n", __func__);
641633
642634 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -645,26 +637,23 @@ static int tc35876x_bridge_probe(struct i2c_client *client, · 2 unmodified lines
645637 return -ENODEV;
646638 }
647639
648− pdata = dev_get_platdata(&client->dev);
649− if (!pdata) {
650− dev_err(&client->dev, "%s: no platform data\n", __func__);
651− return -ENODEV;
652− }
640+ bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW);
641+ if (IS_ERR(bridge_reset))
642+ return PTR_ERR(bridge_reset);
643+ if (bridge_reset)
644+ gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset");
653645
654− if (pdata->gpio_bridge_reset != -1) {
655− gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset");
656− gpio_direction_output(pdata->gpio_bridge_reset, 0);
657− }
658−
659− if (pdata->gpio_panel_bl_en != -1) {
660− gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en");
661− gpio_direction_output(pdata->gpio_panel_bl_en, 0);
662− }
646+ bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW);
647+ if (IS_ERR(bridge_bl_enable))
648+ return PTR_ERR(bridge_bl_enable);
649+ if (bridge_bl_enable)
650+ gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en");
663651
664− if (pdata->gpio_panel_vadd != -1) {
665− gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd");
666− gpio_direction_output(pdata->gpio_panel_vadd, 0);
667− }
652+ backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW);
653+ if (IS_ERR(backlight_voltage))
654+ return PTR_ERR(backlight_voltage);
655+ if (backlight_voltage)
656+ gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd");
668657
669658 tc35876x_client = client;
670659
@@ -673,19 +662,8 @@ static int tc35876x_bridge_probe(struct i2c_client *client, · 2 unmodified lines
673662
674663 static int tc35876x_bridge_remove(struct i2c_client *client)
675664 {
676− struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev);
677−
678665 dev_dbg(&client->dev, "%s\n", __func__);
679666
680− if (pdata->gpio_bridge_reset != -1)
681− gpio_free(pdata->gpio_bridge_reset);
682−
683− if (pdata->gpio_panel_bl_en != -1)
684− gpio_free(pdata->gpio_panel_bl_en);
685−
686− if (pdata->gpio_panel_vadd != -1)
687− gpio_free(pdata->gpio_panel_vadd);
688−
689667 tc35876x_client = NULL;
690668
691669 return 0;
include/linux/platform_data/tc35876x.h+0−11
@@ -1,11 +0,0 @@
1−
2−#ifndef _TC35876X_H
3−#define _TC35876X_H
4−
5−struct tc35876x_platform_data {
6− int gpio_bridge_reset;
7− int gpio_panel_bl_en;
8− int gpio_panel_vadd;
9−};
10−
11−#endif /* _TC35876X_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t