aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2018-02-01 00:41:33 -0800
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-02-01 00:41:33 -0800
commit10a558374f3751cf4eb55143008975641dfc2cf4 (patch)
treeaab0def9d2289f6520ffb62ec4c1d738135447c4 /arch/parisc
parentInput: goodix - use generic touchscreen_properties (diff)
parentLinux 4.15 (diff)
downloadlinux-dev-10a558374f3751cf4eb55143008975641dfc2cf4.tar.xz
linux-dev-10a558374f3751cf4eb55143008975641dfc2cf4.zip
Merge tag 'v4.15' into next
Sync with mainline to get in trackpoint updates and other changes.
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/Kconfig19
-rw-r--r--arch/parisc/Makefile2
-rw-r--r--arch/parisc/boot/compressed/misc.c4
-rw-r--r--arch/parisc/include/asm/atomic.h2
-rw-r--r--arch/parisc/include/asm/compat.h1
-rw-r--r--arch/parisc/include/asm/dma-mapping.h8
-rw-r--r--arch/parisc/include/asm/ldcw.h2
-rw-r--r--arch/parisc/include/asm/pci.h8
-rw-r--r--arch/parisc/include/asm/pdc.h255
-rw-r--r--arch/parisc/include/asm/spinlock.h22
-rw-r--r--arch/parisc/include/asm/thread_info.h5
-rw-r--r--arch/parisc/include/asm/topology.h36
-rw-r--r--arch/parisc/include/uapi/asm/Kbuild1
-rw-r--r--arch/parisc/include/uapi/asm/mman.h1
-rw-r--r--arch/parisc/include/uapi/asm/pdc.h256
-rw-r--r--arch/parisc/kernel/Makefile4
-rw-r--r--arch/parisc/kernel/drivers.c2
-rw-r--r--arch/parisc/kernel/entry.S25
-rw-r--r--arch/parisc/kernel/hpmc.S1
-rw-r--r--arch/parisc/kernel/pacache.S9
-rw-r--r--arch/parisc/kernel/pci-dma.c8
-rw-r--r--arch/parisc/kernel/pdc_cons.c6
-rw-r--r--arch/parisc/kernel/process.c39
-rw-r--r--arch/parisc/kernel/processor.c13
-rw-r--r--arch/parisc/kernel/setup.c2
-rw-r--r--arch/parisc/kernel/signal.c9
-rw-r--r--arch/parisc/kernel/signal32.c13
-rw-r--r--arch/parisc/kernel/signal32.h2
-rw-r--r--arch/parisc/kernel/syscall.S6
-rw-r--r--arch/parisc/kernel/topology.c153
-rw-r--r--arch/parisc/kernel/unwind.c1
-rw-r--r--arch/parisc/lib/delay.c2
-rw-r--r--arch/parisc/mm/init.c10
33 files changed, 552 insertions, 375 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 1fd3eb5b66c6..9792d8cf4f56 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -32,6 +32,7 @@ config PARISC
select GENERIC_PCI_IOMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
+ select GENERIC_CPU_DEVICES
select GENERIC_STRNCPY_FROM_USER
select SYSCTL_ARCH_UNALIGN_ALLOW
select SYSCTL_EXCEPTION_TRACE
@@ -60,9 +61,6 @@ config PARISC
config CPU_BIG_ENDIAN
def_bool y
-config CPU_BIG_ENDIAN
- def_bool y
-
config MMU
def_bool y
@@ -288,6 +286,21 @@ config SMP
If you don't know what to do here, say N.
+config PARISC_CPU_TOPOLOGY
+ bool "Support cpu topology definition"
+ depends on SMP
+ default y
+ help
+ Support PARISC cpu topology definition.
+
+config SCHED_MC
+ bool "Multi-core scheduler support"
+ depends on PARISC_CPU_TOPOLOGY && PA8X00
+ help
+ Multi-core scheduler support improves the CPU scheduler's decision
+ making when dealing with multi-core CPU chips at a cost of slightly
+ increased overhead in some places. If unsure say N here.
+
config IRQSTACKS
bool "Use separate kernel stacks when processing interrupts"
default y
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 01946ebaff72..e2364ff59180 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -22,7 +22,7 @@ KBUILD_IMAGE := vmlinuz
KBUILD_DEFCONFIG := default_defconfig
NM = sh $(srctree)/arch/parisc/nm
-CHECKFLAGS += -D__hppa__=1
+CHECKFLAGS += -D__hppa__=1 -mbig-endian
LIBGCC = $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
export LIBGCC
diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c
index 9345b44b86f0..f57118e1f6b4 100644
--- a/arch/parisc/boot/compressed/misc.c
+++ b/arch/parisc/boot/compressed/misc.c
@@ -123,8 +123,8 @@ int puts(const char *s)
while ((nuline = strchr(s, '\n')) != NULL) {
if (nuline != s)
pdc_iodc_print(s, nuline - s);
- pdc_iodc_print("\r\n", 2);
- s = nuline + 1;
+ pdc_iodc_print("\r\n", 2);
+ s = nuline + 1;
}
if (*s != '\0')
pdc_iodc_print(s, strlen(s));
diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h
index bc54addd589f..88bae6676c9b 100644
--- a/arch/parisc/include/asm/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
@@ -261,7 +261,7 @@ atomic64_set(atomic64_t *v, s64 i)
static __inline__ s64
atomic64_read(const atomic64_t *v)
{
- return ACCESS_ONCE((v)->counter);
+ return READ_ONCE((v)->counter);
}
#define atomic64_inc(v) (atomic64_add( 1,(v)))
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 07f48827afda..acf8aa07cbe0 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -195,7 +195,6 @@ typedef struct compat_siginfo {
} compat_siginfo_t;
#define COMPAT_OFF_T_MAX 0x7fffffff
-#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
struct compat_ipc64_perm {
compat_key_t key;
diff --git a/arch/parisc/include/asm/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h
index 7af4a00b5ce2..01e1fc057c83 100644
--- a/arch/parisc/include/asm/dma-mapping.h
+++ b/arch/parisc/include/asm/dma-mapping.h
@@ -33,14 +33,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
return hppa_dma_ops;
}
-static inline void
-dma_cache_sync(struct device *dev, void *vaddr, size_t size,
- enum dma_data_direction direction)
-{
- if (hppa_dma_ops->sync_single_for_cpu)
- flush_kernel_dcache_range((unsigned long)vaddr, size);
-}
-
static inline void *
parisc_walk_tree(struct device *dev)
{
diff --git a/arch/parisc/include/asm/ldcw.h b/arch/parisc/include/asm/ldcw.h
index dd5a08aaa4da..3eb4bfc1fb36 100644
--- a/arch/parisc/include/asm/ldcw.h
+++ b/arch/parisc/include/asm/ldcw.h
@@ -12,6 +12,7 @@
for the semaphore. */
#define __PA_LDCW_ALIGNMENT 16
+#define __PA_LDCW_ALIGN_ORDER 4
#define __ldcw_align(a) ({ \
unsigned long __ret = (unsigned long) &(a)->lock[0]; \
__ret = (__ret + __PA_LDCW_ALIGNMENT - 1) \
@@ -29,6 +30,7 @@
ldcd). */
#define __PA_LDCW_ALIGNMENT 4
+#define __PA_LDCW_ALIGN_ORDER 2
#define __ldcw_align(a) (&(a)->slock)
#define __LDCW "ldcw,co"
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 6108e9df0296..96b7deec512d 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -88,13 +88,6 @@ struct pci_hba_data {
#endif /* !CONFIG_64BIT */
/*
-** KLUGE: linux/pci.h include asm/pci.h BEFORE declaring struct pci_bus
-** (This eliminates some of the warnings).
-*/
-struct pci_bus;
-struct pci_dev;
-
-/*
* If the PCI device's view of memory is the same as the CPU's view of memory,
* PCI_DMA_BUS_IS_PHYS is true. The networking and block device layers use
* this boolean for bounce buffer decisions.
@@ -162,7 +155,6 @@ extern struct pci_bios_ops *pci_bios;
#ifdef CONFIG_PCI
extern void pcibios_register_hba(struct pci_hba_data *);
-extern void pcibios_set_master(struct pci_dev *);
#else
static inline void pcibios_register_hba(struct pci_hba_data *x)
{
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index efee44a5e063..339e83ddb39e 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -18,261 +18,6 @@ extern unsigned long parisc_cell_loc; /* cell location of CPU (PAT) */
#define PDC_TYPE_SYSTEM_MAP 1 /* 32-bit, but supports PDC_SYSTEM_MAP */
#define PDC_TYPE_SNAKE 2 /* Doesn't support SYSTEM_MAP */
-struct pdc_chassis_info { /* for PDC_CHASSIS_INFO */
- unsigned long actcnt; /* actual number of bytes returned */
- unsigned long maxcnt; /* maximum number of bytes that could be returned */
-};
-
-struct pdc_coproc_cfg { /* for PDC_COPROC_CFG */
- unsigned long ccr_functional;
- unsigned long ccr_present;
- unsigned long revision;
- unsigned long model;
-};
-
-struct pdc_model { /* for PDC_MODEL */
- unsigned long hversion;
- unsigned long sversion;
- unsigned long hw_id;
- unsigned long boot_id;
- unsigned long sw_id;
- unsigned long sw_cap;
- unsigned long arch_rev;
- unsigned long pot_key;
- unsigned long curr_key;
-};
-
-struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */
- unsigned long
-#ifdef CONFIG_64BIT
- cc_padW:32,
-#endif
- cc_alias: 4, /* alias boundaries for virtual addresses */
- cc_block: 4, /* to determine most efficient stride */
- cc_line : 3, /* maximum amount written back as a result of store (multiple of 16 bytes) */
- cc_shift: 2, /* how much to shift cc_block left */
- cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
- cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
- cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
- cc_pad1 : 10, /* reserved */
- cc_hv : 3; /* hversion dependent */
-};
-
-struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
- unsigned long tc_pad0:12, /* reserved */
-#ifdef CONFIG_64BIT
- tc_padW:32,
-#endif
- tc_sh : 2, /* 0 = separate I/D-TLB, else shared I/D-TLB */
- tc_hv : 1, /* HV */
- tc_page : 1, /* 0 = 2K page-size-machine, 1 = 4k page size */
- tc_cst : 3, /* 0 = incoherent operations, else coherent operations */
- tc_aid : 5, /* ITLB: width of access ids of processor (encoded!) */
- tc_sr : 8; /* ITLB: width of space-registers (encoded) */
-};
-
-struct pdc_cache_info { /* main-PDC_CACHE-structure (caches & TLB's) */
- /* I-cache */
- unsigned long ic_size; /* size in bytes */
- struct pdc_cache_cf ic_conf; /* configuration */
- unsigned long ic_base; /* base-addr */
- unsigned long ic_stride;
- unsigned long ic_count;
- unsigned long ic_loop;
- /* D-cache */
- unsigned long dc_size; /* size in bytes */
- struct pdc_cache_cf dc_conf; /* configuration */
- unsigned long dc_base; /* base-addr */
- unsigned long dc_stride;
- unsigned long dc_count;
- unsigned long dc_loop;
- /* Instruction-TLB */
- unsigned long it_size; /* number of entries in I-TLB */
- struct pdc_tlb_cf it_conf; /* I-TLB-configuration */
- unsigned long it_sp_base;
- unsigned long it_sp_stride;
- unsigned long it_sp_count;
- unsigned long it_off_base;
- unsigned long it_off_stride;
- unsigned long it_off_count;
- unsigned long it_loop;
- /* data-TLB */
- unsigned long dt_size; /* number of entries in D-TLB */
- struct pdc_tlb_cf dt_conf; /* D-TLB-configuration */
- unsigned long dt_sp_base;
- unsigned long dt_sp_stride;
- unsigned long dt_sp_count;
- unsigned long dt_off_base;
- unsigned long dt_off_stride;
- unsigned long dt_off_count;
- unsigned long dt_loop;
-};
-
-#if 0
-/* If you start using the next struct, you'll have to adjust it to
- * work with 64-bit firmware I think -PB
- */
-struct pdc_iodc { /* PDC_IODC */
- unsigned char hversion_model;
- unsigned char hversion;
- unsigned char spa;
- unsigned char type;
- unsigned int sversion_rev:4;
- unsigned int sversion_model:19;
- unsigned int sversion_opt:8;
- unsigned char rev;
- unsigned char dep;
- unsigned char features;
- unsigned char pad1;
- unsigned int checksum:16;
- unsigned int length:16;
- unsigned int pad[15];
-} __attribute__((aligned(8))) ;
-#endif
-
-#ifndef CONFIG_PA20
-/* no BLTBs in pa2.0 processors */
-struct pdc_btlb_info_range {
- __u8 res00;
- __u8 num_i;
- __u8 num_d;
- __u8 num_comb;
-};
-
-struct pdc_btlb_info { /* PDC_BLOCK_TLB, return of PDC_BTLB_INFO */
- unsigned int min_size; /* minimum size of BTLB in pages */
- unsigned int max_size; /* maximum size of BTLB in pages */
- struct pdc_btlb_info_range fixed_range_info;
- struct pdc_btlb_info_range variable_range_info;
-};
-
-#endif /* !CONFIG_PA20 */
-
-struct pdc_mem_retinfo { /* PDC_MEM/PDC_MEM_MEMINFO (return info) */
- unsigned long pdt_size;
- unsigned long pdt_entries;
- unsigned long pdt_status;
- unsigned long first_dbe_loc;
- unsigned long good_mem;
-};
-
-struct pdc_mem_read_pdt { /* PDC_MEM/PDC_MEM_READ_PDT (return info) */
- unsigned long pdt_entries;
-};
-
-#ifdef CONFIG_64BIT
-struct pdc_memory_table_raddr { /* PDC_MEM/PDC_MEM_TABLE (return info) */
- unsigned long entries_returned;
- unsigned long entries_total;
-};
-
-struct pdc_memory_table { /* PDC_MEM/PDC_MEM_TABLE (arguments) */
- unsigned long paddr;
- unsigned int pages;
- unsigned int reserved;
-};
-#endif /* CONFIG_64BIT */
-
-struct pdc_system_map_mod_info { /* PDC_SYSTEM_MAP/FIND_MODULE */
- unsigned long mod_addr;
- unsigned long mod_pgs;
- unsigned long add_addrs;
-};
-
-struct pdc_system_map_addr_info { /* PDC_SYSTEM_MAP/FIND_ADDRESS */
- unsigned long mod_addr;
- unsigned long mod_pgs;
-};
-
-struct pdc_initiator { /* PDC_INITIATOR */
- int host_id;
- int factor;
- int width;
- int mode;
-};
-
-struct hardware_path {
- char flags; /* see bit definitions below */
- char bc[6]; /* Bus Converter routing info to a specific */
- /* I/O adaptor (< 0 means none, > 63 resvd) */
- char mod; /* fixed field of specified module */
-};
-
-/*
- * Device path specifications used by PDC.
- */
-struct pdc_module_path {
- struct hardware_path path;
- unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */
-};
-
-#ifndef CONFIG_PA20
-/* Only used on some pre-PA2.0 boxes */
-struct pdc_memory_map { /* PDC_MEMORY_MAP */
- unsigned long hpa; /* mod's register set address */
- unsigned long more_pgs; /* number of additional I/O pgs */
-};
-#endif
-
-struct pdc_tod {
- unsigned long tod_sec;
- unsigned long tod_usec;
-};
-
-/* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
-
-struct pdc_hpmc_pim_11 { /* PDC_PIM */
- __u32 gr[32];
- __u32 cr[32];
- __u32 sr[8];
- __u32 iasq_back;
- __u32 iaoq_back;
- __u32 check_type;
- __u32 cpu_state;
- __u32 rsvd1;
- __u32 cache_check;
- __u32 tlb_check;
- __u32 bus_check;
- __u32 assists_check;
- __u32 rsvd2;
- __u32 assist_state;
- __u32 responder_addr;
- __u32 requestor_addr;
- __u32 path_info;
- __u64 fr[32];
-};
-
-/*
- * architected results from PDC_PIM/transfer hpmc on a PA2.0 machine
- *
- * Note that PDC_PIM doesn't care whether or not wide mode was enabled
- * so the results are different on PA1.1 vs. PA2.0 when in narrow mode.
- *
- * Note also that there are unarchitected results available, which
- * are hversion dependent. Do a "ser pim 0 hpmc" after rebooting, since
- * the firmware is probably the best way of printing hversion dependent
- * data.
- */
-
-struct pdc_hpmc_pim_20 { /* PDC_PIM */
- __u64 gr[32];
- __u64 cr[32];
- __u64 sr[8];
- __u64 iasq_back;
- __u64 iaoq_back;
- __u32 check_type;
- __u32 cpu_state;
- __u32 cache_check;
- __u32 tlb_check;
- __u32 bus_check;
- __u32 assists_check;
- __u32 assist_state;
- __u32 path_info;
- __u64 responder_addr;
- __u64 requestor_addr;
- __u64 fr[32];
-};
-
void pdc_console_init(void); /* in pdc_console.c */
void pdc_console_restart(void);
diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h
index af03359e6ac5..6f84b6acc86e 100644
--- a/arch/parisc/include/asm/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
@@ -32,6 +32,7 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
cpu_relax();
mb();
}
+#define arch_spin_lock_flags arch_spin_lock_flags
static inline void arch_spin_unlock(arch_spinlock_t *x)
{
@@ -169,25 +170,4 @@ static __inline__ int arch_write_trylock(arch_rwlock_t *rw)
return result;
}
-/*
- * read_can_lock - would read_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static __inline__ int arch_read_can_lock(arch_rwlock_t *rw)
-{
- return rw->counter >= 0;
-}
-
-/*
- * write_can_lock - would write_trylock() succeed?
- * @lock: the rwlock in question.
- */
-static __inline__ int arch_write_can_lock(arch_rwlock_t *rw)
-{
- return !rw->counter;
-}
-
-#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
-#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
-
#endif /* __ASM_SPINLOCK_H */
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index c980a02a52bc..598c8d60fa5e 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -35,7 +35,12 @@ struct thread_info {
/* thread information allocation */
+#ifdef CONFIG_IRQSTACKS
+#define THREAD_SIZE_ORDER 2 /* PA-RISC requires at least 16k stack */
+#else
#define THREAD_SIZE_ORDER 3 /* PA-RISC requires at least 32k stack */
+#endif
+
/* Be sure to hunt all references to this down when you change the size of
* the kernel stack */
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
diff --git a/arch/parisc/include/asm/topology.h b/arch/parisc/include/asm/topology.h
new file mode 100644
index 000000000000..6f0750c74e47
--- /dev/null
+++ b/arch/parisc/include/asm/topology.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_PARISC_TOPOLOGY_H
+#define _ASM_PARISC_TOPOLOGY_H
+
+#ifdef CONFIG_PARISC_CPU_TOPOLOGY
+
+#include <linux/cpumask.h>
+
+struct cputopo_parisc {
+ int thread_id;
+ int core_id;
+ int socket_id;
+ cpumask_t thread_sibling;
+ cpumask_t core_sibling;
+};
+
+extern struct cputopo_parisc cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id)
+#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
+#define topology_sibling_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
+
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+
+#else
+
+static inline void init_cpu_topology(void) { }
+static inline void store_cpu_topology(unsigned int cpuid) { }
+
+#endif
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_ARM_TOPOLOGY_H */
diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild
index 196d2a4efb31..286ef5a5904b 100644
--- a/arch/parisc/include/uapi/asm/Kbuild
+++ b/arch/parisc/include/uapi/asm/Kbuild
@@ -2,6 +2,7 @@
include include/uapi/asm-generic/Kbuild.asm
generic-y += auxvec.h
+generic-y += bpf_perf_event.h
generic-y += kvm_para.h
generic-y += param.h
generic-y += poll.h
diff --git a/arch/parisc/include/uapi/asm/mman.h b/arch/parisc/include/uapi/asm/mman.h
index d1af0d74a188..80510ba44c08 100644
--- a/arch/parisc/include/uapi/asm/mman.h
+++ b/arch/parisc/include/uapi/asm/mman.h
@@ -12,6 +12,7 @@
#define MAP_SHARED 0x01 /* Share changes */
#define MAP_PRIVATE 0x02 /* Changes are private */
+#define MAP_SHARED_VALIDATE 0x03 /* share + validate extension flags */
#define MAP_TYPE 0x03 /* Mask for type of mapping */
#define MAP_FIXED 0x04 /* Interpret addr exactly */
#define MAP_ANONYMOUS 0x10 /* don't use a file */
diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h
index 0ad117617f1a..593eeb573138 100644
--- a/arch/parisc/include/uapi/asm/pdc.h
+++ b/arch/parisc/include/uapi/asm/pdc.h
@@ -16,6 +16,7 @@
#define PDC_ERROR -3 /* Call could not complete without an error */
#define PDC_NE_MOD -5 /* Module not found */
#define PDC_NE_CELL_MOD -7 /* Cell module not found */
+#define PDC_NE_BOOTDEV -9 /* Cannot locate a console device or boot device */
#define PDC_INVALID_ARG -10 /* Called with an invalid argument */
#define PDC_BUS_POW_WARN -12 /* Call could not complete in allowed power budget */
#define PDC_NOT_NARROW -17 /* Narrow mode not supported */
@@ -340,9 +341,6 @@
#if !defined(__ASSEMBLY__)
-#include <linux/types.h>
-
-
/* flags of the device_path */
#define PF_AUTOBOOT 0x80
#define PF_AUTOSEARCH 0x40
@@ -418,9 +416,255 @@ struct zeropage {
int pad430[116];
/* [0x600] processor dependent */
- __u32 pad600[1];
- __u32 proc_sti; /* pointer to STI ROM */
- __u32 pad608[126];
+ unsigned int pad600[1];
+ unsigned int proc_sti; /* pointer to STI ROM */
+ unsigned int pad608[126];
+};
+
+struct pdc_chassis_info { /* for PDC_CHASSIS_INFO */
+ unsigned long actcnt; /* actual number of bytes returned */
+ unsigned long maxcnt; /* maximum number of bytes that could be returned */
+};
+
+struct pdc_coproc_cfg { /* for PDC_COPROC_CFG */
+ unsigned long ccr_functional;
+ unsigned long ccr_present;
+ unsigned long revision;
+ unsigned long model;
+};
+
+struct pdc_model { /* for PDC_MODEL */
+ unsigned long hversion;
+ unsigned long sversion;
+ unsigned long hw_id;
+ unsigned long boot_id;
+ unsigned long sw_id;
+ unsigned long sw_cap;
+ unsigned long arch_rev;
+ unsigned long pot_key;
+ unsigned long curr_key;
+};
+
+struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */
+ unsigned long
+#ifdef __LP64__
+ cc_padW:32,
+#endif
+ cc_alias: 4, /* alias boundaries for virtual addresses */
+ cc_block: 4, /* to determine most efficient stride */
+ cc_line : 3, /* maximum amount written back as a result of store (multiple of 16 bytes) */
+ cc_shift: 2, /* how much to shift cc_block left */
+ cc_wt : 1, /* 0 = WT-Dcache, 1 = WB-Dcache */
+ cc_sh : 2, /* 0 = separate I/D-cache, else shared I/D-cache */
+ cc_cst : 3, /* 0 = incoherent D-cache, 1=coherent D-cache */
+ cc_pad1 : 10, /* reserved */
+ cc_hv : 3; /* hversion dependent */
+};
+
+struct pdc_tlb_cf { /* for PDC_CACHE (I/D-TLB's) */
+ unsigned long tc_pad0:12, /* reserved */
+#ifdef __LP64__
+ tc_padW:32,
+#endif
+ tc_sh : 2, /* 0 = separate I/D-TLB, else shared I/D-TLB */
+ tc_hv : 1, /* HV */
+ tc_page : 1, /* 0 = 2K page-size-machine, 1 = 4k page size */
+ tc_cst : 3, /* 0 = incoherent operations, else coherent operations */
+ tc_aid : 5, /* ITLB: width of access ids of processor (encoded!) */
+ tc_sr : 8; /* ITLB: width of space-registers (encoded) */
+};
+
+struct pdc_cache_info { /* main-PDC_CACHE-structure (caches & TLB's) */
+ /* I-cache */
+ unsigned long ic_size; /* size in bytes */
+ struct pdc_cache_cf ic_conf; /* configuration */
+ unsigned long ic_base; /* base-addr */
+ unsigned long ic_stride;
+ unsigned long ic_count;
+ unsigned long ic_loop;
+ /* D-cache */
+ unsigned long dc_size; /* size in bytes */
+ struct pdc_cache_cf dc_conf; /* configuration */
+ unsigned long dc_base; /* base-addr */
+ unsigned long dc_stride;
+ unsigned long dc_count;
+ unsigned long dc_loop;
+ /* Instruction-TLB */
+ unsigned long it_size; /* number of entries in I-TLB */
+ struct pdc_tlb_cf it_conf; /* I-TLB-configuration */
+ unsigned long it_sp_base;
+ unsigned long it_sp_stride;
+ unsigned long it_sp_count;
+ unsigned long it_off_base;
+ unsigned long it_off_stride;
+ unsigned long it_off_count;
+ unsigned long it_loop;
+ /* data-TLB */
+ unsigned long dt_size; /* number of entries in D-TLB */
+ struct pdc_tlb_cf dt_conf; /* D-TLB-configuration */
+ unsigned long dt_sp_base;
+ unsigned long dt_sp_stride;
+ unsigned long dt_sp_count;
+ unsigned long dt_off_base;
+ unsigned long dt_off_stride;
+ unsigned long dt_off_count;
+ unsigned long dt_loop;
+};
+
+/* Might need adjustment to work with 64-bit firmware */
+struct pdc_iodc { /* PDC_IODC */
+ unsigned char hversion_model;
+ unsigned char hversion;
+ unsigned char spa;
+ unsigned char type;
+ unsigned int sversion_rev:4;
+ unsigned int sversion_model:19;
+ unsigned int sversion_opt:8;
+ unsigned char rev;
+ unsigned char dep;
+ unsigned char features;
+ unsigned char pad1;
+ unsigned int checksum:16;
+ unsigned int length:16;
+ unsigned int pad[15];
+} __attribute__((aligned(8))) ;
+
+/* no BLTBs in pa2.0 processors */
+struct pdc_btlb_info_range {
+ unsigned char res00;
+ unsigned char num_i;
+ unsigned char num_d;
+ unsigned char num_comb;
+};
+
+struct pdc_btlb_info { /* PDC_BLOCK_TLB, return of PDC_BTLB_INFO */
+ unsigned int min_size; /* minimum size of BTLB in pages */
+ unsigned int max_size; /* maximum size of BTLB in pages */
+ struct pdc_btlb_info_range fixed_range_info;
+ struct pdc_btlb_info_range variable_range_info;
+};
+
+struct pdc_mem_retinfo { /* PDC_MEM/PDC_MEM_MEMINFO (return info) */
+ unsigned long pdt_size;
+ unsigned long pdt_entries;
+ unsigned long pdt_status;
+ unsigned long first_dbe_loc;
+ unsigned long good_mem;
+};
+
+struct pdc_mem_read_pdt { /* PDC_MEM/PDC_MEM_READ_PDT (return info) */
+ unsigned long pdt_entries;
+};
+
+#ifdef __LP64__
+struct pdc_memory_table_raddr { /* PDC_MEM/PDC_MEM_TABLE (return info) */
+ unsigned long entries_returned;
+ unsigned long entries_total;
+};
+
+struct pdc_memory_table { /* PDC_MEM/PDC_MEM_TABLE (arguments) */
+ unsigned long paddr;
+ unsigned int pages;
+ unsigned int reserved;
+};
+#endif /* __LP64__ */
+
+struct pdc_system_map_mod_info { /* PDC_SYSTEM_MAP/FIND_MODULE */
+ unsigned long mod_addr;
+ unsigned long mod_pgs;
+ unsigned long add_addrs;
+};
+
+struct pdc_system_map_addr_info { /* PDC_SYSTEM_MAP/FIND_ADDRESS */
+ unsigned long mod_addr;
+ unsigned long mod_pgs;
+};
+
+struct pdc_initiator { /* PDC_INITIATOR */
+ int host_id;
+ int factor;
+ int width;
+ int mode;
+};
+
+struct hardware_path {
+ char flags; /* see bit definitions below */
+ char bc[6]; /* Bus Converter routing info to a specific */
+ /* I/O adaptor (< 0 means none, > 63 resvd) */
+ char mod; /* fixed field of specified module */
+};
+
+/*
+ * Device path specifications used by PDC.
+ */
+struct pdc_module_path {
+ struct hardware_path path;
+ unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */
+};
+
+/* Only used on some pre-PA2.0 boxes */
+struct pdc_memory_map { /* PDC_MEMORY_MAP */
+ unsigned long hpa; /* mod's register set address */
+ unsigned long more_pgs; /* number of additional I/O pgs */
+};
+
+struct pdc_tod {
+ unsigned long tod_sec;
+ unsigned long tod_usec;
+};
+
+/* architected results from PDC_PIM/transfer hpmc on a PA1.1 machine */
+
+struct pdc_hpmc_pim_11 { /* PDC_PIM */
+ unsigned int gr[32];
+ unsigned int cr[32];
+ unsigned int sr[8];
+ unsigned int iasq_back;
+ unsigned int iaoq_back;
+ unsigned int check_type;
+ unsigned int cpu_state;
+ unsigned int rsvd1;
+ unsigned int cache_check;
+ unsigned int tlb_check;
+ unsigned int bus_check;
+ unsigned int assists_check;
+ unsigned int rsvd2;
+ unsigned int assist_state;
+ unsigned int responder_addr;
+ unsigned int requestor_addr;
+ unsigned int path_info;
+ unsigned long long fr[32];
+};
+
+/*
+ * architected results from PDC_PIM/transfer hpmc on a PA2.0 machine
+ *
+ * Note that PDC_PIM doesn't care whether or not wide mode was enabled
+ * so the results are different on PA1.1 vs. PA2.0 when in narrow mode.
+ *
+ * Note also that there are unarchitected results available, which
+ * are hversion dependent. Do a "ser pim 0 hpmc" after rebooting, since
+ * the firmware is probably the best way of printing hversion dependent
+ * data.
+ */
+
+struct pdc_hpmc_pim_20 { /* PDC_PIM */
+ unsigned long long gr[32];
+ unsigned long long cr[32];
+ unsigned long long sr[8];
+ unsigned long long iasq_back;
+ unsigned long long iaoq_back;
+ unsigned int check_type;
+ unsigned int cpu_state;
+ unsigned int cache_check;
+ unsigned int tlb_check;
+ unsigned int bus_check;
+ unsigned int assists_check;
+ unsigned int assist_state;
+ unsigned int path_info;
+ unsigned long long responder_addr;
+ unsigned long long requestor_addr;
+ unsigned long long fr[32];
};
#endif /* !defined(__ASSEMBLY__) */
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 649dc3eda448..eafd06ab59ef 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -9,8 +9,7 @@ obj-y := cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \
pa7300lc.o syscall.o entry.o sys_parisc.o firmware.o \
ptrace.o hardware.o inventory.o drivers.o \
signal.o hpmc.o real2.o parisc_ksyms.o unaligned.o \
- process.o processor.o pdc_cons.o pdc_chassis.o unwind.o \
- topology.o
+ process.o processor.o pdc_cons.o pdc_chassis.o unwind.o
ifdef CONFIG_FUNCTION_TRACER
# Do not profile debug and lowlevel utilities
@@ -30,5 +29,6 @@ obj-$(CONFIG_AUDIT) += audit.o
obj64-$(CONFIG_AUDIT) += compat_audit.o
# only supported for PCX-W/U in 64-bit mode at the moment
obj-$(CONFIG_64BIT) += perf.o perf_asm.o $(obj64-y)
+obj-$(CONFIG_PARISC_CPU_TOPOLOGY) += topology.o
obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index d8f77358e2ba..29b99b8964aa 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -870,7 +870,7 @@ static void print_parisc_device(struct parisc_device *dev)
static int count;
print_pa_hwpath(dev, hw_path);
- printk(KERN_INFO "%d. %s at 0x%p [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
+ printk(KERN_INFO "%d. %s at 0x%px [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type,
dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index a4fd296c958e..e95207c0565e 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -35,6 +35,7 @@
#include <asm/pgtable.h>
#include <asm/signal.h>
#include <asm/unistd.h>
+#include <asm/ldcw.h>
#include <asm/thread_info.h>
#include <linux/linkage.h>
@@ -46,6 +47,14 @@
#endif
.import pa_tlb_lock,data
+ .macro load_pa_tlb_lock reg
+#if __PA_LDCW_ALIGNMENT > 4
+ load32 PA(pa_tlb_lock) + __PA_LDCW_ALIGNMENT-1, \reg
+ depi 0,31,__PA_LDCW_ALIGN_ORDER, \reg
+#else
+ load32 PA(pa_tlb_lock), \reg
+#endif
+ .endm
/* space_to_prot macro creates a prot id from a space id */
@@ -457,7 +466,7 @@
.macro tlb_lock spc,ptp,pte,tmp,tmp1,fault
#ifdef CONFIG_SMP
cmpib,COND(=),n 0,\spc,2f
- load32 PA(pa_tlb_lock),\tmp
+ load_pa_tlb_lock \tmp
1: LDCW 0(\tmp),\tmp1
cmpib,COND(=) 0,\tmp1,1b
nop
@@ -480,7 +489,7 @@
/* Release pa_tlb_lock lock. */
.macro tlb_unlock1 spc,tmp
#ifdef CONFIG_SMP
- load32 PA(pa_tlb_lock),\tmp
+ load_pa_tlb_lock \tmp
tlb_unlock0 \spc,\tmp
#endif
.endm
@@ -878,9 +887,6 @@ ENTRY_CFI(syscall_exit_rfi)
STREG %r19,PT_SR7(%r16)
intr_return:
- /* NOTE: Need to enable interrupts incase we schedule. */
- ssm PSW_SM_I, %r0
-
/* check for reschedule */
mfctl %cr30,%r1
LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
@@ -907,6 +913,11 @@ intr_check_sig:
LDREG PT_IASQ1(%r16), %r20
cmpib,COND(=),n 0,%r20,intr_restore /* backward */
+ /* NOTE: We need to enable interrupts if we have to deliver
+ * signals. We used to do this earlier but it caused kernel
+ * stack overflows. */
+ ssm PSW_SM_I, %r0
+
copy %r0, %r25 /* long in_syscall = 0 */
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
@@ -958,6 +969,10 @@ intr_do_resched:
cmpib,COND(=) 0, %r20, intr_do_preempt
nop
+ /* NOTE: We need to enable interrupts if we schedule. We used
+ * to do this earlier but it caused kernel stack overflows. */
+ ssm PSW_SM_I, %r0
+
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */
#endif
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index e3a8e5e4d5de..8d072c44f300 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -305,6 +305,7 @@ ENDPROC_CFI(os_hpmc)
__INITRODATA
+ .align 4
.export os_hpmc_size
os_hpmc_size:
.word .os_hpmc_end-.os_hpmc
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index adf7187f8951..2d40c4ff3f69 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -36,6 +36,7 @@
#include <asm/assembly.h>
#include <asm/pgtable.h>
#include <asm/cache.h>
+#include <asm/ldcw.h>
#include <linux/linkage.h>
.text
@@ -333,8 +334,12 @@ ENDPROC_CFI(flush_data_cache_local)
.macro tlb_lock la,flags,tmp
#ifdef CONFIG_SMP
- ldil L%pa_tlb_lock,%r1
- ldo R%pa_tlb_lock(%r1),\la
+#if __PA_LDCW_ALIGNMENT > 4
+ load32 pa_tlb_lock + __PA_LDCW_ALIGNMENT-1, \la
+ depi 0,31,__PA_LDCW_ALIGN_ORDER, \la
+#else
+ load32 pa_tlb_lock, \la
+#endif
rsm PSW_SM_I,\flags
1: LDCW 0(\la),\tmp
cmpib,<>,n 0,\tmp,3f
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 412231d101f9..c0dfd892f70c 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -572,6 +572,12 @@ static void pa11_dma_sync_sg_for_device(struct device *dev, struct scatterlist *
flush_kernel_vmap_range(sg_virt(sg), sg->length);
}
+static void pa11_dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ flush_kernel_dcache_range((unsigned long)vaddr, size);
+}
+
const struct dma_map_ops pcxl_dma_ops = {
.dma_supported = pa11_dma_supported,
.alloc = pa11_dma_alloc,
@@ -584,6 +590,7 @@ const struct dma_map_ops pcxl_dma_ops = {
.sync_single_for_device = pa11_dma_sync_single_for_device,
.sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .cache_sync = pa11_dma_cache_sync,
};
static void *pcx_dma_alloc(struct device *dev, size_t size,
@@ -620,4 +627,5 @@ const struct dma_map_ops pcx_dma_ops = {
.sync_single_for_device = pa11_dma_sync_single_for_device,
.sync_sg_for_cpu = pa11_dma_sync_sg_for_cpu,
.sync_sg_for_device = pa11_dma_sync_sg_for_device,
+ .cache_sync = pa11_dma_cache_sync,
};
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 10a5ae9553fd..c46bf29ae412 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -91,8 +91,8 @@ static int pdc_console_setup(struct console *co, char *options)
#define PDC_CONS_POLL_DELAY (30 * HZ / 1000)
-static void pdc_console_poll(unsigned long unused);
-static DEFINE_TIMER(pdc_console_timer, pdc_console_poll, 0, 0);
+static void pdc_console_poll(struct timer_list *unused);
+static DEFINE_TIMER(pdc_console_timer, pdc_console_poll);
static struct tty_port tty_port;
static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
@@ -135,7 +135,7 @@ static const struct tty_operations pdc_console_tty_ops = {
.chars_in_buffer = pdc_console_tty_chars_in_buffer,
};
-static void pdc_console_poll(unsigned long unused)
+static void pdc_console_poll(struct timer_list *unused)
{
int data, count = 0;
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 30f92391a93e..cad3e8661cd6 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -39,6 +39,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/fs.h>
+#include <linux/cpu.h>
#include <linux/module.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
@@ -184,6 +185,44 @@ int dump_task_fpu (struct task_struct *tsk, elf_fpregset_t *r)
}
/*
+ * Idle thread support
+ *
+ * Detect when running on QEMU with SeaBIOS PDC Firmware and let
+ * QEMU idle the host too.
+ */
+
+int running_on_qemu __read_mostly;
+
+void __cpuidle arch_cpu_idle_dead(void)
+{
+ /* nop on real hardware, qemu will offline CPU. */
+ asm volatile("or %%r31,%%r31,%%r31\n":::);
+}
+
+void __cpuidle arch_cpu_idle(void)
+{
+ local_irq_enable();
+
+ /* nop on real hardware, qemu will idle sleep. */
+ asm volatile("or %%r10,%%r10,%%r10\n":::);
+}
+
+static int __init parisc_idle_init(void)
+{
+ const char *marker;
+
+ /* check QEMU/SeaBIOS marker in PAGE0 */
+ marker = (char *) &PAGE0->pad0;
+ running_on_qemu = (memcmp(marker, "SeaBIOS", 8) == 0);
+
+ if (!running_on_qemu)
+ cpu_idle_poll_ctrl(1);
+
+ return 0;
+}
+arch_initcall(parisc_idle_init);
+
+/*
* Copy architecture-specific thread state
*/
int
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index e120d63c1b28..45cc65902fce 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -184,6 +184,9 @@ static int __init processor_probe(struct parisc_device *dev)
p->txn_addr = txn_addr; /* save CPU IRQ address */
p->cpu_num = cpu_info.cpu_num;
p->cpu_loc = cpu_info.cpu_loc;
+
+ store_cpu_topology(cpuid);
+
#ifdef CONFIG_SMP
/*
** FIXME: review if any other initialization is clobbered
@@ -325,6 +328,8 @@ int __init init_per_cpu(int cpunum)
set_firmware_width();
ret = pdc_coproc_cfg(&coproc_cfg);
+ store_cpu_topology(cpunum);
+
if(ret >= 0 && coproc_cfg.ccr_functional) {
mtctl(coproc_cfg.ccr_functional, 10); /* 10 == Coprocessor Control Reg */
@@ -388,6 +393,14 @@ show_cpuinfo (struct seq_file *m, void *v)
boot_cpu_data.cpu_hz / 1000000,
boot_cpu_data.cpu_hz % 1000000 );
+#ifdef CONFIG_PARISC_CPU_TOPOLOGY
+ seq_printf(m, "physical id\t: %d\n",
+ topology_physical_package_id(cpu));
+ seq_printf(m, "siblings\t: %d\n",
+ cpumask_weight(topology_core_cpumask(cpu)));
+ seq_printf(m, "core id\t\t: %d\n", topology_core_id(cpu));
+#endif
+
seq_printf(m, "capabilities\t:");
if (boot_cpu_data.pdc.capabilities & PDC_MODEL_OS32)
seq_puts(m, " os32");
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index f7d0c3b33d70..0e9675f857a5 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -408,6 +408,8 @@ void __init start_parisc(void)
cpunum = smp_processor_id();
+ init_cpu_topology();
+
set_firmware_width_unlocked();
ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index f2a4038e275b..342073f44d3f 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -93,7 +93,6 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
unsigned long usp = (regs->gr[30] & ~(0x01UL));
unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
#ifdef CONFIG_64BIT
- compat_sigset_t compat_set;
struct compat_rt_sigframe __user * compat_frame;
if (is_compat_task())
@@ -114,9 +113,8 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
if (is_compat_task()) {
DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
- if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
+ if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
goto give_sigsegv;
- sigset_32to64(&set,&compat_set);
} else
#endif
{
@@ -238,7 +236,6 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
int err = 0;
#ifdef CONFIG_64BIT
struct compat_rt_sigframe __user * compat_frame;
- compat_sigset_t compat_set;
#endif
usp = (regs->gr[30] & ~(0x01UL));
@@ -261,8 +258,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext,
&compat_frame->regs, regs, in_syscall);
- sigset_64to32(&compat_set,set);
- err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
+ err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
+ sizeof(compat_sigset_t));
} else
#endif
{
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index 9e0cb6a577d6..41afa9cd1f55 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -46,19 +46,6 @@
#define DBG(LEVEL, ...)
#endif
-inline void
-sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
-{
- s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
-}
-
-inline void
-sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
-{
- s32->sig[0] = s64->sig[0] & 0xffffffffUL;
- s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
-}
-
long
restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
struct pt_regs *regs)
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
index af51d4ccee42..719e7417732c 100644
--- a/arch/parisc/kernel/signal32.h
+++ b/arch/parisc/kernel/signal32.h
@@ -79,8 +79,6 @@ struct compat_rt_sigframe {
#define FUNCTIONCALLFRAME32 48
#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
-void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
-void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
long restore_sigcontext32(struct compat_sigcontext __user *sc,
struct compat_regfile __user *rf,
struct pt_regs *regs);
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 41e60a9c7db2..e775f80ae28c 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -690,15 +690,15 @@ cas_action:
/* ELF32 Process entry path */
lws_compare_and_swap_2:
#ifdef CONFIG_64BIT
- /* Clip the input registers */
+ /* Clip the input registers. We don't need to clip %r23 as we
+ only use it for word operations */
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
- depdi 0, 31, 32, %r23
#endif
/* Check the validity of the size pointer */
- subi,>>= 4, %r23, %r0
+ subi,>>= 3, %r23, %r0
b,n lws_exit_nosys
/* Jump to the functions which will load the old and new values into
diff --git a/arch/parisc/kernel/topology.c b/arch/parisc/kernel/topology.c
index f5159381fdd6..0a10e4ddc528 100644
--- a/arch/parisc/kernel/topology.c
+++ b/arch/parisc/kernel/topology.c
@@ -1,37 +1,142 @@
/*
- * arch/parisc/kernel/topology.c - Populate sysfs with topology information
+ * arch/parisc/kernel/topology.c
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2017 Helge Deller <deller@gmx.de>
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
+ * based on arch/arm/kernel/topology.c
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
*/
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-#include <linux/cache.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/sched/topology.h>
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
+#include <asm/topology.h>
-static int __init topology_init(void)
+ /*
+ * cpu topology table
+ */
+struct cputopo_parisc cpu_topology[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
{
- int num;
+ return &cpu_topology[cpu].core_sibling;
+}
+
+static void update_siblings_masks(unsigned int cpuid)
+{
+ struct cputopo_parisc *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+ int cpu;
+
+ /* update core and thread sibling masks */
+ for_each_possible_cpu(cpu) {
+ cpu_topo = &cpu_topology[cpu];
+
+ if (cpuid_topo->socket_id != cpu_topo->socket_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+ if (cpuid_topo->core_id != cpu_topo->core_id)
+ continue;
+
+ cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+ if (cpu != cpuid)
+ cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+ }
+ smp_wmb();
+}
+
+static int dualcores_found __initdata;
+
+/*
+ * store_cpu_topology is called at boot when only one cpu is running
+ * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
+ * which prevents simultaneous write access to cpu_topology array
+ */
+void __init store_cpu_topology(unsigned int cpuid)
+{
+ struct cputopo_parisc *cpuid_topo = &cpu_topology[cpuid];
+ struct cpuinfo_parisc *p;
+ int max_socket = -1;
+ unsigned long cpu;
+
+ /* If the cpu topology has been already set, just return */
+ if (cpuid_topo->core_id != -1)
+ return;
- for_each_present_cpu(num) {
- register_cpu(&per_cpu(cpu_devices, num), num);
+ /* create cpu topology mapping */
+ cpuid_topo->thread_id = -1;
+ cpuid_topo->core_id = 0;
+
+ p = &per_cpu(cpu_data, cpuid);
+ for_each_online_cpu(cpu) {
+ const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
+
+ if (cpu == cpuid) /* ignore current cpu */
+ continue;
+
+ if (cpuinfo->cpu_loc == p->cpu_loc) {
+ cpuid_topo->core_id = cpu_topology[cpu].core_id;
+ if (p->cpu_loc) {
+ cpuid_topo->core_id++;
+ cpuid_topo->socket_id = cpu_topology[cpu].socket_id;
+ dualcores_found = 1;
+ continue;
+ }
+ }
+
+ if (cpuid_topo->socket_id == -1)
+ max_socket = max(max_socket, cpu_topology[cpu].socket_id);
}
- return 0;
+
+ if (cpuid_topo->socket_id == -1)
+ cpuid_topo->socket_id = max_socket + 1;
+
+ update_siblings_masks(cpuid);
+
+ pr_info("CPU%u: thread %d, cpu %d, socket %d\n",
+ cpuid, cpu_topology[cpuid].thread_id,
+ cpu_topology[cpuid].core_id,
+ cpu_topology[cpuid].socket_id);
}
-subsys_initcall(topology_init);
+static struct sched_domain_topology_level parisc_mc_topology[] = {
+#ifdef CONFIG_SCHED_MC
+ { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+#endif
+
+ { cpu_cpu_mask, SD_INIT_NAME(DIE) },
+ { NULL, },
+};
+
+/*
+ * init_cpu_topology is called at boot when only one cpu is running
+ * which prevent simultaneous write access to cpu_topology array
+ */
+void __init init_cpu_topology(void)
+{
+ unsigned int cpu;
+
+ /* init core mask and capacity */
+ for_each_possible_cpu(cpu) {
+ struct cputopo_parisc *cpu_topo = &(cpu_topology[cpu]);
+
+ cpu_topo->thread_id = -1;
+ cpu_topo->core_id = -1;
+ cpu_topo->socket_id = -1;
+ cpumask_clear(&cpu_topo->core_sibling);
+ cpumask_clear(&cpu_topo->thread_sibling);
+ }
+ smp_wmb();
+
+ /* Set scheduler topology descriptor */
+ if (dualcores_found)
+ set_sched_topology(parisc_mc_topology);
+}
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 5a657986ebbf..143f90e2f9f3 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -15,7 +15,6 @@
#include <linux/slab.h>
#include <linux/kallsyms.h>
#include <linux/sort.h>
-#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/assembly.h>
diff --git a/arch/parisc/lib/delay.c b/arch/parisc/lib/delay.c
index 7eab4bb8abe6..66e506520505 100644
--- a/arch/parisc/lib/delay.c
+++ b/arch/parisc/lib/delay.c
@@ -16,9 +16,7 @@
#include <linux/preempt.h>
#include <linux/init.h>
-#include <asm/processor.h>
#include <asm/delay.h>
-
#include <asm/special_insns.h> /* for mfctl() */
#include <asm/processor.h> /* for boot_cpu_data */
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 13f7854e0d49..48f41399fc0b 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -631,11 +631,11 @@ void __init mem_init(void)
mem_init_print_info(NULL);
#ifdef CONFIG_DEBUG_KERNEL /* double-sanity-check paranoia */
printk("virtual kernel memory layout:\n"
- " vmalloc : 0x%p - 0x%p (%4ld MB)\n"
- " memory : 0x%p - 0x%p (%4ld MB)\n"
- " .init : 0x%p - 0x%p (%4ld kB)\n"
- " .data : 0x%p - 0x%p (%4ld kB)\n"
- " .text : 0x%p - 0x%p (%4ld kB)\n",
+ " vmalloc : 0x%px - 0x%px (%4ld MB)\n"
+ " memory : 0x%px - 0x%px (%4ld MB)\n"
+ " .init : 0x%px - 0x%px (%4ld kB)\n"
+ " .data : 0x%px - 0x%px (%4ld kB)\n"
+ " .text : 0x%px - 0x%px (%4ld kB)\n",
(void*)VMALLOC_START, (void*)VMALLOC_END,
(VMALLOC_END - VMALLOC_START) >> 20,