Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 247894
b: refs/heads/master
c: 5eb1f4f
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Hellstrom authored and David S. Miller committed Apr 21, 2011
1 parent ce8ce6c commit f6b14f5
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a481b5d0cb5d1884f16460b4846755518360f1ca
refs/heads/master: 5eb1f4fc167f5adc5f15e722e25eff6713fb3406
64 changes: 54 additions & 10 deletions trunk/arch/sparc/kernel/leon_kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,25 +99,68 @@ static inline unsigned long get_irqmask(unsigned int irq)
return mask;
}

#ifdef CONFIG_SMP
static int irq_choose_cpu(const struct cpumask *affinity)
{
cpumask_t mask;

cpus_and(mask, cpu_online_map, *affinity);
if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask))
return 0;
else
return first_cpu(mask);
}
#else
#define irq_choose_cpu(affinity) 0
#endif

static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest,
bool force)
{
unsigned long mask, oldmask, flags;
int oldcpu, newcpu;

mask = (unsigned long)data->chip_data;
oldcpu = irq_choose_cpu(data->affinity);
newcpu = irq_choose_cpu(dest);

if (oldcpu == newcpu)
goto out;

/* unmask on old CPU first before enabling on the selected CPU */
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(oldcpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(oldcpu), (oldmask & ~mask));
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(newcpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(newcpu), (oldmask | mask));
spin_unlock_irqrestore(&leon_irq_lock, flags);
out:
return IRQ_SET_MASK_OK;
}

static void leon_unmask_irq(struct irq_data *data)
{
unsigned long mask, oldmask, flags;
int cpu;

mask = (unsigned long)data->chip_data;
cpu = irq_choose_cpu(data->affinity);
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(0));
LEON3_BYPASS_STORE_PA(LEON_IMASK(0), (oldmask | mask));
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask));
spin_unlock_irqrestore(&leon_irq_lock, flags);
}

static void leon_mask_irq(struct irq_data *data)
{
unsigned long mask, oldmask, flags;
int cpu;

mask = (unsigned long)data->chip_data;
cpu = irq_choose_cpu(data->affinity);
spin_lock_irqsave(&leon_irq_lock, flags);
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(0));
LEON3_BYPASS_STORE_PA(LEON_IMASK(0), (oldmask & ~mask));
oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask));
spin_unlock_irqrestore(&leon_irq_lock, flags);
}

Expand All @@ -144,12 +187,13 @@ static void leon_eoi_irq(struct irq_data *data)
}

static struct irq_chip leon_irq = {
.name = "leon",
.irq_startup = leon_startup_irq,
.irq_shutdown = leon_shutdown_irq,
.irq_mask = leon_mask_irq,
.irq_unmask = leon_unmask_irq,
.irq_eoi = leon_eoi_irq,
.name = "leon",
.irq_startup = leon_startup_irq,
.irq_shutdown = leon_shutdown_irq,
.irq_mask = leon_mask_irq,
.irq_unmask = leon_unmask_irq,
.irq_eoi = leon_eoi_irq,
.irq_set_affinity = leon_set_affinity,
};

/*
Expand Down

0 comments on commit f6b14f5

Please sign in to comment.