mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	video: atmel_lcdfb: add device tree suport
get display timings from device tree Use videomode helpers to get display timings and configurations from device tree Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
This commit is contained in:
		
							parent
							
								
									ce3b64f5f1
								
							
						
					
					
						commit
						b985172b32
					
				
					 3 changed files with 291 additions and 32 deletions
				
			
		
							
								
								
									
										75
									
								
								Documentation/devicetree/bindings/video/atmel,lcdc.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Documentation/devicetree/bindings/video/atmel,lcdc.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,75 @@
 | 
			
		|||
Atmel LCDC Framebuffer
 | 
			
		||||
-----------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Required properties:
 | 
			
		||||
- compatible :
 | 
			
		||||
	"atmel,at91sam9261-lcdc" , 
 | 
			
		||||
	"atmel,at91sam9263-lcdc" ,
 | 
			
		||||
	"atmel,at91sam9g10-lcdc" ,
 | 
			
		||||
	"atmel,at91sam9g45-lcdc" ,
 | 
			
		||||
	"atmel,at91sam9g45es-lcdc" ,
 | 
			
		||||
	"atmel,at91sam9rl-lcdc" ,
 | 
			
		||||
	"atmel,at32ap-lcdc"
 | 
			
		||||
- reg : Should contain 1 register ranges(address and length)
 | 
			
		||||
- interrupts : framebuffer controller interrupt
 | 
			
		||||
- display: a phandle pointing to the display node
 | 
			
		||||
 | 
			
		||||
Required nodes:
 | 
			
		||||
- display: a display node is required to initialize the lcd panel
 | 
			
		||||
	This should be in the board dts.
 | 
			
		||||
- default-mode: a videomode within the display with timing parameters
 | 
			
		||||
	as specified below.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
	fb0: fb@0x00500000 {
 | 
			
		||||
		compatible = "atmel,at91sam9g45-lcdc";
 | 
			
		||||
		reg = <0x00500000 0x1000>;
 | 
			
		||||
		interrupts = <23 3 0>;
 | 
			
		||||
		pinctrl-names = "default";
 | 
			
		||||
		pinctrl-0 = <&pinctrl_fb>;
 | 
			
		||||
		display = <&display0>;
 | 
			
		||||
		status = "okay";
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
Atmel LCDC Display
 | 
			
		||||
-----------------------------------------------------
 | 
			
		||||
Required properties (as per of_videomode_helper):
 | 
			
		||||
 | 
			
		||||
 - atmel,dmacon: dma controler configuration
 | 
			
		||||
 - atmel,lcdcon2: lcd controler configuration
 | 
			
		||||
 - atmel,guard-time: lcd guard time (Delay in frame periods)
 | 
			
		||||
 - bits-per-pixel: lcd panel bit-depth.
 | 
			
		||||
 | 
			
		||||
Optional properties (as per of_videomode_helper):
 | 
			
		||||
 - atmel,lcdcon-backlight: enable backlight
 | 
			
		||||
 - atmel,lcd-wiring-mode: lcd wiring mode "RGB" or "BRG"
 | 
			
		||||
 - atmel,power-control-gpio: gpio to power on or off the LCD (as many as needed)
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
	display0: display {
 | 
			
		||||
		bits-per-pixel = <32>;
 | 
			
		||||
		atmel,lcdcon-backlight;
 | 
			
		||||
		atmel,dmacon = <0x1>;
 | 
			
		||||
		atmel,lcdcon2 = <0x80008002>;
 | 
			
		||||
		atmel,guard-time = <9>;
 | 
			
		||||
		atmel,lcd-wiring-mode = <1>;
 | 
			
		||||
 | 
			
		||||
		display-timings {
 | 
			
		||||
			native-mode = <&timing0>;
 | 
			
		||||
			timing0: timing0 {
 | 
			
		||||
				clock-frequency = <9000000>;
 | 
			
		||||
				hactive = <480>;
 | 
			
		||||
				vactive = <272>;
 | 
			
		||||
				hback-porch = <1>;
 | 
			
		||||
				hfront-porch = <1>;
 | 
			
		||||
				vback-porch = <40>;
 | 
			
		||||
				vfront-porch = <1>;
 | 
			
		||||
				hsync-len = <45>;
 | 
			
		||||
				vsync-len = <1>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -996,6 +996,8 @@ config FB_ATMEL
 | 
			
		|||
	select FB_CFB_FILLRECT
 | 
			
		||||
	select FB_CFB_COPYAREA
 | 
			
		||||
	select FB_CFB_IMAGEBLIT
 | 
			
		||||
	select FB_MODE_HELPERS
 | 
			
		||||
	select VIDEOMODE_HELPERS
 | 
			
		||||
	help
 | 
			
		||||
	  This enables support for the AT91/AT32 LCD Controller.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,11 @@
 | 
			
		|||
#include <linux/gfp.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
#include <linux/platform_data/atmel.h>
 | 
			
		||||
#include <linux/of.h>
 | 
			
		||||
#include <linux/of_device.h>
 | 
			
		||||
#include <linux/of_gpio.h>
 | 
			
		||||
#include <video/of_display_timing.h>
 | 
			
		||||
#include <video/videomode.h>
 | 
			
		||||
 | 
			
		||||
#include <mach/cpu.h>
 | 
			
		||||
#include <asm/gpio.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +62,13 @@ struct atmel_lcdfb_info {
 | 
			
		|||
	struct atmel_lcdfb_config *config;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct atmel_lcdfb_power_ctrl_gpio {
 | 
			
		||||
	int gpio;
 | 
			
		||||
	int active_low;
 | 
			
		||||
 | 
			
		||||
	struct list_head list;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define lcdc_readl(sinfo, reg)		__raw_readl((sinfo)->mmio+(reg))
 | 
			
		||||
#define lcdc_writel(sinfo, reg, val)	__raw_writel((val), (sinfo)->mmio+(reg))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -953,16 +964,187 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
 | 
			
		|||
	clk_disable_unprepare(sinfo->lcdc_clk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_OF
 | 
			
		||||
static const struct of_device_id atmel_lcdfb_dt_ids[] = {
 | 
			
		||||
	{ .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, },
 | 
			
		||||
	{ .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, },
 | 
			
		||||
	{ .compatible = "atmel,at91sam9g10-lcdc" , .data = &at91sam9g10_config, },
 | 
			
		||||
	{ .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, },
 | 
			
		||||
	{ .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, },
 | 
			
		||||
	{ .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, },
 | 
			
		||||
	{ .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, },
 | 
			
		||||
	{ /* sentinel */ }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_DEVICE_TABLE(of, atmel_lcdfb_dt_ids);
 | 
			
		||||
 | 
			
		||||
static const char *atmel_lcdfb_wiring_modes[] = {
 | 
			
		||||
	[ATMEL_LCDC_WIRING_BGR]	= "BRG",
 | 
			
		||||
	[ATMEL_LCDC_WIRING_RGB]	= "RGB",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const int atmel_lcdfb_get_of_wiring_modes(struct device_node *np)
 | 
			
		||||
{
 | 
			
		||||
	const char *mode;
 | 
			
		||||
	int err, i;
 | 
			
		||||
 | 
			
		||||
	err = of_property_read_string(np, "atmel,lcd-wiring-mode", &mode);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		return ATMEL_LCDC_WIRING_BGR;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(atmel_lcdfb_wiring_modes); i++)
 | 
			
		||||
		if (!strcasecmp(mode, atmel_lcdfb_wiring_modes[i]))
 | 
			
		||||
			return i;
 | 
			
		||||
 | 
			
		||||
	return -ENODEV;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void atmel_lcdfb_power_control_gpio(struct atmel_lcdfb_pdata *pdata, int on)
 | 
			
		||||
{
 | 
			
		||||
	struct atmel_lcdfb_power_ctrl_gpio *og;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry(og, &pdata->pwr_gpios, list)
 | 
			
		||||
		gpio_set_value(og->gpio, on);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 | 
			
		||||
{
 | 
			
		||||
	struct fb_info *info = sinfo->info;
 | 
			
		||||
	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
 | 
			
		||||
	struct fb_var_screeninfo *var = &info->var;
 | 
			
		||||
	struct device *dev = &sinfo->pdev->dev;
 | 
			
		||||
	struct device_node *np =dev->of_node;
 | 
			
		||||
	struct device_node *display_np;
 | 
			
		||||
	struct device_node *timings_np;
 | 
			
		||||
	struct display_timings *timings;
 | 
			
		||||
	enum of_gpio_flags flags;
 | 
			
		||||
	struct atmel_lcdfb_power_ctrl_gpio *og;
 | 
			
		||||
	bool is_gpio_power = false;
 | 
			
		||||
	int ret = -ENOENT;
 | 
			
		||||
	int i, gpio;
 | 
			
		||||
 | 
			
		||||
	sinfo->config = (struct atmel_lcdfb_config*)
 | 
			
		||||
		of_match_device(atmel_lcdfb_dt_ids, dev)->data;
 | 
			
		||||
 | 
			
		||||
	display_np = of_parse_phandle(np, "display", 0);
 | 
			
		||||
	if (!display_np) {
 | 
			
		||||
		dev_err(dev, "failed to find display phandle\n");
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = of_property_read_u32(display_np, "bits-per-pixel", &var->bits_per_pixel);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "failed to get property bits-per-pixel\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = of_property_read_u32(display_np, "atmel,guard-time", &pdata->guard_time);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "failed to get property atmel,guard-time\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = of_property_read_u32(display_np, "atmel,lcdcon2", &pdata->default_lcdcon2);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "failed to get property atmel,lcdcon2\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = of_property_read_u32(display_np, "atmel,dmacon", &pdata->default_dmacon);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "failed to get property bits-per-pixel\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = -ENOMEM;
 | 
			
		||||
	for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) {
 | 
			
		||||
		gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio",
 | 
			
		||||
					       i, &flags);
 | 
			
		||||
		if (gpio < 0)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		og = devm_kzalloc(dev, sizeof(*og), GFP_KERNEL);
 | 
			
		||||
		if (!og)
 | 
			
		||||
			goto put_display_node;
 | 
			
		||||
 | 
			
		||||
		og->gpio = gpio;
 | 
			
		||||
		og->active_low = flags & OF_GPIO_ACTIVE_LOW;
 | 
			
		||||
		is_gpio_power = true;
 | 
			
		||||
		ret = devm_gpio_request(dev, gpio, "lcd-power-control-gpio");
 | 
			
		||||
		if (ret) {
 | 
			
		||||
			dev_err(dev, "request gpio %d failed\n", gpio);
 | 
			
		||||
			goto put_display_node;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret = gpio_direction_output(gpio, og->active_low);
 | 
			
		||||
		if (ret) {
 | 
			
		||||
			dev_err(dev, "set direction output gpio %d failed\n", gpio);
 | 
			
		||||
			goto put_display_node;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (is_gpio_power)
 | 
			
		||||
		pdata->atmel_lcdfb_power_control = atmel_lcdfb_power_control_gpio;
 | 
			
		||||
 | 
			
		||||
	ret = atmel_lcdfb_get_of_wiring_modes(display_np);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "invalid atmel,lcd-wiring-mode\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
	pdata->lcd_wiring_mode = ret;
 | 
			
		||||
 | 
			
		||||
	pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
 | 
			
		||||
 | 
			
		||||
	timings = of_get_display_timings(display_np);
 | 
			
		||||
	if (!timings) {
 | 
			
		||||
		dev_err(dev, "failed to get display timings\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	timings_np = of_find_node_by_name(display_np, "display-timings");
 | 
			
		||||
	if (!timings_np) {
 | 
			
		||||
		dev_err(dev, "failed to find display-timings node\n");
 | 
			
		||||
		goto put_display_node;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < of_get_child_count(timings_np); i++) {
 | 
			
		||||
		struct videomode vm;
 | 
			
		||||
		struct fb_videomode fb_vm;
 | 
			
		||||
 | 
			
		||||
		ret = videomode_from_timings(timings, &vm, i);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			goto put_timings_node;
 | 
			
		||||
		ret = fb_videomode_from_videomode(&vm, &fb_vm);
 | 
			
		||||
		if (ret < 0)
 | 
			
		||||
			goto put_timings_node;
 | 
			
		||||
 | 
			
		||||
		fb_add_videomode(&fb_vm, &info->modelist);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
put_timings_node:
 | 
			
		||||
	of_node_put(timings_np);
 | 
			
		||||
put_display_node:
 | 
			
		||||
	of_node_put(display_np);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		||||
{
 | 
			
		||||
	struct device *dev = &pdev->dev;
 | 
			
		||||
	struct fb_info *info;
 | 
			
		||||
	struct atmel_lcdfb_info *sinfo;
 | 
			
		||||
	struct atmel_lcdfb_pdata *pdata;
 | 
			
		||||
	struct fb_videomode fbmode;
 | 
			
		||||
	struct atmel_lcdfb_pdata *pdata = NULL;
 | 
			
		||||
	struct resource *regs = NULL;
 | 
			
		||||
	struct resource *map = NULL;
 | 
			
		||||
	struct fb_modelist *modelist;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	dev_dbg(dev, "%s BEGIN\n", __func__);
 | 
			
		||||
| 
						 | 
				
			
			@ -975,17 +1157,35 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	sinfo = info->par;
 | 
			
		||||
	sinfo->pdev = pdev;
 | 
			
		||||
	sinfo->info = info;
 | 
			
		||||
 | 
			
		||||
	INIT_LIST_HEAD(&info->modelist);
 | 
			
		||||
 | 
			
		||||
	if (pdev->dev.of_node) {
 | 
			
		||||
		ret = atmel_lcdfb_of_init(sinfo);
 | 
			
		||||
		if (ret)
 | 
			
		||||
			goto free_info;
 | 
			
		||||
	} else if (dev_get_platdata(dev)) {
 | 
			
		||||
		struct fb_monspecs *monspecs;
 | 
			
		||||
		int i;
 | 
			
		||||
 | 
			
		||||
	if (dev_get_platdata(dev)) {
 | 
			
		||||
		pdata = dev_get_platdata(dev);
 | 
			
		||||
		monspecs = pdata->default_monspecs;
 | 
			
		||||
		sinfo->pdata = *pdata;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < monspecs->modedb_len; i++)
 | 
			
		||||
			fb_add_videomode(&monspecs->modedb[i], &info->modelist);
 | 
			
		||||
 | 
			
		||||
		sinfo->config = atmel_lcdfb_get_config(pdev);
 | 
			
		||||
 | 
			
		||||
		info->var.bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
 | 
			
		||||
		memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs));
 | 
			
		||||
	} else {
 | 
			
		||||
		dev_err(dev, "cannot get default configuration\n");
 | 
			
		||||
		goto free_info;
 | 
			
		||||
	}
 | 
			
		||||
	sinfo->info = info;
 | 
			
		||||
	sinfo->pdev = pdev;
 | 
			
		||||
	sinfo->config = atmel_lcdfb_get_config(pdev);
 | 
			
		||||
 | 
			
		||||
	if (!sinfo->config)
 | 
			
		||||
		goto free_info;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -994,7 +1194,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
	info->pseudo_palette = sinfo->pseudo_palette;
 | 
			
		||||
	info->fbops = &atmel_lcdfb_ops;
 | 
			
		||||
 | 
			
		||||
	memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs));
 | 
			
		||||
	info->fix = atmel_lcdfb_fix;
 | 
			
		||||
 | 
			
		||||
	/* Enable LCDC Clocks */
 | 
			
		||||
| 
						 | 
				
			
			@ -1010,14 +1209,11 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
	}
 | 
			
		||||
	atmel_lcdfb_start_clock(sinfo);
 | 
			
		||||
 | 
			
		||||
	ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
 | 
			
		||||
			info->monspecs.modedb_len, info->monspecs.modedb,
 | 
			
		||||
			pdata->default_bpp);
 | 
			
		||||
	if (!ret) {
 | 
			
		||||
		dev_err(dev, "no suitable video mode found\n");
 | 
			
		||||
		goto stop_clk;
 | 
			
		||||
	}
 | 
			
		||||
	modelist = list_first_entry(&info->modelist,
 | 
			
		||||
			struct fb_modelist, list);
 | 
			
		||||
	fb_videomode_to_var(&info->var, &modelist->mode);
 | 
			
		||||
 | 
			
		||||
	atmel_lcdfb_check_var(&info->var, info);
 | 
			
		||||
 | 
			
		||||
	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 | 
			
		||||
	if (!regs) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1101,18 +1297,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
		goto unregister_irqs;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * This makes sure that our colour bitfield
 | 
			
		||||
	 * descriptors are correctly initialised.
 | 
			
		||||
	 */
 | 
			
		||||
	atmel_lcdfb_check_var(&info->var, info);
 | 
			
		||||
 | 
			
		||||
	ret = fb_set_var(info, &info->var);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		dev_warn(dev, "unable to set display parameters\n");
 | 
			
		||||
		goto free_cmap;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dev_set_drvdata(dev, info);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,13 +1305,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
	ret = register_framebuffer(info);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		dev_err(dev, "failed to register framebuffer device: %d\n", ret);
 | 
			
		||||
		goto free_cmap;
 | 
			
		||||
		goto reset_drvdata;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* add selected videomode to modelist */
 | 
			
		||||
	fb_var_to_videomode(&fbmode, &info->var);
 | 
			
		||||
	fb_add_videomode(&fbmode, &info->modelist);
 | 
			
		||||
 | 
			
		||||
	/* Power up the LCDC screen */
 | 
			
		||||
	atmel_lcdfb_power_control(sinfo, 1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1136,7 +1316,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
 | 
			
		|||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
free_cmap:
 | 
			
		||||
reset_drvdata:
 | 
			
		||||
	dev_set_drvdata(dev, NULL);
 | 
			
		||||
	fb_dealloc_cmap(&info->cmap);
 | 
			
		||||
unregister_irqs:
 | 
			
		||||
	cancel_work_sync(&sinfo->task);
 | 
			
		||||
| 
						 | 
				
			
			@ -1254,6 +1435,7 @@ static struct platform_driver atmel_lcdfb_driver = {
 | 
			
		|||
	.driver		= {
 | 
			
		||||
		.name	= "atmel_lcdfb",
 | 
			
		||||
		.owner	= THIS_MODULE,
 | 
			
		||||
		.of_match_table	= of_match_ptr(atmel_lcdfb_dt_ids),
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue