diff options
| -rw-r--r-- | drivers/video/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/video/sh_mobile_lcdcfb.c | 170 | ||||
| -rw-r--r-- | include/video/sh_mobile_lcdc.h | 1 |
3 files changed, 150 insertions, 22 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dd483bfe3951..d0c821992a99 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
| @@ -1893,6 +1893,7 @@ config FB_SH_MOBILE_LCDC | |||
| 1893 | select FB_SYS_COPYAREA | 1893 | select FB_SYS_COPYAREA |
| 1894 | select FB_SYS_IMAGEBLIT | 1894 | select FB_SYS_IMAGEBLIT |
| 1895 | select FB_SYS_FOPS | 1895 | select FB_SYS_FOPS |
| 1896 | select FB_DEFERRED_IO | ||
| 1896 | ---help--- | 1897 | ---help--- |
| 1897 | Frame buffer driver for the on-chip SH-Mobile LCD controller. | 1898 | Frame buffer driver for the on-chip SH-Mobile LCD controller. |
| 1898 | 1899 | ||
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e339d829183c..0e2b8fd24df1 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
| @@ -16,7 +16,9 @@ | |||
| 16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
| 17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
| 19 | #include <linux/interrupt.h> | ||
| 19 | #include <video/sh_mobile_lcdc.h> | 20 | #include <video/sh_mobile_lcdc.h> |
| 21 | #include <asm/atomic.h> | ||
| 20 | 22 | ||
| 21 | #define PALETTE_NR 16 | 23 | #define PALETTE_NR 16 |
| 22 | 24 | ||
| @@ -30,11 +32,14 @@ struct sh_mobile_lcdc_chan { | |||
| 30 | u32 pseudo_palette[PALETTE_NR]; | 32 | u32 pseudo_palette[PALETTE_NR]; |
| 31 | struct fb_info info; | 33 | struct fb_info info; |
| 32 | dma_addr_t dma_handle; | 34 | dma_addr_t dma_handle; |
| 35 | struct fb_deferred_io defio; | ||
| 33 | }; | 36 | }; |
| 34 | 37 | ||
| 35 | struct sh_mobile_lcdc_priv { | 38 | struct sh_mobile_lcdc_priv { |
| 36 | void __iomem *base; | 39 | void __iomem *base; |
| 40 | int irq; | ||
| 37 | #ifdef CONFIG_HAVE_CLK | 41 | #ifdef CONFIG_HAVE_CLK |
| 42 | atomic_t clk_usecnt; | ||
| 38 | struct clk *dot_clk; | 43 | struct clk *dot_clk; |
| 39 | struct clk *clk; | 44 | struct clk *clk; |
| 40 | #endif | 45 | #endif |
| @@ -57,7 +62,7 @@ struct sh_mobile_lcdc_priv { | |||
| 57 | 62 | ||
| 58 | /* per-channel registers */ | 63 | /* per-channel registers */ |
| 59 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, | 64 | enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R, |
| 60 | LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; | 65 | LDSM2R, LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR }; |
| 61 | 66 | ||
| 62 | static unsigned long lcdc_offs_mainlcd[] = { | 67 | static unsigned long lcdc_offs_mainlcd[] = { |
| 63 | [LDDCKPAT1R] = 0x400, | 68 | [LDDCKPAT1R] = 0x400, |
| @@ -67,6 +72,7 @@ static unsigned long lcdc_offs_mainlcd[] = { | |||
| 67 | [LDMT3R] = 0x420, | 72 | [LDMT3R] = 0x420, |
| 68 | [LDDFR] = 0x424, | 73 | [LDDFR] = 0x424, |
| 69 | [LDSM1R] = 0x428, | 74 | [LDSM1R] = 0x428, |
| 75 | [LDSM2R] = 0x42c, | ||
| 70 | [LDSA1R] = 0x430, | 76 | [LDSA1R] = 0x430, |
| 71 | [LDMLSR] = 0x438, | 77 | [LDMLSR] = 0x438, |
| 72 | [LDHCNR] = 0x448, | 78 | [LDHCNR] = 0x448, |
| @@ -84,6 +90,7 @@ static unsigned long lcdc_offs_sublcd[] = { | |||
| 84 | [LDMT3R] = 0x608, | 90 | [LDMT3R] = 0x608, |
| 85 | [LDDFR] = 0x60c, | 91 | [LDDFR] = 0x60c, |
| 86 | [LDSM1R] = 0x610, | 92 | [LDSM1R] = 0x610, |
| 93 | [LDSM2R] = 0x614, | ||
| 87 | [LDSA1R] = 0x618, | 94 | [LDSA1R] = 0x618, |
| 88 | [LDMLSR] = 0x620, | 95 | [LDMLSR] = 0x620, |
| 89 | [LDHCNR] = 0x624, | 96 | [LDHCNR] = 0x624, |
| @@ -97,6 +104,8 @@ static unsigned long lcdc_offs_sublcd[] = { | |||
| 97 | #define LCDC_RESET 0x00000100 | 104 | #define LCDC_RESET 0x00000100 |
| 98 | #define DISPLAY_BEU 0x00000008 | 105 | #define DISPLAY_BEU 0x00000008 |
| 99 | #define LCDC_ENABLE 0x00000001 | 106 | #define LCDC_ENABLE 0x00000001 |
| 107 | #define LDINTR_FE 0x00000400 | ||
| 108 | #define LDINTR_FS 0x00000004 | ||
| 100 | 109 | ||
| 101 | static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, | 110 | static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan, |
| 102 | int reg_nr, unsigned long data) | 111 | int reg_nr, unsigned long data) |
| @@ -171,6 +180,65 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = { | |||
| 171 | lcdc_sys_read_data, | 180 | lcdc_sys_read_data, |
| 172 | }; | 181 | }; |
| 173 | 182 | ||
| 183 | #ifdef CONFIG_HAVE_CLK | ||
| 184 | static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) | ||
| 185 | { | ||
| 186 | if (atomic_inc_and_test(&priv->clk_usecnt)) { | ||
| 187 | clk_enable(priv->clk); | ||
| 188 | if (priv->dot_clk) | ||
| 189 | clk_enable(priv->dot_clk); | ||
| 190 | } | ||
| 191 | } | ||
| 192 | |||
| 193 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) | ||
| 194 | { | ||
| 195 | if (atomic_sub_return(1, &priv->clk_usecnt) == -1) { | ||
| 196 | if (priv->dot_clk) | ||
| 197 | clk_disable(priv->dot_clk); | ||
| 198 | clk_disable(priv->clk); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | #else | ||
| 202 | static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv) {} | ||
| 203 | static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv) {} | ||
| 204 | #endif | ||
| 205 | |||
| 206 | static void sh_mobile_lcdc_deferred_io(struct fb_info *info, | ||
| 207 | struct list_head *pagelist) | ||
| 208 | { | ||
| 209 | struct sh_mobile_lcdc_chan *ch = info->par; | ||
| 210 | |||
| 211 | /* enable clocks before accessing hardware */ | ||
| 212 | sh_mobile_lcdc_clk_on(ch->lcdc); | ||
| 213 | |||
| 214 | /* trigger panel update */ | ||
| 215 | lcdc_write_chan(ch, LDSM2R, 1); | ||
| 216 | } | ||
| 217 | |||
| 218 | static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info) | ||
| 219 | { | ||
| 220 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
| 221 | |||
| 222 | if (fbdefio) | ||
| 223 | schedule_delayed_work(&info->deferred_work, fbdefio->delay); | ||
| 224 | } | ||
| 225 | |||
| 226 | static irqreturn_t sh_mobile_lcdc_irq(int irq, void *data) | ||
| 227 | { | ||
| 228 | struct sh_mobile_lcdc_priv *priv = data; | ||
| 229 | unsigned long tmp; | ||
| 230 | |||
| 231 | /* acknowledge interrupt */ | ||
| 232 | tmp = lcdc_read(priv, _LDINTR); | ||
| 233 | tmp &= 0xffffff00; /* mask in high 24 bits */ | ||
| 234 | tmp |= 0x000000ff ^ LDINTR_FS; /* status in low 8 */ | ||
| 235 | lcdc_write(priv, _LDINTR, tmp); | ||
| 236 | |||
| 237 | /* disable clocks */ | ||
| 238 | sh_mobile_lcdc_clk_off(priv); | ||
| 239 | return IRQ_HANDLED; | ||
| 240 | } | ||
| 241 | |||
| 174 | static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, | 242 | static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv, |
| 175 | int start) | 243 | int start) |
| 176 | { | 244 | { |
| @@ -208,11 +276,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 208 | int k, m; | 276 | int k, m; |
| 209 | int ret = 0; | 277 | int ret = 0; |
| 210 | 278 | ||
| 211 | #ifdef CONFIG_HAVE_CLK | 279 | /* enable clocks before accessing the hardware */ |
| 212 | clk_enable(priv->clk); | 280 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) |
| 213 | if (priv->dot_clk) | 281 | if (priv->ch[k].enabled) |
| 214 | clk_enable(priv->dot_clk); | 282 | sh_mobile_lcdc_clk_on(priv); |
| 215 | #endif | 283 | |
| 216 | /* reset */ | 284 | /* reset */ |
| 217 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); | 285 | lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); |
| 218 | lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); | 286 | lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); |
| @@ -255,7 +323,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 255 | lcdc_write(priv, _LDDCKSTPR, 0); | 323 | lcdc_write(priv, _LDDCKSTPR, 0); |
| 256 | lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); | 324 | lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0); |
| 257 | 325 | ||
| 258 | /* interrupts are disabled */ | 326 | /* interrupts are disabled to begin with */ |
| 259 | lcdc_write(priv, _LDINTR, 0); | 327 | lcdc_write(priv, _LDINTR, 0); |
| 260 | 328 | ||
| 261 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { | 329 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { |
| @@ -316,9 +384,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 316 | return ret; | 384 | return ret; |
| 317 | } | 385 | } |
| 318 | 386 | ||
| 319 | /* --- display_lcdc_data() --- */ | ||
| 320 | lcdc_write(priv, _LDINTR, 0x00000f00); | ||
| 321 | |||
| 322 | /* word and long word swap */ | 387 | /* word and long word swap */ |
| 323 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); | 388 | lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6); |
| 324 | 389 | ||
| @@ -340,8 +405,24 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
| 340 | /* set line size */ | 405 | /* set line size */ |
| 341 | lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); | 406 | lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length); |
| 342 | 407 | ||
| 343 | /* continuous read mode */ | 408 | /* setup deferred io if SYS bus */ |
| 344 | lcdc_write_chan(ch, LDSM1R, 0); | 409 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; |
| 410 | if (ch->ldmt1r_value & (1 << 12) && tmp) { | ||
| 411 | ch->defio.deferred_io = sh_mobile_lcdc_deferred_io; | ||
| 412 | ch->defio.delay = msecs_to_jiffies(tmp); | ||
| 413 | ch->info.fbdefio = &ch->defio; | ||
| 414 | fb_deferred_io_init(&ch->info); | ||
| 415 | |||
| 416 | /* one-shot mode */ | ||
| 417 | lcdc_write_chan(ch, LDSM1R, 1); | ||
| 418 | |||
| 419 | /* enable "Frame End Interrupt Enable" bit */ | ||
| 420 | lcdc_write(priv, _LDINTR, LDINTR_FE); | ||
| 421 | |||
| 422 | } else { | ||
| 423 | /* continuous read mode */ | ||
| 424 | lcdc_write_chan(ch, LDSM1R, 0); | ||
| 425 | } | ||
| 345 | } | 426 | } |
| 346 | 427 | ||
| 347 | /* display output */ | 428 | /* display output */ |
| @@ -365,6 +446,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
| 365 | { | 446 | { |
| 366 | struct sh_mobile_lcdc_chan *ch; | 447 | struct sh_mobile_lcdc_chan *ch; |
| 367 | struct sh_mobile_lcdc_board_cfg *board_cfg; | 448 | struct sh_mobile_lcdc_board_cfg *board_cfg; |
| 449 | unsigned long tmp; | ||
| 368 | int k; | 450 | int k; |
| 369 | 451 | ||
| 370 | /* tell the board code to disable the panel */ | 452 | /* tell the board code to disable the panel */ |
| @@ -373,16 +455,22 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) | |||
| 373 | board_cfg = &ch->cfg.board_cfg; | 455 | board_cfg = &ch->cfg.board_cfg; |
| 374 | if (board_cfg->display_off) | 456 | if (board_cfg->display_off) |
| 375 | board_cfg->display_off(board_cfg->board_data); | 457 | board_cfg->display_off(board_cfg->board_data); |
| 458 | |||
| 459 | /* cleanup deferred io if SYS bus */ | ||
| 460 | tmp = ch->cfg.sys_bus_cfg.deferred_io_msec; | ||
| 461 | if (ch->ldmt1r_value & (1 << 12) && tmp) { | ||
| 462 | fb_deferred_io_cleanup(&ch->info); | ||
| 463 | ch->info.fbdefio = NULL; | ||
| 464 | } | ||
| 376 | } | 465 | } |
| 377 | 466 | ||
| 378 | /* stop the lcdc */ | 467 | /* stop the lcdc */ |
| 379 | sh_mobile_lcdc_start_stop(priv, 0); | 468 | sh_mobile_lcdc_start_stop(priv, 0); |
| 380 | 469 | ||
| 381 | #ifdef CONFIG_HAVE_CLK | 470 | /* stop clocks */ |
| 382 | if (priv->dot_clk) | 471 | for (k = 0; k < ARRAY_SIZE(priv->ch); k++) |
| 383 | clk_disable(priv->dot_clk); | 472 | if (priv->ch[k].enabled) |
| 384 | clk_disable(priv->clk); | 473 | sh_mobile_lcdc_clk_off(priv); |
| 385 | #endif | ||
| 386 | } | 474 | } |
| 387 | 475 | ||
| 388 | static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) | 476 | static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) |
| @@ -446,6 +534,7 @@ static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, | |||
| 446 | priv->lddckr = icksel << 16; | 534 | priv->lddckr = icksel << 16; |
| 447 | 535 | ||
| 448 | #ifdef CONFIG_HAVE_CLK | 536 | #ifdef CONFIG_HAVE_CLK |
| 537 | atomic_set(&priv->clk_usecnt, -1); | ||
| 449 | snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); | 538 | snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); |
| 450 | priv->clk = clk_get(&pdev->dev, clk_name); | 539 | priv->clk = clk_get(&pdev->dev, clk_name); |
| 451 | if (IS_ERR(priv->clk)) { | 540 | if (IS_ERR(priv->clk)) { |
| @@ -497,13 +586,34 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { | |||
| 497 | .accel = FB_ACCEL_NONE, | 586 | .accel = FB_ACCEL_NONE, |
| 498 | }; | 587 | }; |
| 499 | 588 | ||
| 589 | static void sh_mobile_lcdc_fillrect(struct fb_info *info, | ||
| 590 | const struct fb_fillrect *rect) | ||
| 591 | { | ||
| 592 | sys_fillrect(info, rect); | ||
| 593 | sh_mobile_lcdc_deferred_io_touch(info); | ||
| 594 | } | ||
| 595 | |||
| 596 | static void sh_mobile_lcdc_copyarea(struct fb_info *info, | ||
| 597 | const struct fb_copyarea *area) | ||
| 598 | { | ||
| 599 | sys_copyarea(info, area); | ||
| 600 | sh_mobile_lcdc_deferred_io_touch(info); | ||
| 601 | } | ||
| 602 | |||
| 603 | static void sh_mobile_lcdc_imageblit(struct fb_info *info, | ||
| 604 | const struct fb_image *image) | ||
| 605 | { | ||
| 606 | sys_imageblit(info, image); | ||
| 607 | sh_mobile_lcdc_deferred_io_touch(info); | ||
| 608 | } | ||
| 609 | |||
| 500 | static struct fb_ops sh_mobile_lcdc_ops = { | 610 | static struct fb_ops sh_mobile_lcdc_ops = { |
| 501 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, | 611 | .fb_setcolreg = sh_mobile_lcdc_setcolreg, |
| 502 | .fb_read = fb_sys_read, | 612 | .fb_read = fb_sys_read, |
| 503 | .fb_write = fb_sys_write, | 613 | .fb_write = fb_sys_write, |
| 504 | .fb_fillrect = sys_fillrect, | 614 | .fb_fillrect = sh_mobile_lcdc_fillrect, |
| 505 | .fb_copyarea = sys_copyarea, | 615 | .fb_copyarea = sh_mobile_lcdc_copyarea, |
| 506 | .fb_imageblit = sys_imageblit, | 616 | .fb_imageblit = sh_mobile_lcdc_imageblit, |
| 507 | }; | 617 | }; |
| 508 | 618 | ||
| 509 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) | 619 | static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) |
| @@ -564,8 +674,9 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 564 | } | 674 | } |
| 565 | 675 | ||
| 566 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 676 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 567 | if (res == NULL) { | 677 | i = platform_get_irq(pdev, 0); |
| 568 | dev_err(&pdev->dev, "cannot find IO resource\n"); | 678 | if (!res || i < 0) { |
| 679 | dev_err(&pdev->dev, "cannot get platform resources\n"); | ||
| 569 | error = -ENOENT; | 680 | error = -ENOENT; |
| 570 | goto err0; | 681 | goto err0; |
| 571 | } | 682 | } |
| @@ -577,6 +688,14 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 577 | goto err0; | 688 | goto err0; |
| 578 | } | 689 | } |
| 579 | 690 | ||
| 691 | error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, | ||
| 692 | pdev->dev.bus_id, priv); | ||
| 693 | if (error) { | ||
| 694 | dev_err(&pdev->dev, "unable to request irq\n"); | ||
| 695 | goto err1; | ||
| 696 | } | ||
| 697 | |||
| 698 | priv->irq = i; | ||
| 580 | platform_set_drvdata(pdev, priv); | 699 | platform_set_drvdata(pdev, priv); |
| 581 | pdata = pdev->dev.platform_data; | 700 | pdata = pdev->dev.platform_data; |
| 582 | 701 | ||
| @@ -660,6 +779,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 660 | info->fix.smem_start = priv->ch[i].dma_handle; | 779 | info->fix.smem_start = priv->ch[i].dma_handle; |
| 661 | info->screen_base = buf; | 780 | info->screen_base = buf; |
| 662 | info->device = &pdev->dev; | 781 | info->device = &pdev->dev; |
| 782 | info->par = &priv->ch[i]; | ||
| 663 | } | 783 | } |
| 664 | 784 | ||
| 665 | if (error) | 785 | if (error) |
| @@ -687,6 +807,10 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
| 687 | (int) priv->ch[i].cfg.lcd_cfg.xres, | 807 | (int) priv->ch[i].cfg.lcd_cfg.xres, |
| 688 | (int) priv->ch[i].cfg.lcd_cfg.yres, | 808 | (int) priv->ch[i].cfg.lcd_cfg.yres, |
| 689 | priv->ch[i].cfg.bpp); | 809 | priv->ch[i].cfg.bpp); |
| 810 | |||
| 811 | /* deferred io mode: disable clock to save power */ | ||
| 812 | if (info->fbdefio) | ||
| 813 | sh_mobile_lcdc_clk_off(priv); | ||
| 690 | } | 814 | } |
| 691 | 815 | ||
| 692 | return 0; | 816 | return 0; |
| @@ -728,6 +852,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
| 728 | if (priv->base) | 852 | if (priv->base) |
| 729 | iounmap(priv->base); | 853 | iounmap(priv->base); |
| 730 | 854 | ||
| 855 | if (priv->irq) | ||
| 856 | free_irq(priv->irq, priv); | ||
| 731 | kfree(priv); | 857 | kfree(priv); |
| 732 | return 0; | 858 | return 0; |
| 733 | } | 859 | } |
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index 1a4bc6ada606..25144ab22b95 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h | |||
| @@ -37,6 +37,7 @@ enum { LCDC_CLK_BUS, LCDC_CLK_PERIPHERAL, LCDC_CLK_EXTERNAL }; | |||
| 37 | struct sh_mobile_lcdc_sys_bus_cfg { | 37 | struct sh_mobile_lcdc_sys_bus_cfg { |
| 38 | unsigned long ldmt2r; | 38 | unsigned long ldmt2r; |
| 39 | unsigned long ldmt3r; | 39 | unsigned long ldmt3r; |
| 40 | unsigned long deferred_io_msec; | ||
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 42 | struct sh_mobile_lcdc_sys_bus_ops { | 43 | struct sh_mobile_lcdc_sys_bus_ops { |
