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

Commit 778e26de authored by Patrik Jakobsson's avatar Patrik Jakobsson
Browse files

drm/gma500: Move asle interrupt work into a work task

Previously the backlight code was called from IRQ context which isn't
allowed. This patch moves all the asle work into a work task which takes
care of the locking bug reported by users.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=64221


Signed-off-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
parent c7829b29
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -173,10 +173,13 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
	return 0;
}

void psb_intel_opregion_asle_intr(struct drm_device *dev)
static void psb_intel_opregion_asle_work(struct work_struct *work)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct opregion_asle *asle = dev_priv->opregion.asle;
	struct psb_intel_opregion *opregion =
		container_of(work, struct psb_intel_opregion, asle_work);
	struct drm_psb_private *dev_priv =
		container_of(opregion, struct drm_psb_private, opregion);
	struct opregion_asle *asle = opregion->asle;
	u32 asle_stat = 0;
	u32 asle_req;

@@ -190,9 +193,18 @@ void psb_intel_opregion_asle_intr(struct drm_device *dev)
	}

	if (asle_req & ASLE_SET_BACKLIGHT)
		asle_stat |= asle_set_backlight(dev, asle->bclp);
		asle_stat |= asle_set_backlight(dev_priv->dev, asle->bclp);

	asle->aslc = asle_stat;

}

void psb_intel_opregion_asle_intr(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = dev->dev_private;

	if (dev_priv->opregion.asle)
		schedule_work(&dev_priv->opregion.asle_work);
}

#define ASLE_ALS_EN    (1<<0)
@@ -282,6 +294,8 @@ void psb_intel_opregion_fini(struct drm_device *dev)
		unregister_acpi_notifier(&psb_intel_opregion_notifier);
	}

	cancel_work_sync(&opregion->asle_work);

	/* just clear all opregion memory pointers now */
	iounmap(opregion->header);
	opregion->header = NULL;
@@ -304,6 +318,9 @@ int psb_intel_opregion_setup(struct drm_device *dev)
		DRM_DEBUG_DRIVER("ACPI Opregion not supported\n");
		return -ENOTSUPP;
	}

	INIT_WORK(&opregion->asle_work, psb_intel_opregion_asle_work);

	DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy);
	base = acpi_os_ioremap(opregion_phy, 8*1024);
	if (!base)
+1 −0
Original line number Diff line number Diff line
@@ -266,6 +266,7 @@ struct psb_intel_opregion {
	struct opregion_asle *asle;
	void *vbt;
	u32 __iomem *lid_state;
	struct work_struct asle_work;
};

struct sdvo_device_mapping {