Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 68271
b: refs/heads/master
c: f18d533
h: refs/heads/master
i:
  68269: 82b251b
  68267: ff4f439
  68263: 4025206
  68255: 1f52508
v: v3
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Sep 21, 2007
1 parent 6058ed5 commit 8bc6beb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 22 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: 9964fa8bf952c5c4df9676223fab4cd886d18200
refs/heads/master: f18d533e3cd476aedf41fe1e6e9dc3e0a2446bba
78 changes: 57 additions & 21 deletions trunk/arch/sh/kernel/cpu/irq/intc.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ struct intc_handle_int {

struct intc_desc_int {
unsigned long *reg;
#ifdef CONFIG_SMP
unsigned long *smp;
#endif
unsigned int nr_reg;
struct intc_handle_int *prio;
unsigned int nr_prio;
Expand All @@ -48,6 +51,16 @@ struct intc_desc_int {
struct irq_chip chip;
};

#ifdef CONFIG_SMP
#define IS_SMP(x) x.smp
#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1)
#else
#define IS_SMP(x) 0
#define INTC_REG(d, x, c) (d->reg[(x)])
#define SMP_NR(d, x) 1
#endif

static unsigned int intc_prio_level[NR_IRQS]; /* for now */

static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
Expand Down Expand Up @@ -177,11 +190,14 @@ static void (*intc_disable_fns[])(unsigned long addr,
static inline void _intc_enable(unsigned int irq, unsigned long handle)
{
struct intc_desc_int *d = get_intc_desc(irq);
unsigned long addr = d->reg[_INTC_ADDR_E(handle)];
unsigned long addr;
unsigned int cpu;

intc_enable_fns[_INTC_MODE(handle)](addr, handle,
intc_reg_fns[_INTC_FN(handle)],
irq);
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) {
addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu);
intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\
[_INTC_FN(handle)], irq);
}
}

static void intc_enable(unsigned int irq)
Expand All @@ -191,13 +207,16 @@ static void intc_enable(unsigned int irq)

static void intc_disable(unsigned int irq)
{
struct intc_desc_int *desc = get_intc_desc(irq);
struct intc_desc_int *d = get_intc_desc(irq);
unsigned long handle = (unsigned long) get_irq_chip_data(irq);
unsigned long addr = desc->reg[_INTC_ADDR_D(handle)];
unsigned long addr;
unsigned int cpu;

intc_disable_fns[_INTC_MODE(handle)](addr, handle,
intc_reg_fns[_INTC_FN(handle)],
irq);
for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) {
addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu);
intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\
[_INTC_FN(handle)], irq);
}
}

static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp,
Expand Down Expand Up @@ -276,7 +295,7 @@ static int intc_set_sense(unsigned int irq, unsigned int type)

ihp = intc_find_irq(d->sense, d->nr_sense, irq);
if (ihp) {
addr = d->reg[_INTC_ADDR_E(ihp->handle)];
addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
}
return 0;
Expand Down Expand Up @@ -536,9 +555,26 @@ static void __init intc_register_irq(struct intc_desc *desc,
d->chip.mask(irq);
}

static unsigned int __init save_reg(struct intc_desc_int *d,
unsigned int cnt,
unsigned long value,
unsigned int smp)
{
if (value) {
d->reg[cnt] = value;
#ifdef CONFIG_SMP
d->smp[cnt] = smp;
#endif
return 1;
}

return 0;
}


void __init register_intc_controller(struct intc_desc *desc)
{
unsigned int i, k;
unsigned int i, k, smp;
struct intc_desc_int *d;

d = alloc_bootmem(sizeof(*d));
Expand All @@ -548,34 +584,34 @@ void __init register_intc_controller(struct intc_desc *desc)
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;

d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg));
#ifdef CONFIG_SMP
d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp));
#endif
k = 0;

if (desc->mask_regs) {
for (i = 0; i < desc->nr_mask_regs; i++) {
if (desc->mask_regs[i].set_reg)
d->reg[k++] = desc->mask_regs[i].set_reg;
if (desc->mask_regs[i].clr_reg)
d->reg[k++] = desc->mask_regs[i].clr_reg;
smp = IS_SMP(desc->mask_regs[i]);
k += save_reg(d, k, desc->mask_regs[i].set_reg, smp);
k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp);
}
}

if (desc->prio_regs) {
d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio));

for (i = 0; i < desc->nr_prio_regs; i++) {
if (desc->prio_regs[i].set_reg)
d->reg[k++] = desc->prio_regs[i].set_reg;
if (desc->prio_regs[i].clr_reg)
d->reg[k++] = desc->prio_regs[i].clr_reg;
smp = IS_SMP(desc->prio_regs[i]);
k += save_reg(d, k, desc->prio_regs[i].set_reg, smp);
k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp);
}
}

if (desc->sense_regs) {
d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense));

for (i = 0; i < desc->nr_sense_regs; i++) {
if (desc->sense_regs[i].reg)
d->reg[k++] = desc->sense_regs[i].reg;
k += save_reg(d, k, desc->sense_regs[i].reg, 0);
}
}

Expand Down
12 changes: 12 additions & 0 deletions trunk/include/asm-sh/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,30 @@ struct intc_group {
struct intc_mask_reg {
unsigned long set_reg, clr_reg, reg_width;
intc_enum enum_ids[32];
#ifdef CONFIG_SMP
unsigned long smp;
#endif
};

struct intc_prio_reg {
unsigned long set_reg, clr_reg, reg_width, field_width;
intc_enum enum_ids[16];
#ifdef CONFIG_SMP
unsigned long smp;
#endif
};

struct intc_sense_reg {
unsigned long reg, reg_width, field_width;
intc_enum enum_ids[16];
};

#ifdef CONFIG_SMP
#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8)
#else
#define INTC_SMP(stride, nr)
#endif

struct intc_desc {
struct intc_vect *vectors;
unsigned int nr_vectors;
Expand Down

0 comments on commit 8bc6beb

Please sign in to comment.