Merge branch 'sh/for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* 'sh/for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: serial: sh-sci: fix sci interrupt handler video: hitfb: Move over to dev_pm_ops. video: hitfb: Convert to framebuffer_alloc(). video: sh_mobile_lcdcfb: Convert to framebuffer_alloc(). sh: add r8a66597 usb0 host to the se7724 board usb: allow sh7724 to enable on-chip r8a66597 sh-sci: update receive error handling for muxed irqs sh: define PERF_COUNTER_INDEX_OFFSET.
This commit is contained in:
Коммит
622f8061a6
|
@ -19,6 +19,7 @@
|
||||||
#include <linux/smc91x.h>
|
#include <linux/smc91x.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#include <linux/usb/r8a66597.h>
|
||||||
#include <video/sh_mobile_lcdc.h>
|
#include <video/sh_mobile_lcdc.h>
|
||||||
#include <media/sh_mobile_ceu.h>
|
#include <media/sh_mobile_ceu.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
@ -302,6 +303,34 @@ static struct platform_device sh_eth_device = {
|
||||||
.resource = sh_eth_resources,
|
.resource = sh_eth_resources,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct r8a66597_platdata sh7724_usb0_host_data = {
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource sh7724_usb0_host_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = 0xa4d80000,
|
||||||
|
.end = 0xa4d800ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = 65,
|
||||||
|
.end = 65,
|
||||||
|
.flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device sh7724_usb0_host_device = {
|
||||||
|
.name = "r8a66597_hcd",
|
||||||
|
.id = 0,
|
||||||
|
.dev = {
|
||||||
|
.dma_mask = NULL, /* not use dma */
|
||||||
|
.coherent_dma_mask = 0xffffffff,
|
||||||
|
.platform_data = &sh7724_usb0_host_data,
|
||||||
|
},
|
||||||
|
.num_resources = ARRAY_SIZE(sh7724_usb0_host_resources),
|
||||||
|
.resource = sh7724_usb0_host_resources,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *ms7724se_devices[] __initdata = {
|
static struct platform_device *ms7724se_devices[] __initdata = {
|
||||||
&heartbeat_device,
|
&heartbeat_device,
|
||||||
&smc91x_eth_device,
|
&smc91x_eth_device,
|
||||||
|
@ -311,6 +340,7 @@ static struct platform_device *ms7724se_devices[] __initdata = {
|
||||||
&ceu1_device,
|
&ceu1_device,
|
||||||
&keysc_device,
|
&keysc_device,
|
||||||
&sh_eth_device,
|
&sh_eth_device,
|
||||||
|
&sh7724_usb0_host_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EEPROM_OP 0xBA206000
|
#define EEPROM_OP 0xBA206000
|
||||||
|
@ -364,6 +394,7 @@ static void __init sh_eth_init(void)
|
||||||
#define SW4140 0xBA201000
|
#define SW4140 0xBA201000
|
||||||
#define FPGA_OUT 0xBA200400
|
#define FPGA_OUT 0xBA200400
|
||||||
#define PORT_HIZA 0xA4050158
|
#define PORT_HIZA 0xA4050158
|
||||||
|
#define PORT_MSELCRB 0xA4050182
|
||||||
|
|
||||||
#define SW41_A 0x0100
|
#define SW41_A 0x0100
|
||||||
#define SW41_B 0x0200
|
#define SW41_B 0x0200
|
||||||
|
@ -373,6 +404,7 @@ static void __init sh_eth_init(void)
|
||||||
#define SW41_F 0x2000
|
#define SW41_F 0x2000
|
||||||
#define SW41_G 0x4000
|
#define SW41_G 0x4000
|
||||||
#define SW41_H 0x8000
|
#define SW41_H 0x8000
|
||||||
|
|
||||||
static int __init devices_setup(void)
|
static int __init devices_setup(void)
|
||||||
{
|
{
|
||||||
u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
|
u16 sw = ctrl_inw(SW4140); /* select camera, monitor */
|
||||||
|
@ -385,6 +417,12 @@ static int __init devices_setup(void)
|
||||||
(1 << 14)), /* RMII */
|
(1 << 14)), /* RMII */
|
||||||
FPGA_OUT);
|
FPGA_OUT);
|
||||||
|
|
||||||
|
/* turn on USB clocks, use external clock */
|
||||||
|
ctrl_outw((ctrl_inw(PORT_MSELCRB) & ~0xc000) | 0x8000, PORT_MSELCRB);
|
||||||
|
|
||||||
|
/* enable USB0 port */
|
||||||
|
ctrl_outw(0x0600, 0xa40501d4);
|
||||||
|
|
||||||
/* enable IRQ 0,1,2 */
|
/* enable IRQ 0,1,2 */
|
||||||
gpio_request(GPIO_FN_INTC_IRQ0, NULL);
|
gpio_request(GPIO_FN_INTC_IRQ0, NULL);
|
||||||
gpio_request(GPIO_FN_INTC_IRQ1, NULL);
|
gpio_request(GPIO_FN_INTC_IRQ1, NULL);
|
||||||
|
|
|
@ -4,4 +4,6 @@
|
||||||
/* SH only supports software counters through this interface. */
|
/* SH only supports software counters through this interface. */
|
||||||
static inline void set_perf_counter_pending(void) {}
|
static inline void set_perf_counter_pending(void) {}
|
||||||
|
|
||||||
|
#define PERF_COUNTER_INDEX_OFFSET 0
|
||||||
|
|
||||||
#endif /* __ASM_SH_PERF_COUNTER_H */
|
#endif /* __ASM_SH_PERF_COUNTER_H */
|
||||||
|
|
|
@ -707,24 +707,25 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr)
|
||||||
|
|
||||||
static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
|
static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
|
||||||
{
|
{
|
||||||
unsigned short ssr_status, scr_status;
|
unsigned short ssr_status, scr_status, err_enabled;
|
||||||
struct uart_port *port = ptr;
|
struct uart_port *port = ptr;
|
||||||
irqreturn_t ret = IRQ_NONE;
|
irqreturn_t ret = IRQ_NONE;
|
||||||
|
|
||||||
ssr_status = sci_in(port, SCxSR);
|
ssr_status = sci_in(port, SCxSR);
|
||||||
scr_status = sci_in(port, SCSCR);
|
scr_status = sci_in(port, SCSCR);
|
||||||
|
err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE);
|
||||||
|
|
||||||
/* Tx Interrupt */
|
/* Tx Interrupt */
|
||||||
if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE))
|
if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE))
|
||||||
ret = sci_tx_interrupt(irq, ptr);
|
ret = sci_tx_interrupt(irq, ptr);
|
||||||
/* Rx Interrupt */
|
/* Rx Interrupt */
|
||||||
if ((ssr_status & 0x0002) && (scr_status & SCI_CTRL_FLAGS_RIE))
|
if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE))
|
||||||
ret = sci_rx_interrupt(irq, ptr);
|
ret = sci_rx_interrupt(irq, ptr);
|
||||||
/* Error Interrupt */
|
/* Error Interrupt */
|
||||||
if ((ssr_status & 0x0080) && (scr_status & SCI_CTRL_FLAGS_REIE))
|
if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
|
||||||
ret = sci_er_interrupt(irq, ptr);
|
ret = sci_er_interrupt(irq, ptr);
|
||||||
/* Break Interrupt */
|
/* Break Interrupt */
|
||||||
if ((ssr_status & 0x0010) && (scr_status & SCI_CTRL_FLAGS_REIE))
|
if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
|
||||||
ret = sci_br_interrupt(irq, ptr);
|
ret = sci_br_interrupt(irq, ptr);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -337,10 +337,10 @@ config USB_R8A66597_HCD
|
||||||
|
|
||||||
config SUPERH_ON_CHIP_R8A66597
|
config SUPERH_ON_CHIP_R8A66597
|
||||||
boolean "Enable SuperH on-chip R8A66597 USB"
|
boolean "Enable SuperH on-chip R8A66597 USB"
|
||||||
depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723)
|
depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
|
||||||
help
|
help
|
||||||
This driver enables support for the on-chip R8A66597 in the
|
This driver enables support for the on-chip R8A66597 in the
|
||||||
SH7366 and SH7723 processors.
|
SH7366, SH7723 and SH7724 processors.
|
||||||
|
|
||||||
config USB_WHCI_HCD
|
config USB_WHCI_HCD
|
||||||
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
|
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
|
||||||
|
|
|
@ -44,9 +44,6 @@ static struct fb_fix_screeninfo hitfb_fix __initdata = {
|
||||||
.accel = FB_ACCEL_NONE,
|
.accel = FB_ACCEL_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 pseudo_palette[16];
|
|
||||||
static struct fb_info fb_info;
|
|
||||||
|
|
||||||
static inline void hitfb_accel_wait(void)
|
static inline void hitfb_accel_wait(void)
|
||||||
{
|
{
|
||||||
while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ;
|
while (fb_readw(HD64461_GRCFGR) & HD64461_GRCFGR_ACCSTATUS) ;
|
||||||
|
@ -331,6 +328,8 @@ static struct fb_ops hitfb_ops = {
|
||||||
static int __init hitfb_probe(struct platform_device *dev)
|
static int __init hitfb_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
unsigned short lcdclor, ldr3, ldvndr;
|
unsigned short lcdclor, ldr3, ldvndr;
|
||||||
|
struct fb_info *info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (fb_get_options("hitfb", NULL))
|
if (fb_get_options("hitfb", NULL))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -384,32 +383,53 @@ static int __init hitfb_probe(struct platform_device *dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fb_info.fbops = &hitfb_ops;
|
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
|
||||||
fb_info.var = hitfb_var;
|
if (unlikely(!info))
|
||||||
fb_info.fix = hitfb_fix;
|
return -ENOMEM;
|
||||||
fb_info.pseudo_palette = pseudo_palette;
|
|
||||||
fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
|
info->fbops = &hitfb_ops;
|
||||||
|
info->var = hitfb_var;
|
||||||
|
info->fix = hitfb_fix;
|
||||||
|
info->pseudo_palette = info->par;
|
||||||
|
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
|
||||||
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
|
FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA;
|
||||||
|
|
||||||
fb_info.screen_base = (void *)hitfb_fix.smem_start;
|
info->screen_base = (void *)hitfb_fix.smem_start;
|
||||||
|
|
||||||
fb_alloc_cmap(&fb_info.cmap, 256, 0);
|
ret = fb_alloc_cmap(&info->cmap, 256, 0);
|
||||||
|
if (unlikely(ret < 0))
|
||||||
|
goto err_fb;
|
||||||
|
|
||||||
if (register_framebuffer(&fb_info) < 0)
|
ret = register_framebuffer(info);
|
||||||
return -EINVAL;
|
if (unlikely(ret < 0))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
platform_set_drvdata(dev, info);
|
||||||
|
|
||||||
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
printk(KERN_INFO "fb%d: %s frame buffer device\n",
|
||||||
fb_info.node, fb_info.fix.id);
|
info->node, info->fix.id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
err_fb:
|
||||||
|
framebuffer_release(info);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __exit hitfb_remove(struct platform_device *dev)
|
static int __exit hitfb_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
return unregister_framebuffer(&fb_info);
|
struct fb_info *info = platform_get_drvdata(dev);
|
||||||
|
|
||||||
|
unregister_framebuffer(info);
|
||||||
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
framebuffer_release(info);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
static int hitfb_suspend(struct device *dev)
|
||||||
static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
|
|
||||||
{
|
{
|
||||||
u16 v;
|
u16 v;
|
||||||
|
|
||||||
|
@ -421,7 +441,7 @@ static int hitfb_suspend(struct platform_device *dev, pm_message_t state)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hitfb_resume(struct platform_device *dev)
|
static int hitfb_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
u16 v;
|
u16 v;
|
||||||
|
|
||||||
|
@ -435,17 +455,19 @@ static int hitfb_resume(struct platform_device *dev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static struct dev_pm_ops hitfb_dev_pm_ops = {
|
||||||
|
.suspend = hitfb_suspend,
|
||||||
|
.resume = hitfb_resume,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_driver hitfb_driver = {
|
static struct platform_driver hitfb_driver = {
|
||||||
.probe = hitfb_probe,
|
.probe = hitfb_probe,
|
||||||
.remove = __exit_p(hitfb_remove),
|
.remove = __exit_p(hitfb_remove),
|
||||||
#ifdef CONFIG_PM
|
|
||||||
.suspend = hitfb_suspend,
|
|
||||||
.resume = hitfb_resume,
|
|
||||||
#endif
|
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "hitfb",
|
.name = "hitfb",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.pm = &hitfb_dev_pm_ops,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct sh_mobile_lcdc_chan {
|
||||||
unsigned long enabled; /* ME and SE in LDCNT2R */
|
unsigned long enabled; /* ME and SE in LDCNT2R */
|
||||||
struct sh_mobile_lcdc_chan_cfg cfg;
|
struct sh_mobile_lcdc_chan_cfg cfg;
|
||||||
u32 pseudo_palette[PALETTE_NR];
|
u32 pseudo_palette[PALETTE_NR];
|
||||||
struct fb_info info;
|
struct fb_info *info;
|
||||||
dma_addr_t dma_handle;
|
dma_addr_t dma_handle;
|
||||||
struct fb_deferred_io defio;
|
struct fb_deferred_io defio;
|
||||||
struct scatterlist *sglist;
|
struct scatterlist *sglist;
|
||||||
|
@ -442,22 +442,22 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
|
||||||
/* set bpp format in PKF[4:0] */
|
/* set bpp format in PKF[4:0] */
|
||||||
tmp = lcdc_read_chan(ch, LDDFR);
|
tmp = lcdc_read_chan(ch, LDDFR);
|
||||||
tmp &= ~(0x0001001f);
|
tmp &= ~(0x0001001f);
|
||||||
tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0;
|
tmp |= (ch->info->var.bits_per_pixel == 16) ? 3 : 0;
|
||||||
lcdc_write_chan(ch, LDDFR, tmp);
|
lcdc_write_chan(ch, LDDFR, tmp);
|
||||||
|
|
||||||
/* point out our frame buffer */
|
/* point out our frame buffer */
|
||||||
lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start);
|
lcdc_write_chan(ch, LDSA1R, ch->info->fix.smem_start);
|
||||||
|
|
||||||
/* set line size */
|
/* set line size */
|
||||||
lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
|
lcdc_write_chan(ch, LDMLSR, ch->info->fix.line_length);
|
||||||
|
|
||||||
/* setup deferred io if SYS bus */
|
/* setup deferred io if SYS bus */
|
||||||
tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
|
tmp = ch->cfg.sys_bus_cfg.deferred_io_msec;
|
||||||
if (ch->ldmt1r_value & (1 << 12) && tmp) {
|
if (ch->ldmt1r_value & (1 << 12) && tmp) {
|
||||||
ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
|
ch->defio.deferred_io = sh_mobile_lcdc_deferred_io;
|
||||||
ch->defio.delay = msecs_to_jiffies(tmp);
|
ch->defio.delay = msecs_to_jiffies(tmp);
|
||||||
ch->info.fbdefio = &ch->defio;
|
ch->info->fbdefio = &ch->defio;
|
||||||
fb_deferred_io_init(&ch->info);
|
fb_deferred_io_init(ch->info);
|
||||||
|
|
||||||
/* one-shot mode */
|
/* one-shot mode */
|
||||||
lcdc_write_chan(ch, LDSM1R, 1);
|
lcdc_write_chan(ch, LDSM1R, 1);
|
||||||
|
@ -503,12 +503,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
|
||||||
* flush frame, and wait for frame end interrupt
|
* flush frame, and wait for frame end interrupt
|
||||||
* clean up deferred io and enable clock
|
* clean up deferred io and enable clock
|
||||||
*/
|
*/
|
||||||
if (ch->info.fbdefio) {
|
if (ch->info->fbdefio) {
|
||||||
ch->frame_end = 0;
|
ch->frame_end = 0;
|
||||||
schedule_delayed_work(&ch->info.deferred_work, 0);
|
schedule_delayed_work(&ch->info->deferred_work, 0);
|
||||||
wait_event(ch->frame_end_wait, ch->frame_end);
|
wait_event(ch->frame_end_wait, ch->frame_end);
|
||||||
fb_deferred_io_cleanup(&ch->info);
|
fb_deferred_io_cleanup(ch->info);
|
||||||
ch->info.fbdefio = NULL;
|
ch->info->fbdefio = NULL;
|
||||||
sh_mobile_lcdc_clk_on(priv);
|
sh_mobile_lcdc_clk_on(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,9 +817,16 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
|
||||||
priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
|
priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
|
||||||
|
|
||||||
for (i = 0; i < j; i++) {
|
for (i = 0; i < j; i++) {
|
||||||
info = &priv->ch[i].info;
|
|
||||||
cfg = &priv->ch[i].cfg;
|
cfg = &priv->ch[i].cfg;
|
||||||
|
|
||||||
|
priv->ch[i].info = framebuffer_alloc(0, &pdev->dev);
|
||||||
|
if (!priv->ch[i].info) {
|
||||||
|
dev_err(&pdev->dev, "unable to allocate fb_info\n");
|
||||||
|
error = -ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = priv->ch[i].info;
|
||||||
info->fbops = &sh_mobile_lcdc_ops;
|
info->fbops = &sh_mobile_lcdc_ops;
|
||||||
info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
|
info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
|
||||||
info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
|
info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
|
||||||
|
@ -872,7 +879,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
|
||||||
for (i = 0; i < j; i++) {
|
for (i = 0; i < j; i++) {
|
||||||
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
|
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
|
||||||
|
|
||||||
info = &ch->info;
|
info = ch->info;
|
||||||
|
|
||||||
if (info->fbdefio) {
|
if (info->fbdefio) {
|
||||||
priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
|
priv->ch->sglist = vmalloc(sizeof(struct scatterlist) *
|
||||||
|
@ -915,15 +922,15 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
|
for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
|
||||||
if (priv->ch[i].info.dev)
|
if (priv->ch[i].info->dev)
|
||||||
unregister_framebuffer(&priv->ch[i].info);
|
unregister_framebuffer(priv->ch[i].info);
|
||||||
|
|
||||||
sh_mobile_lcdc_stop(priv);
|
sh_mobile_lcdc_stop(priv);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
|
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
|
||||||
info = &priv->ch[i].info;
|
info = priv->ch[i].info;
|
||||||
|
|
||||||
if (!info->device)
|
if (!info || !info->device)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (priv->ch[i].sglist)
|
if (priv->ch[i].sglist)
|
||||||
|
@ -932,6 +939,7 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
|
||||||
dma_free_coherent(&pdev->dev, info->fix.smem_len,
|
dma_free_coherent(&pdev->dev, info->fix.smem_len,
|
||||||
info->screen_base, priv->ch[i].dma_handle);
|
info->screen_base, priv->ch[i].dma_handle);
|
||||||
fb_dealloc_cmap(&info->cmap);
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
framebuffer_release(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_HAVE_CLK
|
#ifdef CONFIG_HAVE_CLK
|
||||||
|
|
Загрузка…
Ссылка в новой задаче