Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 498f9620 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull fbdev fixes from Tomi Valkeinen:
 - fix build errors for bf54x-lq043fb and imxfb
 - fbcon fix for da8xx-fb
 - omapdss fixes for hdmi audio, irq handling and fclk calculation

* tag 'fbdev-fixes-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
  video: bf54x-lq043fb: fix build error
  OMAPDSS: Change struct reg_field to dispc_reg_field
  OMAPDSS: Take pixelclock unit change into account in hdmi_compute_acr()
  OMAPDSS: fix shared irq handlers
  video: imxfb: Select LCD_CLASS_DEVICE unconditionally
  OMAPDSS: fix rounding when calculating fclk rate
  video: da8xx-fb: Fix casting of info->pseudo_palette
parents 5f63517c c26ef3eb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -359,6 +359,8 @@ config FB_SA1100
config FB_IMX
	tristate "Freescale i.MX1/21/25/27 LCD support"
	depends on FB && ARCH_MXC
	select BACKLIGHT_LCD_SUPPORT
	select LCD_CLASS_DEVICE
	select FB_CFB_FILLRECT
	select FB_CFB_COPYAREA
	select FB_CFB_IMAGEBLIT
+1 −1
Original line number Diff line number Diff line
@@ -49,13 +49,13 @@
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>

#include <asm/blackfin.h>
#include <asm/irq.h>
#include <asm/dpmc.h>
#include <asm/dma-mapping.h>
#include <asm/dma.h>
#include <asm/gpio.h>
#include <asm/portmux.h>

#include <mach/bf54x-lq043.h>
+1 −9
Original line number Diff line number Diff line
@@ -663,15 +663,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
			(green << info->var.green.offset) |
			(blue << info->var.blue.offset);

		switch (info->var.bits_per_pixel) {
		case 16:
			((u16 *) (info->pseudo_palette))[regno] = v;
			break;
		case 24:
		case 32:
		((u32 *) (info->pseudo_palette))[regno] = v;
			break;
		}
		if (palette[0] != 0x4000) {
			update_hw = 1;
			palette[0] = 0x4000;
+57 −10
Original line number Diff line number Diff line
@@ -101,6 +101,8 @@ static struct {
	void __iomem    *base;

	int irq;
	irq_handler_t user_handler;
	void *user_data;

	unsigned long core_clk_rate;
	unsigned long tv_pclk_rate;
@@ -113,6 +115,8 @@ static struct {
	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];

	const struct dispc_features *feat;

	bool is_enabled;
} dispc;

enum omap_color_component {
@@ -141,12 +145,18 @@ enum mgr_reg_fields {
	DISPC_MGR_FLD_NUM,
};

struct dispc_reg_field {
	u16 reg;
	u8 high;
	u8 low;
};

static const struct {
	const char *name;
	u32 vsync_irq;
	u32 framedone_irq;
	u32 sync_lost_irq;
	struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
	struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
} mgr_desc[] = {
	[OMAP_DSS_CHANNEL_LCD] = {
		.name		= "LCD",
@@ -238,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx)

static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
{
	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
	return REG_GET(rfld.reg, rfld.high, rfld.low);
}

static void mgr_fld_write(enum omap_channel channel,
					enum mgr_reg_fields regfld, int val) {
	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
	REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
}

@@ -3669,16 +3679,44 @@ static int __init dispc_init_features(struct platform_device *pdev)
	return 0;
}

static irqreturn_t dispc_irq_handler(int irq, void *arg)
{
	if (!dispc.is_enabled)
		return IRQ_NONE;

	return dispc.user_handler(irq, dispc.user_data);
}

int dispc_request_irq(irq_handler_t handler, void *dev_id)
{
	return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
			     IRQF_SHARED, "OMAP DISPC", dev_id);
	int r;

	if (dispc.user_handler != NULL)
		return -EBUSY;

	dispc.user_handler = handler;
	dispc.user_data = dev_id;

	/* ensure the dispc_irq_handler sees the values above */
	smp_wmb();

	r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
			     IRQF_SHARED, "OMAP DISPC", &dispc);
	if (r) {
		dispc.user_handler = NULL;
		dispc.user_data = NULL;
	}

	return r;
}
EXPORT_SYMBOL(dispc_request_irq);

void dispc_free_irq(void *dev_id)
{
	devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
	devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);

	dispc.user_handler = NULL;
	dispc.user_data = NULL;
}
EXPORT_SYMBOL(dispc_free_irq);

@@ -3750,6 +3788,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)

static int dispc_runtime_suspend(struct device *dev)
{
	dispc.is_enabled = false;
	/* ensure the dispc_irq_handler sees the is_enabled value */
	smp_wmb();
	/* wait for current handler to finish before turning the DISPC off */
	synchronize_irq(dispc.irq);

	dispc_save_context();

	return 0;
@@ -3763,12 +3807,15 @@ static int dispc_runtime_resume(struct device *dev)
	 * _omap_dispc_initial_config(). We can thus use it to detect if
	 * we have lost register context.
	 */
	if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
		return 0;

	if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
		_omap_dispc_initial_config();

		dispc_restore_context();
	}

	dispc.is_enabled = true;
	/* ensure the dispc_irq_handler sees the is_enabled value */
	smp_wmb();

	return 0;
}
+20 −0
Original line number Diff line number Diff line
@@ -297,6 +297,8 @@ struct dsi_data {

	int irq;

	bool is_enabled;

	struct clk *dss_clk;
	struct clk *sys_clk;

@@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
	dsidev = (struct platform_device *) arg;
	dsi = dsi_get_dsidrv_data(dsidev);

	if (!dsi->is_enabled)
		return IRQ_NONE;

	spin_lock(&dsi->irq_lock);

	irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
@@ -5671,6 +5676,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)

static int dsi_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);

	dsi->is_enabled = false;
	/* ensure the irq handler sees the is_enabled value */
	smp_wmb();
	/* wait for current handler to finish before turning the DSI off */
	synchronize_irq(dsi->irq);

	dispc_runtime_put();

	return 0;
@@ -5678,12 +5692,18 @@ static int dsi_runtime_suspend(struct device *dev)

static int dsi_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
	int r;

	r = dispc_runtime_get();
	if (r)
		return r;

	dsi->is_enabled = true;
	/* ensure the irq handler sees the is_enabled value */
	smp_wmb();

	return 0;
}

Loading