Skip to content

Commit

Permalink
Merge branches 'irq-cleanup-for-linus' and 'irq-fixes-for-linus' of g…
Browse files Browse the repository at this point in the history
…it://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'irq-cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  vlynq: Convert irq functions

* 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  genirq; Fix cleanup fallout
  genirq: Fix typo and remove unused variable
  genirq: Fix new kernel-doc warnings
  genirq: Add setter for AFFINITY_SET in irq_data state
  genirq: Provide setter inline for IRQD_IRQ_INPROGRESS
  genirq: Remove handle_IRQ_event
  arm: Ns9xxx: Remove private irq flow handler
  powerpc: cell: Use the core flow handler
  genirq: Provide edge_eoi flow handler
  genirq: Move INPROGRESS, MASKED and DISABLED state flags to irq_data
  genirq: Split irq_set_affinity() so it can be called with lock held.
  genirq: Add chip flag for restricting cpu_on/offline calls
  genirq: Add chip hooks for taking CPUs on/off line.
  genirq: Add irq disabled flag to irq_data state
  genirq: Reserve the irq when calling irq_set_chip()
  • Loading branch information
Linus Torvalds committed Mar 29, 2011
3 parents 5ede9dd + 8ec4ad2 + 0ef5ca1 commit e5217fb
Show file tree
Hide file tree
Showing 14 changed files with 297 additions and 235 deletions.
58 changes: 4 additions & 54 deletions arch/arm/mach-ns9xxx/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,11 @@ static void ns9xxx_mask_irq(struct irq_data *d)
__raw_writel(ic, SYS_IC(prio / 4));
}

static void ns9xxx_ack_irq(struct irq_data *d)
static void ns9xxx_eoi_irq(struct irq_data *d)
{
__raw_writel(0, SYS_ISRADDR);
}

static void ns9xxx_maskack_irq(struct irq_data *d)
{
ns9xxx_mask_irq(d);
ns9xxx_ack_irq(d);
}

static void ns9xxx_unmask_irq(struct irq_data *d)
{
/* XXX: better use cpp symbols */
Expand All @@ -52,56 +46,11 @@ static void ns9xxx_unmask_irq(struct irq_data *d)
}

static struct irq_chip ns9xxx_chip = {
.irq_ack = ns9xxx_ack_irq,
.irq_eoi = ns9xxx_eoi_irq,
.irq_mask = ns9xxx_mask_irq,
.irq_mask_ack = ns9xxx_maskack_irq,
.irq_unmask = ns9xxx_unmask_irq,
};

#if 0
#define handle_irq handle_level_irq
#else
static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
{
struct irqaction *action;
irqreturn_t action_ret;

raw_spin_lock(&desc->lock);

BUG_ON(desc->status & IRQ_INPROGRESS);

desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
kstat_incr_irqs_this_cpu(irq, desc);

action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
goto out_mask;

desc->status |= IRQ_INPROGRESS;
raw_spin_unlock(&desc->lock);

action_ret = handle_IRQ_event(irq, action);

/* XXX: There is no direct way to access noirqdebug, so check
* unconditionally for spurious irqs...
* Maybe this function should go to kernel/irq/chip.c? */
note_interrupt(irq, desc, action_ret);

raw_spin_lock(&desc->lock);
desc->status &= ~IRQ_INPROGRESS;

if (desc->status & IRQ_DISABLED)
out_mask:
desc->irq_data.chip->irq_mask(&desc->irq_data);

/* ack unconditionally to unmask lower prio irqs */
desc->irq_data.chip->irq_ack(&desc->irq_data);

raw_spin_unlock(&desc->lock);
}
#define handle_irq handle_prio_irq
#endif

void __init ns9xxx_init_irq(void)
{
int i;
Expand All @@ -119,7 +68,8 @@ void __init ns9xxx_init_irq(void)

for (i = 0; i <= 31; ++i) {
set_irq_chip(i, &ns9xxx_chip);
set_irq_handler(i, handle_irq);
set_irq_handler(i, handle_fasteoi_irq);
set_irq_flags(i, IRQF_VALID);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
1 change: 1 addition & 0 deletions arch/powerpc/platforms/cell/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ config PPC_CELL_COMMON
select PPC_INDIRECT_IO
select PPC_NATIVE
select PPC_RTAS
select IRQ_EDGE_EOI_HANDLER

config PPC_CELL_NATIVE
bool
Expand Down
50 changes: 1 addition & 49 deletions arch/powerpc/platforms/cell/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,54 +235,6 @@ static int iic_host_match(struct irq_host *h, struct device_node *node)
"IBM,CBEA-Internal-Interrupt-Controller");
}

extern int noirqdebug;

static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
{
struct irq_chip *chip = get_irq_desc_chip(desc);

raw_spin_lock(&desc->lock);

desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);

/*
* If we're currently running this IRQ, or its disabled,
* we shouldn't process the IRQ. Mark it pending, handle
* the necessary masking and go out
*/
if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
!desc->action)) {
desc->status |= IRQ_PENDING;
goto out_eoi;
}

kstat_incr_irqs_this_cpu(irq, desc);

/* Mark the IRQ currently in progress.*/
desc->status |= IRQ_INPROGRESS;

do {
struct irqaction *action = desc->action;
irqreturn_t action_ret;

if (unlikely(!action))
goto out_eoi;

desc->status &= ~IRQ_PENDING;
raw_spin_unlock(&desc->lock);
action_ret = handle_IRQ_event(irq, action);
if (!noirqdebug)
note_interrupt(irq, desc, action_ret);
raw_spin_lock(&desc->lock);

} while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);

desc->status &= ~IRQ_INPROGRESS;
out_eoi:
chip->irq_eoi(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}

static int iic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
Expand All @@ -295,7 +247,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
handle_iic_irq);
break;
default:
set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq);
set_irq_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq);
}
return 0;
}
Expand Down
64 changes: 31 additions & 33 deletions drivers/vlynq/vlynq.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,40 +135,40 @@ static void vlynq_reset(struct vlynq_device *dev)
msleep(5);
}

static void vlynq_irq_unmask(unsigned int irq)
static void vlynq_irq_unmask(struct irq_data *d)
{
u32 val;
struct vlynq_device *dev = get_irq_chip_data(irq);
struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
u32 val;

BUG_ON(!dev);
virq = irq - dev->irq_start;
virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq);
writel(val, &dev->remote->int_device[virq >> 2]);
}

static void vlynq_irq_mask(unsigned int irq)
static void vlynq_irq_mask(struct irq_data *d)
{
u32 val;
struct vlynq_device *dev = get_irq_chip_data(irq);
struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
u32 val;

BUG_ON(!dev);
virq = irq - dev->irq_start;
virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
val &= ~(VINT_ENABLE << VINT_OFFSET(virq));
writel(val, &dev->remote->int_device[virq >> 2]);
}

static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
static int vlynq_irq_type(struct irq_data *d, unsigned int flow_type)
{
u32 val;
struct vlynq_device *dev = get_irq_chip_data(irq);
struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
u32 val;

BUG_ON(!dev);
virq = irq - dev->irq_start;
virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
switch (flow_type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
Expand All @@ -192,21 +192,19 @@ static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
return 0;
}

static void vlynq_local_ack(unsigned int irq)
static void vlynq_local_ack(struct irq_data *d)
{
struct vlynq_device *dev = get_irq_chip_data(irq);

struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
u32 status = readl(&dev->local->status);

pr_debug("%s: local status: 0x%08x\n",
dev_name(&dev->dev), status);
writel(status, &dev->local->status);
}

static void vlynq_remote_ack(unsigned int irq)
static void vlynq_remote_ack(struct irq_data *d)
{
struct vlynq_device *dev = get_irq_chip_data(irq);

struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
u32 status = readl(&dev->remote->status);

pr_debug("%s: remote status: 0x%08x\n",
Expand Down Expand Up @@ -238,23 +236,23 @@ static irqreturn_t vlynq_irq(int irq, void *dev_id)

static struct irq_chip vlynq_irq_chip = {
.name = "vlynq",
.unmask = vlynq_irq_unmask,
.mask = vlynq_irq_mask,
.set_type = vlynq_irq_type,
.irq_unmask = vlynq_irq_unmask,
.irq_mask = vlynq_irq_mask,
.irq_set_type = vlynq_irq_type,
};

static struct irq_chip vlynq_local_chip = {
.name = "vlynq local error",
.unmask = vlynq_irq_unmask,
.mask = vlynq_irq_mask,
.ack = vlynq_local_ack,
.irq_unmask = vlynq_irq_unmask,
.irq_mask = vlynq_irq_mask,
.irq_ack = vlynq_local_ack,
};

static struct irq_chip vlynq_remote_chip = {
.name = "vlynq local error",
.unmask = vlynq_irq_unmask,
.mask = vlynq_irq_mask,
.ack = vlynq_remote_ack,
.irq_unmask = vlynq_irq_unmask,
.irq_mask = vlynq_irq_mask,
.irq_ack = vlynq_remote_ack,
};

static int vlynq_setup_irq(struct vlynq_device *dev)
Expand Down Expand Up @@ -291,17 +289,17 @@ static int vlynq_setup_irq(struct vlynq_device *dev)
for (i = dev->irq_start; i <= dev->irq_end; i++) {
virq = i - dev->irq_start;
if (virq == dev->local_irq) {
set_irq_chip_and_handler(i, &vlynq_local_chip,
irq_set_chip_and_handler(i, &vlynq_local_chip,
handle_level_irq);
set_irq_chip_data(i, dev);
irq_set_chip_data(i, dev);
} else if (virq == dev->remote_irq) {
set_irq_chip_and_handler(i, &vlynq_remote_chip,
irq_set_chip_and_handler(i, &vlynq_remote_chip,
handle_level_irq);
set_irq_chip_data(i, dev);
irq_set_chip_data(i, dev);
} else {
set_irq_chip_and_handler(i, &vlynq_irq_chip,
irq_set_chip_and_handler(i, &vlynq_irq_chip,
handle_simple_irq);
set_irq_chip_data(i, dev);
irq_set_chip_data(i, dev);
writel(0, &dev->remote->int_device[virq >> 2]);
}
}
Expand Down
Loading

0 comments on commit e5217fb

Please sign in to comment.