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

Commit 7b7426c8 authored by Jens Axboe's avatar Jens Axboe
Browse files

m32r: convert to generic helpers for IPI function calls



This converts m32r to use the new helpers for smp_call_function() and
friends, and adds support for smp_call_function_single(). Not tested,
not even compiled.

Cc: Hirokazu Takata <takata@linux-m32r.org>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent f6dd9fa5
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -296,6 +296,7 @@ config PREEMPT


config SMP
config SMP
	bool "Symmetric multi-processing support"
	bool "Symmetric multi-processing support"
	select USE_GENERIC_SMP_HELPERS
	---help---
	---help---
	  This enables support for systems with more than one CPU. If you have
	  This enables support for systems with more than one CPU. If you have
	  a system with only one CPU, like most personal computers, say N. If
	  a system with only one CPU, like most personal computers, say N. If
+0 −3
Original line number Original line Diff line number Diff line
@@ -43,9 +43,6 @@ EXPORT_SYMBOL(dcache_dummy);
#endif
#endif
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(cpu_data);


/* Global SMP stuff */
EXPORT_SYMBOL(smp_call_function);

/* TLB flushing */
/* TLB flushing */
EXPORT_SYMBOL(smp_flush_tlb_page);
EXPORT_SYMBOL(smp_flush_tlb_page);
#endif
#endif
+13 −115
Original line number Original line Diff line number Diff line
@@ -34,22 +34,6 @@
/* Data structures and variables                                             */
/* Data structures and variables                                             */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/


/*
 * Structure and data for smp_call_function(). This is designed to minimise
 * static memory requirements. It also looks cleaner.
 */
static DEFINE_SPINLOCK(call_lock);

struct call_data_struct {
	void (*func) (void *info);
	void *info;
	atomic_t started;
	atomic_t finished;
	int wait;
} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));

static struct call_data_struct *call_data;

/*
/*
 * For flush_cache_all()
 * For flush_cache_all()
 */
 */
@@ -96,9 +80,6 @@ void smp_invalidate_interrupt(void);
void smp_send_stop(void);
void smp_send_stop(void);
static void stop_this_cpu(void *);
static void stop_this_cpu(void *);


int smp_call_function(void (*) (void *), void *, int, int);
void smp_call_function_interrupt(void);

void smp_send_timer(void);
void smp_send_timer(void);
void smp_ipi_timer_interrupt(struct pt_regs *);
void smp_ipi_timer_interrupt(struct pt_regs *);
void smp_local_timer_interrupt(void);
void smp_local_timer_interrupt(void);
@@ -565,86 +546,14 @@ static void stop_this_cpu(void *dummy)
	for ( ; ; );
	for ( ; ; );
}
}


/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
void arch_send_call_function_ipi(cpumask_t mask)
/* Call function Routines                                                    */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

/*==========================================================================*
 * Name:         smp_call_function
 *
 * Description:  This routine sends a 'CALL_FUNCTION_IPI' to all other CPUs
 *               in the system.
 *
 * Born on Date: 2002.02.05
 *
 * Arguments:    *func - The function to run. This must be fast and
 *                       non-blocking.
 *               *info - An arbitrary pointer to pass to the function.
 *               nonatomic - currently unused.
 *               wait - If true, wait (atomically) until function has
 *                      completed on other CPUs.
 *
 * Returns:      0 on success, else a negative status code. Does not return
 *               until remote CPUs are nearly ready to execute <<func>> or
 *               are or have executed.
 *
 * Cautions:     You must not call this function with disabled interrupts or
 *               from a hardware interrupt handler, you may call it from a
 *               bottom half handler.
 *
 * Modification log:
 * Date       Who Description
 * ---------- --- --------------------------------------------------------
 *
 *==========================================================================*/
int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
	int wait)
{
{
	struct call_data_struct data;
	send_IPI_mask(mask, CALL_FUNCTION_IPI, 0);
	int cpus;

#ifdef DEBUG_SMP
	unsigned long flags;
	__save_flags(flags);
	if (!(flags & 0x0040))	/* Interrupt Disable NONONO */
		BUG();
#endif /* DEBUG_SMP */

	/* Holding any lock stops cpus from going down. */
	spin_lock(&call_lock);
	cpus = num_online_cpus() - 1;

	if (!cpus) {
		spin_unlock(&call_lock);
		return 0;
}
}


	/* Can deadlock when called with interrupts disabled */
void arch_send_call_function_single_ipi(int cpu)
	WARN_ON(irqs_disabled());
{

	send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNC_SINGLE_IPI, 0);
	data.func = func;
	data.info = info;
	atomic_set(&data.started, 0);
	data.wait = wait;
	if (wait)
		atomic_set(&data.finished, 0);

	call_data = &data;
	mb();

	/* Send a message to all other CPUs and wait for them to respond */
	send_IPI_allbutself(CALL_FUNCTION_IPI, 0);

	/* Wait for response */
	while (atomic_read(&data.started) != cpus)
		barrier();

	if (wait)
		while (atomic_read(&data.finished) != cpus)
			barrier();
	spin_unlock(&call_lock);

	return 0;
}
}


/*==========================================================================*
/*==========================================================================*
@@ -666,27 +575,16 @@ int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
 *==========================================================================*/
 *==========================================================================*/
void smp_call_function_interrupt(void)
void smp_call_function_interrupt(void)
{
{
	void (*func) (void *info) = call_data->func;
	void *info = call_data->info;
	int wait = call_data->wait;

	/*
	 * Notify initiating CPU that I've grabbed the data and am
	 * about to execute the function
	 */
	mb();
	atomic_inc(&call_data->started);
	/*
	 * At this point the info structure may be out of scope unless wait==1
	 */
	irq_enter();
	irq_enter();
	(*func)(info);
	generic_smp_call_function_interrupt();
	irq_exit();
	irq_exit();

	if (wait) {
		mb();
		atomic_inc(&call_data->finished);
}
}

void smp_call_function_single_interrupt(void)
{
	irq_enter();
	generic_smp_call_function_single_interrupt();
	irq_exit();
}
}


/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
+2 −1
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ extern void smp_invalidate_interrupt(void);
extern void smp_call_function_interrupt(void);
extern void smp_call_function_interrupt(void);
extern void smp_ipi_timer_interrupt(void);
extern void smp_ipi_timer_interrupt(void);
extern void smp_flush_cache_all_interrupt(void);
extern void smp_flush_cache_all_interrupt(void);
extern void smp_call_function_single_interrupt(void);


/*
/*
 * for Boot AP function
 * for Boot AP function
@@ -103,7 +104,7 @@ void set_eit_vector_entries(void)
	eit_vector[186] = (unsigned long)smp_call_function_interrupt;
	eit_vector[186] = (unsigned long)smp_call_function_interrupt;
	eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
	eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
	eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
	eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
	eit_vector[189] = 0;
	eit_vector[189] = (unsigned long)smp_call_function_single_interrupt;
	eit_vector[190] = 0;
	eit_vector[190] = 0;
	eit_vector[191] = 0;
	eit_vector[191] = 0;
#endif
#endif
+4 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,9 @@ static __inline__ unsigned int num_booting_cpus(void)
extern void smp_send_timer(void);
extern void smp_send_timer(void);
extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);


extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi(cpumask_t mask);

#endif	/* not __ASSEMBLY__ */
#endif	/* not __ASSEMBLY__ */


#define NO_PROC_ID (0xff)	/* No processor magic marker */
#define NO_PROC_ID (0xff)	/* No processor magic marker */
@@ -104,6 +107,7 @@ extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
#define LOCAL_TIMER_IPI		(M32R_IRQ_IPI3-M32R_IRQ_IPI0)
#define LOCAL_TIMER_IPI		(M32R_IRQ_IPI3-M32R_IRQ_IPI0)
#define INVALIDATE_CACHE_IPI	(M32R_IRQ_IPI4-M32R_IRQ_IPI0)
#define INVALIDATE_CACHE_IPI	(M32R_IRQ_IPI4-M32R_IRQ_IPI0)
#define CPU_BOOT_IPI		(M32R_IRQ_IPI5-M32R_IRQ_IPI0)
#define CPU_BOOT_IPI		(M32R_IRQ_IPI5-M32R_IRQ_IPI0)
#define CALL_FUNC_SINGLE_IPI	(M32R_IRQ_IPI6-M32R_IRQ_IPI0)


#define IPI_SHIFT	(0)
#define IPI_SHIFT	(0)
#define NR_IPIS		(8)
#define NR_IPIS		(8)