Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next
Browse files Browse the repository at this point in the history
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()
  ...
  • Loading branch information
torvalds committed Jul 8, 2017
2 parents 8b6b317 + 0cd52df commit fe1b518
Show file tree
Hide file tree
Showing 24 changed files with 890 additions and 492 deletions.
5 changes: 5 additions & 0 deletions arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
76 changes: 67 additions & 9 deletions arch/sparc/include/asm/cmpxchg_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -65,26 +104,43 @@ 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");

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");

return new;
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 load;
}

/* This function doesn't exist, so you'll get a linker error
Expand All @@ -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:
Expand Down
8 changes: 8 additions & 0 deletions arch/sparc/include/asm/ldc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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,
Expand Down
24 changes: 21 additions & 3 deletions arch/sparc/include/asm/mdesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions arch/sparc/include/asm/qrwlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#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 */
7 changes: 7 additions & 0 deletions arch/sparc/include/asm/qspinlock.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef _ASM_SPARC_QSPINLOCK_H
#define _ASM_SPARC_QSPINLOCK_H

#include <asm-generic/qspinlock_types.h>
#include <asm-generic/qspinlock.h>

#endif /* _ASM_SPARC_QSPINLOCK_H */
2 changes: 1 addition & 1 deletion arch/sparc/include/asm/setup.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Just a place holder.
* Just a place holder.
*/
#ifndef _SPARC_SETUP_H
#define _SPARC_SETUP_H
Expand Down
Loading

0 comments on commit fe1b518

Please sign in to comment.