diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2009-12-16 18:00:46 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-22 20:14:03 -0500 |
commit | c31ad97f1886a2ff0f3356dc31d50c57944365da (patch) | |
tree | 4e6de647819a7acdcd7651efeb7c1db14a6179c7 | |
parent | d79766fab9975c6414ebab7d2abf017834a48c35 (diff) |
drm/radeon/kms: prevent parallel AtomBIOS calls
This just adds a mutex around the atombios table execution
so we don't call it from two contexts at once.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/radeon/atom.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/atom.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 1 |
3 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 6578d19dff93..388140a7e651 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -58,6 +58,7 @@ typedef struct { | |||
58 | } atom_exec_context; | 58 | } atom_exec_context; |
59 | 59 | ||
60 | int atom_debug = 0; | 60 | int atom_debug = 0; |
61 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); | ||
61 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); | 62 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); |
62 | 63 | ||
63 | static uint32_t atom_arg_mask[8] = | 64 | static uint32_t atom_arg_mask[8] = |
@@ -573,7 +574,7 @@ static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) | |||
573 | else | 574 | else |
574 | SDEBUG(" table: %d\n", idx); | 575 | SDEBUG(" table: %d\n", idx); |
575 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) | 576 | if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) |
576 | atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift); | 577 | atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); |
577 | } | 578 | } |
578 | 579 | ||
579 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) | 580 | static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) |
@@ -1040,7 +1041,7 @@ static struct { | |||
1040 | atom_op_shr, ATOM_ARG_MC}, { | 1041 | atom_op_shr, ATOM_ARG_MC}, { |
1041 | atom_op_debug, 0},}; | 1042 | atom_op_debug, 0},}; |
1042 | 1043 | ||
1043 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | 1044 | static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) |
1044 | { | 1045 | { |
1045 | int base = CU16(ctx->cmd_table + 4 + 2 * index); | 1046 | int base = CU16(ctx->cmd_table + 4 + 2 * index); |
1046 | int len, ws, ps, ptr; | 1047 | int len, ws, ps, ptr; |
@@ -1092,6 +1093,13 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | |||
1092 | kfree(ectx.ws); | 1093 | kfree(ectx.ws); |
1093 | } | 1094 | } |
1094 | 1095 | ||
1096 | void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) | ||
1097 | { | ||
1098 | mutex_lock(&ctx->mutex); | ||
1099 | atom_execute_table_locked(ctx, index, params); | ||
1100 | mutex_unlock(&ctx->mutex); | ||
1101 | } | ||
1102 | |||
1095 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; | 1103 | static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; |
1096 | 1104 | ||
1097 | static void atom_index_iio(struct atom_context *ctx, int base) | 1105 | static void atom_index_iio(struct atom_context *ctx, int base) |
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h index 6671848e5ea1..47fd943f6d14 100644 --- a/drivers/gpu/drm/radeon/atom.h +++ b/drivers/gpu/drm/radeon/atom.h | |||
@@ -120,6 +120,7 @@ struct card_info { | |||
120 | 120 | ||
121 | struct atom_context { | 121 | struct atom_context { |
122 | struct card_info *card; | 122 | struct card_info *card; |
123 | struct mutex mutex; | ||
123 | void *bios; | 124 | void *bios; |
124 | uint32_t cmd_table, data_table; | 125 | uint32_t cmd_table, data_table; |
125 | uint16_t *iio; | 126 | uint16_t *iio; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 02bcdb1240c0..99b95ca42a71 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -481,6 +481,7 @@ int radeon_atombios_init(struct radeon_device *rdev) | |||
481 | atom_card_info->pll_write = cail_pll_write; | 481 | atom_card_info->pll_write = cail_pll_write; |
482 | 482 | ||
483 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); | 483 | rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios); |
484 | mutex_init(&rdev->mode_info.atom_context->mutex); | ||
484 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); | 485 | radeon_atom_initialize_bios_scratch_regs(rdev->ddev); |
485 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); | 486 | atom_allocate_fb_scratch(rdev->mode_info.atom_context); |
486 | return 0; | 487 | return 0; |