From a5616bd0f19730a780c354110454ce37209f1ded Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:20:55 +0900 Subject: sh: sh_mobile i2c clock framework support Add clock framework support to the sh_mobile i2c driver and adjust the processor specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/i2c/busses/i2c-sh_mobile.c | 73 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 3384a717fec..6c3d60b939b 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -160,9 +160,39 @@ struct sh_mobile_i2c_data { static void activate_ch(struct sh_mobile_i2c_data *pd) { + unsigned long i2c_clk; + u_int32_t num; + u_int32_t denom; + u_int32_t tmp; + /* Make sure the clock is enabled */ clk_enable(pd->clk); + /* Get clock rate after clock is enabled */ + i2c_clk = clk_get_rate(pd->clk); + + /* Calculate the value for iccl. From the data sheet: + * iccl = (p clock / transfer rate) * (L / (L + H)) + * where L and H are the SCL low/high ratio (5/4 in this case). + * We also round off the result. + */ + num = i2c_clk * 5; + denom = NORMAL_SPEED * 9; + tmp = num * 10 / denom; + if (tmp % 10 >= 5) + pd->iccl = (u_int8_t)((num/denom) + 1); + else + pd->iccl = (u_int8_t)(num/denom); + + /* Calculate the value for icch. From the data sheet: + icch = (p clock / transfer rate) * (H / (L + H)) */ + num = i2c_clk * 4; + tmp = num * 10 / denom; + if (tmp % 10 >= 5) + pd->icch = (u_int8_t)((num/denom) + 1); + else + pd->icch = (u_int8_t)(num/denom); + /* Enable channel and configure rx ack */ iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); @@ -459,40 +489,6 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = { .master_xfer = sh_mobile_i2c_xfer, }; -static void sh_mobile_i2c_setup_channel(struct platform_device *dev) -{ - struct sh_mobile_i2c_data *pd = platform_get_drvdata(dev); - unsigned long peripheral_clk = clk_get_rate(pd->clk); - u_int32_t num; - u_int32_t denom; - u_int32_t tmp; - - spin_lock_init(&pd->lock); - init_waitqueue_head(&pd->wait); - - /* Calculate the value for iccl. From the data sheet: - * iccl = (p clock / transfer rate) * (L / (L + H)) - * where L and H are the SCL low/high ratio (5/4 in this case). - * We also round off the result. - */ - num = peripheral_clk * 5; - denom = NORMAL_SPEED * 9; - tmp = num * 10 / denom; - if (tmp % 10 >= 5) - pd->iccl = (u_int8_t)((num/denom) + 1); - else - pd->iccl = (u_int8_t)(num/denom); - - /* Calculate the value for icch. From the data sheet: - icch = (p clock / transfer rate) * (H / (L + H)) */ - num = peripheral_clk * 4; - tmp = num * 10 / denom; - if (tmp % 10 >= 5) - pd->icch = (u_int8_t)((num/denom) + 1); - else - pd->icch = (u_int8_t)(num/denom); -} - static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook) { struct resource *res; @@ -533,6 +529,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) struct sh_mobile_i2c_data *pd; struct i2c_adapter *adap; struct resource *res; + char clk_name[8]; int size; int ret; @@ -542,9 +539,10 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) return -ENOMEM; } - pd->clk = clk_get(&dev->dev, "peripheral_clk"); + snprintf(clk_name, sizeof(clk_name), "i2c%d", dev->id); + pd->clk = clk_get(&dev->dev, clk_name); if (IS_ERR(pd->clk)) { - dev_err(&dev->dev, "cannot get peripheral clock\n"); + dev_err(&dev->dev, "cannot get clock \"%s\"\n", clk_name); ret = PTR_ERR(pd->clk); goto err; } @@ -586,7 +584,8 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) strlcpy(adap->name, dev->name, sizeof(adap->name)); - sh_mobile_i2c_setup_channel(dev); + spin_lock_init(&pd->lock); + init_waitqueue_head(&pd->wait); ret = i2c_add_numbered_adapter(adap); if (ret < 0) { -- cgit v1.2.3 From 090d951b69f29a8d5777c63570d4cd61d7efeb22 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:21:23 +0900 Subject: sh: sh_mobile keysc clock framework support Add clock framework support to the sh_mobile keysc driver and adjust the board specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/input/keyboard/sh_keysc.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index c600ab7f93e..5c8a1bcf7ca 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ static const struct { struct sh_keysc_priv { void __iomem *iomem_base; + struct clk *clk; unsigned long last_keys; struct input_dev *input; struct sh_keysc_info pdata; @@ -125,6 +127,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) struct sh_keysc_info *pdata; struct resource *res; struct input_dev *input; + char clk_name[8]; int i, k; int irq, error; @@ -165,11 +168,19 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) goto err1; } + snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id); + priv->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + error = PTR_ERR(priv->clk); + goto err2; + } + priv->input = input_allocate_device(); if (!priv->input) { dev_err(&pdev->dev, "failed to allocate input device\n"); error = -ENOMEM; - goto err2; + goto err3; } input = priv->input; @@ -187,7 +198,7 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); - goto err3; + goto err4; } for (i = 0; i < SH_KEYSC_MAXKEYS; i++) { @@ -199,18 +210,22 @@ static int __devinit sh_keysc_probe(struct platform_device *pdev) error = input_register_device(input); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err4; + goto err5; } + clk_enable(priv->clk); + iowrite16((sh_keysc_mode[pdata->mode].kymd << 8) | pdata->scan_timing, priv->iomem_base + KYCR1_OFFS); iowrite16(0, priv->iomem_base + KYOUTDR_OFFS); iowrite16(KYCR2_IRQ_LEVEL, priv->iomem_base + KYCR2_OFFS); return 0; - err4: + err5: free_irq(irq, pdev); - err3: + err4: input_free_device(input); + err3: + clk_put(priv->clk); err2: iounmap(priv->iomem_base); err1: @@ -230,6 +245,9 @@ static int __devexit sh_keysc_remove(struct platform_device *pdev) free_irq(platform_get_irq(pdev, 0), pdev); iounmap(priv->iomem_base); + clk_disable(priv->clk); + clk_put(priv->clk); + platform_set_drvdata(pdev, NULL); kfree(priv); return 0; -- cgit v1.2.3 From a42b6dd69cb1c61c5f5a24061a227c22071786de Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:21:44 +0900 Subject: sh: sh_mobile ceu clock framework support Add clock framework support to the sh_mobile ceu and adjust the board specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/media/video/sh_mobile_ceu_camera.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2407607f2ef..536b1a9b310 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -89,6 +90,7 @@ struct sh_mobile_ceu_dev { unsigned int irq; void __iomem *base; + struct clk *clk; unsigned long video_limit; /* lock used to protect videobuf */ @@ -309,6 +311,8 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) if (ret) goto err; + clk_enable(pcdev->clk); + ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ while (ceu_read(pcdev, CSTSR) & 1) msleep(1); @@ -342,6 +346,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) } spin_unlock_irqrestore(&pcdev->lock, flags); + clk_disable(pcdev->clk); + icd->ops->release(icd); dev_info(&icd->dev, @@ -550,6 +556,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) struct sh_mobile_ceu_dev *pcdev; struct resource *res; void __iomem *base; + char clk_name[8]; unsigned int irq; int err = 0; @@ -615,6 +622,14 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) goto exit_release_mem; } + snprintf(clk_name, sizeof(clk_name), "ceu%d", pdev->id); + pcdev->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(pcdev->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + err = PTR_ERR(pcdev->clk); + goto exit_free_irq; + } + pcdev->ici.priv = pcdev; pcdev->ici.dev.parent = &pdev->dev; pcdev->ici.nr = pdev->id; @@ -623,10 +638,12 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) err = soc_camera_host_register(&pcdev->ici); if (err) - goto exit_free_irq; + goto exit_free_clk; return 0; +exit_free_clk: + clk_put(pcdev->clk); exit_free_irq: free_irq(pcdev->irq, pcdev); exit_release_mem: @@ -645,6 +662,7 @@ static int sh_mobile_ceu_remove(struct platform_device *pdev) struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); soc_camera_host_unregister(&pcdev->ici); + clk_put(pcdev->clk); free_irq(pcdev->irq, pcdev); if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) dma_release_declared_memory(&pdev->dev); -- cgit v1.2.3 From af5be79a7f8d7067588dc2863d37f7cd22e5f2de Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:22:13 +0900 Subject: sh: sh_mobile usbf clock framework support Add clock framework support to the usbf/m66592 driver and adjust the cpu specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/usb/gadget/m66592-udc.c | 34 +++++++++++++++++++++++++--------- drivers/usb/gadget/m66592-udc.h | 27 +++++++-------------------- 2 files changed, 32 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 77b44fb48f0..201c67b625c 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -623,7 +623,6 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) #if defined(CONFIG_SUPERH_BUILT_IN_M66592) static void init_controller(struct m66592 *m66592) { - usbf_start_clock(); m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ m66592_bclr(m66592, M66592_USBE, M66592_SYSCFG); m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); @@ -671,9 +670,7 @@ static void init_controller(struct m66592 *m66592) static void disable_controller(struct m66592 *m66592) { -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) - usbf_stop_clock(); -#else +#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) m66592_bclr(m66592, M66592_SCKE, M66592_SYSCFG); udelay(1); m66592_bclr(m66592, M66592_PLLC, M66592_SYSCFG); @@ -686,9 +683,7 @@ static void disable_controller(struct m66592 *m66592) static void m66592_start_xclock(struct m66592 *m66592) { -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) - usbf_start_clock(); -#else +#if !defined(CONFIG_SUPERH_BUILT_IN_M66592) u16 tmp; tmp = m66592_read(m66592, M66592_SYSCFG); @@ -1539,7 +1534,10 @@ static int __exit m66592_remove(struct platform_device *pdev) iounmap(m66592->reg); free_irq(platform_get_irq(pdev, 0), m66592); m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); - usbf_stop_clock(); +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) + clk_disable(m66592->clk); + clk_put(m66592->clk); +#endif kfree(m66592); return 0; } @@ -1556,6 +1554,9 @@ static int __init m66592_probe(struct platform_device *pdev) int irq; void __iomem *reg = NULL; struct m66592 *m66592 = NULL; +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) + char clk_name[8]; +#endif int ret = 0; int i; @@ -1614,6 +1615,16 @@ static int __init m66592_probe(struct platform_device *pdev) goto clean_up; } +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) + snprintf(clk_name, sizeof(clk_name), "usbf%d", pdev->id); + m66592->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(m66592->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + ret = PTR_ERR(m66592->clk); + goto clean_up2; + } + clk_enable(m66592->clk); +#endif INIT_LIST_HEAD(&m66592->gadget.ep_list); m66592->gadget.ep0 = &m66592->ep[0].ep; INIT_LIST_HEAD(&m66592->gadget.ep0->ep_list); @@ -1645,7 +1656,7 @@ static int __init m66592_probe(struct platform_device *pdev) m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); if (m66592->ep0_req == NULL) - goto clean_up2; + goto clean_up3; m66592->ep0_req->complete = nop_completion; init_controller(m66592); @@ -1653,6 +1664,11 @@ static int __init m66592_probe(struct platform_device *pdev) dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); return 0; +clean_up3: +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) + clk_disable(m66592->clk); + clk_put(m66592->clk); +#endif clean_up2: free_irq(irq, m66592); clean_up: diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index f118f00f146..286ce07e796 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h @@ -23,6 +23,10 @@ #ifndef __M66592_UDC_H__ #define __M66592_UDC_H__ +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) +#include +#endif + #define M66592_SYSCFG 0x00 #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ #define M66592_XTAL48 0x8000 /* 48MHz */ @@ -476,6 +480,9 @@ struct m66592_ep { struct m66592 { spinlock_t lock; void __iomem *reg; +#if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) + struct clk *clk; +#endif struct usb_gadget gadget; struct usb_gadget_driver *driver; @@ -604,26 +611,6 @@ static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, #define m66592_bset(m66592, val, offset) \ m66592_mdfy(m66592, val, 0, offset) -#if defined(CONFIG_SUPERH_BUILT_IN_M66592) -#include -#define MSTPCR2 0xA4150038 /* for SH7722 */ -#define MSTPCR2_USB 0x00000800 - -static inline void usbf_start_clock(void) -{ - ctrl_outl(ctrl_inl(MSTPCR2) & ~MSTPCR2_USB, MSTPCR2); -} - -static inline void usbf_stop_clock(void) -{ - ctrl_outl(ctrl_inl(MSTPCR2) | MSTPCR2_USB, MSTPCR2); -} - -#else -#define usbf_start_clock(x) -#define usbf_stop_clock(x) -#endif /* if defined(CONFIG_SUPERH_BUILT_IN_M66592) */ - #endif /* ifndef __M66592_UDC_H__ */ -- cgit v1.2.3 From 765786e0aead7faf6c333176d22948c6f155fff1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:22:38 +0900 Subject: sh: sh_mobile usb clock framework support Add clock framework support to the usb/r8a66597 driver and adjust the cpu specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/usb/host/r8a66597-hcd.c | 35 +++++++++++++++++++++++++++++++++-- drivers/usb/host/r8a66597.h | 8 +++++++- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 2376f24f3c8..d99b9c7098b 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -114,6 +114,9 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597) int i = 0; #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#if defined(CONFIG_HAVE_CLK) + clk_enable(r8a66597->clk); +#endif do { r8a66597_write(r8a66597, SCKE, SYSCFG0); tmp = r8a66597_read(r8a66597, SYSCFG0); @@ -154,7 +157,11 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597) { r8a66597_bclr(r8a66597, SCKE, SYSCFG0); udelay(1); -#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#if defined(CONFIG_HAVE_CLK) + clk_disable(r8a66597->clk); +#endif +#else r8a66597_bclr(r8a66597, PLLC, SYSCFG0); r8a66597_bclr(r8a66597, XCKE, SYSCFG0); r8a66597_bclr(r8a66597, USBE, SYSCFG0); @@ -2261,6 +2268,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) del_timer_sync(&r8a66597->rh_timer); usb_remove_hcd(hcd); iounmap((void *)r8a66597->reg); +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) + clk_put(r8a66597->clk); +#endif usb_put_hcd(hcd); return 0; } @@ -2268,6 +2278,9 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) #define resource_len(r) (((r)->end - (r)->start) + 1) static int __init r8a66597_probe(struct platform_device *pdev) { +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) + char clk_name[8]; +#endif struct resource *res = NULL, *ires; int irq = -1; void __iomem *reg = NULL; @@ -2320,6 +2333,16 @@ static int __init r8a66597_probe(struct platform_device *pdev) memset(r8a66597, 0, sizeof(struct r8a66597)); dev_set_drvdata(&pdev->dev, r8a66597); +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) + snprintf(clk_name, sizeof(clk_name), "usb%d", pdev->id); + r8a66597->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(r8a66597->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + ret = PTR_ERR(r8a66597->clk); + goto clean_up2; + } +#endif + spin_lock_init(&r8a66597->lock); init_timer(&r8a66597->rh_timer); r8a66597->rh_timer.function = r8a66597_timer; @@ -2365,11 +2388,19 @@ static int __init r8a66597_probe(struct platform_device *pdev) ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); if (ret != 0) { dev_err(&pdev->dev, "Failed to add hcd\n"); - goto clean_up; + goto clean_up3; } return 0; +clean_up3: +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) + clk_put(r8a66597->clk); +#endif + +clean_up2: + usb_put_hcd(hcd); + clean_up: if (reg) iounmap(reg); diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 84ee0141731..ecacde4d69b 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h @@ -26,6 +26,10 @@ #ifndef __R8A66597_H__ #define __R8A66597_H__ +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) +#include +#endif + #define SYSCFG0 0x00 #define SYSCFG1 0x02 #define SYSSTS0 0x04 @@ -481,7 +485,9 @@ struct r8a66597_root_hub { struct r8a66597 { spinlock_t lock; unsigned long reg; - +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) + struct clk *clk; +#endif struct r8a66597_device device0; struct r8a66597_root_hub root_hub[R8A66597_MAX_ROOT_HUB]; struct list_head pipe_queue[R8A66597_MAX_NUM_PIPE]; -- cgit v1.2.3 From b51339fff240ff179730f8963a758147fd60f3ec Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 31 Oct 2008 20:23:26 +0900 Subject: sh: sh_mobile lcdc clock framework support Add clock framework support to the lcdc driver and adjust the board specific code accordingly. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index efff672fd7b..c81ee00c54d 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -35,6 +35,7 @@ struct sh_mobile_lcdc_chan { struct sh_mobile_lcdc_priv { void __iomem *base; #ifdef CONFIG_HAVE_CLK + struct clk *dot_clk; struct clk *clk; #endif unsigned long lddckr; @@ -207,6 +208,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) int k, m; int ret = 0; +#ifdef CONFIG_HAVE_CLK + clk_enable(priv->clk); + if (priv->dot_clk) + clk_enable(priv->dot_clk); +#endif /* reset */ lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET); lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0); @@ -371,6 +377,12 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv) /* stop the lcdc */ sh_mobile_lcdc_start_stop(priv, 0); + +#ifdef CONFIG_HAVE_CLK + if (priv->dot_clk) + clk_disable(priv->dot_clk); + clk_disable(priv->clk); +#endif } static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) @@ -413,9 +425,13 @@ static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch) return -EINVAL; } -static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, +static int sh_mobile_lcdc_setup_clocks(struct platform_device *pdev, + int clock_source, struct sh_mobile_lcdc_priv *priv) { +#ifdef CONFIG_HAVE_CLK + char clk_name[8]; +#endif char *str; int icksel; @@ -430,14 +446,20 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, priv->lddckr = icksel << 16; #ifdef CONFIG_HAVE_CLK + snprintf(clk_name, sizeof(clk_name), "lcdc%d", pdev->id); + priv->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(priv->clk)) { + dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); + return PTR_ERR(priv->clk); + } + if (str) { - priv->clk = clk_get(dev, str); - if (IS_ERR(priv->clk)) { - dev_err(dev, "cannot get clock %s\n", str); - return PTR_ERR(priv->clk); + priv->dot_clk = clk_get(&pdev->dev, str); + if (IS_ERR(priv->dot_clk)) { + dev_err(&pdev->dev, "cannot get dot clock %s\n", str); + clk_put(priv->clk); + return PTR_ERR(priv->dot_clk); } - - clk_enable(priv->clk); } #endif @@ -587,8 +609,7 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) goto err1; } - error = sh_mobile_lcdc_setup_clocks(&pdev->dev, - pdata->clock_source, priv); + error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); if (error) { dev_err(&pdev->dev, "unable to setup clocks\n"); goto err1; @@ -697,10 +718,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) } #ifdef CONFIG_HAVE_CLK - if (priv->clk) { - clk_disable(priv->clk); - clk_put(priv->clk); - } + if (priv->dot_clk) + clk_put(priv->dot_clk); + clk_put(priv->clk); #endif if (priv->base) -- cgit v1.2.3 From af505b1eab55445e832bebbe5686f5bd22f1b717 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 13 Nov 2008 12:20:26 +0900 Subject: media: sh_mobile_ceu_camera: Add HAVE_CLK dependency. Signed-off-by: Paul Mundt --- drivers/media/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 47102c2c825..057fd7e160c 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -759,7 +759,7 @@ config VIDEO_PXA27x config VIDEO_SH_MOBILE_CEU tristate "SuperH Mobile CEU Interface driver" - depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA + depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK select VIDEOBUF_DMA_CONTIG ---help--- This is a v4l2 driver for the SuperH Mobile CEU Interface -- cgit v1.2.3 From e7c98dc76d5823444059205e0c7aca49743679f3 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Thu, 13 Nov 2008 18:18:35 +0900 Subject: serial: sh-sci: Codestyle cleanup patch. Trivial coding style cleanups. Signed-off-by: Michael Trimarchi Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 130 +++++++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 165fc010978..31532e97fb9 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -101,6 +101,12 @@ static void sci_stop_tx(struct uart_port *port); static struct sci_port sci_ports[SCI_NPORTS]; static struct uart_driver sci_uart_driver; +static inline struct sci_port * +to_sci_port(struct uart_port *uart) +{ + return container_of(uart, struct sci_port, port); +} + #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && \ defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) static inline void handle_error(struct uart_port *port) @@ -124,7 +130,8 @@ static int get_char(struct uart_port *port) } } while (!(status & SCxSR_RDxF(port))); c = sci_in(port, SCxRDR); - sci_in(port, SCxSR); /* Dummy read */ + /* Dummy read */ + sci_in(port, SCxSR); sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); spin_unlock_irqrestore(&port->lock, flags); @@ -161,7 +168,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) int checksum; - int usegdb=0; + int usegdb = 0; #ifdef CONFIG_SH_STANDARD_BIOS /* This call only does a trap the first time it is @@ -181,7 +188,8 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) put_char(port, 'O'); /* 'O'utput to console */ checksum = 'O'; - for (i=0; iport)) < 0) + /* Keep trying to read a character, this could be neater */ + while ((c = get_char(&kgdb_sci_port->port)) < 0) cpu_relax(); - return c; + return c; } static inline void kgdb_sci_putchar(int c) { - put_char(&kgdb_sci_port->port, c); + put_char(&kgdb_sci_port->port, c); } #endif /* CONFIG_SH_KGDB */ #if defined(__H8300S__) enum { sci_disable, sci_enable }; -static void h8300_sci_config(struct uart_port* port, unsigned int ctrl) +static void h8300_sci_config(struct uart_port *port, unsigned int ctrl) { - volatile unsigned char *mstpcrl=(volatile unsigned char *)MSTPCRL; + volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL; int ch = (port->mapbase - SMR0) >> 3; unsigned char mask = 1 << (ch+1); - if (ctrl == sci_disable) { + if (ctrl == sci_disable) *mstpcrl |= mask; - } else { + else *mstpcrl &= ~mask; - } } static inline void h8300_sci_enable(struct uart_port *port) @@ -251,7 +258,7 @@ static inline void h8300_sci_disable(struct uart_port *port) #endif #if defined(__H8300H__) || defined(__H8300S__) -static void sci_init_pins_sci(struct uart_port* port, unsigned int cflag) +static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) { int ch = (port->mapbase - SMR0) >> 3; @@ -285,14 +292,13 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) #endif #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) -static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) +static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) { unsigned int fcr_val = 0; set_sh771x_scif_pfc(port); - if (cflag & CRTSCTS) { + if (cflag & CRTSCTS) fcr_val |= SCFCR_MCE; - } sci_out(port, SCFCR, fcr_val); } #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) @@ -419,18 +425,26 @@ static inline int scif_rxroom(struct uart_port *port) #elif defined(CONFIG_CPU_SUBTYPE_SH7763) static inline int scif_txroom(struct uart_port *port) { - if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ + if ((port->mapbase == 0xffe00000) || + (port->mapbase == 0xffe08000)) { + /* SCIF0/1*/ return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); - else /* SCIF2 */ + } else { + /* SCIF2 */ return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); + } } static inline int scif_rxroom(struct uart_port *port) { - if((port->mapbase == 0xffe00000) || (port->mapbase == 0xffe08000)) /* SCIF0/1*/ + if ((port->mapbase == 0xffe00000) || + (port->mapbase == 0xffe08000)) { + /* SCIF0/1*/ return sci_in(port, SCRFDR) & 0xff; - else /* SCIF2 */ + } else { + /* SCIF2 */ return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; + } } #else static inline int scif_txroom(struct uart_port *port) @@ -446,12 +460,12 @@ static inline int scif_rxroom(struct uart_port *port) static inline int sci_txroom(struct uart_port *port) { - return ((sci_in(port, SCxSR) & SCI_TDRE) != 0); + return (sci_in(port, SCxSR) & SCI_TDRE) != 0; } static inline int sci_rxroom(struct uart_port *port) { - return ((sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0); + return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; } /* ********************************************************************** * @@ -469,11 +483,10 @@ static void sci_transmit_chars(struct uart_port *port) status = sci_in(port, SCxSR); if (!(status & SCxSR_TDxE(port))) { ctrl = sci_in(port, SCSCR); - if (uart_circ_empty(xmit)) { + if (uart_circ_empty(xmit)) ctrl &= ~SCI_CTRL_FLAGS_TIE; - } else { + else ctrl |= SCI_CTRL_FLAGS_TIE; - } sci_out(port, SCSCR, ctrl); return; } @@ -521,11 +534,11 @@ static void sci_transmit_chars(struct uart_port *port) } /* On SH3, SCIF may read end-of-break as a space->mark char */ -#define STEPFN(c) ({int __c=(c); (((__c-1)|(__c)) == -1); }) +#define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); }) static inline void sci_receive_chars(struct uart_port *port) { - struct sci_port *sci_port = (struct sci_port *)port; + struct sci_port *sci_port = to_sci_port(port); struct tty_struct *tty = port->info->port.tty; int i, count, copied = 0; unsigned short status; @@ -550,13 +563,13 @@ static inline void sci_receive_chars(struct uart_port *port) if (port->type == PORT_SCI) { char c = sci_in(port, SCxRDR); - if (uart_handle_sysrq_char(port, c) || sci_port->break_flag) + if (uart_handle_sysrq_char(port, c) || + sci_port->break_flag) count = 0; - else { + else tty_insert_flip_char(tty, c, TTY_NORMAL); - } } else { - for (i=0; ibreak_flag) { sci_port->break_flag = 1; @@ -666,10 +679,11 @@ static inline int sci_handle_errors(struct uart_port *port) /* Do sysrq handling. */ if (uart_handle_break(port)) return 0; - pr_debug("sci: BREAK detected\n"); + pr_debug("sci: BREAK detected\n"); if (tty_insert_flip_char(tty, 0, TTY_BREAK)) - copied++; - } + copied++; + } + } else { /* frame error */ if (tty_insert_flip_char(tty, 0, TTY_FRAME)) @@ -764,7 +778,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) } } else { #if defined(SCIF_ORER) - if((sci_in(port, SCLSR) & SCIF_ORER) != 0) { + if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { struct tty_struct *tty = port->info->port.tty; sci_out(port, SCLSR, 0); @@ -801,8 +815,8 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) struct uart_port *port = ptr; irqreturn_t ret = IRQ_NONE; - ssr_status = sci_in(port,SCxSR); - scr_status = sci_in(port,SCSCR); + ssr_status = sci_in(port, SCxSR); + scr_status = sci_in(port, SCSCR); /* Tx Interrupt */ if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) @@ -832,7 +846,7 @@ static int sci_notifier(struct notifier_block *self, int i; if ((phase == CPUFREQ_POSTCHANGE) || - (phase == CPUFREQ_RESUMECHANGE)){ + (phase == CPUFREQ_RESUMECHANGE)) { for (i = 0; i < SCI_NPORTS; i++) { struct uart_port *port = &sci_ports[i].port; struct clk *clk; @@ -904,12 +918,12 @@ static void sci_free_irq(struct sci_port *port) { int i; - if (port->irqs[0] == port->irqs[1]) { - if (!port->irqs[0]) - printk("sci: sci_free_irq error\n"); + if (port->irqs[0] == port->irqs[1]) { + if (!port->irqs[0]) + printk(KERN_ERR "sci: sci_free_irq error\n"); else - free_irq(port->irqs[0], port); - } else { + free_irq(port->irqs[0], port); + } else { for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { if (!port->irqs[i]) continue; @@ -1060,12 +1074,12 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_out(port, SCSMR, smr_val); if (t > 0) { - if(t >= 256) { + if (t >= 256) { sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); t >>= 2; - } else { + } else sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3); - } + sci_out(port, SCBRR, t); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } @@ -1076,16 +1090,20 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_out(port, SCSCR, SCSCR_INIT(port)); if ((termios->c_cflag & CREAD) != 0) - sci_start_rx(port,0); + sci_start_rx(port, 0); } static const char *sci_type(struct uart_port *port) { switch (port->type) { - case PORT_SCI: return "sci"; - case PORT_SCIF: return "scif"; - case PORT_IRDA: return "irda"; - case PORT_SCIFA: return "scifa"; + case PORT_IRDA: + return "irda"; + case PORT_SCI: + return "sci"; + case PORT_SCIF: + return "scif"; + case PORT_SCIFA: + return "scifa"; } return NULL; @@ -1387,9 +1405,9 @@ console_initcall(kgdb_console_init); #endif /* CONFIG_SH_KGDB_CONSOLE */ #if defined(CONFIG_SH_KGDB_CONSOLE) -#define SCI_CONSOLE &kgdb_console +#define SCI_CONSOLE (&kgdb_console) #elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE) -#define SCI_CONSOLE &serial_console +#define SCI_CONSOLE (&serial_console) #else #define SCI_CONSOLE 0 #endif -- cgit v1.2.3 From d6435102d4ca3b5655c0105abe924abec17ffeb8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 18 Nov 2008 12:40:39 +0900 Subject: usb: Fix up sh_mobile usbf clock framework warnings. drivers/usb/gadget/m66592-udc.c: In function 'm66592_probe': drivers/usb/gadget/m66592-udc.c:1672: warning: label 'clean_up2' defined but not used drivers/usb/host/r8a66597-hcd.c: In function 'r8a66597_probe': drivers/usb/host/r8a66597-hcd.c:2401: warning: label 'clean_up2' defined but not used Added by commit 985fc7c81c7852f2e104c71cbe913ace683c9e6a ("sh: sh_mobile usbf clock framework support"). Reported-by: Stephen Rothwell Signed-off-by: Paul Mundt --- drivers/usb/gadget/m66592-udc.c | 2 +- drivers/usb/host/r8a66597-hcd.c | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 201c67b625c..3a8879ec206 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c @@ -1668,8 +1668,8 @@ clean_up3: #if defined(CONFIG_SUPERH_BUILT_IN_M66592) && defined(CONFIG_HAVE_CLK) clk_disable(m66592->clk); clk_put(m66592->clk); -#endif clean_up2: +#endif free_irq(irq, m66592); clean_up: if (m66592) { diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index d99b9c7098b..c21f14e0666 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2396,9 +2396,8 @@ static int __init r8a66597_probe(struct platform_device *pdev) clean_up3: #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) && defined(CONFIG_HAVE_CLK) clk_put(r8a66597->clk); -#endif - clean_up2: +#endif usb_put_hcd(hcd); clean_up: -- cgit v1.2.3 From 679dc3c92ca7894c3df70ee3333ff9878e7d90b9 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 14:34:25 +0900 Subject: sh: sh7760fb: Fix color pallette setting The setting of the color palette was wrong, fixed it. And removed fb_setcmap, and added fb_setcolreg function. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- drivers/video/sh7760fb.c | 86 +++++++++++------------------------------------- 1 file changed, 19 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c index 8d0212da451..653bdfee305 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/sh7760fb.c @@ -13,6 +13,8 @@ * * Thanks to Siegfried Schaefer * for his original source and testing! + * + * sh7760_setcolreg get from drivers/video/sh_mobile_lcdcfb.c */ #include @@ -53,29 +55,6 @@ static irqreturn_t sh7760fb_irq(int irq, void *data) return IRQ_HANDLED; } -static void sh7760fb_wait_vsync(struct fb_info *info) -{ - struct sh7760fb_par *par = info->par; - - if (par->pd->novsync) - return; - - iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK, - par->base + LDINTR); - - if (par->irq < 0) { - /* poll for vert. retrace: status bit is sticky */ - while (!(ioread16(par->base + LDINTR) & VINT_CHECK)) - cpu_relax(); - } else { - /* a "wait_for_irq_event(par->irq)" would be extremely nice */ - init_completion(&par->vsync); - enable_irq(par->irq); - wait_for_completion(&par->vsync); - disable_irq_nosync(par->irq); - } -} - /* wait_for_lps - wait until power supply has reached a certain state. */ static int wait_for_lps(struct sh7760fb_par *par, int val) { @@ -117,55 +96,28 @@ static int sh7760fb_blank(int blank, struct fb_info *info) return wait_for_lps(par, lps); } -/* set color registers */ -static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info) +static int sh7760_setcolreg (u_int regno, + u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info) { - struct sh7760fb_par *par = info->par; - u32 s = cmap->start; - u32 l = cmap->len; - u16 *r = cmap->red; - u16 *g = cmap->green; - u16 *b = cmap->blue; - u32 col, tmo; - int ret; + u32 *palette = info->pseudo_palette; - ret = 0; + if (regno >= 16) + return -EINVAL; - sh7760fb_wait_vsync(info); + /* only FB_VISUAL_TRUECOLOR supported */ - /* request palette access */ - iowrite16(LDPALCR_PALEN, par->base + LDPALCR); + red >>= 16 - info->var.red.length; + green >>= 16 - info->var.green.length; + blue >>= 16 - info->var.blue.length; + transp >>= 16 - info->var.transp.length; - /* poll for access grant */ - tmo = 100; - while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo)) - cpu_relax(); + palette[regno] = (red << info->var.red.offset) | + (green << info->var.green.offset) | + (blue << info->var.blue.offset) | + (transp << info->var.transp.offset); - if (!tmo) { - ret = 1; - dev_dbg(info->dev, "no palette access!\n"); - goto out; - } - - while (l && (s < 256)) { - col = ((*r) & 0xff) << 16; - col |= ((*g) & 0xff) << 8; - col |= ((*b) & 0xff); - col &= SH7760FB_PALETTE_MASK; - iowrite32(col, par->base + LDPR(s)); - - if (s < 16) - ((u32 *) (info->pseudo_palette))[s] = s; - - s++; - l--; - r++; - g++; - b++; - } -out: - iowrite16(0, par->base + LDPALCR); - return ret; + return 0; } static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info, @@ -406,7 +358,7 @@ static struct fb_ops sh7760fb_ops = { .owner = THIS_MODULE, .fb_blank = sh7760fb_blank, .fb_check_var = sh7760fb_check_var, - .fb_setcmap = sh7760fb_setcmap, + .fb_setcolreg = sh7760_setcolreg, .fb_set_par = sh7760fb_set_par, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, -- cgit v1.2.3 From 5c72f303a2b7862dbba79f4176ddc922a440b567 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 21 Nov 2008 14:35:29 +0900 Subject: sh: sh7760fb: Add support SH7720/SH7721 of Renesas SH7720 and 7721 has IP of Frame Buffer same as SH7760. This driver can support these. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3f3ce13fef4..593bbc73101 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2021,17 +2021,19 @@ config FB_COBALT depends on FB && MIPS_COBALT config FB_SH7760 - bool "SH7760/SH7763 LCDC support" - depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller. - Supports display resolutions up to 1024x1024 pixel, grayscale and - color operation, with depths ranging from 1 bpp to 8 bpp monochrome - and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for - panels <= 320 pixel horizontal resolution. + bool "SH7760/SH7763/SH7720/SH7721 LCDC support" + depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Support for the SH7760/SH7763/SH7720/SH7721 integrated + (D)STN/TFT LCD Controller. + Supports display resolutions up to 1024x1024 pixel, grayscale and + color operation, with depths ranging from 1 bpp to 8 bpp monochrome + and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for + panels <= 320 pixel horizontal resolution. config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" -- cgit v1.2.3 From 2825999e8a9bd7ab7e25a7e7475c7cdd10371a13 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Fri, 28 Nov 2008 22:48:20 +0900 Subject: sh: Add support for SH7201 CPU subtype. This patch adds support for the SH-2A FPU based SH7201 processor subtype. Signed-off-by: Peter Griffin Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 9f33b064172..6da755d6352 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -133,13 +133,20 @@ # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ # define SCIF_OPER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ +#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ + defined(CONFIG_CPU_SUBTYPE_SH7203) || \ defined(CONFIG_CPU_SUBTYPE_SH7206) || \ defined(CONFIG_CPU_SUBTYPE_SH7263) # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ # define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ # define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ +# if defined(CONFIG_CPU_SUBTYPE_SH7201) +# define SCSPTR4 0xfffeA020 /* 16 bit SCIF */ +# define SCSPTR5 0xfffeA820 /* 16 bit SCIF */ +# define SCSPTR6 0xfffeB020 /* 16 bit SCIF */ +# define SCSPTR7 0xfffeB820 /* 16 bit SCIF */ +# endif # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7619) # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ @@ -664,7 +671,8 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7203) || \ +#elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ + defined(CONFIG_CPU_SUBTYPE_SH7203) || \ defined(CONFIG_CPU_SUBTYPE_SH7206) || \ defined(CONFIG_CPU_SUBTYPE_SH7263) static inline int sci_rxd_in(struct uart_port *port) @@ -677,6 +685,16 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ if (port->mapbase == 0xfffe9800) return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ +#if defined(CONFIG_CPU_SUBTYPE_SH7201) + if (port->mapbase == 0xfffeA000) + return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffeA800) + return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffeB000) + return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ + if (port->mapbase == 0xfffeB800) + return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ +#endif return 1; } #elif defined(CONFIG_CPU_SUBTYPE_SH7619) -- cgit v1.2.3 From 07d2a1a1cd8d609a4bc320a492670de57ec6bde1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 11 Dec 2008 19:06:43 +0900 Subject: serial: sh-sci: Implement CONSOLE_POLL support and kill off old kgdb console. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 201 +++++------------------------------------------- 1 file changed, 20 insertions(+), 181 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 31532e97fb9..231f77b1649 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -51,7 +51,6 @@ #ifdef CONFIG_SUPERH #include #include -#include #endif #include "sh-sci.h" @@ -85,10 +84,6 @@ struct sci_port { #endif }; -#ifdef CONFIG_SH_KGDB -static struct sci_port *kgdb_sci_port; -#endif - #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE static struct sci_port *serial_console_port; #endif @@ -107,21 +102,18 @@ to_sci_port(struct uart_port *uart) return container_of(uart, struct sci_port, port); } -#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && \ - defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) static inline void handle_error(struct uart_port *port) { /* Clear error flags */ sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); } -static int get_char(struct uart_port *port) +static int sci_poll_get_char(struct uart_port *port) { - unsigned long flags; unsigned short status; int c; - spin_lock_irqsave(&port->lock, flags); do { status = sci_in(port, SCxSR); if (status & SCxSR_ERRORS(port)) { @@ -129,24 +121,20 @@ static int get_char(struct uart_port *port) continue; } } while (!(status & SCxSR_RDxF(port))); + c = sci_in(port, SCxRDR); + /* Dummy read */ sci_in(port, SCxSR); sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); - spin_unlock_irqrestore(&port->lock, flags); return c; } -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ -#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || defined(CONFIG_SH_KGDB) -static void put_char(struct uart_port *port, char c) +static void sci_poll_put_char(struct uart_port *port, unsigned char c) { - unsigned long flags; unsigned short status; - spin_lock_irqsave(&port->lock, flags); - do { status = sci_in(port, SCxSR); } while (!(status & SCxSR_TDxE(port))); @@ -154,82 +142,8 @@ static void put_char(struct uart_port *port, char c) sci_in(port, SCxSR); /* Dummy read */ sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); sci_out(port, SCxTDR, c); - - spin_unlock_irqrestore(&port->lock, flags); } -#endif - -#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE -static void put_string(struct sci_port *sci_port, const char *buffer, int count) -{ - struct uart_port *port = &sci_port->port; - const unsigned char *p = buffer; - int i; - -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) - int checksum; - int usegdb = 0; - -#ifdef CONFIG_SH_STANDARD_BIOS - /* This call only does a trap the first time it is - * called, and so is safe to do here unconditionally - */ - usegdb |= sh_bios_in_gdb_mode(); -#endif -#ifdef CONFIG_SH_KGDB - usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); -#endif - - if (usegdb) { - /* $#. */ - do { - unsigned char c; - put_char(port, '$'); - put_char(port, 'O'); /* 'O'utput to console */ - checksum = 'O'; - - /* Don't use run length encoding */ - for (i = 0; i < count; i++) { - int h, l; - - c = *p++; - h = hex_asc_hi(c); - l = hex_asc_lo(c); - put_char(port, h); - put_char(port, l); - checksum += h + l; - } - put_char(port, '#'); - put_char(port, hex_asc_hi(checksum)); - put_char(port, hex_asc_lo(checksum)); - } while (get_char(port) != '+'); - } else -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - for (i = 0; i < count; i++) { - if (*p == 10) - put_char(port, '\r'); - put_char(port, *p++); - } -} -#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ - -#ifdef CONFIG_SH_KGDB -static int kgdb_sci_getchar(void) -{ - int c; - - /* Keep trying to read a character, this could be neater */ - while ((c = get_char(&kgdb_sci_port->port)) < 0) - cpu_relax(); - - return c; -} - -static inline void kgdb_sci_putchar(int c) -{ - put_char(&kgdb_sci_port->port, c); -} -#endif /* CONFIG_SH_KGDB */ +#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ #if defined(__H8300S__) enum { sci_disable, sci_enable }; @@ -1181,6 +1095,10 @@ static struct uart_ops sci_uart_ops = { .request_port = sci_request_port, .config_port = sci_config_port, .verify_port = sci_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = sci_poll_get_char, + .poll_put_char = sci_poll_put_char, +#endif }; static void __init sci_init_ports(void) @@ -1247,7 +1165,15 @@ int __init early_sci_setup(struct uart_port *port) static void serial_console_write(struct console *co, const char *s, unsigned count) { - put_string(serial_console_port, s, count); + struct uart_port *port = &serial_console_port->port; + int i; + + for (i = 0; i < count; i++) { + if (*s == 10) + sci_poll_put_char(port, '\r'); + + sci_poll_put_char(port, *s++); + } } static int __init serial_console_setup(struct console *co, char *options) @@ -1325,88 +1251,7 @@ static int __init sci_console_init(void) console_initcall(sci_console_init); #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ -#ifdef CONFIG_SH_KGDB_CONSOLE -/* - * FIXME: Most of this can go away.. at the moment, we rely on - * arch/sh/kernel/setup.c to do the command line parsing for kgdb, though - * most of that can easily be done here instead. - * - * For the time being, just accept the values that were parsed earlier.. - */ -static void __init kgdb_console_get_options(struct uart_port *port, int *baud, - int *parity, int *bits) -{ - *baud = kgdb_baud; - *parity = tolower(kgdb_parity); - *bits = kgdb_bits - '0'; -} - -/* - * The naming here is somewhat misleading, since kgdb_console_setup() takes - * care of the early-on initialization for kgdb, regardless of whether we - * actually use kgdb as a console or not. - * - * On the plus side, this lets us kill off the old kgdb_sci_setup() nonsense. - */ -int __init kgdb_console_setup(struct console *co, char *options) -{ - struct uart_port *port = &sci_ports[kgdb_portnum].port; - int baud = 38400; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - if (co->index != kgdb_portnum) - co->index = kgdb_portnum; - - kgdb_sci_port = &sci_ports[co->index]; - port = &kgdb_sci_port->port; - - /* - * Also need to check port->type, we don't actually have any - * UPIO_PORT ports, but uart_report_port() handily misreports - * it anyways if we don't have a port available by the time this is - * called. - */ - if (!port->type) - return -ENODEV; - if (!port->membase || !port->mapbase) - return -ENODEV; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else - kgdb_console_get_options(port, &baud, &parity, &bits); - - kgdb_getchar = kgdb_sci_getchar; - kgdb_putchar = kgdb_sci_putchar; - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -static struct console kgdb_console = { - .name = "ttySC", - .device = uart_console_device, - .write = kgdb_console_write, - .setup = kgdb_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &sci_uart_driver, -}; - -/* Register the KGDB console so we get messages (d'oh!) */ -static int __init kgdb_console_init(void) -{ - sci_init_ports(); - register_console(&kgdb_console); - return 0; -} -console_initcall(kgdb_console_init); -#endif /* CONFIG_SH_KGDB_CONSOLE */ - -#if defined(CONFIG_SH_KGDB_CONSOLE) -#define SCI_CONSOLE (&kgdb_console) -#elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE) +#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) #define SCI_CONSOLE (&serial_console) #else #define SCI_CONSOLE 0 @@ -1481,12 +1326,6 @@ static int __devinit sci_probe(struct platform_device *dev) uart_add_one_port(&sci_uart_driver, &sciport->port); } -#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) - kgdb_sci_port = &sci_ports[kgdb_portnum]; - kgdb_getchar = kgdb_sci_getchar; - kgdb_putchar = kgdb_sci_putchar; -#endif - #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); dev_info(&dev->dev, "CPU frequency notifier registered\n"); -- cgit v1.2.3 From 027e68724935599417faa7dd4123c117d18e2483 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Dec 2008 18:36:16 +0900 Subject: serial: sh-sci: Fix up the cpufreq notifier to use the proper port clock. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 231f77b1649..2cbefd2ca52 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -748,7 +748,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) return ret; } -#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK /* * Here we define a transistion notifier so that we can update all of our * ports' baud rate when the peripheral clock changes. @@ -756,41 +756,20 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) static int sci_notifier(struct notifier_block *self, unsigned long phase, void *p) { - struct cpufreq_freqs *freqs = p; int i; if ((phase == CPUFREQ_POSTCHANGE) || - (phase == CPUFREQ_RESUMECHANGE)) { + (phase == CPUFREQ_RESUMECHANGE)) for (i = 0; i < SCI_NPORTS; i++) { - struct uart_port *port = &sci_ports[i].port; - struct clk *clk; - - /* - * Update the uartclk per-port if frequency has - * changed, since it will no longer necessarily be - * consistent with the old frequency. - * - * Really we want to be able to do something like - * uart_change_speed() or something along those lines - * here to implicitly reset the per-port baud rate.. - * - * Clean this up later.. - */ - clk = clk_get(NULL, "module_clk"); - port->uartclk = clk_get_rate(clk); - clk_put(clk); + struct sci_port *s = &sci_ports[i]; + s->port.uartclk = clk_get_rate(s->clk); } - printk(KERN_INFO "%s: got a postchange notification " - "for cpu %d (old %d, new %d)\n", - __func__, freqs->cpu, freqs->old, freqs->new); - } - return NOTIFY_OK; } static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; -#endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */ +#endif static int sci_request_irq(struct sci_port *port) { @@ -1326,9 +1305,8 @@ static int __devinit sci_probe(struct platform_device *dev) uart_add_one_port(&sci_uart_driver, &sciport->port); } -#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) +#ifdef CONFIG_HAVE_CLK cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); - dev_info(&dev->dev, "CPU frequency notifier registered\n"); #endif #ifdef CONFIG_SH_STANDARD_BIOS @@ -1348,6 +1326,10 @@ static int __devexit sci_remove(struct platform_device *dev) { int i; +#ifdef CONFIG_HAVE_CLK + cpufreq_unregister_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); +#endif + for (i = 0; i < SCI_NPORTS; i++) uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); -- cgit v1.2.3 From 762c69e3cad67a5cc5a01ba74e0b552ae4615258 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Dec 2008 18:55:26 +0900 Subject: serial: sh-sci: pr_debug() -> dev_dbg() conversion. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 49 ++++++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 2cbefd2ca52..0251077693d 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -496,7 +496,7 @@ static inline void sci_receive_chars(struct uart_port *port) } /* Nonzero => end-of-break */ - pr_debug("scif: debounce<%02x>\n", c); + dev_dbg(port->dev, "debounce<%02x>\n", c); sci_port->break_flag = 0; if (STEPFN(c)) { @@ -513,12 +513,13 @@ static inline void sci_receive_chars(struct uart_port *port) /* Store data and status */ if (status&SCxSR_FER(port)) { flag = TTY_FRAME; - pr_debug("sci: frame error\n"); + dev_notice(port->dev, "frame error\n"); } else if (status&SCxSR_PER(port)) { flag = TTY_PARITY; - pr_debug("sci: parity error\n"); + dev_notice(port->dev, "parity error\n"); } else flag = TTY_NORMAL; + tty_insert_flip_char(tty, c, flag); } } @@ -578,7 +579,8 @@ static inline int sci_handle_errors(struct uart_port *port) /* overrun error */ if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) copied++; - pr_debug("sci: overrun error\n"); + + dev_notice(port->dev, "overrun error"); } if (status & SCxSR_FER(port)) { @@ -593,7 +595,9 @@ static inline int sci_handle_errors(struct uart_port *port) /* Do sysrq handling. */ if (uart_handle_break(port)) return 0; - pr_debug("sci: BREAK detected\n"); + + dev_dbg(port->dev, "BREAK detected\n"); + if (tty_insert_flip_char(tty, 0, TTY_BREAK)) copied++; } @@ -602,7 +606,8 @@ static inline int sci_handle_errors(struct uart_port *port) /* frame error */ if (tty_insert_flip_char(tty, 0, TTY_FRAME)) copied++; - pr_debug("sci: frame error\n"); + + dev_notice(port->dev, "frame error\n"); } } @@ -610,7 +615,8 @@ static inline int sci_handle_errors(struct uart_port *port) /* parity error */ if (tty_insert_flip_char(tty, 0, TTY_PARITY)) copied++; - pr_debug("sci: parity error\n"); + + dev_notice(port->dev, "parity error"); } if (copied) @@ -637,7 +643,8 @@ static inline int sci_handle_breaks(struct uart_port *port) /* Notify of BREAK */ if (tty_insert_flip_char(tty, 0, TTY_BREAK)) copied++; - pr_debug("sci: BREAK detected\n"); + + dev_dbg(port->dev, "BREAK detected\n"); } #if defined(SCIF_ORER) @@ -646,7 +653,7 @@ static inline int sci_handle_breaks(struct uart_port *port) sci_out(port, SCLSR, 0); if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { copied++; - pr_debug("sci: overrun error\n"); + dev_notice(port->dev, "overrun error\n"); } } #endif @@ -698,7 +705,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) sci_out(port, SCLSR, 0); tty_insert_flip_char(tty, 0, TTY_OVERRUN); tty_flip_buffer_push(tty); - pr_debug("scif: overrun error\n"); + dev_notice(port->dev, "overrun error\n"); } #endif sci_rx_interrupt(irq, ptr); @@ -782,23 +789,22 @@ static int sci_request_irq(struct sci_port *port) "SCI Transmit Data Empty", "SCI Break" }; if (port->irqs[0] == port->irqs[1]) { - if (!port->irqs[0]) { - printk(KERN_ERR "sci: Cannot allocate irq.(IRQ=0)\n"); + if (unlikely(!port->irqs[0])) return -ENODEV; - } if (request_irq(port->irqs[0], sci_mpxed_interrupt, IRQF_DISABLED, "sci", port)) { - printk(KERN_ERR "sci: Cannot allocate irq.\n"); + dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; } } else { for (i = 0; i < ARRAY_SIZE(handlers); i++) { - if (!port->irqs[i]) + if (unlikely(!port->irqs[i])) continue; + if (request_irq(port->irqs[i], handlers[i], IRQF_DISABLED, desc[i], port)) { - printk(KERN_ERR "sci: Cannot allocate irq.\n"); + dev_err(port->port.dev, "Can't allocate IRQ\n"); return -ENODEV; } } @@ -811,12 +817,9 @@ static void sci_free_irq(struct sci_port *port) { int i; - if (port->irqs[0] == port->irqs[1]) { - if (!port->irqs[0]) - printk(KERN_ERR "sci: sci_free_irq error\n"); - else - free_irq(port->irqs[0], port); - } else { + if (port->irqs[0] == port->irqs[1]) + free_irq(port->irqs[0], port); + else { for (i = 0; i < ARRAY_SIZE(port->irqs); i++) { if (!port->irqs[i]) continue; @@ -1040,7 +1043,7 @@ static void sci_config_port(struct uart_port *port, int flags) port->membase = ioremap_nocache(port->mapbase, 0x40); #endif - printk(KERN_ERR "sci: can't remap port#%d\n", port->line); + dev_err(port->dev, "can't remap port#%d\n", port->line); } } -- cgit v1.2.3 From d830fa4584a4015989b9b396a80779f28f277baa Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Dec 2008 19:29:38 +0900 Subject: serial: sh-sci: Tidy up fifo overrun error handling. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 45 ++++++++++++++++++++++++--------------------- drivers/serial/sh-sci.h | 11 +++++------ 2 files changed, 29 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 0251077693d..b0feea49398 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -625,6 +625,27 @@ static inline int sci_handle_errors(struct uart_port *port) return copied; } +static inline int sci_handle_fifo_overrun(struct uart_port *port) +{ + struct tty_struct *tty = port->info->port.tty; + int copied = 0; + + if (port->type != PORT_SCIF) + return 0; + + if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { + sci_out(port, SCLSR, 0); + + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_flip_buffer_push(tty); + + dev_notice(port->dev, "overrun error\n"); + copied++; + } + + return copied; +} + static inline int sci_handle_breaks(struct uart_port *port) { int copied = 0; @@ -647,20 +668,11 @@ static inline int sci_handle_breaks(struct uart_port *port) dev_dbg(port->dev, "BREAK detected\n"); } -#if defined(SCIF_ORER) - /* XXX: Handle SCIF overrun error */ - if (port->type != PORT_SCI && (sci_in(port, SCLSR) & SCIF_ORER) != 0) { - sci_out(port, SCLSR, 0); - if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { - copied++; - dev_notice(port->dev, "overrun error\n"); - } - } -#endif - if (copied) tty_flip_buffer_push(tty); + copied += sci_handle_fifo_overrun(port); + return copied; } @@ -698,16 +710,7 @@ static irqreturn_t sci_er_interrupt(int irq, void *ptr) sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port)); } } else { -#if defined(SCIF_ORER) - if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { - struct tty_struct *tty = port->info->port.tty; - - sci_out(port, SCLSR, 0); - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - tty_flip_buffer_push(tty); - dev_notice(port->dev, "overrun error\n"); - } -#endif + sci_handle_fifo_overrun(port); sci_rx_interrupt(irq, ptr); } diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 6da755d6352..4479a91e247 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -232,6 +232,10 @@ # define SCIF_TXROOM_MAX 16 #endif +#ifndef SCIF_ORER +#define SCIF_ORER 0x0000 +#endif + #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) #define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) @@ -239,12 +243,7 @@ #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) - -#if defined(CONFIG_CPU_SUBTYPE_SH7705) -# define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER) -#else -# define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : 0x0000) -#endif +#define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER) #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7720) || \ -- cgit v1.2.3 From d5701647f1aaaea5da20023976d86af79ab84707 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 16 Dec 2008 20:07:27 +0900 Subject: serial: sh-sci: Generalize port pin initialization. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 145 ++++++++++++++---------------------------------- drivers/serial/sh-sci.h | 12 ---- 2 files changed, 43 insertions(+), 114 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index b0feea49398..cf663b71869 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -64,10 +64,6 @@ struct sci_port { /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ unsigned int irqs[SCIx_NR_IRQS]; - /* Port pin configuration */ - void (*init_pins)(struct uart_port *port, - unsigned int cflag); - /* Port enable callback */ void (*enable)(struct uart_port *port); @@ -172,7 +168,7 @@ static inline void h8300_sci_disable(struct uart_port *port) #endif #if defined(__H8300H__) || defined(__H8300S__) -static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) +static void sci_init_pins(struct uart_port *port, unsigned int cflag) { int ch = (port->mapbase - SMR0) >> 3; @@ -187,140 +183,99 @@ static void sci_init_pins_sci(struct uart_port *port, unsigned int cflag) /* tx mark output*/ H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; } -#else -#define sci_init_pins_sci NULL -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) -static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; - - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - - sci_out(port, SCFCR, fcr_val); -} -#else -#define sci_init_pins_irda NULL -#endif - -#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - unsigned int fcr_val = 0; - - set_sh771x_scif_pfc(port); - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - sci_out(port, SCFCR, fcr_val); + if (port->mapbase == 0xA4400000) { + __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); + __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); + } else if (port->mapbase == 0xA4410000) + __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); } #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; if (cflag & CRTSCTS) { /* enable RTS/CTS */ if (port->mapbase == 0xa4430000) { /* SCIF0 */ /* Clear PTCR bit 9-2; enable all scif pins but sck */ - data = ctrl_inw(PORT_PTCR); - ctrl_outw((data & 0xfc03), PORT_PTCR); + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xfc03), PORT_PTCR); } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ /* Clear PVCR bit 9-2 */ - data = ctrl_inw(PORT_PVCR); - ctrl_outw((data & 0xfc03), PORT_PVCR); + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xfc03), PORT_PVCR); } - fcr_val |= SCFCR_MCE; } else { if (port->mapbase == 0xa4430000) { /* SCIF0 */ /* Clear PTCR bit 5-2; enable only tx and rx */ - data = ctrl_inw(PORT_PTCR); - ctrl_outw((data & 0xffc3), PORT_PTCR); + data = __raw_readw(PORT_PTCR); + __raw_writew((data & 0xffc3), PORT_PTCR); } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ /* Clear PVCR bit 5-2 */ - data = ctrl_inw(PORT_PVCR); - ctrl_outw((data & 0xffc3), PORT_PVCR); + data = __raw_readw(PORT_PVCR); + __raw_writew((data & 0xffc3), PORT_PVCR); } } - sci_out(port, SCFCR, fcr_val); } #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; /* We need to set SCPCR to enable RTS/CTS */ - data = ctrl_inw(SCPCR); + data = __raw_readw(SCPCR); /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ - ctrl_outw(data & 0x0fcf, SCPCR); + __raw_writew(data & 0x0fcf, SCPCR); - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - else { + if (!(cflag & CRTSCTS)) { /* We need to set SCPCR to enable RTS/CTS */ - data = ctrl_inw(SCPCR); + data = __raw_readw(SCPCR); /* Clear out SCP7MD1,0, SCP4MD1,0, Set SCP6MD1,0 = {01} (output) */ - ctrl_outw((data & 0x0fcf) | 0x1000, SCPCR); + __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); data = ctrl_inb(SCPDR); /* Set /RTS2 (bit6) = 0 */ ctrl_outb(data & 0xbf, SCPDR); } - - sci_out(port, SCFCR, fcr_val); } #elif defined(CONFIG_CPU_SUBTYPE_SH7722) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) { - unsigned int fcr_val = 0; unsigned short data; if (port->mapbase == 0xffe00000) { - data = ctrl_inw(PSCR); + data = __raw_readw(PSCR); data &= ~0x03cf; - if (cflag & CRTSCTS) - fcr_val |= SCFCR_MCE; - else + if (!(cflag & CRTSCTS)) data |= 0x0340; - ctrl_outw(data, PSCR); + __raw_writew(data, PSCR); } - /* SCIF1 and SCIF2 should be setup by board code */ - - sci_out(port, SCFCR, fcr_val); -} -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - /* Nothing to do here.. */ - sci_out(port, SCFCR, 0); } -#else -/* For SH7750 */ -static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) -{ - unsigned int fcr_val = 0; - - if (cflag & CRTSCTS) { - fcr_val |= SCFCR_MCE; - } else { -#if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366) - /* Nothing */ #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) || \ defined(CONFIG_CPU_SUBTYPE_SHX3) - ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + if (!(cflag & CRTSCTS)) + __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ +} +#elif defined(CONFIG_CPU_SH4) +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + if (!(cflag & CRTSCTS)) + __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ +} #else - ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ -#endif - } - sci_out(port, SCFCR, fcr_val); +static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) +{ + /* Nothing to do */ } #endif @@ -941,7 +896,6 @@ static void sci_shutdown(struct uart_port *port) static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { - struct sci_port *s = &sci_ports[port->line]; unsigned int status, baud, smr_val; int t = -1; @@ -983,8 +937,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } - if (likely(s->init_pins)) - s->init_pins(port, termios->c_cflag); + sci_init_pins(port, termios->c_cflag); + sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); sci_out(port, SCSCR, SCSCR_INIT(port)); @@ -1025,19 +979,6 @@ static void sci_config_port(struct uart_port *port, int flags) port->type = s->type; - switch (port->type) { - case PORT_SCI: - s->init_pins = sci_init_pins_sci; - break; - case PORT_SCIF: - case PORT_SCIFA: - s->init_pins = sci_init_pins_scif; - break; - case PORT_IRDA: - s->init_pins = sci_init_pins_irda; - break; - } - if (port->flags & UPF_IOREMAP && !port->membase) { #if defined(CONFIG_SUPERH64) port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 4479a91e247..38c600c0dbb 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -507,18 +507,6 @@ static inline int sci_rxd_in(struct uart_port *port) { return sci_in(port,SCxSR)&0x0010 ? 1 : 0; } -static inline void set_sh771x_scif_pfc(struct uart_port *port) -{ - if (port->mapbase == 0xA4400000){ - ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR); - ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR); - return; - } - if (port->mapbase == 0xA4410000){ - ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR); - return; - } -} #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) static inline int sci_rxd_in(struct uart_port *port) -- cgit v1.2.3 From 1f6fd5c916c8416588f5797e7837b9e81b3251a5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 17 Dec 2008 14:53:24 +0900 Subject: serial: sh-sci: sci_poll_get_char() is only used by CONFIG_CONSOLE_POLL. sci_poll_put_char() happens to also be used by the serial console, while sci_poll_get_char() is only used by CONFIG_CONSOLE_POLL. Add another gnarly ifdef to shut up the compiler. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index cf663b71869..a628081e586 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -99,6 +99,8 @@ to_sci_port(struct uart_port *uart) } #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) + +#ifdef CONFIG_CONSOLE_POLL static inline void handle_error(struct uart_port *port) { /* Clear error flags */ @@ -126,6 +128,7 @@ static int sci_poll_get_char(struct uart_port *port) return c; } +#endif static void sci_poll_put_char(struct uart_port *port, unsigned char c) { -- cgit v1.2.3 From 2540c111ead82cad605ec2b14a1905ad914cc124 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 17 Dec 2008 17:29:49 +0900 Subject: sh_mobile_lcdc: use FB_SYS helpers instead of FB_CFB Since the sh_mobile_lcdc hardware has the framebuffer(s) in system RAM, use FB_SYS instead of FB_CFB. Also hook in read and write helpers. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 8 ++++---- drivers/video/sh_mobile_lcdcfb.c | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 593bbc73101..dd483bfe395 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1889,10 +1889,10 @@ config FB_W100 config FB_SH_MOBILE_LCDC tristate "SuperH Mobile LCDC framebuffer support" depends on FB && SUPERH - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default m + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index c81ee00c54d..e339d829183 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -499,9 +499,11 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = { static struct fb_ops sh_mobile_lcdc_ops = { .fb_setcolreg = sh_mobile_lcdc_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_read = fb_sys_read, + .fb_write = fb_sys_write, + .fb_fillrect = sys_fillrect, + .fb_copyarea = sys_copyarea, + .fb_imageblit = sys_imageblit, }; static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp) -- cgit v1.2.3 From 87884bd8ae42c875adbd62c84f47ed1cbb3e5090 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:09 +0900 Subject: video: fix deferred io fsync() If CONFIG_FB_DEFERRED_IO is set, but there are framebuffers registered that does not make use of deferred io, then fsync() on those framebuffers will result in a crash. Fix that. This is needed for sh_mobile_lcdcfb since we always enable deferred io at compile time but we may disable deferred io for some types of hardware configurations. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 4835bdc4e9f..e6dafeddfa5 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -60,6 +60,10 @@ int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) { struct fb_info *info = file->private_data; + /* Skip if deferred io is complied-in but disabled on this fbdev */ + if (!info->fbdefio) + return 0; + /* Kill off the delayed work */ cancel_rearming_delayed_work(&info->deferred_work); -- cgit v1.2.3 From 6e1038a95bebb8a1ad6066c95aa9c3af6963c9ff Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:23 +0900 Subject: video: deferred io cleanup Make sure the mmap callback is set to NULL in the deferred io cleanup function. This way we can enable and disable deferred io on the fly. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index e6dafeddfa5..06060ccd3c2 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -202,6 +202,9 @@ void fb_deferred_io_cleanup(struct fb_info *info) page = vmalloc_to_page(screen_base + i); page->mapping = NULL; } + + info->fbops->fb_mmap = NULL; + mutex_destroy(&fbdefio->lock); } EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); -- cgit v1.2.3 From 37b4837959cb9aa60686ca0d85f73d819251abad Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:32 +0900 Subject: video: deferred io with physically contiguous memory Extend the deferred io code from only supporting vmalloc()ed frame buffer memory to support both vmalloc()ed and physically contiguous frame buffer memory. The sh_mobile_lcdcfb hardware does not support scatter gather so we need physically contiguous memory to back our frame buffer. Signed-off-by: Magnus Damm Acked-by: Jaya Kumar Signed-off-by: Paul Mundt --- drivers/video/fb_defio.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index 06060ccd3c2..082026546ae 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c @@ -24,6 +24,19 @@ #include #include +struct page *fb_deferred_io_page(struct fb_info *info, unsigned long offs) +{ + void *screen_base = (void __force *) info->screen_base; + struct page *page; + + if (is_vmalloc_addr(screen_base + offs)) + page = vmalloc_to_page(screen_base + offs); + else + page = pfn_to_page((info->fix.smem_start + offs) >> PAGE_SHIFT); + + return page; +} + /* this is to find and return the vmalloc-ed fb pages */ static int fb_deferred_io_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -31,14 +44,12 @@ static int fb_deferred_io_fault(struct vm_area_struct *vma, unsigned long offset; struct page *page; struct fb_info *info = vma->vm_private_data; - /* info->screen_base is virtual memory */ - void *screen_base = (void __force *) info->screen_base; offset = vmf->pgoff << PAGE_SHIFT; if (offset >= info->fix.smem_len) return VM_FAULT_SIGBUS; - page = vmalloc_to_page(screen_base + offset); + page = fb_deferred_io_page(info, offset); if (!page) return VM_FAULT_SIGBUS; @@ -188,7 +199,6 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_open); void fb_deferred_io_cleanup(struct fb_info *info) { - void *screen_base = (void __force *) info->screen_base; struct fb_deferred_io *fbdefio = info->fbdefio; struct page *page; int i; @@ -199,7 +209,7 @@ void fb_deferred_io_cleanup(struct fb_info *info) /* clear out the mapping that we setup */ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { - page = vmalloc_to_page(screen_base + i); + page = fb_deferred_io_page(info, i); page->mapping = NULL; } -- cgit v1.2.3 From 8564557a03c12adb9c4b76ae1e86db4113a04d13 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 19 Dec 2008 15:34:41 +0900 Subject: video: sh_mobile_lcdcfb deferred io support This patch adds sh_mobile_lcdcfb deferred io support for SYS panels. The LCDC hardware block managed by the sh_mobile_lcdcfb driver supports RGB or SYS panel configurations. SYS panels come with an external display controller that is resposible for refreshing the actual LCD panel. RGB panels are controlled directly by the LCDC and they need to be refreshed by the LCDC hardware. In the case of SYS panels we can save some power by configuring the LCDC hardware block in one-shot mode. In this one-shot mode panel refresh is managed by software. This works well together with deferred io since it allows us to stop clocks for most of the time and only enable clocks when we actually want to trigger an update. When there is no fbdev activity the clocks are kept stopped which allows us to deep sleep. The refresh rate in deferred io mode is set using platform data. The same platform data can also be used to disable deferred io mode. As with other deferred io frame buffers user space code should use fsync() on the frame buffer device to trigger an update. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/video/Kconfig | 1 + drivers/video/sh_mobile_lcdcfb.c | 170 ++++++++++++++++++++++++++++++++++----- 2 files changed, 149 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index dd483bfe395..d0c821992a9 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1893,6 +1893,7 @@ config FB_SH_MOBILE_LCDC select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT select FB_SYS_FOPS + select FB_DEFERRED_IO ---help--- Frame buffer driver for the on-chip SH-Mobile LCD controller. diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index e339d829183..0e2b8fd24df 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -16,7 +16,9 @@ #include #include #include +#include #include