GPF fix in atomic flipping, sun4i overflow fix.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbypLRAAoJEAx081l5xIa+mMMP/1ywMk9LSQhECJrU58f9XAts vOiFrtgy4HLxUw7Nj8PFV3tXTAhuNfITJ5az01ggLPpFH4KtVRtHUM9xMc7wRUJe 5seR6AntgiwjZ5VU036+BMD1j6c1cD7OA7BY2moio3PAbXv+wmQ2P3qwGl5pxzVR 20emwYgQSfkiThblI2MwNvV1os8Gy6bDO9vowVc1+vpYkWvCf5lEVvaZRsujZl1/ FvLamGVIs19VlNMUzlUFKqv8c54qnv1y7CpZtNNZEGDitT+/fPC1BmyyxTMaNl7Z iMhfHwT4hFy9CS4EcLqFvGgKZSGrC9IzSjiCYWo/uXsqDMv8SrlH33adBlcwMM7q 5ECALrSLF0BKWuD3dU/GipYHB0FmEm9U6nbruHpO9k3HyayJ3+mU2NjvCncxzLFb J/lywag+GeB3pcNUNIuvN4IIBl85ytJTUV+yU1DYlxb644cPighlLZqMcAJJg5kP 045ixmSKiPyLv2hVUn5DsrnzMx1S7j9HUZwzsg4BXuguYu7pz6p3ui3sjgZuN+vU ryvpmM0YeySB6BfbVTqTNFzRtN6ozcy6KIu/TKNh1qudE46ktA0+/7NkZ+dN5HN4 RqZQarbCTq2x4mpOFWBFwdjl0ehhtcAFL9eKJoD55PxzbV/8P205gD5loUVQI+qi Qwawgc3Mn3Z/PbZhrKtI =ZlVF -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2018-10-20-1' of git://anongit.freedesktop.org/drm/drm Dave writes: "drm fixes for 4.19 final (part 2) Looked like two stragglers snuck in, one very urgent the pageflipping was missing a reference that could result in a GPF on non-i915 drivers, the other is an overflow in the sun4i dotclock calcs resulting in a mode not getting set." * tag 'drm-fixes-2018-10-20-1' of git://anongit.freedesktop.org/drm/drm: drm/sun4i: Fix an ulong overflow in the dotclock driver drm: Get ref on CRTC commit object when waiting for flip_done
This commit is contained in:
commit
270b77a0f3
|
@ -174,6 +174,11 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
|
||||||
state->crtcs[i].state = NULL;
|
state->crtcs[i].state = NULL;
|
||||||
state->crtcs[i].old_state = NULL;
|
state->crtcs[i].old_state = NULL;
|
||||||
state->crtcs[i].new_state = NULL;
|
state->crtcs[i].new_state = NULL;
|
||||||
|
|
||||||
|
if (state->crtcs[i].commit) {
|
||||||
|
drm_crtc_commit_put(state->crtcs[i].commit);
|
||||||
|
state->crtcs[i].commit = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < config->num_total_plane; i++) {
|
for (i = 0; i < config->num_total_plane; i++) {
|
||||||
|
|
|
@ -1408,15 +1408,16 @@ EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
|
||||||
void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
|
void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
|
||||||
struct drm_atomic_state *old_state)
|
struct drm_atomic_state *old_state)
|
||||||
{
|
{
|
||||||
struct drm_crtc_state *new_crtc_state;
|
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
|
for (i = 0; i < dev->mode_config.num_crtc; i++) {
|
||||||
struct drm_crtc_commit *commit = new_crtc_state->commit;
|
struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!commit)
|
crtc = old_state->crtcs[i].ptr;
|
||||||
|
|
||||||
|
if (!crtc || !commit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
|
ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
|
||||||
|
@ -1934,6 +1935,9 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
|
||||||
drm_crtc_commit_get(commit);
|
drm_crtc_commit_get(commit);
|
||||||
|
|
||||||
commit->abort_completion = true;
|
commit->abort_completion = true;
|
||||||
|
|
||||||
|
state->crtcs[i].commit = commit;
|
||||||
|
drm_crtc_commit_get(commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
|
for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
|
||||||
|
|
|
@ -81,9 +81,19 @@ static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
|
for (i = tcon->dclk_min_div; i <= tcon->dclk_max_div; i++) {
|
||||||
unsigned long ideal = rate * i;
|
u64 ideal = (u64)rate * i;
|
||||||
unsigned long rounded;
|
unsigned long rounded;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ideal has overflowed the max value that can be stored in an
|
||||||
|
* unsigned long, and every clk operation we might do on a
|
||||||
|
* truncated u64 value will give us incorrect results.
|
||||||
|
* Let's just stop there since bigger dividers will result in
|
||||||
|
* the same overflow issue.
|
||||||
|
*/
|
||||||
|
if (ideal > ULONG_MAX)
|
||||||
|
goto out;
|
||||||
|
|
||||||
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
|
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
|
||||||
ideal);
|
ideal);
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,17 @@ struct __drm_planes_state {
|
||||||
struct __drm_crtcs_state {
|
struct __drm_crtcs_state {
|
||||||
struct drm_crtc *ptr;
|
struct drm_crtc *ptr;
|
||||||
struct drm_crtc_state *state, *old_state, *new_state;
|
struct drm_crtc_state *state, *old_state, *new_state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @commit:
|
||||||
|
*
|
||||||
|
* A reference to the CRTC commit object that is kept for use by
|
||||||
|
* drm_atomic_helper_wait_for_flip_done() after
|
||||||
|
* drm_atomic_helper_commit_hw_done() is called. This ensures that a
|
||||||
|
* concurrent commit won't free a commit object that is still in use.
|
||||||
|
*/
|
||||||
|
struct drm_crtc_commit *commit;
|
||||||
|
|
||||||
s32 __user *out_fence_ptr;
|
s32 __user *out_fence_ptr;
|
||||||
u64 last_vblank_count;
|
u64 last_vblank_count;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue