@@ -651,6 +651,8 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
SDEBUG(" count: %d\n", count);
if (arg == ATOM_UNIT_MICROSEC)
udelay(count);
+ else if (ctx->ctx->atomic)
+ mdelay(count);
else
schedule_timeout_uninterruptible(msecs_to_jiffies(count));
}
@@ -1191,8 +1193,9 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
{
int r;
+ unsigned long flags;
- mutex_lock(&ctx->mutex);
+ spin_lock_irqsave(&ctx->spinlock, flags);
/* reset reg block */
ctx->reg_block = 0;
/* reset fb window */
@@ -1200,7 +1203,26 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
/* reset io mode */
ctx->io_mode = ATOM_IO_MM;
r = atom_execute_table_locked(ctx, index, params);
- mutex_unlock(&ctx->mutex);
+ spin_unlock_irqrestore(&ctx->spinlock, flags);
+ return r;
+}
+
+int atom_execute_table_atomic(struct atom_context *ctx, int index, uint32_t * params)
+{
+ int r;
+ unsigned long flags;
+ spin_lock_irqsave(&ctx->spinlock, flags);
+ /* reset reg block */
+ ctx->reg_block = 0;
+ /* reset fb window */
+ ctx->fb_base = 0;
+ /* reset io mode */
+ ctx->io_mode = ATOM_IO_MM;
+ /* be atomic */
+ ctx->atomic = true;
+ r = atom_execute_table_locked(ctx, index, params);
+ ctx->atomic = false;
+ spin_unlock_irqrestore(&ctx->spinlock, flags);
return r;
}
@@ -121,7 +121,7 @@ struct card_info {
struct atom_context {
struct card_info *card;
- struct mutex mutex;
+ spinlock_t spinlock;
void *bios;
uint32_t cmd_table, data_table;
uint16_t *iio;
@@ -135,12 +135,14 @@ struct atom_context {
int cs_equal, cs_above;
int io_mode;
uint32_t *scratch;
+ bool atomic;
};
extern int atom_debug;
struct atom_context *atom_parse(struct card_info *, void *);
int atom_execute_table(struct atom_context *, int, uint32_t *);
+int atom_execute_table_atomic(struct atom_context *, int, uint32_t *);
int atom_asic_init(struct atom_context *);
void atom_destroy(struct atom_context *);
bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
@@ -384,7 +384,7 @@ int radeon_atombios_init(struct radeon_device *rdev)
atom_card_info->pll_write = cail_pll_write;
rdev->mode_info.atom_context = atom_parse(atom_card_info, rdev->bios);
- mutex_init(&rdev->mode_info.atom_context->mutex);
+ spin_lock_init(&rdev->mode_info.atom_context->spinlock);
radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
atom_allocate_fb_scratch(rdev->mode_info.atom_context);
return 0;