We want to perform radeon memory reclocking in interrupt context, so need
to ensure that we don't do anything that may sleep. Add an alternate
entry point to the atom interpreter that flags things appropriately and
make behaviour conditional on that.

Signed-off-by: Matthew Garrett <m...@redhat.com.
---
 drivers/gpu/drm/radeon/atom.c          |   26 ++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/atom.h          |    4 +++-
 drivers/gpu/drm/radeon/radeon_device.c |    2 +-
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index 247f8ee..bd5c5b5 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -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;
 }
 
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index cd1b64a..c26f5e1 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -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,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 75f7b1e..3a711a9 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -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;
-- 
1.6.5.2


------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to