Skip to content

Commit

Permalink
Merge tag 'arc-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/vgupta/arc

Pull ARC changes from Vineet Gupta:
 "Mostly cleanup/refactoring in core intc, cache flush, IPI send..."

* tag 'arc-v3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  mm, arc: remove obsolete pagefault oom killer comment
  ARC: help gcc elide icache helper for !SMP
  ARC: move common ops for line/full cache into helpers
  ARC: cache boot reporting updates
  ARC: [intc] mask/unmask can be hidden again
  ARC: [plat-arcfpga] No need for init_irq hack
  ARC: [intc] don't mask all IRQ by default
  ARC: prune extra header includes from smp.c
  ARC: update some comments
  ARC: [SMP] unify cpu private IRQ requests (TIMER/IPI)
  • Loading branch information
Linus Torvalds committed Aug 9, 2014
2 parents d7b1fd9 + 2a5e95d commit e853ccf
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 174 deletions.
2 changes: 1 addition & 1 deletion arch/arc/include/asm/arcregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ struct cpuinfo_arc_mmu {
};

struct cpuinfo_arc_cache {
unsigned int sz, line_len, assoc, ver;
unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6;
};

struct cpuinfo_arc_ccm {
Expand Down
4 changes: 4 additions & 0 deletions arch/arc/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
#define TIMER0_IRQ 3
#define TIMER1_IRQ 4

#include <linux/interrupt.h>
#include <asm-generic/irq.h>

extern void arc_init_IRQ(void);
void arc_local_timer_setup(void);
void arc_request_percpu_irq(int irq, int cpu,
irqreturn_t (*isr)(int irq, void *dev),
const char *irq_nm, void *percpu_dev);

#endif
18 changes: 0 additions & 18 deletions arch/arc/include/asm/irqflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,6 @@ static inline int arch_irqs_disabled(void)
return arch_irqs_disabled_flags(arch_local_save_flags());
}

static inline void arch_mask_irq(unsigned int irq)
{
unsigned int ienb;

ienb = read_aux_reg(AUX_IENABLE);
ienb &= ~(1 << irq);
write_aux_reg(AUX_IENABLE, ienb);
}

static inline void arch_unmask_irq(unsigned int irq)
{
unsigned int ienb;

ienb = read_aux_reg(AUX_IENABLE);
ienb |= (1 << irq);
write_aux_reg(AUX_IENABLE, ienb);
}

#else

#ifdef CONFIG_TRACE_IRQFLAGS
Expand Down
53 changes: 41 additions & 12 deletions arch/arc/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,16 @@

/*
* Early Hardware specific Interrupt setup
* -Platform independent, needed for each CPU (not foldable into init_IRQ)
* -Called very early (start_kernel -> setup_arch -> setup_processor)
* -Platform Independent (must for any ARC700)
* -Needed for each CPU (hence not foldable into init_IRQ)
*
* what it does ?
* -Disable all IRQs (on CPU side)
* -Optionally, setup the High priority Interrupts as Level 2 IRQs
*/
void arc_init_IRQ(void)
{
int level_mask = 0;

/* Disable all IRQs: enable them as devices request */
write_aux_reg(AUX_IENABLE, 0);

/* setup any high priority Interrupts (Level2 in ARCompact jargon) */
level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
Expand All @@ -60,20 +55,28 @@ void arc_init_IRQ(void)
* below, per IRQ.
*/

static void arc_mask_irq(struct irq_data *data)
static void arc_irq_mask(struct irq_data *data)
{
arch_mask_irq(data->irq);
unsigned int ienb;

ienb = read_aux_reg(AUX_IENABLE);
ienb &= ~(1 << data->irq);
write_aux_reg(AUX_IENABLE, ienb);
}

static void arc_unmask_irq(struct irq_data *data)
static void arc_irq_unmask(struct irq_data *data)
{
arch_unmask_irq(data->irq);
unsigned int ienb;

ienb = read_aux_reg(AUX_IENABLE);
ienb |= (1 << data->irq);
write_aux_reg(AUX_IENABLE, ienb);
}

static struct irq_chip onchip_intc = {
.name = "ARC In-core Intc",
.irq_mask = arc_mask_irq,
.irq_unmask = arc_unmask_irq,
.irq_mask = arc_irq_mask,
.irq_unmask = arc_irq_unmask,
};

static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
Expand Down Expand Up @@ -150,6 +153,32 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
set_irq_regs(old_regs);
}

void arc_request_percpu_irq(int irq, int cpu,
irqreturn_t (*isr)(int irq, void *dev),
const char *irq_nm,
void *percpu_dev)
{
/* Boot cpu calls request, all call enable */
if (!cpu) {
int rc;

/*
* These 2 calls are essential to making percpu IRQ APIs work
* Ideally these details could be hidden in irq chip map function
* but the issue is IPIs IRQs being static (non-DT) and platform
* specific, so we can't identify them there.
*/
irq_set_percpu_devid(irq);
irq_modify_status(irq, IRQ_NOAUTOEN, 0); /* @irq, @clr, @set */

rc = request_percpu_irq(irq, isr, irq_nm, percpu_dev);
if (rc)
panic("Percpu IRQ request failed for %d\n", irq);
}

enable_percpu_irq(irq, 0);
}

/*
* arch_local_irq_enable - Enable interrupts.
*
Expand Down
23 changes: 4 additions & 19 deletions arch/arc/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,15 @@
* -- Initial Write (Borrowed heavily from ARM)
*/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/profile.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/mm.h>
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/atomic.h>
#include <linux/percpu.h>
#include <linux/cpumask.h>
#include <linux/spinlock_types.h>
#include <linux/reboot.h>
#include <asm/processor.h>
#include <asm/setup.h>
Expand Down Expand Up @@ -136,7 +128,7 @@ void start_kernel_secondary(void)
pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu);

if (machine_desc->init_smp)
machine_desc->init_smp(smp_processor_id());
machine_desc->init_smp(cpu);

arc_local_timer_setup();

Expand Down Expand Up @@ -338,18 +330,11 @@ irqreturn_t do_IPI(int irq, void *dev_id)
*/
static DEFINE_PER_CPU(int, ipi_dev);

static struct irqaction arc_ipi_irq = {
.name = "IPI Interrupt",
.flags = IRQF_PERCPU,
.handler = do_IPI,
};

int smp_ipi_irq_setup(int cpu, int irq)
{
if (!cpu)
return setup_irq(irq, &arc_ipi_irq);
else
arch_unmask_irq(irq);
int *dev = per_cpu_ptr(&ipi_dev, cpu);

arc_request_percpu_irq(irq, cpu, do_IPI, "IPI Interrupt", dev);

return 0;
}
28 changes: 10 additions & 18 deletions arch/arc/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ static struct clocksource arc_counter = {
/********** Clock Event Device *********/

/*
* Arm the timer to interrupt after @limit cycles
* Arm the timer to interrupt after @cycles
* The distinction for oneshot/periodic is done in arc_event_timer_ack() below
*/
static void arc_timer_event_setup(unsigned int limit)
static void arc_timer_event_setup(unsigned int cycles)
{
write_aux_reg(ARC_REG_TIMER0_LIMIT, limit);
write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */

write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
Expand All @@ -168,6 +168,10 @@ static void arc_clkevent_set_mode(enum clock_event_mode mode,
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
/*
* At X Hz, 1 sec = 1000ms -> X cycles;
* 10ms -> X / 100 cycles
*/
arc_timer_event_setup(arc_get_core_freq() / HZ);
break;
case CLOCK_EVT_MODE_ONESHOT:
Expand Down Expand Up @@ -210,12 +214,6 @@ static irqreturn_t timer_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}

static struct irqaction arc_timer_irq = {
.name = "Timer0 (clock-evt-dev)",
.flags = IRQF_TIMER | IRQF_PERCPU,
.handler = timer_irq_handler,
};

/*
* Setup the local event timer for @cpu
*/
Expand All @@ -228,15 +226,9 @@ void arc_local_timer_setup()
clockevents_config_and_register(evt, arc_get_core_freq(),
0, ARC_TIMER_MAX);

/*
* setup the per-cpu timer IRQ handler - for all cpus
* For non boot CPU explicitly unmask at intc
* setup_irq() -> .. -> irq_startup() already does this on boot-cpu
*/
if (!cpu)
setup_irq(TIMER0_IRQ, &arc_timer_irq);
else
arch_unmask_irq(TIMER0_IRQ);
/* setup the per-cpu timer IRQ handler - for all cpus */
arc_request_percpu_irq(TIMER0_IRQ, cpu, timer_irq_handler,
"Timer0 (per-cpu-tick)", evt);
}

/*
Expand Down
Loading

0 comments on commit e853ccf

Please sign in to comment.