* [WIP/RFC 08/31] fbdev: sh_mobile_hdmi: Implement sh_mobile_lcdc_entity interface
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 43 +++++++++++++++++++++++++++++----------
1 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index e888081..ce858d6 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -208,6 +208,8 @@ enum hotplug_state {
};
struct sh_hdmi {
+ struct sh_mobile_lcdc_entity entity;
+
void __iomem *base;
enum hotplug_state hp_state; /* hot-plug status */
u8 preprogrammed_vic; /* use a pre-programmed VIC or
@@ -225,6 +227,9 @@ struct sh_hdmi {
struct notifier_block notifier;
};
+#define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity)
+#define notifier_to_sh_hdmi(n) container_of(n, struct sh_hdmi, notifier)
+
static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
{
iowrite8(data, hdmi->base + reg);
@@ -999,13 +1004,14 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
}
/* locking: called with info->lock held, or before register_framebuffer() */
-static void sh_hdmi_display_on(void *arg, struct fb_info *info)
+static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
+ struct fb_info *info)
{
/*
* info is guaranteed to be valid, when we are called, because our
* FB_EVENT_FB_UNBIND notify is also called with info->lock held
*/
- struct sh_hdmi *hdmi = arg;
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
struct sh_mobile_lcdc_chan *ch = info->par;
dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state);
@@ -1032,16 +1038,31 @@ static void sh_hdmi_display_on(void *arg, struct fb_info *info)
}
}
+static void sh_hdmi_display_on(void *arg, struct fb_info *info)
+{
+ __sh_hdmi_display_on(arg, info);
+}
+
/* locking: called with info->lock held */
-static void sh_hdmi_display_off(void *arg)
+static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
{
- struct sh_hdmi *hdmi = arg;
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi);
/* PS mode e->a */
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
+static void sh_hdmi_display_off(void *arg)
+{
+ __sh_hdmi_display_off(arg);
+}
+
+static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
+ .display_on = __sh_hdmi_display_on,
+ .display_off = __sh_hdmi_display_off,
+};
+
static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
{
struct fb_info *info = hdmi->info;
@@ -1153,7 +1174,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (lock_fb_info(info)) {
info->var.width = hdmi->var.width;
info->var.height = hdmi->var.height;
- sh_hdmi_display_on(hdmi, info);
+ __sh_hdmi_display_on(&hdmi->entity, info);
unlock_fb_info(info);
}
} else {
@@ -1192,9 +1213,7 @@ static int sh_hdmi_notify(struct notifier_block *nb,
{
struct fb_event *event = data;
struct fb_info *info = event->info;
- struct sh_mobile_lcdc_chan *ch = info->par;
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
- struct sh_hdmi *hdmi = board_cfg->board_data;
+ struct sh_hdmi *hdmi = notifier_to_sh_hdmi(nb);
if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
return NOTIFY_DONE;
@@ -1246,6 +1265,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
mutex_init(&hdmi->mutex);
hdmi->dev = &pdev->dev;
+ hdmi->entity.owner = THIS_MODULE;
+ hdmi->entity.ops = &sh_hdmi_ops;
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
if (IS_ERR(hdmi->hdmi_clk)) {
@@ -1285,12 +1306,12 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto emap;
}
- platform_set_drvdata(pdev, hdmi);
+ platform_set_drvdata(pdev, &hdmi->entity);
/* Set up LCDC callbacks */
board_cfg = &pdata->lcd_chan->board_cfg;
board_cfg->owner = THIS_MODULE;
- board_cfg->board_data = hdmi;
+ board_cfg->board_data = &hdmi->entity;
board_cfg->display_on = sh_hdmi_display_on;
board_cfg->display_off = sh_hdmi_display_off;
@@ -1344,7 +1365,7 @@ egetclk:
static int __exit sh_hdmi_remove(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
- struct sh_hdmi *hdmi = platform_get_drvdata(pdev);
+ struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev));
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
int irq = platform_get_irq(pdev, 0);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 09/31] fbdev: sh_mipi_dsi: Implement sh_mobile_lcdc_entity interface
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 49 +++++++++++++++++++++++++++++++++++--------
1 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 24640c8..31a403d 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -22,6 +22,8 @@
#include <video/sh_mipi_dsi.h>
#include <video/sh_mobile_lcdc.h>
+#include "sh_mobile_lcdcfb.h"
+
#define SYSCTRL 0x0000
#define SYSCONF 0x0004
#define TIMSET 0x0008
@@ -47,6 +49,8 @@
#define MAX_SH_MIPI_DSI 2
struct sh_mipi {
+ struct sh_mobile_lcdc_entity entity;
+
void __iomem *base;
void __iomem *linkbase;
struct clk *dsit_clk;
@@ -58,6 +62,8 @@ struct sh_mipi {
void (*next_display_off)(void *board_data);
};
+#define to_sh_mipi(e) container_of(e, struct sh_mipi, entity)
+
static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
/* Protect the above array */
@@ -118,33 +124,55 @@ static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
static void sh_mipi_shutdown(struct platform_device *pdev)
{
- struct sh_mipi *mipi = platform_get_drvdata(pdev);
+ struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
sh_mipi_dsi_enable(mipi, false);
}
-static void mipi_display_on(void *arg, struct fb_info *info)
+static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
+ struct fb_info *info)
{
- struct sh_mipi *mipi = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
pm_runtime_get_sync(mipi->dev);
sh_mipi_dsi_enable(mipi, true);
+}
+
+static void mipi_display_on(void *arg, struct fb_info *info)
+{
+ struct sh_mobile_lcdc_entity *entity = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
+
+ __mipi_display_on(entity, info);
if (mipi->next_display_on)
mipi->next_display_on(mipi->next_board_data, info);
}
+static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
+{
+ struct sh_mipi *mipi = to_sh_mipi(entity);
+
+ sh_mipi_dsi_enable(mipi, false);
+ pm_runtime_put(mipi->dev);
+}
+
static void mipi_display_off(void *arg)
{
- struct sh_mipi *mipi = arg;
+ struct sh_mobile_lcdc_entity *entity = arg;
+ struct sh_mipi *mipi = to_sh_mipi(entity);
if (mipi->next_display_off)
mipi->next_display_off(mipi->next_board_data);
- sh_mipi_dsi_enable(mipi, false);
- pm_runtime_put(mipi->dev);
+ __mipi_display_off(entity);
}
+static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
+ .display_on = __mipi_display_on,
+ .display_off = __mipi_display_off,
+};
+
static int __init sh_mipi_setup(struct sh_mipi *mipi,
struct sh_mipi_dsi_info *pdata)
{
@@ -383,6 +411,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
goto ealloc;
}
+ mipi->entity.owner = THIS_MODULE;
+ mipi->entity.ops = &mipi_ops;
+
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "MIPI register region already claimed\n");
ret = -EBUSY;
@@ -466,7 +497,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
goto emipisetup;
mutex_unlock(&array_lock);
- platform_set_drvdata(pdev, mipi);
+ platform_set_drvdata(pdev, &mipi->entity);
/* Save original LCDC callbacks */
mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data;
@@ -474,7 +505,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off;
/* Set up LCDC callbacks */
- pdata->lcd_chan->board_cfg.board_data = mipi;
+ pdata->lcd_chan->board_cfg.board_data = &mipi->entity;
pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
@@ -515,7 +546,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- struct sh_mipi *mipi = platform_get_drvdata(pdev);
+ struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
int i, ret;
mutex_lock(&array_lock);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 10/31] fbdev: sh_mobile_lcdc: Handle HDMI/MIPI transmitter device directly
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Pass a pointer to the transmitter device through platform data, retrieve
the corresponding sh_mobile_lcdc_entity structure in the probe method
and call the transmitter display_on/off methods directly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 29 ++++++++++++++++++++++++-----
drivers/video/sh_mobile_lcdcfb.h | 2 ++
include/video/sh_mobile_lcdc.h | 2 ++
3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 78f531c..9fd93f7 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -338,6 +338,9 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ if (ch->tx_dev)
+ ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
+
/* HDMI must be enabled before LCDC configuration */
if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
board_cfg->display_on(board_cfg->board_data, ch->info);
@@ -353,6 +356,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
board_cfg->display_off(board_cfg->board_data);
module_put(board_cfg->owner);
}
+
+ if (ch->tx_dev)
+ ch->tx_dev->ops->display_off(ch->tx_dev);
}
/* -----------------------------------------------------------------------------
@@ -1491,18 +1497,21 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
sh_mobile_lcdc_stop(priv);
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
- info = priv->ch[i].info;
+ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
+ info = ch->info;
if (!info || !info->device)
continue;
- if (priv->ch[i].sglist)
- vfree(priv->ch[i].sglist);
+ if (ch->tx_dev)
+ module_put(ch->cfg.tx_dev->dev.driver->owner);
+
+ if (ch->sglist)
+ vfree(ch->sglist);
if (info->screen_base)
dma_free_coherent(&pdev->dev, info->fix.smem_len,
- info->screen_base,
- priv->ch[i].dma_handle);
+ info->screen_base, ch->dma_handle);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
@@ -1597,6 +1606,16 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
info->pseudo_palette = &ch->pseudo_palette;
info->flags = FBINFO_FLAG_DEFAULT;
+ if (cfg->tx_dev) {
+ if (!cfg->tx_dev->dev.driver ||
+ !try_module_get(cfg->tx_dev->dev.driver->owner)) {
+ dev_warn(priv->dev, "unable to get transmitter "
+ "device\n");
+ return -EINVAL;
+ }
+ ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
+ }
+
/* Iterate through the modes to validate them and find the highest
* resolution.
*/
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index f1451c6..c992a98 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -41,6 +41,8 @@ struct sh_mobile_lcdc_entity {
*/
struct sh_mobile_lcdc_chan {
struct sh_mobile_lcdc_priv *lcdc;
+ struct sh_mobile_lcdc_entity *tx_dev;
+
unsigned long *reg_offs;
unsigned long ldmt1r_value;
unsigned long enabled; /* ME and SE in LDCNT2R */
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index fe30b75..0ec59e1 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -186,6 +186,8 @@ struct sh_mobile_lcdc_chan_cfg {
struct sh_mobile_lcdc_bl_info bl_info;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
struct sh_mobile_meram_cfg *meram_cfg;
+
+ struct platform_device *tx_dev; /* HDMI/MIPI transmitter device */
};
struct sh_mobile_lcdc_info {
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 11/31] arm: mach-shmobile: Add LCDC tx_dev field to platform data
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Make sure the transmitter devices get registered before the associated
LCDC devices.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ap4evb.c | 272 ++++++++++++++++---------------
arch/arm/mach-shmobile/board-mackerel.c | 66 ++++----
2 files changed, 176 insertions(+), 162 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 485b151..7085966 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -443,82 +443,6 @@ static struct platform_device usb1_host_device = {
.resource = usb1_host_resources,
};
-static const struct fb_videomode ap4evb_lcdc_modes[] = {
- {
-#ifdef CONFIG_AP4EVB_QHD
- .name = "R63302(QHD)",
- .xres = 544,
- .yres = 961,
- .left_margin = 72,
- .right_margin = 600,
- .hsync_len = 16,
- .upper_margin = 8,
- .lower_margin = 8,
- .vsync_len = 2,
- .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
-#else
- .name = "WVGA Panel",
- .xres = 800,
- .yres = 480,
- .left_margin = 220,
- .right_margin = 110,
- .hsync_len = 70,
- .upper_margin = 20,
- .lower_margin = 5,
- .vsync_len = 5,
- .sync = 0,
-#endif
- },
-};
-static struct sh_mobile_meram_cfg lcd_meram_cfg = {
- .icb[0] = {
- .marker_icb = 28,
- .cache_icb = 24,
- .meram_offset = 0x0,
- .meram_size = 0x40,
- },
- .icb[1] = {
- .marker_icb = 29,
- .cache_icb = 25,
- .meram_offset = 0x40,
- .meram_size = 0x40,
- },
-};
-
-static struct sh_mobile_lcdc_info lcdc_info = {
- .meram_dev = &meram_info,
- .ch[0] = {
- .chan = LCDC_CHAN_MAINLCD,
- .fourcc = V4L2_PIX_FMT_RGB565,
- .lcd_cfg = ap4evb_lcdc_modes,
- .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
- .meram_cfg = &lcd_meram_cfg,
- }
-};
-
-static struct resource lcdc_resources[] = {
- [0] = {
- .name = "LCDC",
- .start = 0xfe940000, /* P4-only space */
- .end = 0xfe943fff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = intcs_evt2irq(0x580),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device lcdc_device = {
- .name = "sh_mobile_lcdc_fb",
- .num_resources = ARRAY_SIZE(lcdc_resources),
- .resource = lcdc_resources,
- .dev = {
- .platform_data = &lcdc_info,
- .coherent_dma_mask = ~0,
- },
-};
-
/*
* QHD display
*/
@@ -575,6 +499,8 @@ static struct resource mipidsi0_resources[] = {
},
};
+static struct sh_mobile_lcdc_info lcdc_info;
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc_info.ch[0],
@@ -597,6 +523,86 @@ static struct platform_device *qhd_devices[] __initdata = {
};
#endif /* CONFIG_AP4EVB_QHD */
+/* LCDC0 */
+static const struct fb_videomode ap4evb_lcdc_modes[] = {
+ {
+#ifdef CONFIG_AP4EVB_QHD
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+#else
+ .name = "WVGA Panel",
+ .xres = 800,
+ .yres = 480,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 70,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .sync = 0,
+#endif
+ },
+};
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+ .icb[0] = {
+ .marker_icb = 28,
+ .cache_icb = 24,
+ .meram_offset = 0x0,
+ .meram_size = 0x40,
+ },
+ .icb[1] = {
+ .marker_icb = 29,
+ .cache_icb = 25,
+ .meram_offset = 0x40,
+ .meram_size = 0x40,
+ },
+};
+
+static struct sh_mobile_lcdc_info lcdc_info = {
+ .meram_dev = &meram_info,
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .lcd_cfg = ap4evb_lcdc_modes,
+ .num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
+ .meram_cfg = &lcd_meram_cfg,
+#ifdef CONFIG_AP4EVB_QHD
+ .tx_dev = &mipidsi0_device,
+#endif
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
/* FSI */
#define IRQ_FSI evt2irq(0x1840)
static int __fsi_set_rate(struct clk *clk, long rate, int enable)
@@ -763,6 +769,62 @@ static struct platform_device fsi_device = {
static struct platform_device fsi_ak4643_device = {
.name = "sh_fsi2_a_ak4643",
};
+
+/* LCDC1 */
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq);
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info;
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
+ .flags = HDMI_SND_SRC_SPDIF,
+ .clk_optimize_parent = ap4evb_clk_optimize,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
+static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
+ unsigned long *parent_freq)
+{
+ struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
+ long error;
+
+ if (IS_ERR(hdmi_ick)) {
+ int ret = PTR_ERR(hdmi_ick);
+ pr_err("Cannot get HDMI ICK: %d\n", ret);
+ return ret;
+ }
+
+ error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
+
+ clk_put(hdmi_ick);
+
+ return error;
+}
+
static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.icb[0] = {
.marker_icb = 30,
@@ -788,6 +850,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
.meram_cfg = &hdmi_meram_cfg,
+ .tx_dev = &hdmi_device,
}
};
@@ -815,63 +878,10 @@ static struct platform_device lcdc1_device = {
},
};
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
- unsigned long *parent_freq);
-
-
-static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
- .flags = HDMI_SND_SRC_SPDIF,
- .clk_optimize_parent = ap4evb_clk_optimize,
-};
-
-static struct resource hdmi_resources[] = {
- [0] = {
- .name = "HDMI",
- .start = 0xe6be0000,
- .end = 0xe6be00ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
- .start = evt2irq(0x17e0),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device hdmi_device = {
- .name = "sh-mobile-hdmi",
- .num_resources = ARRAY_SIZE(hdmi_resources),
- .resource = hdmi_resources,
- .id = -1,
- .dev = {
- .platform_data = &hdmi_info,
- },
-};
-
static struct platform_device fsi_hdmi_device = {
.name = "sh_fsi2_b_hdmi",
};
-static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
- unsigned long *parent_freq)
-{
- struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
- long error;
-
- if (IS_ERR(hdmi_ick)) {
- int ret = PTR_ERR(hdmi_ick);
- pr_err("Cannot get HDMI ICK: %d\n", ret);
- return ret;
- }
-
- error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
-
- clk_put(hdmi_ick);
-
- return error;
-}
-
static struct gpio_led ap4evb_leds[] = {
{
.name = "led4",
@@ -1006,9 +1016,9 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&fsi_ak4643_device,
&fsi_hdmi_device,
&sh_mmcif_device,
- &lcdc1_device,
- &lcdc_device,
&hdmi_device,
+ &lcdc_device,
+ &lcdc1_device,
&ceu_device,
&ap4evb_camera,
&meram_device,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 6f42cd8..fbb88a5 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -430,6 +430,38 @@ static struct platform_device lcdc_device = {
},
};
+/* HDMI */
+static struct sh_mobile_lcdc_info hdmi_lcdc_info;
+
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .lcd_chan = &hdmi_lcdc_info.ch[0],
+ .flags = HDMI_SND_SRC_SPDIF,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be00ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
+ .start = evt2irq(0x17e0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.icb[0] = {
.marker_icb = 30,
@@ -444,7 +476,7 @@ static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
.meram_size = 0x100,
},
};
-/* HDMI */
+
static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
.meram_dev = &mackerel_meram_info,
.clock_source = LCDC_CLK_EXTERNAL,
@@ -455,6 +487,7 @@ static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
.meram_cfg = &hdmi_meram_cfg,
+ .tx_dev = &hdmi_device,
}
};
@@ -482,35 +515,6 @@ static struct platform_device hdmi_lcdc_device = {
},
};
-static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &hdmi_lcdc_info.ch[0],
- .flags = HDMI_SND_SRC_SPDIF,
-};
-
-static struct resource hdmi_resources[] = {
- [0] = {
- .name = "HDMI",
- .start = 0xe6be0000,
- .end = 0xe6be00ff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
- .start = evt2irq(0x17e0),
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device hdmi_device = {
- .name = "sh-mobile-hdmi",
- .num_resources = ARRAY_SIZE(hdmi_resources),
- .resource = hdmi_resources,
- .id = -1,
- .dev = {
- .platform_data = &hdmi_info,
- },
-};
-
static struct platform_device fsi_hdmi_device = {
.name = "sh_fsi2_b_hdmi",
};
@@ -1304,8 +1308,8 @@ static struct platform_device *mackerel_devices[] __initdata = {
&sh_mmcif_device,
&ceu_device,
&mackerel_camera,
- &hdmi_lcdc_device,
&hdmi_device,
+ &hdmi_lcdc_device,
&meram_device,
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 12/31] fbdev: sh_mipi_dsi: Don't hook up into board_cfg display operations
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The display_on/off operations are now accessed through the
sh_mobile_lcdc_entity operations.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 51 +++---------------------------------------
1 files changed, 4 insertions(+), 47 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 31a403d..e198067 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -56,10 +56,6 @@ struct sh_mipi {
struct clk *dsit_clk;
struct clk *dsip_clk;
struct device *dev;
-
- void *next_board_data;
- void (*next_display_on)(void *board_data, struct fb_info *info);
- void (*next_display_off)(void *board_data);
};
#define to_sh_mipi(e) container_of(e, struct sh_mipi, entity)
@@ -129,7 +125,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
+static void mipi_display_on(struct sh_mobile_lcdc_entity *entity,
struct fb_info *info)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
@@ -138,18 +134,7 @@ static void __mipi_display_on(struct sh_mobile_lcdc_entity *entity,
sh_mipi_dsi_enable(mipi, true);
}
-static void mipi_display_on(void *arg, struct fb_info *info)
-{
- struct sh_mobile_lcdc_entity *entity = arg;
- struct sh_mipi *mipi = to_sh_mipi(entity);
-
- __mipi_display_on(entity, info);
-
- if (mipi->next_display_on)
- mipi->next_display_on(mipi->next_board_data, info);
-}
-
-static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
+static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
@@ -157,20 +142,9 @@ static void __mipi_display_off(struct sh_mobile_lcdc_entity *entity)
pm_runtime_put(mipi->dev);
}
-static void mipi_display_off(void *arg)
-{
- struct sh_mobile_lcdc_entity *entity = arg;
- struct sh_mipi *mipi = to_sh_mipi(entity);
-
- if (mipi->next_display_off)
- mipi->next_display_off(mipi->next_board_data);
-
- __mipi_display_off(entity);
-}
-
static const struct sh_mobile_lcdc_entity_ops mipi_ops = {
- .display_on = __mipi_display_on,
- .display_off = __mipi_display_off,
+ .display_on = mipi_display_on,
+ .display_off = mipi_display_off,
};
static int __init sh_mipi_setup(struct sh_mipi *mipi,
@@ -499,17 +473,6 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
mutex_unlock(&array_lock);
platform_set_drvdata(pdev, &mipi->entity);
- /* Save original LCDC callbacks */
- mipi->next_board_data = pdata->lcd_chan->board_cfg.board_data;
- mipi->next_display_on = pdata->lcd_chan->board_cfg.display_on;
- mipi->next_display_off = pdata->lcd_chan->board_cfg.display_off;
-
- /* Set up LCDC callbacks */
- pdata->lcd_chan->board_cfg.board_data = &mipi->entity;
- pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
- pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
- pdata->lcd_chan->board_cfg.owner = THIS_MODULE;
-
return 0;
emipisetup:
@@ -543,7 +506,6 @@ efindslot:
static int __exit sh_mipi_remove(struct platform_device *pdev)
{
- struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
struct sh_mipi *mipi = to_sh_mipi(platform_get_drvdata(pdev));
@@ -566,11 +528,6 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
if (ret < 0)
return ret;
- pdata->lcd_chan->board_cfg.owner = NULL;
- pdata->lcd_chan->board_cfg.display_on = NULL;
- pdata->lcd_chan->board_cfg.display_off = NULL;
- pdata->lcd_chan->board_cfg.board_data = NULL;
-
pm_runtime_disable(&pdev->dev);
clk_disable(mipi->dsip_clk);
clk_disable(mipi->dsit_clk);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 13/31] fbdev: sh_mobile_hdmi: Don't hook up into board_cfg display operations
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The display_on/off operations are now accessed through the
sh_mobile_lcdc_entity operations.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 35 +++++------------------------------
1 files changed, 5 insertions(+), 30 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index ce858d6..d89645e 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1004,7 +1004,7 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
}
/* locking: called with info->lock held, or before register_framebuffer() */
-static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
+static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
struct fb_info *info)
{
/*
@@ -1038,13 +1038,8 @@ static void __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
}
}
-static void sh_hdmi_display_on(void *arg, struct fb_info *info)
-{
- __sh_hdmi_display_on(arg, info);
-}
-
/* locking: called with info->lock held */
-static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
+static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
{
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
@@ -1053,14 +1048,9 @@ static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL);
}
-static void sh_hdmi_display_off(void *arg)
-{
- __sh_hdmi_display_off(arg);
-}
-
static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
- .display_on = __sh_hdmi_display_on,
- .display_off = __sh_hdmi_display_off,
+ .display_on = sh_hdmi_display_on,
+ .display_off = sh_hdmi_display_off,
};
static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
@@ -1174,7 +1164,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (lock_fb_info(info)) {
info->var.width = hdmi->var.width;
info->var.height = hdmi->var.height;
- __sh_hdmi_display_on(&hdmi->entity, info);
+ sh_hdmi_display_on(&hdmi->entity, info);
unlock_fb_info(info);
}
} else {
@@ -1248,7 +1238,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct sh_mobile_lcdc_board_cfg *board_cfg;
int irq = platform_get_irq(pdev, 0), ret;
struct sh_hdmi *hdmi;
long rate;
@@ -1308,13 +1297,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, &hdmi->entity);
- /* Set up LCDC callbacks */
- board_cfg = &pdata->lcd_chan->board_cfg;
- board_cfg->owner = THIS_MODULE;
- board_cfg->board_data = &hdmi->entity;
- board_cfg->display_on = sh_hdmi_display_on;
- board_cfg->display_off = sh_hdmi_display_off;
-
INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
pm_runtime_enable(&pdev->dev);
@@ -1364,21 +1346,14 @@ egetclk:
static int __exit sh_hdmi_remove(struct platform_device *pdev)
{
- struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev));
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg;
int irq = platform_get_irq(pdev, 0);
snd_soc_unregister_codec(&pdev->dev);
fb_unregister_client(&hdmi->notifier);
- board_cfg->display_on = NULL;
- board_cfg->display_off = NULL;
- board_cfg->board_data = NULL;
- board_cfg->owner = NULL;
-
/* No new work will be scheduled, wait for running ISR */
free_irq(irq, hdmi);
/* Wait for already scheduled work */
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 14/31] arm: mach-shmobile: Don't initialize the hdmi_info lcd_chan field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused and will be removed. Don't initialize it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ap4evb.c | 3 ---
arch/arm/mach-shmobile/board-mackerel.c | 3 ---
2 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 7085966..851e1ac 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -774,10 +774,7 @@ static struct platform_device fsi_ak4643_device = {
static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
unsigned long *parent_freq);
-static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info;
-
static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
.flags = HDMI_SND_SRC_SPDIF,
.clk_optimize_parent = ap4evb_clk_optimize,
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index fbb88a5..332f07e 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -431,10 +431,7 @@ static struct platform_device lcdc_device = {
};
/* HDMI */
-static struct sh_mobile_lcdc_info hdmi_lcdc_info;
-
static struct sh_mobile_hdmi_info hdmi_info = {
- .lcd_chan = &hdmi_lcdc_info.ch[0],
.flags = HDMI_SND_SRC_SPDIF,
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 15/31] fbdev: sh_mobile_hdmi: Remove sh_mobile_hdmi_info lcd_chan field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
include/video/sh_mobile_hdmi.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/include/video/sh_mobile_hdmi.h b/include/video/sh_mobile_hdmi.h
index 0b8d2cf..728f9de 100644
--- a/include/video/sh_mobile_hdmi.h
+++ b/include/video/sh_mobile_hdmi.h
@@ -31,7 +31,6 @@ struct clk;
#define HDMI_SND_SRC_HBR (3 << 0)
struct sh_mobile_hdmi_info {
- struct sh_mobile_lcdc_chan_cfg *lcd_chan;
unsigned int flags;
long (*clk_optimize_parent)(unsigned long target, unsigned long *best_freq,
unsigned long *parent_freq);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 16/31] fbdev: sh_mobile_lcdc: Remove board configuration owner field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 8 ++------
include/video/sh_mobile_lcdc.h | 2 --
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 9fd93f7..543f957 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -342,20 +342,16 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
/* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
+ if (board_cfg->display_on)
board_cfg->display_on(board_cfg->board_data, ch->info);
- module_put(board_cfg->owner);
- }
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
+ if (board_cfg->display_off)
board_cfg->display_off(board_cfg->board_data);
- module_put(board_cfg->owner);
- }
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 0ec59e1..b1b3e8d 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -147,9 +147,7 @@ struct sh_mobile_lcdc_sys_bus_ops {
unsigned long (*read_data)(void *handle);
};
-struct module;
struct sh_mobile_lcdc_board_cfg {
- struct module *owner;
void *board_data;
int (*setup_sys)(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 17/31] fbdev: sh_mobile_lcdc: Remove board configuration board_data field
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field is unused, remove it. Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ag5evm.c | 14 ++------------
arch/arm/mach-shmobile/board-mackerel.c | 4 ++--
arch/sh/boards/mach-ap325rxa/setup.c | 8 ++++----
arch/sh/boards/mach-ecovec24/setup.c | 4 ++--
arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 10 ++++------
arch/sh/boards/mach-migor/lcd_qvga.c | 3 +--
arch/sh/boards/mach-se/7724/setup.c | 2 --
arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 16 ++++++++--------
arch/sh/include/mach-migor/mach/migor.h | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 16 +++++++---------
include/video/sh_mobile_lcdc.h | 13 ++++++-------
11 files changed, 37 insertions(+), 55 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index d0c30a4..139fbd1 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -235,16 +235,6 @@ static void lcd_backlight_reset(void)
gpio_set_value(GPIO_PORT235, 1);
}
-static void lcd_on(void *board_data, struct fb_info *info)
-{
- lcd_backlight_on();
-}
-
-static void lcd_off(void *board_data)
-{
- lcd_backlight_reset();
-}
-
/* LCDC0 */
static const struct fb_videomode lcdc0_modes[] = {
{
@@ -274,8 +264,8 @@ static struct sh_mobile_lcdc_info lcdc0_info = {
.lcd_cfg = lcdc0_modes,
.num_cfg = ARRAY_SIZE(lcdc0_modes),
.board_cfg = {
- .display_on = lcd_on,
- .display_off = lcd_off,
+ .display_on = lcd_backlight_on,
+ .display_off = lcd_backlight_reset,
},
}
};
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 332f07e..9d0d7b2 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -355,14 +355,14 @@ static struct fb_videomode mackerel_lcdc_modes[] = {
},
};
-static int mackerel_set_brightness(void *board_data, int brightness)
+static int mackerel_set_brightness(int brightness)
{
gpio_set_value(GPIO_PORT31, brightness);
return 0;
}
-static int mackerel_get_brightness(void *board_data)
+static int mackerel_get_brightness(void)
{
return gpio_get_value(GPIO_PORT31);
}
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 0a53ecd..477767e 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -156,7 +156,7 @@ static struct platform_device nand_flash_device = {
#define PORT_DRVCRA 0xA405018A
#define PORT_DRVCRB 0xA405018C
-static int ap320_wvga_set_brightness(void *board_data, int brightness)
+static int ap320_wvga_set_brightness(int brightness)
{
if (brightness) {
gpio_set_value(GPIO_PTS3, 0);
@@ -169,12 +169,12 @@ static int ap320_wvga_set_brightness(void *board_data, int brightness)
return 0;
}
-static int ap320_wvga_get_brightness(void *board_data)
+static int ap320_wvga_get_brightness(void)
{
return gpio_get_value(GPIO_PTS3);
}
-static void ap320_wvga_power_on(void *board_data, struct fb_info *info)
+static void ap320_wvga_power_on(void)
{
msleep(100);
@@ -182,7 +182,7 @@ static void ap320_wvga_power_on(void *board_data, struct fb_info *info)
__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);
}
-static void ap320_wvga_power_off(void *board_data)
+static void ap320_wvga_power_off(void)
{
/* ASD AP-320/325 LCD OFF */
__raw_writew(0, FPGA_LCDREG);
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 75e466f..7c592f8 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -310,14 +310,14 @@ static const struct fb_videomode ecovec_dvi_modes[] = {
},
};
-static int ecovec24_set_brightness(void *board_data, int brightness)
+static int ecovec24_set_brightness(int brightness)
{
gpio_set_value(GPIO_PTR1, brightness);
return 0;
}
-static int ecovec24_get_brightness(void *board_data)
+static int ecovec24_get_brightness(void)
{
return gpio_get_value(GPIO_PTR1);
}
diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
index 25e145f..c148b36 100644
--- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
+++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c
@@ -251,8 +251,7 @@ static void display_on(void *sohandle,
write_memory_start(sohandle, so);
}
-int kfr2r09_lcd_setup(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+int kfr2r09_lcd_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
/* power on */
gpio_set_value(GPIO_PTF4, 0); /* PROTECT/ -> L */
@@ -273,8 +272,7 @@ int kfr2r09_lcd_setup(void *board_data, void *sohandle,
return 0;
}
-void kfr2r09_lcd_start(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
write_memory_start(sohandle, so);
}
@@ -327,12 +325,12 @@ static int kfr2r09_lcd_backlight(int on)
return 0;
}
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info)
+void kfr2r09_lcd_on(void)
{
kfr2r09_lcd_backlight(1);
}
-void kfr2r09_lcd_off(void *board_data)
+void kfr2r09_lcd_off(void)
{
kfr2r09_lcd_backlight(0);
}
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c
index de9014a..8bccd34 100644
--- a/arch/sh/boards/mach-migor/lcd_qvga.c
+++ b/arch/sh/boards/mach-migor/lcd_qvga.c
@@ -113,8 +113,7 @@ static const unsigned short magic3_data[] = {
0x0010, 0x16B0, 0x0011, 0x0111, 0x0007, 0x0061,
};
-int migor_lcd_qvga_setup(void *board_data, void *sohandle,
- struct sh_mobile_lcdc_sys_bus_ops *so)
+int migor_lcd_qvga_setup(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so)
{
unsigned long xres = 320;
unsigned long yres = 240;
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index ab81abd..334b463 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -185,8 +185,6 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.width = 152,
.height = 91,
},
- .board_cfg = {
- },
}
};
diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
index 07e635b..ba3d93d 100644
--- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
+++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h
@@ -4,21 +4,21 @@
#include <video/sh_mobile_lcdc.h>
#if defined(CONFIG_FB_SH_MOBILE_LCDC) || defined(CONFIG_FB_SH_MOBILE_LCDC_MODULE)
-void kfr2r09_lcd_on(void *board_data, struct fb_info *info);
-void kfr2r09_lcd_off(void *board_data);
-int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_on(void);
+void kfr2r09_lcd_off(void);
+int kfr2r09_lcd_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
-void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+void kfr2r09_lcd_start(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#else
-static void kfr2r09_lcd_on(void *board_data) {}
-static void kfr2r09_lcd_off(void *board_data) {}
-static int kfr2r09_lcd_setup(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_on(void) {}
+static void kfr2r09_lcd_off(void) {}
+static int kfr2r09_lcd_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
{
return -ENODEV;
}
-static void kfr2r09_lcd_start(void *board_data, void *sys_ops_handle,
+static void kfr2r09_lcd_start(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops)
{
}
diff --git a/arch/sh/include/mach-migor/mach/migor.h b/arch/sh/include/mach-migor/mach/migor.h
index 42fccf9..7de7bb7 100644
--- a/arch/sh/include/mach-migor/mach/migor.h
+++ b/arch/sh/include/mach-migor/mach/migor.h
@@ -9,7 +9,7 @@
#include <video/sh_mobile_lcdc.h>
-int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
+int migor_lcd_qvga_setup(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
#endif /* __ASM_SH_MIGOR_H */
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 543f957..cb0d9b6 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -314,14 +314,12 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
/* trigger panel update */
dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
if (bcfg->start_transfer)
- bcfg->start_transfer(bcfg->board_data, ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
} else {
if (bcfg->start_transfer)
- bcfg->start_transfer(bcfg->board_data, ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
}
}
@@ -343,7 +341,7 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
/* HDMI must be enabled before LCDC configuration */
if (board_cfg->display_on)
- board_cfg->display_on(board_cfg->board_data, ch->info);
+ board_cfg->display_on();
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
@@ -351,7 +349,7 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
if (board_cfg->display_off)
- board_cfg->display_off(board_cfg->board_data);
+ board_cfg->display_off();
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
@@ -689,7 +687,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
board_cfg = &ch->cfg.board_cfg;
if (board_cfg->setup_sys) {
- ret = board_cfg->setup_sys(board_cfg->board_data, ch,
+ ret = board_cfg->setup_sys(ch,
&sh_mobile_lcdc_sys_bus_ops);
if (ret)
return ret;
@@ -1325,7 +1323,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
- return cfg->set_brightness(cfg->board_data, brightness);
+ return cfg->set_brightness(brightness);
}
static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
@@ -1333,7 +1331,7 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
- return cfg->get_brightness(cfg->board_data);
+ return cfg->get_brightness();
}
static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index b1b3e8d..a1e6596 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -148,15 +148,14 @@ struct sh_mobile_lcdc_sys_bus_ops {
};
struct sh_mobile_lcdc_board_cfg {
- void *board_data;
- int (*setup_sys)(void *board_data, void *sys_ops_handle,
+ int (*setup_sys)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
- void (*start_transfer)(void *board_data, void *sys_ops_handle,
+ void (*start_transfer)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
- void (*display_on)(void *board_data, struct fb_info *info);
- void (*display_off)(void *board_data);
- int (*set_brightness)(void *board_data, int brightness);
- int (*get_brightness)(void *board_data);
+ void (*display_on)(void);
+ void (*display_off)(void);
+ int (*set_brightness)(int brightness);
+ int (*get_brightness)(void);
};
struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 18/31] fbdev: sh_mobile_lcdc: Move brightness ops to sh_mobile_lcdc_bl_info
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-mackerel.c | 6 ++----
arch/sh/boards/mach-ap325rxa/setup.c | 4 ++--
arch/sh/boards/mach-ecovec24/setup.c | 6 ++----
drivers/video/sh_mobile_lcdcfb.c | 6 ++----
include/video/sh_mobile_lcdc.h | 4 ++--
5 files changed, 10 insertions(+), 16 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9d0d7b2..ecd1982 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -395,13 +395,11 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.flags = 0,
.lcd_size_cfg.width = 152,
.lcd_size_cfg.height = 91,
- .board_cfg = {
- .set_brightness = mackerel_set_brightness,
- .get_brightness = mackerel_get_brightness,
- },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = mackerel_set_brightness,
+ .get_brightness = mackerel_get_brightness,
},
.meram_cfg = &lcd_meram_cfg,
}
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 477767e..315d79a 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -219,12 +219,12 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.board_cfg = {
.display_on = ap320_wvga_power_on,
.display_off = ap320_wvga_power_off,
- .set_brightness = ap320_wvga_set_brightness,
- .get_brightness = ap320_wvga_get_brightness,
},
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = ap320_wvga_set_brightness,
+ .get_brightness = ap320_wvga_get_brightness,
},
}
};
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 7c592f8..b957b54 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -331,13 +331,11 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.width = 152,
.height = 91,
},
- .board_cfg = {
- .set_brightness = ecovec24_set_brightness,
- .get_brightness = ecovec24_get_brightness,
- },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
+ .set_brightness = ecovec24_set_brightness,
+ .get_brightness = ecovec24_get_brightness,
},
}
};
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index cb0d9b6..a490c7a 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1316,22 +1316,20 @@ static struct fb_ops sh_mobile_lcdc_ops = {
static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
- struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
int brightness = bdev->props.brightness;
if (bdev->props.power != FB_BLANK_UNBLANK ||
bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
brightness = 0;
- return cfg->set_brightness(brightness);
+ return ch->cfg.bl_info.set_brightness(brightness);
}
static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev)
{
struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev);
- struct sh_mobile_lcdc_board_cfg *cfg = &ch->cfg.board_cfg;
- return cfg->get_brightness();
+ return ch->cfg.bl_info.get_brightness();
}
static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev,
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index a1e6596..541b2b3 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -154,8 +154,6 @@ struct sh_mobile_lcdc_board_cfg {
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
void (*display_on)(void);
void (*display_off)(void);
- int (*set_brightness)(int brightness);
- int (*get_brightness)(void);
};
struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
@@ -167,6 +165,8 @@ struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
struct sh_mobile_lcdc_bl_info {
const char *name;
int max_brightness;
+ int (*set_brightness)(int brightness);
+ int (*get_brightness)(void);
};
struct sh_mobile_lcdc_chan_cfg {
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 19/31] fbdev: sh_mobile_lcdc: Merge board_cfg and lcd_size_cfg into panel_cfg
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
Update board code accordingly.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
arch/arm/mach-shmobile/board-ag5evm.c | 6 ++--
arch/arm/mach-shmobile/board-ap4evb.c | 8 +++---
arch/arm/mach-shmobile/board-mackerel.c | 6 +++-
arch/sh/boards/mach-ap325rxa/setup.c | 6 +---
arch/sh/boards/mach-ecovec24/setup.c | 2 +-
arch/sh/boards/mach-kfr2r09/setup.c | 4 +--
arch/sh/boards/mach-migor/setup.c | 8 ++----
arch/sh/boards/mach-se/7724/setup.c | 2 +-
drivers/video/sh_mobile_lcdcfb.c | 35 +++++++++++++++----------------
include/video/sh_mobile_lcdc.h | 12 +++-------
10 files changed, 40 insertions(+), 49 deletions(-)
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 139fbd1..c8b57a7 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -258,12 +258,12 @@ static struct sh_mobile_lcdc_info lcdc0_info = {
.interface_type = RGB24,
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
- .lcd_size_cfg.width = 44,
- .lcd_size_cfg.height = 79,
.fourcc = V4L2_PIX_FMT_RGB565,
.lcd_cfg = lcdc0_modes,
.num_cfg = ARRAY_SIZE(lcdc0_modes),
- .board_cfg = {
+ .panel_cfg = {
+ .width = 44,
+ .height = 79,
.display_on = lcd_backlight_on,
.display_off = lcd_backlight_reset,
},
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 851e1ac..f8d0b4d 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -1326,8 +1326,8 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB24;
lcdc_info.ch[0].clock_divider = 1;
lcdc_info.ch[0].flags = LCDC_FLAGS_DWPOL;
- lcdc_info.ch[0].lcd_size_cfg.width = 44;
- lcdc_info.ch[0].lcd_size_cfg.height = 79;
+ lcdc_info.ch[0].panel_cfg.width = 44;
+ lcdc_info.ch[0].panel_cfg.height = 79;
platform_add_devices(qhd_devices, ARRAY_SIZE(qhd_devices));
@@ -1368,8 +1368,8 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].interface_type = RGB18;
lcdc_info.ch[0].clock_divider = 3;
lcdc_info.ch[0].flags = 0;
- lcdc_info.ch[0].lcd_size_cfg.width = 152;
- lcdc_info.ch[0].lcd_size_cfg.height = 91;
+ lcdc_info.ch[0].panel_cfg.width = 152;
+ lcdc_info.ch[0].panel_cfg.height = 91;
/* enable TouchScreen */
irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index ecd1982..1bdcf61 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -393,8 +393,10 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.interface_type = RGB24,
.clock_divider = 3,
.flags = 0,
- .lcd_size_cfg.width = 152,
- .lcd_size_cfg.height = 91,
+ .panel_cfg = {
+ .width = 152,
+ .height = 91,
+ },
.bl_info = {
.name = "sh_mobile_lcdc_bl",
.max_brightness = 1,
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 315d79a..4d1df51 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -212,11 +212,9 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.clock_divider = 1,
.lcd_cfg = ap325rxa_lcdc_modes,
.num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),
- .lcd_size_cfg = { /* 7.0 inch */
- .width = 152,
+ .panel_cfg = {
+ .width = 152, /* 7.0 inch */
.height = 91,
- },
- .board_cfg = {
.display_on = ap320_wvga_power_on,
.display_off = ap320_wvga_power_off,
},
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index b957b54..3f3f2ec 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -327,7 +327,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.interface_type = RGB18,
.chan = LCDC_CHAN_MAINLCD,
.fourcc = V4L2_PIX_FMT_RGB565,
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 208c9b0..615cb4b 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -152,11 +152,9 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.flags = LCDC_FLAGS_DWPOL,
.lcd_cfg = kfr2r09_lcdc_modes,
.num_cfg = ARRAY_SIZE(kfr2r09_lcdc_modes),
- .lcd_size_cfg = {
+ .panel_cfg = {
.width = 35,
.height = 58,
- },
- .board_cfg = {
.setup_sys = kfr2r09_lcd_setup,
.start_transfer = kfr2r09_lcd_start,
.display_on = kfr2r09_lcd_on,
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 69f8d7d..b052946 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -249,7 +249,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_divider = 2,
.lcd_cfg = migor_lcd_modes,
.num_cfg = ARRAY_SIZE(migor_lcd_modes),
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
@@ -263,11 +263,9 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_divider = 10,
.lcd_cfg = migor_lcd_modes,
.num_cfg = ARRAY_SIZE(migor_lcd_modes),
- .lcd_size_cfg = { /* 2.4 inch */
- .width = 49,
+ .panel_cfg = {
+ .width = 49, /* 2.4 inch */
.height = 37,
- },
- .board_cfg = {
.setup_sys = migor_lcd_qvga_setup,
},
.sys_bus_cfg = {
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 334b463..56e7361 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -181,7 +181,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.chan = LCDC_CHAN_MAINLCD,
.fourcc = V4L2_PIX_FMT_RGB565,
.clock_divider = 1,
- .lcd_size_cfg = { /* 7.0 inch */
+ .panel_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
},
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index a490c7a..eff475d 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -288,7 +288,7 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct sh_mobile_lcdc_chan *ch = info->par;
- struct sh_mobile_lcdc_board_cfg *bcfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
/* enable clocks before accessing hardware */
sh_mobile_lcdc_clk_on(ch->lcdc);
@@ -313,13 +313,13 @@ static void sh_mobile_lcdc_deferred_io(struct fb_info *info,
/* trigger panel update */
dma_map_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
- if (bcfg->start_transfer)
- bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
+ if (panel->start_transfer)
+ panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
dma_unmap_sg(info->dev, ch->sglist, nr_pages, DMA_TO_DEVICE);
} else {
- if (bcfg->start_transfer)
- bcfg->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
+ if (panel->start_transfer)
+ panel->start_transfer(ch, &sh_mobile_lcdc_sys_bus_ops);
lcdc_write_chan(ch, LDSM2R, LDSM2R_OSTRG);
}
}
@@ -334,22 +334,22 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
{
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
if (ch->tx_dev)
ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
/* HDMI must be enabled before LCDC configuration */
- if (board_cfg->display_on)
- board_cfg->display_on();
+ if (panel->display_on)
+ panel->display_on();
}
static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
{
- struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
- if (board_cfg->display_off)
- board_cfg->display_off();
+ if (panel->display_off)
+ panel->display_off();
if (ch->tx_dev)
ch->tx_dev->ops->display_off(ch->tx_dev);
@@ -679,16 +679,15 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
lcdc_wait_bit(priv, _LDCNT2R, LDCNT2R_BR, 0);
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
- struct sh_mobile_lcdc_board_cfg *board_cfg;
+ struct sh_mobile_lcdc_panel_cfg *panel;
ch = &priv->ch[k];
if (!ch->enabled)
continue;
- board_cfg = &ch->cfg.board_cfg;
- if (board_cfg->setup_sys) {
- ret = board_cfg->setup_sys(ch,
- &sh_mobile_lcdc_sys_bus_ops);
+ panel = &ch->cfg.panel_cfg;
+ if (panel->setup_sys) {
+ ret = panel->setup_sys(ch, &sh_mobile_lcdc_sys_bus_ops);
if (ret)
return ret;
}
@@ -1654,8 +1653,8 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
*/
var = &info->var;
fb_videomode_to_var(var, mode);
- var->width = cfg->lcd_size_cfg.width;
- var->height = cfg->lcd_size_cfg.height;
+ var->width = cfg->panel_cfg.width;
+ var->height = cfg->panel_cfg.height;
var->yres_virtual = var->yres * 2;
var->activate = FB_ACTIVATE_NOW;
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 541b2b3..84163e4 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -147,7 +147,9 @@ struct sh_mobile_lcdc_sys_bus_ops {
unsigned long (*read_data)(void *handle);
};
-struct sh_mobile_lcdc_board_cfg {
+struct sh_mobile_lcdc_panel_cfg {
+ unsigned long width; /* Panel width in mm */
+ unsigned long height; /* Panel height in mm */
int (*setup_sys)(void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
void (*start_transfer)(void *sys_ops_handle,
@@ -156,11 +158,6 @@ struct sh_mobile_lcdc_board_cfg {
void (*display_off)(void);
};
-struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
- unsigned long width;
- unsigned long height;
-};
-
/* backlight info */
struct sh_mobile_lcdc_bl_info {
const char *name;
@@ -178,8 +175,7 @@ struct sh_mobile_lcdc_chan_cfg {
unsigned long flags; /* LCDC_FLAGS_... */
const struct fb_videomode *lcd_cfg;
int num_cfg;
- struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
- struct sh_mobile_lcdc_board_cfg board_cfg;
+ struct sh_mobile_lcdc_panel_cfg panel_cfg;
struct sh_mobile_lcdc_bl_info bl_info;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
struct sh_mobile_meram_cfg *meram_cfg;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 20/31] sh_mobile_lcdc: Add an lcdc channel pointer to sh_mobile_lcdc_entity
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The field will be used by the transmitter drivers to access
sh_mobile_lcdc_chan fields such as fb_info.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 5 ++++-
drivers/video/sh_mobile_lcdcfb.h | 2 ++
2 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index eff475d..f8bdbe9 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1494,8 +1494,10 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
if (!info || !info->device)
continue;
- if (ch->tx_dev)
+ if (ch->tx_dev) {
+ ch->tx_dev->lcdc = NULL;
module_put(ch->cfg.tx_dev->dev.driver->owner);
+ }
if (ch->sglist)
vfree(ch->sglist);
@@ -1605,6 +1607,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
return -EINVAL;
}
ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
+ ch->tx_dev->lcdc = ch;
}
/* Iterate through the modes to validate them and find the highest
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index c992a98..b57a847 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -19,6 +19,7 @@ struct fb_info;
struct module;
struct sh_mobile_lcdc_entity;
struct sh_mobile_lcdc_priv;
+struct sh_mobile_lcdc_chan;
struct sh_mobile_lcdc_entity_ops {
/* Display */
@@ -30,6 +31,7 @@ struct sh_mobile_lcdc_entity_ops {
struct sh_mobile_lcdc_entity {
struct module *owner;
const struct sh_mobile_lcdc_entity_ops *ops;
+ struct sh_mobile_lcdc_chan *lcdc;
};
/*
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 21/31] sh_mobile_hdmi: Use sh_mobile_lcdc_entity::channel to access fb_info
From: Laurent Pinchart @ 2011-09-19 0:27 UTC (permalink / raw)
To: linux-fbdev
The fb_info parameter passed to the display_on operation will be
removed, don't use it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 81 ++++++---------------------------------
1 files changed, 13 insertions(+), 68 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index d89645e..deca755 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -219,16 +219,12 @@ struct sh_hdmi {
u8 edid_blocks;
struct clk *hdmi_clk;
struct device *dev;
- struct fb_info *info;
- struct mutex mutex; /* Protect the info pointer */
struct delayed_work edid_work;
struct fb_var_screeninfo var;
struct fb_monspecs monspec;
- struct notifier_block notifier;
};
#define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity)
-#define notifier_to_sh_hdmi(n) container_of(n, struct sh_hdmi, notifier)
static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
{
@@ -737,10 +733,11 @@ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
unsigned long *parent_rate)
{
+ struct fb_info *info = hdmi->entity.lcdc
+ ? hdmi->entity.lcdc->info : NULL;
struct fb_var_screeninfo tmpvar;
struct fb_var_screeninfo *var = &tmpvar;
const struct fb_videomode *mode, *found = NULL;
- struct fb_info *info = hdmi->info;
struct fb_modelist *modelist = NULL;
unsigned int f_width = 0, f_height = 0, f_refresh = 0;
unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
@@ -1012,13 +1009,11 @@ static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
* FB_EVENT_FB_UNBIND notify is also called with info->lock held
*/
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
- struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_chan *ch = entity->lcdc;
+ struct fb_info *info = ch->info;
dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state);
- /* No need to lock */
- hdmi->info = info;
-
/*
* hp_state can be set to
* HDMI_HOTPLUG_DISCONNECTED: on monitor unplug
@@ -1038,7 +1033,6 @@ static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
}
}
-/* locking: called with info->lock held */
static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
{
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
@@ -1055,15 +1049,14 @@ static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
{
- struct fb_info *info = hdmi->info;
- struct sh_mobile_lcdc_chan *ch = info->par;
+ struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
struct fb_videomode mode1, mode2;
fb_var_to_videomode(&mode1, old_var);
fb_var_to_videomode(&mode2, new_var);
- dev_dbg(info->dev, "Old %ux%u, new %ux%u\n",
+ dev_dbg(hdmi->dev, "Old %ux%u, new %ux%u\n",
mode1.xres, mode1.yres, mode2.xres, mode2.yres);
if (fb_mode_is_equal(&mode1, &mode2)) {
@@ -1073,7 +1066,7 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
return false;
}
- dev_dbg(info->dev, "Switching %u -> %u lines\n",
+ dev_dbg(hdmi->dev, "Switching %u -> %u lines\n",
mode1.yres, mode2.yres);
*old_var = *new_var;
@@ -1119,17 +1112,15 @@ static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
static void sh_hdmi_edid_work_fn(struct work_struct *work)
{
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
- struct sh_mobile_lcdc_chan *ch;
int ret;
dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__, hdmi,
hdmi->hp_state);
- mutex_lock(&hdmi->mutex);
-
if (hdmi->hp_state = HDMI_HOTPLUG_CONNECTED) {
- struct fb_info *info = hdmi->info;
+ struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
unsigned long parent_rate = 0, hdmi_rate;
+ struct fb_info *info;
ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
if (ret < 0)
@@ -1147,10 +1138,10 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
/* Switched to another (d) power-save mode */
msleep(10);
- if (!info)
+ if (ch = NULL)
goto out;
- ch = info->par;
+ info = ch->info;
console_lock();
@@ -1175,7 +1166,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
console_unlock();
} else {
ret = 0;
- if (!hdmi->info)
+ if (hdmi->entity.lcdc = NULL)
goto out;
hdmi->monspec.modedb_len = 0;
@@ -1185,7 +1176,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
console_lock();
/* HDMI disconnect */
- fb_set_suspend(hdmi->info, 1);
+ fb_set_suspend(hdmi->entity.lcdc->info, 1);
console_unlock();
}
@@ -1193,47 +1184,10 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
out:
if (ret < 0 && ret != -EAGAIN)
hdmi->hp_state = HDMI_HOTPLUG_DISCONNECTED;
- mutex_unlock(&hdmi->mutex);
dev_dbg(hdmi->dev, "%s(%p): end\n", __func__, hdmi);
}
-static int sh_hdmi_notify(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct fb_event *event = data;
- struct fb_info *info = event->info;
- struct sh_hdmi *hdmi = notifier_to_sh_hdmi(nb);
-
- if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
- return NOTIFY_DONE;
-
- switch(action) {
- case FB_EVENT_FB_REGISTERED:
- /* Unneeded, activation taken care by sh_hdmi_display_on() */
- break;
- case FB_EVENT_FB_UNREGISTERED:
- /*
- * We are called from unregister_framebuffer() with the
- * info->lock held. This is bad for us, because we can race with
- * the scheduled work, which has to call fb_set_suspend(), which
- * takes info->lock internally, so, sh_hdmi_edid_work_fn()
- * cannot take and hold info->lock for the whole function
- * duration. Using an additional lock creates a classical AB-BA
- * lock up. Therefore, we have to release the info->lock
- * temporarily, synchronise with the work queue and re-acquire
- * the info->lock.
- */
- unlock_fb_info(info);
- mutex_lock(&hdmi->mutex);
- hdmi->info = NULL;
- mutex_unlock(&hdmi->mutex);
- lock_fb_info(info);
- return NOTIFY_OK;
- }
- return NOTIFY_DONE;
-}
-
static int __init sh_hdmi_probe(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
@@ -1251,8 +1205,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
return -ENOMEM;
}
- mutex_init(&hdmi->mutex);
-
hdmi->dev = &pdev->dev;
hdmi->entity.owner = THIS_MODULE;
hdmi->entity.ops = &sh_hdmi_ops;
@@ -1320,9 +1272,6 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
goto ecodec;
}
- hdmi->notifier.notifier_call = sh_hdmi_notify;
- fb_register_client(&hdmi->notifier);
-
return 0;
ecodec:
@@ -1338,7 +1287,6 @@ ereqreg:
erate:
clk_put(hdmi->hdmi_clk);
egetclk:
- mutex_destroy(&hdmi->mutex);
kfree(hdmi);
return ret;
@@ -1352,8 +1300,6 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
snd_soc_unregister_codec(&pdev->dev);
- fb_unregister_client(&hdmi->notifier);
-
/* No new work will be scheduled, wait for running ISR */
free_irq(irq, hdmi);
/* Wait for already scheduled work */
@@ -1364,7 +1310,6 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
clk_put(hdmi->hdmi_clk);
iounmap(hdmi->base);
release_mem_region(res->start, resource_size(res));
- mutex_destroy(&hdmi->mutex);
kfree(hdmi);
return 0;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 22/31] fbdev: sh_mobile_lcdc: Remove fb_info parameter to display_on operation
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
The parameter is unused, remove it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 3 +--
drivers/video/sh_mobile_hdmi.c | 10 ++--------
drivers/video/sh_mobile_lcdcfb.c | 2 +-
drivers/video/sh_mobile_lcdcfb.h | 3 +--
4 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index e198067..f5d380c 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -125,8 +125,7 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static void mipi_display_on(struct sh_mobile_lcdc_entity *entity,
- struct fb_info *info)
+static void mipi_display_on(struct sh_mobile_lcdc_entity *entity)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index deca755..88de4e0 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1000,14 +1000,8 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
return IRQ_HANDLED;
}
-/* locking: called with info->lock held, or before register_framebuffer() */
-static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity,
- struct fb_info *info)
+static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
{
- /*
- * info is guaranteed to be valid, when we are called, because our
- * FB_EVENT_FB_UNBIND notify is also called with info->lock held
- */
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
struct sh_mobile_lcdc_chan *ch = entity->lcdc;
struct fb_info *info = ch->info;
@@ -1155,7 +1149,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
if (lock_fb_info(info)) {
info->var.width = hdmi->var.width;
info->var.height = hdmi->var.height;
- sh_hdmi_display_on(&hdmi->entity, info);
+ sh_hdmi_display_on(&hdmi->entity);
unlock_fb_info(info);
}
} else {
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index f8bdbe9..afd00cc 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -337,7 +337,7 @@ static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
if (ch->tx_dev)
- ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
+ ch->tx_dev->ops->display_on(ch->tx_dev);
/* HDMI must be enabled before LCDC configuration */
if (panel->display_on)
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index b57a847..50c2d1f 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -23,8 +23,7 @@ struct sh_mobile_lcdc_chan;
struct sh_mobile_lcdc_entity_ops {
/* Display */
- void (*display_on)(struct sh_mobile_lcdc_entity *entity,
- struct fb_info *info);
+ void (*display_on)(struct sh_mobile_lcdc_entity *entity);
void (*display_off)(struct sh_mobile_lcdc_entity *entity);
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 23/31] fbdev: sh_mobile_lcdc: Return display connection state in display_on
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Return true if the display is connected and false otherwise. Set the fb
info state to FBINFO_STATE_SUSPENDED in the sh_mobile_lcdc driver when
the display is not connected.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 4 +++-
drivers/video/sh_mobile_hdmi.c | 9 +++++----
drivers/video/sh_mobile_lcdcfb.c | 8 ++++++--
drivers/video/sh_mobile_lcdcfb.h | 2 +-
4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index f5d380c..3ead395 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -125,12 +125,14 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static void mipi_display_on(struct sh_mobile_lcdc_entity *entity)
+static bool mipi_display_on(struct sh_mobile_lcdc_entity *entity)
{
struct sh_mipi *mipi = to_sh_mipi(entity);
pm_runtime_get_sync(mipi->dev);
sh_mipi_dsi_enable(mipi, true);
+
+ return true;
}
static void mipi_display_off(struct sh_mobile_lcdc_entity *entity)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 88de4e0..4b87c6e 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1000,13 +1000,13 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
+static bool sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
{
struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity);
struct sh_mobile_lcdc_chan *ch = entity->lcdc;
- struct fb_info *info = ch->info;
- dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state);
+ dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi,
+ hdmi->hp_state);
/*
* hp_state can be set to
@@ -1021,10 +1021,11 @@ static void sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity)
dev_dbg(hdmi->dev, "HDMI running\n");
break;
case HDMI_HOTPLUG_DISCONNECTED:
- info->state = FBINFO_STATE_SUSPENDED;
default:
hdmi->var = ch->display_var;
}
+
+ return hdmi->hp_state != HDMI_HOTPLUG_DISCONNECTED;
}
static void sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index afd00cc..d6c117b 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -335,9 +335,13 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
{
struct sh_mobile_lcdc_panel_cfg *panel = &ch->cfg.panel_cfg;
+ bool connected;
- if (ch->tx_dev)
- ch->tx_dev->ops->display_on(ch->tx_dev);
+ if (ch->tx_dev) {
+ connected = ch->tx_dev->ops->display_on(ch->tx_dev);
+ if (!connected)
+ ch->info->state = FBINFO_STATE_SUSPENDED;
+ }
/* HDMI must be enabled before LCDC configuration */
if (panel->display_on)
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 50c2d1f..8f1e007 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -23,7 +23,7 @@ struct sh_mobile_lcdc_chan;
struct sh_mobile_lcdc_entity_ops {
/* Display */
- void (*display_on)(struct sh_mobile_lcdc_entity *entity);
+ bool (*display_on)(struct sh_mobile_lcdc_entity *entity);
void (*display_off)(struct sh_mobile_lcdc_entity *entity);
};
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 24/31] sh_mobile_lcdc: Add display notify callback to sh_mobile_lcdc_chan
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
The callback implements 3 notification events:
- SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT notifies the LCDC that the
display has been connected
- SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT notifies the LCDC that the
display has been disconnected
- SH_MOBILE_LCDC_EVENT_DISPLAY_MODE notifies that LCDC that a display
mode has been detected
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 77 ++++++++++++++++++++++++++++++++++++++
drivers/video/sh_mobile_lcdcfb.h | 10 +++++
2 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index d6c117b..19ac3c5 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -359,6 +359,82 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
ch->tx_dev->ops->display_off(ch->tx_dev);
}
+static bool
+sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch,
+ const struct fb_var_screeninfo *new_var)
+{
+ struct fb_var_screeninfo *old_var = &ch->display_var;
+ struct fb_videomode old_mode;
+ struct fb_videomode new_mode;
+
+ fb_var_to_videomode(&old_mode, old_var);
+ fb_var_to_videomode(&new_mode, new_var);
+
+ dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n",
+ old_mode.xres, old_mode.yres, new_mode.xres, new_mode.yres);
+
+ if (fb_mode_is_equal(&old_mode, &new_mode)) {
+ /* It can be a different monitor with an equal video-mode */
+ old_var->width = new_var->width;
+ old_var->height = new_var->height;
+ return false;
+ }
+
+ dev_dbg(ch->info->dev, "Switching %u -> %u lines\n",
+ old_mode.yres, new_mode.yres);
+ *old_var = *new_var;
+
+ return true;
+}
+
+static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
+ enum sh_mobile_lcdc_entity_event event,
+ struct fb_var_screeninfo *var)
+{
+ struct fb_info *info = ch->info;
+ int ret = 0;
+
+ switch (event) {
+ case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT:
+ /* HDMI plug in */
+ console_lock();
+
+ if (!sh_mobile_lcdc_must_reconfigure(ch, var) &&
+ info->state = FBINFO_STATE_RUNNING) {
+ /* First activation with the default monitor - just turn
+ * on, if we run a resume here, the logo disappears.
+ */
+ if (lock_fb_info(info)) {
+ info->var.width = var->width;
+ info->var.height = var->height;
+ sh_mobile_lcdc_display_on(ch);
+ unlock_fb_info(info);
+ }
+ } else {
+ /* New monitor or have to wake up */
+ fb_set_suspend(info, 0);
+ }
+
+ console_unlock();
+ break;
+
+ case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT:
+ /* HDMI disconnect */
+ console_lock();
+ fb_set_suspend(info, 1);
+ console_unlock();
+ break;
+
+ case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE:
+ /* Validate a proposed new mode */
+ var->bits_per_pixel = info->var.bits_per_pixel;
+ ret = info->fbops->fb_check_var(var, info);
+ break;
+ }
+
+ return ret;
+}
+
/* -----------------------------------------------------------------------------
* Format helpers
*/
@@ -1589,6 +1665,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
int i;
mutex_init(&ch->open_lock);
+ ch->notify = sh_mobile_lcdc_display_notify;
/* Allocate the frame buffer device. */
ch->info = framebuffer_alloc(0, priv->dev);
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index 8f1e007..ec57533 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -27,6 +27,12 @@ struct sh_mobile_lcdc_entity_ops {
void (*display_off)(struct sh_mobile_lcdc_entity *entity);
};
+enum sh_mobile_lcdc_entity_event {
+ SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT,
+ SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT,
+ SH_MOBILE_LCDC_EVENT_DISPLAY_MODE,
+};
+
struct sh_mobile_lcdc_entity {
struct module *owner;
const struct sh_mobile_lcdc_entity_ops *ops;
@@ -67,6 +73,10 @@ struct sh_mobile_lcdc_chan {
unsigned long base_addr_y;
unsigned long base_addr_c;
unsigned int pitch;
+
+ int (*notify)(struct sh_mobile_lcdc_chan *ch,
+ enum sh_mobile_lcdc_entity_event event,
+ struct fb_var_screeninfo *var);
};
#endif
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 25/31] sh_mobile_hdmi: Use LCDC notification callback
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Instead of accessing the LCDC channel and fb_info structures directly,
use the LCDC notification callback to inform the LCDC driver about
display-related events.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 88 +++++++---------------------------------
1 files changed, 15 insertions(+), 73 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 4b87c6e..c17e3ad 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -733,12 +733,11 @@ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,
static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
unsigned long *parent_rate)
{
- struct fb_info *info = hdmi->entity.lcdc
- ? hdmi->entity.lcdc->info : NULL;
- struct fb_var_screeninfo tmpvar;
- struct fb_var_screeninfo *var = &tmpvar;
+ struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
+ struct fb_info *info = ch ? ch->info : NULL;
+ struct fb_var_screeninfo var;
const struct fb_videomode *mode, *found = NULL;
- struct fb_modelist *modelist = NULL;
+ const struct fb_modelist *modelist = NULL;
unsigned int f_width = 0, f_height = 0, f_refresh = 0;
unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
bool scanning = false, preferred_bad = false;
@@ -856,12 +855,10 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
}
/* Check if supported: sufficient fb memory, supported clock-rate */
- fb_videomode_to_var(var, mode);
+ fb_videomode_to_var(&var, mode);
- var->bits_per_pixel = info->var.bits_per_pixel;
-
- if (info && info->fbops->fb_check_var &&
- info->fbops->fb_check_var(var, info)) {
+ if (ch && ch->notify &&
+ ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_MODE, &var)) {
scanning = true;
preferred_bad = true;
continue;
@@ -1042,32 +1039,6 @@ static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = {
.display_off = sh_hdmi_display_off,
};
-static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi)
-{
- struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
- struct fb_var_screeninfo *new_var = &hdmi->var, *old_var = &ch->display_var;
- struct fb_videomode mode1, mode2;
-
- fb_var_to_videomode(&mode1, old_var);
- fb_var_to_videomode(&mode2, new_var);
-
- dev_dbg(hdmi->dev, "Old %ux%u, new %ux%u\n",
- mode1.xres, mode1.yres, mode2.xres, mode2.yres);
-
- if (fb_mode_is_equal(&mode1, &mode2)) {
- /* It can be a different monitor with an equal video-mode */
- old_var->width = new_var->width;
- old_var->height = new_var->height;
- return false;
- }
-
- dev_dbg(hdmi->dev, "Switching %u -> %u lines\n",
- mode1.yres, mode2.yres);
- *old_var = *new_var;
-
- return true;
-}
-
/**
* sh_hdmi_clk_configure() - set HDMI clock frequency and enable the clock
* @hdmi: driver context
@@ -1107,15 +1078,14 @@ static long sh_hdmi_clk_configure(struct sh_hdmi *hdmi, unsigned long hdmi_rate,
static void sh_hdmi_edid_work_fn(struct work_struct *work)
{
struct sh_hdmi *hdmi = container_of(work, struct sh_hdmi, edid_work.work);
+ struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
int ret;
dev_dbg(hdmi->dev, "%s(%p): begin, hotplug status %d\n", __func__, hdmi,
hdmi->hp_state);
if (hdmi->hp_state = HDMI_HOTPLUG_CONNECTED) {
- struct sh_mobile_lcdc_chan *ch = hdmi->entity.lcdc;
unsigned long parent_rate = 0, hdmi_rate;
- struct fb_info *info;
ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
if (ret < 0)
@@ -1133,47 +1103,19 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
/* Switched to another (d) power-save mode */
msleep(10);
- if (ch = NULL)
- goto out;
-
- info = ch->info;
-
- console_lock();
-
- /* HDMI plug in */
- if (!sh_hdmi_must_reconfigure(hdmi) &&
- info->state = FBINFO_STATE_RUNNING) {
- /*
- * First activation with the default monitor - just turn
- * on, if we run a resume here, the logo disappears
- */
- if (lock_fb_info(info)) {
- info->var.width = hdmi->var.width;
- info->var.height = hdmi->var.height;
- sh_hdmi_display_on(&hdmi->entity);
- unlock_fb_info(info);
- }
- } else {
- /* New monitor or have to wake up */
- fb_set_suspend(info, 0);
- }
-
- console_unlock();
+ if (ch && ch->notify)
+ ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT,
+ &hdmi->var);
} else {
- ret = 0;
- if (hdmi->entity.lcdc = NULL)
- goto out;
-
hdmi->monspec.modedb_len = 0;
fb_destroy_modedb(hdmi->monspec.modedb);
hdmi->monspec.modedb = NULL;
- console_lock();
-
- /* HDMI disconnect */
- fb_set_suspend(hdmi->entity.lcdc->info, 1);
+ if (ch && ch->notify)
+ ch->notify(ch, SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT,
+ NULL);
- console_unlock();
+ ret = 0;
}
out:
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 26/31] media: Initialize media controller core with subsys_initcall
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
The media controller core needs to be initialized before the frame
buffer devices. Use subsys_initcall() instead of module_init().
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/media-devnode.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
index 7b42ace..06a06b1 100644
--- a/drivers/media/media-devnode.c
+++ b/drivers/media/media-devnode.c
@@ -312,8 +312,8 @@ static void __exit media_devnode_exit(void)
unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
}
-module_init(media_devnode_init)
-module_exit(media_devnode_exit)
+subsys_initcall(media_devnode_init);
+module_exit(media_devnode_exit);
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
MODULE_DESCRIPTION("Device node registration for media drivers");
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 27/31] fbdev: Add media controller support
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Initialize and register a single-pad media entity when media controller
support is available.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/fbmem.c | 21 +++++++++++++++++++++
drivers/video/fbsysfs.c | 11 +++++++++++
include/linux/fb.h | 8 ++++++++
3 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 5aac00e..26154fb 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -35,6 +35,7 @@
#include <asm/fb.h>
+#include <media/media-device.h>
/*
* Frame buffer device initialization and setup routines
@@ -1572,6 +1573,7 @@ static int do_register_framebuffer(struct fb_info *fb_info)
int i;
struct fb_event event;
struct fb_videomode mode;
+ int ret;
if (fb_check_foreignness(fb_info))
return -ENOSYS;
@@ -1625,6 +1627,21 @@ static int do_register_framebuffer(struct fb_info *fb_info)
fb_add_videomode(&mode, &fb_info->modelist);
registered_fb[i] = fb_info;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ if (fb_info->mdev) {
+ fb_info->entity.type = MEDIA_ENT_T_DEVNODE_FB;
+ fb_info->entity.name = fb_info->name;
+ fb_info->entity.fb.major = FB_MAJOR;
+ fb_info->entity.fb.minor = i;
+ ret = media_device_register_entity(fb_info->mdev,
+ &fb_info->entity);
+ if (ret < 0)
+ printk(KERN_WARNING
+ "%s: media_device_register_entity failed\n",
+ __func__);
+ }
+#endif
+
event.info = fb_info;
if (!lock_fb_info(fb_info))
return -ENODEV;
@@ -1651,6 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
if (ret)
return -EINVAL;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ if (fb_info->mdev)
+ media_device_unregister_entity(&fb_info->entity);
+#endif
if (fb_info->pixmap.addr &&
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
kfree(fb_info->pixmap.addr);
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 04251ce..5d1ce86 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -63,6 +63,14 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
mutex_init(&info->bl_curve_mutex);
#endif
+#ifdef CONFIG_MEDIA_CONTROLLER
+ info->pad.flags = MEDIA_PAD_FL_SOURCE;
+ if (media_entity_init(&info->entity, 1, &info->pad, 0) < 0) {
+ kfree(info);
+ return NULL;
+ }
+#endif
+
return info;
#undef PADDING
#undef BYTES_PER_LONG
@@ -80,6 +88,9 @@ EXPORT_SYMBOL(framebuffer_alloc);
*/
void framebuffer_release(struct fb_info *info)
{
+#ifdef CONFIG_MEDIA_CONTROLLER
+ media_entity_cleanup(&info->entity);
+#endif
kfree(info->apertures);
kfree(info);
}
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 98b23e3..24b7368 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -423,9 +423,11 @@ struct fb_cursor {
#include <linux/list.h>
#include <linux/backlight.h>
#include <linux/slab.h>
+#include <media/media-entity.h>
#include <asm/io.h>
struct vm_area_struct;
+struct media_device;
struct fb_info;
struct device;
struct file;
@@ -879,6 +881,12 @@ struct fb_info {
#endif
struct fb_ops *fbops;
+#ifdef CONFIG_MEDIA_CONTROLLER
+ char name[32]; /* Device name */
+ struct media_pad pad; /* Output pad */
+ struct media_device *mdev; /* Optional media device */
+ struct media_entity entity; /* Media entity */
+#endif
struct device *device; /* This is the parent */
struct device *dev; /* This is this fb device */
int class_flag; /* private sysfs flags */
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 28/31] fbdev: sh_mobile_lcdc: Make LCDC entity inherit from media_entity
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index ec57533..fa60d00 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -5,6 +5,7 @@
#include <linux/fb.h>
#include <linux/mutex.h>
#include <linux/wait.h>
+#include <media/media-entity.h>
/* per-channel registers */
enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
@@ -34,6 +35,7 @@ enum sh_mobile_lcdc_entity_event {
};
struct sh_mobile_lcdc_entity {
+ struct media_entity entity;
struct module *owner;
const struct sh_mobile_lcdc_entity_ops *ops;
struct sh_mobile_lcdc_chan *lcdc;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 29/31] fbdev: sh_mipi_dsi: Add media controller support
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Initialize the entity associated with the MIPI/DSI transmitter.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mipi_dsi.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 3ead395..93ee3ee 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -50,6 +50,7 @@
struct sh_mipi {
struct sh_mobile_lcdc_entity entity;
+ struct media_pad pads[2];
void __iomem *base;
void __iomem *linkbase;
@@ -364,8 +365,9 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
unsigned long rate, f_current;
- int idx = pdev->id, ret;
+ int idx = pdev->id;
char dsip_clk[] = "dsi.p_clk";
+ int ret;
if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
return -ENODEV;
@@ -389,6 +391,17 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
mipi->entity.owner = THIS_MODULE;
mipi->entity.ops = &mipi_ops;
+ /* Initialize the panel media entity. */
+ mipi->pads[0].flags = MEDIA_PAD_FL_SINK;
+ mipi->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_init(&mipi->entity.entity, 2, mipi->pads, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to initialize MIPI entity\n");
+ goto ereqreg;
+ }
+
+ mipi->entity.entity.name = "MIPI/DSI transmitter";
+
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
dev_err(&pdev->dev, "MIPI register region already claimed\n");
ret = -EBUSY;
@@ -497,6 +510,7 @@ ereqreg2:
emap:
release_mem_region(res->start, resource_size(res));
ereqreg:
+ media_entity_cleanup(&mipi->entity.entity);
kfree(mipi);
ealloc:
efindslot:
@@ -541,6 +555,7 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
if (res)
release_mem_region(res->start, resource_size(res));
platform_set_drvdata(pdev, NULL);
+ media_entity_cleanup(&mipi->entity.entity);
kfree(mipi);
return 0;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 30/31] fbdev: sh_mobile_hdmi: Add media controller support
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Initialize the entity associated with the HDMI transmitter.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_hdmi.c | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index c17e3ad..c30c6a0 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -209,6 +209,7 @@ enum hotplug_state {
struct sh_hdmi {
struct sh_mobile_lcdc_entity entity;
+ struct media_pad pads[2];
void __iomem *base;
enum hotplug_state hp_state; /* hot-plug status */
@@ -1129,9 +1130,10 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
{
struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data;
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0), ret;
+ int irq = platform_get_irq(pdev, 0);
struct sh_hdmi *hdmi;
long rate;
+ int ret;
if (!res || !pdata || irq < 0)
return -ENODEV;
@@ -1146,6 +1148,17 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
hdmi->entity.owner = THIS_MODULE;
hdmi->entity.ops = &sh_hdmi_ops;
+ /* Initialize the panel media entity. */
+ hdmi->pads[0].flags = MEDIA_PAD_FL_SINK;
+ hdmi->pads[1].flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_init(&hdmi->entity.entity, 2, hdmi->pads, 0);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to initialize HDMI entity\n");
+ goto egetclk;
+ }
+
+ hdmi->entity.entity.name = "HDMI transmitter";
+
hdmi->hdmi_clk = clk_get(&pdev->dev, "ick");
if (IS_ERR(hdmi->hdmi_clk)) {
ret = PTR_ERR(hdmi->hdmi_clk);
@@ -1224,6 +1237,7 @@ ereqreg:
erate:
clk_put(hdmi->hdmi_clk);
egetclk:
+ media_entity_cleanup(&hdmi->entity.entity);
kfree(hdmi);
return ret;
@@ -1247,6 +1261,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
clk_put(hdmi->hdmi_clk);
iounmap(hdmi->base);
release_mem_region(res->start, resource_size(res));
+ media_entity_cleanup(&hdmi->entity.entity);
kfree(hdmi);
return 0;
--
1.7.3.4
^ permalink raw reply related
* [WIP/RFC 31/31] fbdev: sh_mobile_lcdc: Add media controller support
From: Laurent Pinchart @ 2011-09-19 0:28 UTC (permalink / raw)
To: linux-fbdev
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/Kconfig | 1 +
drivers/video/sh_mobile_lcdcfb.c | 116 ++++++++++++++++++++++++++++++++++++--
drivers/video/sh_mobile_lcdcfb.h | 8 +++
3 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..c18e1b8 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1977,6 +1977,7 @@ config FB_SH_MOBILE_LCDC
select FB_SYS_FOPS
select FB_DEFERRED_IO
select FB_BACKLIGHT
+ select MEDIA_CONTROLLER
select SH_MIPI_DSI if SH_LCD_MIPI_DSI
---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 19ac3c5..ac8b82d 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -26,6 +26,9 @@
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
+#include <media/media-device.h>
+#include <media/media-entity.h>
+
#include <video/sh_mobile_lcdc.h>
#include <video/sh_mobile_meram.h>
@@ -38,17 +41,22 @@
#define MAX_YRES 1080
struct sh_mobile_lcdc_priv {
+ struct media_device mdev;
+ struct device *dev;
+ struct sh_mobile_meram_info *meram_dev;
+
void __iomem *base;
int irq;
- atomic_t hw_usecnt;
- struct device *dev;
struct clk *dot_clk;
+
+ atomic_t hw_usecnt;
unsigned long lddckr;
+
struct sh_mobile_lcdc_chan ch[2];
struct notifier_block notifier;
+
int started;
int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
- struct sh_mobile_meram_info *meram_dev;
};
/* -----------------------------------------------------------------------------
@@ -1532,6 +1540,84 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
}
/* -----------------------------------------------------------------------------
+ * Media controller init/cleanup
+ */
+
+static int __devinit sh_mobile_lcdc_media_init(struct sh_mobile_lcdc_chan *ch)
+{
+ int ret;
+
+ /* Initialize the panel media entity. */
+ ch->panel.pad.flags = MEDIA_PAD_FL_SINK;
+ ret = media_entity_init(&ch->panel.entity, 1, &ch->panel.pad, 0);
+ if (ret < 0)
+ return ret;
+
+ ch->panel.entity.name = "Panel";
+
+ /* Create links. */
+ if (ch->tx_dev) {
+ ret = media_entity_create_link(&ch->info->entity, 0,
+ &ch->tx_dev->entity, 0,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
+
+ ret = media_entity_create_link(&ch->tx_dev->entity, 1,
+ &ch->panel.entity, 0,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = media_entity_create_link(&ch->info->entity, 0,
+ &ch->panel.entity, 0,
+ MEDIA_LNK_FL_IMMUTABLE |
+ MEDIA_LNK_FL_ENABLED);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __devinit
+sh_mobile_lcdc_media_register(struct sh_mobile_lcdc_priv *priv)
+{
+ unsigned int i;
+ int ret;
+
+ priv->mdev.dev = priv->dev;
+ strlcpy(priv->mdev.model, "SH Mobile LCDC", sizeof(priv->mdev.model));
+
+ ret = media_device_register(&priv->mdev);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
+ struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
+
+ if (ch->info = NULL)
+ continue;
+
+ if (ch->tx_dev) {
+ ret = media_device_register_entity(&priv->mdev,
+ &ch->tx_dev->entity);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = media_device_register_entity(&priv->mdev,
+ &ch->panel.entity);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* -----------------------------------------------------------------------------
* Probe/remove and driver init/exit
*/
@@ -1587,6 +1673,9 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
info->screen_base, ch->dma_handle);
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
+
+ media_device_unregister_entity(&ch->panel.entity);
+ media_entity_cleanup(&ch->panel.entity);
}
for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
@@ -1651,8 +1740,9 @@ sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
static int __devinit
sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
- struct sh_mobile_lcdc_chan *ch)
+ struct sh_mobile_lcdc_chan *ch, unsigned int index)
{
+ struct platform_device *pdev = to_platform_device(priv->dev);
struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg;
const struct fb_videomode *max_mode;
const struct fb_videomode *mode;
@@ -1679,6 +1769,8 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
info->par = ch;
info->pseudo_palette = &ch->pseudo_palette;
info->flags = FBINFO_FLAG_DEFAULT;
+ snprintf(info->name, sizeof(info->name), "LCDC %u channel %u", pdev->id,
+ index);
if (cfg->tx_dev) {
if (!cfg->tx_dev->dev.driver ||
@@ -1691,6 +1783,12 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
ch->tx_dev->lcdc = ch;
}
+ ret = sh_mobile_lcdc_media_init(ch);
+ if (ret < 0) {
+ dev_err(priv->dev, "unable to initialize media entities\n");
+ return ret;
+ }
+
/* Iterate through the modes to validate them and find the highest
* resolution.
*/
@@ -1907,11 +2005,18 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
for (i = 0; i < num_channels; i++) {
struct sh_mobile_lcdc_chan *ch = priv->ch + i;
- error = sh_mobile_lcdc_channel_init(priv, ch);
+ error = sh_mobile_lcdc_channel_init(priv, ch, i);
if (error)
goto err1;
}
+ error = sh_mobile_lcdc_media_register(priv);
+ if (error) {
+ dev_err(&pdev->dev, "media device registration failed (%d)\n",
+ error);
+ goto err1;
+ }
+
error = sh_mobile_lcdc_start(priv);
if (error) {
dev_err(&pdev->dev, "unable to start hardware\n");
@@ -1931,6 +2036,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
}
}
+ info->mdev = &priv->mdev;
info->bl_dev = ch->bl;
error = register_framebuffer(info);
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
index fa60d00..98ed5f4 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/sh_mobile_lcdcfb.h
@@ -79,6 +79,14 @@ struct sh_mobile_lcdc_chan {
int (*notify)(struct sh_mobile_lcdc_chan *ch,
enum sh_mobile_lcdc_entity_event event,
struct fb_var_screeninfo *var);
+
+ struct media_pad pad;
+ struct media_entity entity;
+
+ struct {
+ struct media_pad pad;
+ struct media_entity entity;
+ } panel;
};
#endif
--
1.7.3.4
^ permalink raw reply related
* linux-next: manual merge of the fbdev tree with the mips tree
From: Stephen Rothwell @ 2011-09-19 6:22 UTC (permalink / raw)
To: Florian Tobias Schandinat, linux-fbdev
Cc: linux-next, linux-kernel, Manuel Lauss, Ralf Baechle, Paul Mundt
Hi all,
Today's linux-next merge of the fbdev tree got a conflict in
drivers/video/Kconfig between commit 9d7dec27ace1 ("MIPS: Alchemy: remove
all CONFIG_SOC_AU1??? defines") from the mips tree and commit
4ee584615102 ("au1200fb: switch to FB_SYS helpers") from the fbdev tree.
Just context changes. I fixed it up (see below) and can carry the fix as
necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/video/Kconfig
index 55a7df4,8165c55..0000000
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@@ -1755,10 -1764,11 +1764,11 @@@ config FB_AU110
config FB_AU1200
bool "Au1200 LCD Driver"
- depends on (FB = y) && MIPS && SOC_AU1200
+ depends on (FB = y) && MIPS_ALCHEMY
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
help
This is the framebuffer driver for the AMD Au1200 SOC. It can drive
various panels and CRTs by passing in kernel cmd line option
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox