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

Commit fe1b5180 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sparc updates from David Miller:

 1) Queued spinlocks and rwlocks for sparc64, from Babu Moger.

 2) Some const'ification from Arvind Yadav.

 3) LDC/VIO driver infrastructure changes to facilitate future upcoming
    drivers, from Jag Raman.

 4) Initialize sched_clock() et al. early so that the initial printk
    timestamps are all done while the implementation is available and
    functioning. From Pavel Tatashin.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next: (38 commits)
  sparc: kernel: pmc: make of_device_ids const.
  sparc64: fix typo in property
  sparc64: add port_id to VIO device metadata
  sparc64: Enhance search for VIO device in MDESC
  sparc64: enhance VIO device probing
  sparc64: check if a client is allowed to register for MDESC notifications
  sparc64: remove restriction on VIO device name size
  sparc64: refactor code to obtain cfg_handle property from MDESC
  sparc64: add MDESC node name property to VIO device metadata
  sparc64: mdesc: use __GFP_REPEAT action modifier for VM allocation
  sparc64: expand MDESC interface
  sparc64: skip handshake for LDC channels in RAW mode
  sparc64: specify the device class in VIO version info. packet
  sparc64: ensure VIO operations are defined while being used
  sparc: kernel: apc: make of_device_ids const
  sparc/time: make of_device_ids const
  sparc64: broken %tick frequency on spitfire cpus
  sparc64: use prom interface to get %stick frequency
  sparc64: optimize functions that access tick
  sparc64: add hot-patched and inlined get_tick()
  ...
parents 8b6b3172 0cd52df8
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -83,6 +83,8 @@ config SPARC64
	select ARCH_SUPPORTS_ATOMIC_RMW
	select HAVE_NMI
	select HAVE_REGS_AND_STACK_ACCESS_API
	select ARCH_USE_QUEUED_RWLOCKS
	select ARCH_USE_QUEUED_SPINLOCKS

config ARCH_DEFCONFIG
	string
@@ -92,6 +94,9 @@ config ARCH_DEFCONFIG
config ARCH_PROC_KCORE_TEXT
	def_bool y

config CPU_BIG_ENDIAN
	def_bool y

config ARCH_ATU
	bool
	default y if SPARC64
+67 −9
Original line number Diff line number Diff line
@@ -6,6 +6,17 @@
#ifndef __ARCH_SPARC64_CMPXCHG__
#define __ARCH_SPARC64_CMPXCHG__

static inline unsigned long
__cmpxchg_u32(volatile int *m, int old, int new)
{
	__asm__ __volatile__("cas [%2], %3, %0"
			     : "=&r" (new)
			     : "0" (new), "r" (m), "r" (old)
			     : "memory");

	return new;
}

static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
{
	unsigned long tmp1, tmp2;
@@ -44,10 +55,38 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long

void __xchg_called_with_bad_pointer(void);

/*
 * Use 4 byte cas instruction to achieve 2 byte xchg. Main logic
 * here is to get the bit shift of the byte we are interested in.
 * The XOR is handy for reversing the bits for big-endian byte order.
 */
static inline unsigned long
xchg16(__volatile__ unsigned short *m, unsigned short val)
{
	unsigned long maddr = (unsigned long)m;
	int bit_shift = (((unsigned long)m & 2) ^ 2) << 3;
	unsigned int mask = 0xffff << bit_shift;
	unsigned int *ptr = (unsigned int  *) (maddr & ~2);
	unsigned int old32, new32, load32;

	/* Read the old value */
	load32 = *ptr;

	do {
		old32 = load32;
		new32 = (load32 & (~mask)) | val << bit_shift;
		load32 = __cmpxchg_u32(ptr, old32, new32);
	} while (load32 != old32);

	return (load32 & mask) >> bit_shift;
}

static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
				       int size)
{
	switch (size) {
	case 2:
		return xchg16(ptr, x);
	case 4:
		return xchg32(ptr, x);
	case 8:
@@ -65,10 +104,11 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,

#include <asm-generic/cmpxchg-local.h>


static inline unsigned long
__cmpxchg_u32(volatile int *m, int old, int new)
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
{
	__asm__ __volatile__("cas [%2], %3, %0"
	__asm__ __volatile__("casx [%2], %3, %0"
			     : "=&r" (new)
			     : "0" (new), "r" (m), "r" (old)
			     : "memory");
@@ -76,15 +116,31 @@ __cmpxchg_u32(volatile int *m, int old, int new)
	return new;
}

/*
 * Use 4 byte cas instruction to achieve 1 byte cmpxchg. Main logic
 * here is to get the bit shift of the byte we are interested in.
 * The XOR is handy for reversing the bits for big-endian byte order
 */
static inline unsigned long
__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
__cmpxchg_u8(volatile unsigned char *m, unsigned char old, unsigned char new)
{
	__asm__ __volatile__("casx [%2], %3, %0"
			     : "=&r" (new)
			     : "0" (new), "r" (m), "r" (old)
			     : "memory");
	unsigned long maddr = (unsigned long)m;
	int bit_shift = (((unsigned long)m & 3) ^ 3) << 3;
	unsigned int mask = 0xff << bit_shift;
	unsigned int *ptr = (unsigned int *) (maddr & ~3);
	unsigned int old32, new32, load;
	unsigned int load32 = *ptr;

	do {
		new32 = (load32 & ~mask) | (new << bit_shift);
		old32 = (load32 & ~mask) | (old << bit_shift);
		load32 = __cmpxchg_u32(ptr, old32, new32);
		if (load32 == old32)
			return old;
		load = (load32 & mask) >> bit_shift;
	} while (load == old);

	return new;
	return load;
}

/* This function doesn't exist, so you'll get a linker error
@@ -95,6 +151,8 @@ static inline unsigned long
__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
{
	switch (size) {
		case 1:
			return __cmpxchg_u8(ptr, old, new);
		case 4:
			return __cmpxchg_u32(ptr, old, new);
		case 8:
+8 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ struct ldc_channel_config {
#define LDC_STATE_READY		0x03
#define LDC_STATE_CONNECTED	0x04

#define	LDC_PACKET_SIZE		64

struct ldc_channel;

/* Allocate state for a channel.  */
@@ -72,6 +74,12 @@ int ldc_connect(struct ldc_channel *lp);
int ldc_disconnect(struct ldc_channel *lp);

int ldc_state(struct ldc_channel *lp);
void ldc_set_state(struct ldc_channel *lp, u8 state);
int ldc_mode(struct ldc_channel *lp);
void __ldc_print(struct ldc_channel *lp, const char *caller);
int ldc_rx_reset(struct ldc_channel *lp);

#define	ldc_print(chan)	__ldc_print(chan, __func__)

/* Read and write operations.  Only valid when the link is up.  */
int ldc_write(struct ldc_channel *lp, const void *buf,
+21 −3
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ struct mdesc_handle *mdesc_grab(void);
void mdesc_release(struct mdesc_handle *);

#define MDESC_NODE_NULL		(~(u64)0)
#define MDESC_MAX_STR_LEN	256

u64 mdesc_node_by_name(struct mdesc_handle *handle,
		       u64 from_node, const char *name);
@@ -62,15 +63,32 @@ u64 mdesc_arc_target(struct mdesc_handle *hp, u64 arc);
void mdesc_update(void);

struct mdesc_notifier_client {
	void (*add)(struct mdesc_handle *handle, u64 node);
	void (*remove)(struct mdesc_handle *handle, u64 node);

	void (*add)(struct mdesc_handle *handle, u64 node,
		    const char *node_name);
	void (*remove)(struct mdesc_handle *handle, u64 node,
		       const char *node_name);
	const char			*node_name;
	struct mdesc_notifier_client	*next;
};

void mdesc_register_notifier(struct mdesc_notifier_client *client);

union md_node_info {
	struct vdev_port {
		u64 id;				/* id */
		u64 parent_cfg_hdl;		/* parent config handle */
		const char *name;		/* name (property) */
	} vdev_port;
	struct ds_port {
		u64 id;				/* id */
	} ds_port;
};

u64 mdesc_get_node(struct mdesc_handle *hp, const char *node_name,
		   union md_node_info *node_info);
int mdesc_get_node_info(struct mdesc_handle *hp, u64 node,
			const char *node_name, union md_node_info *node_info);

void mdesc_fill_in_cpu_data(cpumask_t *mask);
void mdesc_populate_present_mask(cpumask_t *mask);
void mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask);
+7 −0
Original line number Diff line number Diff line
#ifndef _ASM_SPARC_QRWLOCK_H
#define _ASM_SPARC_QRWLOCK_H

#include <asm-generic/qrwlock_types.h>
#include <asm-generic/qrwlock.h>

#endif /* _ASM_SPARC_QRWLOCK_H */
Loading