diff options
Diffstat (limited to 'drivers/video/backlight/gpio_backlight.c')
| -rw-r--r-- | drivers/video/backlight/gpio_backlight.c | 76 | 
1 files changed, 57 insertions, 19 deletions
diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 5fa217f9f44..1cea68848f1 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -13,6 +13,8 @@  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <linux/platform_data/gpio_backlight.h>  #include <linux/platform_device.h>  #include <linux/slab.h> @@ -23,6 +25,7 @@ struct gpio_backlight {  	int gpio;  	int active; +	int def_value;  };  static int gpio_backlight_update_status(struct backlight_device *bl) @@ -35,7 +38,8 @@ static int gpio_backlight_update_status(struct backlight_device *bl)  	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))  		brightness = 0; -	gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active); +	gpio_set_value_cansleep(gbl->gpio, +				brightness ? gbl->active : !gbl->active);  	return 0;  } @@ -60,16 +64,42 @@ static const struct backlight_ops gpio_backlight_ops = {  	.check_fb	= gpio_backlight_check_fb,  }; +static int gpio_backlight_probe_dt(struct platform_device *pdev, +				   struct gpio_backlight *gbl) +{ +	struct device_node *np = pdev->dev.of_node; +	enum of_gpio_flags gpio_flags; + +	gbl->gpio = of_get_gpio_flags(np, 0, &gpio_flags); + +	if (!gpio_is_valid(gbl->gpio)) { +		if (gbl->gpio != -EPROBE_DEFER) { +			dev_err(&pdev->dev, +				"Error: The gpios parameter is missing or invalid.\n"); +		} +		return gbl->gpio; +	} + +	gbl->active = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + +	gbl->def_value = of_property_read_bool(np, "default-on"); + +	return 0; +} +  static int gpio_backlight_probe(struct platform_device *pdev)  { -	struct gpio_backlight_platform_data *pdata = pdev->dev.platform_data; +	struct gpio_backlight_platform_data *pdata = +		dev_get_platdata(&pdev->dev);  	struct backlight_properties props;  	struct backlight_device *bl;  	struct gpio_backlight *gbl; +	struct device_node *np = pdev->dev.of_node;  	int ret; -	if (!pdata) { -		dev_err(&pdev->dev, "failed to find platform data\n"); +	if (!pdata && !np) { +		dev_err(&pdev->dev, +			"failed to find platform data or device tree node.\n");  		return -ENODEV;  	} @@ -78,14 +108,22 @@ static int gpio_backlight_probe(struct platform_device *pdev)  		return -ENOMEM;  	gbl->dev = &pdev->dev; -	gbl->fbdev = pdata->fbdev; -	gbl->gpio = pdata->gpio; -	gbl->active = pdata->active_low ? 0 : 1; + +	if (np) { +		ret = gpio_backlight_probe_dt(pdev, gbl); +		if (ret) +			return ret; +	} else { +		gbl->fbdev = pdata->fbdev; +		gbl->gpio = pdata->gpio; +		gbl->active = pdata->active_low ? 0 : 1; +		gbl->def_value = pdata->def_value; +	}  	ret = devm_gpio_request_one(gbl->dev, gbl->gpio, GPIOF_DIR_OUT |  				    (gbl->active ? GPIOF_INIT_LOW  						 : GPIOF_INIT_HIGH), -				    pdata->name); +				    pdata ? pdata->name : "backlight");  	if (ret < 0) {  		dev_err(&pdev->dev, "unable to request GPIO\n");  		return ret; @@ -94,35 +132,35 @@ static int gpio_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = 1; -	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, gbl, -				       &gpio_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev), +					&pdev->dev, gbl, &gpio_backlight_ops, +					&props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl);  	} -	bl->props.brightness = pdata->def_value; +	bl->props.brightness = gbl->def_value;  	backlight_update_status(bl);  	platform_set_drvdata(pdev, bl);  	return 0;  } -static int gpio_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0; -} +#ifdef CONFIG_OF +static struct of_device_id gpio_backlight_of_match[] = { +	{ .compatible = "gpio-backlight" }, +	{ /* sentinel */ } +}; +#endif  static struct platform_driver gpio_backlight_driver = {  	.driver		= {  		.name		= "gpio-backlight",  		.owner		= THIS_MODULE, +		.of_match_table = of_match_ptr(gpio_backlight_of_match),  	},  	.probe		= gpio_backlight_probe, -	.remove		= gpio_backlight_remove,  };  module_platform_driver(gpio_backlight_driver);  | 
