Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e853ccf0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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)
parents d7b1fd91 2a5e95d4
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -296,7 +296,7 @@ struct cpuinfo_arc_mmu {
};
};


struct cpuinfo_arc_cache {
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 {
struct cpuinfo_arc_ccm {
+4 −0
Original line number Original line Diff line number Diff line
@@ -16,9 +16,13 @@
#define TIMER0_IRQ      3
#define TIMER0_IRQ      3
#define TIMER1_IRQ      4
#define TIMER1_IRQ      4


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


extern void arc_init_IRQ(void);
extern void arc_init_IRQ(void);
void arc_local_timer_setup(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
#endif
+0 −18
Original line number Original line Diff line number Diff line
@@ -131,24 +131,6 @@ static inline int arch_irqs_disabled(void)
	return arch_irqs_disabled_flags(arch_local_save_flags());
	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
#else


#ifdef CONFIG_TRACE_IRQFLAGS
#ifdef CONFIG_TRACE_IRQFLAGS
+41 −12
Original line number Original line Diff line number Diff line
@@ -19,21 +19,16 @@


/*
/*
 * Early Hardware specific Interrupt setup
 * 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)
 * -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 ?
 * what it does ?
 * -Disable all IRQs (on CPU side)
 * -Optionally, setup the High priority Interrupts as Level 2 IRQs
 * -Optionally, setup the High priority Interrupts as Level 2 IRQs
 */
 */
void arc_init_IRQ(void)
void arc_init_IRQ(void)
{
{
	int level_mask = 0;
	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) */
       /* setup any high priority Interrupts (Level2 in ARCompact jargon) */
	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ3_LV2) << 3;
	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
	level_mask |= IS_ENABLED(CONFIG_ARC_IRQ5_LV2) << 5;
@@ -60,20 +55,28 @@ void arc_init_IRQ(void)
 * below, per IRQ.
 * 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 = {
static struct irq_chip onchip_intc = {
	.name           = "ARC In-core Intc",
	.name           = "ARC In-core Intc",
	.irq_mask	= arc_mask_irq,
	.irq_mask	= arc_irq_mask,
	.irq_unmask	= arc_unmask_irq,
	.irq_unmask	= arc_irq_unmask,
};
};


static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
static int arc_intc_domain_map(struct irq_domain *d, unsigned int irq,
@@ -150,6 +153,32 @@ void arch_do_IRQ(unsigned int irq, struct pt_regs *regs)
	set_irq_regs(old_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.
 * arch_local_irq_enable - Enable interrupts.
 *
 *
+4 −19
Original line number Original line Diff line number Diff line
@@ -12,23 +12,15 @@
 *    -- Initial Write (Borrowed heavily from ARM)
 *    -- Initial Write (Borrowed heavily from ARM)
 */
 */


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


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


	arc_local_timer_setup();
	arc_local_timer_setup();


@@ -338,18 +330,11 @@ irqreturn_t do_IPI(int irq, void *dev_id)
 */
 */
static DEFINE_PER_CPU(int, ipi_dev);
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)
int smp_ipi_irq_setup(int cpu, int irq)
{
{
	if (!cpu)
	int *dev = per_cpu_ptr(&ipi_dev, cpu);
		return setup_irq(irq, &arc_ipi_irq);

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


	return 0;
	return 0;
}
}
Loading