summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/booting-without-of.txt59
-rw-r--r--arch/powerpc/boot/crt0.S1
-rw-r--r--arch/powerpc/kernel/of_platform.c2
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c33
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c57
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c62
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c161
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
-rw-r--r--arch/powerpc/platforms/celleb/Makefile2
-rw-r--r--arch/powerpc/platforms/pasemi/iommu.c8
-rw-r--r--arch/sh/boards/se/73180/setup.c4
-rw-r--r--arch/sh/boards/superh/microdev/irq.c1
-rw-r--r--arch/sh/cchips/voyagergx/irq.c13
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c2
-rw-r--r--arch/sh/mm/ioremap.c1
-rw-r--r--arch/sparc64/Kconfig9
-rw-r--r--arch/sparc64/kernel/Makefile4
-rw-r--r--arch/sparc64/kernel/entry.S62
-rw-r--r--arch/sparc64/kernel/mdesc.c53
-rw-r--r--arch/sparc64/kernel/prom.c5
-rw-r--r--arch/sparc64/kernel/setup.c19
-rw-r--r--arch/sparc64/kernel/smp.c21
-rw-r--r--arch/sparc64/kernel/sysfs.c297
-rw-r--r--drivers/ata/Kconfig1
-rw-r--r--drivers/video/console/Makefile2
-rw-r--r--drivers/video/ffb.c4
-rw-r--r--drivers/video/sunxvr2500.c17
-rw-r--r--drivers/video/sunxvr500.c6
-rw-r--r--include/asm-frv/system.h1
-rw-r--r--include/asm-sh/se73180.h11
-rw-r--r--include/asm-sparc64/cpudata.h2
-rw-r--r--include/asm-sparc64/dma-mapping.h83
-rw-r--r--include/asm-sparc64/hypervisor.h5
-rw-r--r--include/asm-sparc64/smp.h2
-rw-r--r--include/asm-sparc64/topology.h13
-rw-r--r--kernel/signal.c16
-rwxr-xr-x[-rw-r--r--]scripts/checkpatch.pl0
39 files changed, 800 insertions, 247 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index b49ce169a63..d42d98107d4 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1,7 +1,6 @@
Booting the Linux/ppc kernel without Open Firmware
--------------------------------------------------
-
(c) 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>,
IBM Corp.
(c) 2005 Becky Bruce <becky.bruce at freescale.com>,
@@ -9,6 +8,62 @@
(c) 2006 MontaVista Software, Inc.
Flash chip node definition
+Table of Contents
+=================
+
+ I - Introduction
+ 1) Entry point for arch/powerpc
+ 2) Board support
+
+ II - The DT block format
+ 1) Header
+ 2) Device tree generalities
+ 3) Device tree "structure" block
+ 4) Device tree "strings" block
+
+ III - Required content of the device tree
+ 1) Note about cells and address representation
+ 2) Note about "compatible" properties
+ 3) Note about "name" properties
+ 4) Note about node and property names and character set
+ 5) Required nodes and properties
+ a) The root node
+ b) The /cpus node
+ c) The /cpus/* nodes
+ d) the /memory node(s)
+ e) The /chosen node
+ f) the /soc<SOCname> node
+
+ IV - "dtc", the device tree compiler
+
+ V - Recommendations for a bootloader
+
+ VI - System-on-a-chip devices and nodes
+ 1) Defining child nodes of an SOC
+ 2) Representing devices without a current OF specification
+ a) MDIO IO device
+ c) PHY nodes
+ b) Gianfar-compatible ethernet nodes
+ d) Interrupt controllers
+ e) I2C
+ f) Freescale SOC USB controllers
+ g) Freescale SOC SEC Security Engines
+ h) Board Control and Status (BCSR)
+ i) Freescale QUICC Engine module (QE)
+ g) Flash chip nodes
+
+ VII - Specifying interrupt information for devices
+ 1) interrupts property
+ 2) interrupt-parent property
+ 3) OpenPIC Interrupt Controllers
+ 4) ISA Interrupt Controllers
+
+ Appendix A - Sample SOC node for MPC8540
+
+
+Revision Information
+====================
+
May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet.
May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or
@@ -1687,7 +1742,7 @@ platforms are moved over to use the flattened-device-tree model.
};
};
- g) Flash chip nodes
+ j) Flash chip nodes
Flash chips (Memory Technology Devices) are often used for solid state
file systems on embedded devices.
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S
index 5a4215c4b01..f1c4dfc635b 100644
--- a/arch/powerpc/boot/crt0.S
+++ b/arch/powerpc/boot/crt0.S
@@ -13,6 +13,7 @@
.text
/* a procedure descriptor used when booting this as a COFF file */
+ .globl _zimage_start_opd
_zimage_start_opd:
.long _zimage_start, 0, 0, 0
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index d501c23e515..d454f61c9c7 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -433,7 +433,7 @@ static int __devinit of_pci_phb_probe(struct of_device *dev,
* Note also that we don't do ISA, this will also be fixed with a
* more massive rework.
*/
- pci_setup_phb_io(phb, 0);
+ pci_setup_phb_io(phb, pci_io_base == 0);
/* Init pci_dn data structures */
pci_devs_phb_init_dynamic(phb);
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
index f9ac3fe3be9..ac445998d83 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -67,6 +67,7 @@ static u64 MIC_Slow_Next_Timer_table[] = {
0x00003FC000000000ull,
};
+static unsigned int pmi_frequency_limit = 0;
/*
* hardware specific functions
*/
@@ -164,7 +165,6 @@ static int set_pmode(int cpu, unsigned int slow_mode) {
static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
{
- struct cpufreq_policy policy;
u8 cpu;
u8 cbe_pmode_new;
@@ -173,15 +173,27 @@ static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
cpu = cbe_node_to_cpu(pmi_msg.data1);
cbe_pmode_new = pmi_msg.data2;
- cpufreq_get_policy(&policy, cpu);
+ pmi_frequency_limit = cbe_freqs[cbe_pmode_new].frequency;
- policy.max = min(policy.max, cbe_freqs[cbe_pmode_new].frequency);
- policy.min = min(policy.min, policy.max);
+ pr_debug("cbe_handle_pmi: max freq=%d\n", pmi_frequency_limit);
+}
+
+static int pmi_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct cpufreq_policy *policy = data;
- pr_debug("cbe_handle_pmi: new policy.min=%d policy.max=%d\n", policy.min, policy.max);
- cpufreq_set_policy(&policy);
+ if (event != CPUFREQ_INCOMPATIBLE)
+ return 0;
+
+ cpufreq_verify_within_limits(policy, 0, pmi_frequency_limit);
+ return 0;
}
+static struct notifier_block pmi_notifier_block = {
+ .notifier_call = pmi_notifier,
+};
+
static struct pmi_handler cbe_pmi_handler = {
.type = PMI_TYPE_FREQ_CHANGE,
.handle_pmi_message = cbe_cpufreq_handle_pmi,
@@ -238,12 +250,21 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
+ if (pmi_dev) {
+ /* frequency might get limited later, initialize limit with max_freq */
+ pmi_frequency_limit = max_freq;
+ cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+ }
+
/* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */
return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs);
}
static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
{
+ if (pmi_dev)
+ cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER);
+
cpufreq_frequency_table_put_attr(policy->cpu);
return 0;
}
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 8654749e317..7c51cb54bca 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -39,7 +39,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
if (spu_init_csa(&ctx->csa))
goto out_free;
spin_lock_init(&ctx->mmio_lock);
- spin_lock_init(&ctx->mapping_lock);
+ mutex_init(&ctx->mapping_lock);
kref_init(&ctx->kref);
mutex_init(&ctx->state_mutex);
mutex_init(&ctx->run_mutex);
@@ -103,6 +103,7 @@ void spu_forget(struct spu_context *ctx)
void spu_unmap_mappings(struct spu_context *ctx)
{
+ mutex_lock(&ctx->mapping_lock);
if (ctx->local_store)
unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1);
if (ctx->mfc)
@@ -117,6 +118,7 @@ void spu_unmap_mappings(struct spu_context *ctx)
unmap_mapping_range(ctx->mss, 0, 0x1000, 1);
if (ctx->psmap)
unmap_mapping_range(ctx->psmap, 0, 0x20000, 1);
+ mutex_unlock(&ctx->mapping_lock);
}
/**
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 45614c73c78..b1e7e2f8a2e 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -45,11 +45,11 @@ spufs_mem_open(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = ctx;
if (!i->i_openers++)
ctx->local_store = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -59,10 +59,10 @@ spufs_mem_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->local_store = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -217,6 +217,7 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr,
static const struct file_operations spufs_mem_fops = {
.open = spufs_mem_open,
+ .release = spufs_mem_release,
.read = spufs_mem_read,
.write = spufs_mem_write,
.llseek = generic_file_llseek,
@@ -309,11 +310,11 @@ static int spufs_cntl_open(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = ctx;
if (!i->i_openers++)
ctx->cntl = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return simple_attr_open(inode, file, spufs_cntl_get,
spufs_cntl_set, "0x%08lx");
}
@@ -326,10 +327,10 @@ spufs_cntl_release(struct inode *inode, struct file *file)
simple_attr_close(inode, file);
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->cntl = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -812,11 +813,11 @@ static int spufs_signal1_open(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = ctx;
if (!i->i_openers++)
ctx->signal1 = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return nonseekable_open(inode, file);
}
@@ -826,10 +827,10 @@ spufs_signal1_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->signal1 = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -936,11 +937,11 @@ static int spufs_signal2_open(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = ctx;
if (!i->i_openers++)
ctx->signal2 = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return nonseekable_open(inode, file);
}
@@ -950,10 +951,10 @@ spufs_signal2_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->signal2 = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -1154,10 +1155,10 @@ static int spufs_mss_open(struct inode *inode, struct file *file)
file->private_data = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!i->i_openers++)
ctx->mss = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return nonseekable_open(inode, file);
}
@@ -1167,10 +1168,10 @@ spufs_mss_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->mss = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -1211,11 +1212,11 @@ static int spufs_psmap_open(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = i->i_ctx;
if (!i->i_openers++)
ctx->psmap = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return nonseekable_open(inode, file);
}
@@ -1225,10 +1226,10 @@ spufs_psmap_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->psmap = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
@@ -1281,11 +1282,11 @@ static int spufs_mfc_open(struct inode *inode, struct file *file)
if (atomic_read(&inode->i_count) != 1)
return -EBUSY;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
file->private_data = ctx;
if (!i->i_openers++)
ctx->mfc = inode->i_mapping;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return nonseekable_open(inode, file);
}
@@ -1295,10 +1296,10 @@ spufs_mfc_release(struct inode *inode, struct file *file)
struct spufs_inode_info *i = SPUFS_I(inode);
struct spu_context *ctx = i->i_ctx;
- spin_lock(&ctx->mapping_lock);
+ mutex_lock(&ctx->mapping_lock);
if (!--i->i_openers)
ctx->mfc = NULL;
- spin_unlock(&ctx->mapping_lock);
+ mutex_unlock(&ctx->mapping_lock);
return 0;
}
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 7150730e2ff..9807206e021 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -177,7 +177,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
int mode, struct spu_context *ctx)
{
- struct dentry *dentry;
+ struct dentry *dentry, *tmp;
int ret;
while (files->name && files->name[0]) {
@@ -193,7 +193,20 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
}
return 0;
out:
- spufs_prune_dir(dir);
+ /*
+ * remove all children from dir. dir->inode is not set so don't
+ * just simply use spufs_prune_dir() and panic afterwards :)
+ * dput() looks like it will do the right thing:
+ * - dec parent's ref counter
+ * - remove child from parent's child list
+ * - free child's inode if possible
+ * - free child
+ */
+ list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
+ dput(dentry);
+ }
+
+ shrink_dcache_parent(dir);
return ret;
}
@@ -274,6 +287,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
goto out;
out_free_ctx:
+ spu_forget(ctx);
put_spu_context(ctx);
out_iput:
iput(inode);
@@ -349,37 +363,6 @@ out:
return ret;
}
-static int spufs_rmgang(struct inode *root, struct dentry *dir)
-{
- /* FIXME: this fails if the dir is not empty,
- which causes a leak of gangs. */
- return simple_rmdir(root, dir);
-}
-
-static int spufs_gang_close(struct inode *inode, struct file *file)
-{
- struct inode *parent;
- struct dentry *dir;
- int ret;
-
- dir = file->f_path.dentry;
- parent = dir->d_parent->d_inode;
-
- ret = spufs_rmgang(parent, dir);
- WARN_ON(ret);
-
- return dcache_dir_close(inode, file);
-}
-
-const struct file_operations spufs_gang_fops = {
- .open = dcache_dir_open,
- .release = spufs_gang_close,
- .llseek = dcache_dir_lseek,
- .read = generic_read_dir,
- .readdir = dcache_readdir,
- .fsync = simple_sync_file,
-};
-
static int
spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
{
@@ -407,7 +390,6 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
inode->i_fop = &simple_dir_operations;
d_instantiate(dentry, inode);
- dget(dentry);
dir->i_nlink++;
dentry->d_inode->i_nlink++;
return ret;
@@ -437,7 +419,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
goto out;
}
- filp->f_op = &spufs_gang_fops;
+ filp->f_op = &simple_dir_operations;
fd_install(ret, filp);
out:
return ret;
@@ -458,8 +440,10 @@ static int spufs_create_gang(struct inode *inode,
* in error path of *_open().
*/
ret = spufs_gang_open(dget(dentry), mntget(mnt));
- if (ret < 0)
- WARN_ON(spufs_rmgang(inode, dentry));
+ if (ret < 0) {
+ int err = simple_rmdir(inode, dentry);
+ WARN_ON(err);
+ }
out:
mutex_unlock(&inode->i_mutex);
@@ -600,6 +584,10 @@ spufs_create_root(struct super_block *sb, void *data)
struct inode *inode;
int ret;
+ ret = -ENODEV;
+ if (!spu_management_ops)
+ goto out;
+
ret = -ENOMEM;
inode = spufs_new_inode(sb, S_IFDIR | 0775);
if (!inode)
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index b6ecb30e7d5..3b831e07f1e 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -93,43 +93,6 @@ void spu_stop_tick(struct spu_context *ctx)
}
}
-void spu_sched_tick(struct work_struct *work)
-{
- struct spu_context *ctx =
- container_of(work, struct spu_context, sched_work.work);
- struct spu *spu;
- int preempted = 0;
-
- /*
- * If this context is being stopped avoid rescheduling from the
- * scheduler tick because we would block on the state_mutex.
- * The caller will yield the spu later on anyway.
- */
- if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags))
- return;
-
- mutex_lock(&ctx->state_mutex);
- spu = ctx->spu;
- if (spu) {
- int best = sched_find_first_bit(spu_prio->bitmap);
- if (best <= ctx->prio) {
- spu_deactivate(ctx);
- preempted = 1;
- }
- }
- mutex_unlock(&ctx->state_mutex);
-
- if (preempted) {
- /*
- * We need to break out of the wait loop in spu_run manually
- * to ensure this context gets put on the runqueue again
- * ASAP.
- */
- wake_up(&ctx->stop_wq);
- } else
- spu_start_tick(ctx);
-}
-
/**
* spu_add_to_active_list - add spu to active list
* @spu: spu to add to the active list
@@ -273,34 +236,6 @@ static void spu_prio_wait(struct spu_context *ctx)
remove_wait_queue(&ctx->stop_wq, &wait);
}
-/**
- * spu_reschedule - try to find a runnable context for a spu
- * @spu: spu available
- *
- * This function is called whenever a spu becomes idle. It looks for the
- * most suitable runnable spu context and schedules it for execution.
- */
-static void spu_reschedule(struct spu *spu)
-{
- int best;
-
- spu_free(spu);
-
- spin_lock(&spu_prio->runq_lock);
- best = sched_find_first_bit(spu_prio->bitmap);
- if (best < MAX_PRIO) {
- struct list_head *rq = &spu_prio->runq[best];
- struct spu_context *ctx;
-
- BUG_ON(list_empty(rq));
-
- ctx = list_entry(rq->next, struct spu_context, rq);
- __spu_del_from_rq(ctx);
- wake_up(&ctx->stop_wq);
- }
- spin_unlock(&spu_prio->runq_lock);
-}
-
static struct spu *spu_get_idle(struct spu_context *ctx)
{
struct spu *spu = NULL;
@@ -429,6 +364,51 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
}
/**
+ * grab_runnable_context - try to find a runnable context
+ *
+ * Remove the highest priority context on the runqueue and return it
+ * to the caller. Returns %NULL if no runnable context was found.
+ */
+static struct spu_context *grab_runnable_context(int prio)
+{
+ struct spu_context *ctx = NULL;
+ int best;
+
+ spin_lock(&spu_prio->runq_lock);
+ best = sched_find_first_bit(spu_prio->bitmap);
+ if (best < prio) {
+ struct list_head *rq = &spu_prio->runq[best];
+
+ BUG_ON(list_empty(rq));
+
+ ctx = list_entry(rq->next, struct spu_context, rq);
+ __spu_del_from_rq(ctx);
+ }
+ spin_unlock(&spu_prio->runq_lock);
+
+ return ctx;
+}
+
+static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
+{
+ struct spu *spu = ctx->spu;
+ struct spu_context *new = NULL;
+
+ if (spu) {
+ new = grab_runnable_context(max_prio);
+ if (new || force) {
+ spu_unbind_context(spu, ctx);
+ spu_free(spu);
+ if (new)
+ wake_up(&new->stop_wq);
+ }
+
+ }
+
+ return new != NULL;
+}
+
+/**
* spu_deactivate - unbind a context from it's physical spu
* @ctx: spu context to unbind
*
@@ -437,12 +417,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
*/
void spu_deactivate(struct spu_context *ctx)
{
- struct spu *spu = ctx->spu;
-
- if (spu) {
- spu_unbind_context(spu, ctx);
- spu_reschedule(spu);
- }
+ __spu_deactivate(ctx, 1, MAX_PRIO);
}
/**
@@ -455,21 +430,43 @@ void spu_deactivate(struct spu_context *ctx)
*/
void spu_yield(struct spu_context *ctx)
{
- struct spu *spu;
-
- if (mutex_trylock(&ctx->state_mutex)) {
- if ((spu = ctx->spu) != NULL) {
- int best = sched_find_first_bit(spu_prio->bitmap);
- if (best < MAX_PRIO) {
- pr_debug("%s: yielding SPU %d NODE %d\n",
- __FUNCTION__, spu->number, spu->node);
- spu_deactivate(ctx);
- }
- }
+ if (!(ctx->flags & SPU_CREATE_NOSCHED)) {
+ mutex_lock(&ctx->state_mutex);
+ __spu_deactivate(ctx, 0, MAX_PRIO);
mutex_unlock(&ctx->state_mutex);
}
}
+void spu_sched_tick(struct work_struct *work)
+{
+ struct spu_context *ctx =
+ container_of(work, struct spu_context, sched_work.work);
+ int preempted;
+
+ /*
+ * If this context is being stopped avoid rescheduling from the
+ * scheduler tick because we would block on the state_mutex.
+ * The caller will yield the spu later on anyway.
+ */
+ if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags))
+ return;
+
+ mutex_lock(&ctx->state_mutex);
+ preempted = __spu_deactivate(ctx, 0, ctx->prio + 1);
+ mutex_unlock(&ctx->state_mutex);
+
+ if (preempted) {
+ /*
+ * We need to break out of the wait loop in spu_run manually
+ * to ensure this context gets put on the runqueue again
+ * ASAP.
+ */
+ wake_up(&ctx->stop_wq);
+ } else {
+ spu_start_tick(ctx);
+ }
+}
+
int __init spu_sched_init(void)
{
int i;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 0a947fd7de5..47617e8014a 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -55,7 +55,7 @@ struct spu_context {
struct address_space *signal2; /* 'signal2' area mappings. */
struct address_space *mss; /* 'mss' area mappings. */
struct address_space *psmap; /* 'psmap' area mappings. */
- spinlock_t mapping_lock;
+ struct mutex mapping_lock;
u64 object_id; /* user space pointer for oprofile */
enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile
index f4f82520dc4..5240046d867 100644
--- a/arch/powerpc/platforms/celleb/Makefile
+++ b/arch/powerpc/platforms/celleb/Makefile
@@ -4,5 +4,5 @@ obj-y += interrupt.o iommu.o setup.o \
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o
-obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o
+obj-$(CONFIG_SERIAL_TXX9) += scc_sio.o
obj-$(CONFIG_SPU_BASE) += spu_priv1.o
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 95fa6a7d15e..f33b21b9f5d 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -31,8 +31,6 @@
#define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT)
#define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1)
-#define IOBMAP_PAGE_FACTOR (PAGE_SHIFT - IOBMAP_PAGE_SHIFT)
-
#define IOB_BASE 0xe0000000
#define IOB_SIZE 0x3000
/* Configuration registers */
@@ -97,9 +95,6 @@ static void iobmap_build(struct iommu_table *tbl, long index,
bus_addr = (tbl->it_offset + index) << PAGE_SHIFT;
- npages <<= IOBMAP_PAGE_FACTOR;
- index <<= IOBMAP_PAGE_FACTOR;
-
ip = ((u32 *)tbl->it_base) + index;
while (npages--) {
@@ -125,9 +120,6 @@ static void iobmap_free(struct iommu_table *tbl, long index,
bus_addr = (tbl->it_offset + index) << PAGE_SHIFT;
- npages <<= IOBMAP_PAGE_FACTOR;
- index <<= IOBMAP_PAGE_FACTOR;
-
ip = ((u32 *)tbl->it_base) + index;
while (npages--) {
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c
index 911ce1cdbd7..e143017c897 100644
--- a/arch/sh/boards/se/73180/setup.c
+++ b/arch/sh/boards/se/73180/setup.c
@@ -38,8 +38,8 @@ static struct platform_device *se73180_devices[] __initdata = {
static int __init se73180_devices_setup(void)
{
- return platform_add_devices(sh7343se_platform_devices,
- ARRAY_SIZE(sh7343se_platform_devices));
+ return platform_add_devices(se73180_devices,
+ ARRAY_SIZE(se73180_devices));
}
__initcall(se73180_devices_setup);
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
index cc1cb04fa61..4d335077a3f 100644
--- a/arch/sh/boards/superh/microdev/irq.c
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/microdev.h>
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index 70f12907647..d70e5c8461b 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -28,7 +28,7 @@ static void disable_voyagergx_irq(unsigned int irq)
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
- pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+ pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = readl((void __iomem *)VOYAGER_INT_MASK);
val &= ~mask;
writel(val, (void __iomem *)VOYAGER_INT_MASK);
@@ -39,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq)
unsigned long val;
unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
- pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
+ pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask);
val = readl((void __iomem *)VOYAGER_INT_MASK);
val |= mask;
writel(val, (void __iomem *)VOYAGER_INT_MASK);
@@ -125,11 +125,12 @@ int voyagergx_irq_demux(int irq)
i = 17;
else
printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val);
- pr_debug("voyagergx_irq_demux %d \n", i);
- if (i < VOYAGER_IRQ_NUM) {
+ pr_debug("voyagergx_irq_demux %ld \n", i);
+ if (i < VOYAGER_IRQ_NUM) {
irq = VOYAGER_IRQ_BASE + i;
- if (voyagergx_demux[i].func != 0)
- irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev);
+ if (voyagergx_demux[i].func != 0)
+ irq = voyagergx_demux[i].func(irq,
+ voyagergx_demux[i].dev);
}
}
return irq;
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 659cc081e5e..b0b59d4a33c 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -320,7 +320,9 @@ skip_restore:
.align 2
5: .long 0x00001000 ! DSP
+#ifdef CONFIG_KGDB_NMI
6: .long in_nmi
+#endif
7: .long 0x30000000
! common exception handler
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index fcb2c41bc34..a33429463e9 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -111,7 +111,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static int shoc_clk_set_rate(struct clk *clk, unsigned long rate)
+static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
{
unsigned long frqcr3;
unsigned int tmp;
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index be03d74e99c..0c7b7e33abd 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -22,6 +22,7 @@
#include <asm/addrspace.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include <asm/mmu.h>
/*
* Remap an arbitrary physical address space into the kernel virtual
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index bd00f89eed1..89a1b469b93 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -396,6 +396,15 @@ config SCHED_SMT
when dealing with UltraSPARC cpus at a cost of slightly increased
overhead in some places. If unsure say N here.
+config SCHED_MC
+ bool "Multi-core scheduler support"
+ depends on SMP
+ default y
+ 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.
+
source "kernel/Kconfig.preempt"
config CMDLINE_BOOL
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index d8d19093d12..f964bf28d21 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.70 2002/02/09 19:49:30 davem Exp $
+#
# Makefile for the linux kernel.
#
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror
extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o setup.o cpu.o idprom.o \
- traps.o auxio.o una_asm.o \
+ traps.o auxio.o una_asm.o sysfs.o \
irq.o ptrace.o time.o sys_sparc.o signal.o \
unaligned.o central.o pci.o starfire.o semaphore.o \
power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index ed712e0b337..7d1a11822a1 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -2514,9 +2514,9 @@ sun4v_ncs_request:
nop
.size sun4v_ncs_request, .-sun4v_ncs_request
- .globl sun4v_scv_send
- .type sun4v_scv_send,#function
-sun4v_scv_send:
+ .globl sun4v_svc_send
+ .type sun4v_svc_send,#function
+sun4v_svc_send:
save %sp, -192, %sp
mov %i0, %o0
mov %i1, %o1
@@ -2526,11 +2526,11 @@ sun4v_scv_send:
stx %o1, [%i3]
ret
restore
- .size sun4v_scv_send, .-sun4v_scv_send
+ .size sun4v_svc_send, .-sun4v_svc_send
- .globl sun4v_scv_recv
- .type sun4v_scv_recv,#function
-sun4v_scv_recv:
+ .globl sun4v_svc_recv
+ .type sun4v_svc_recv,#function
+sun4v_svc_recv:
save %sp, -192, %sp
mov %i0, %o0
mov %i1, %o1
@@ -2540,33 +2540,55 @@ sun4v_scv_recv:
stx %o1, [%i3]
ret
restore
- .size sun4v_scv_recv, .-sun4v_scv_recv
+ .size sun4v_svc_recv, .-sun4v_svc_recv
- .globl sun4v_scv_getstatus
- .type sun4v_scv_getstatus,#function
-sun4v_scv_getstatus:
+ .globl sun4v_svc_getstatus
+ .type sun4v_svc_getstatus,#function
+sun4v_svc_getstatus:
mov HV_FAST_SVC_GETSTATUS, %o5
mov %o1, %o4
ta HV_FAST_TRAP
stx %o1, [%o4]
retl
nop
- .size sun4v_scv_getstatus, .-sun4v_scv_getstatus
+ .size sun4v_svc_getstatus, .-sun4v_svc_getstatus
- .globl sun4v_scv_setstatus
- .type sun4v_scv_setstatus,#function
-sun4v_scv_setstatus:
+ .globl sun4v_svc_setstatus
+ .type sun4v_svc_setstatus,#function
+sun4v_svc_setstatus:
mov HV_FAST_SVC_SETSTATUS, %o5
ta HV_FAST_TRAP
retl
nop
- .size sun4v_scv_setstatus, .-sun4v_scv_setstatus
+ .size sun4v_svc_setstatus, .-sun4v_svc_setstatus
- .globl sun4v_scv_clrstatus
- .type sun4v_scv_clrstatus,#function
-sun4v_scv_clrstatus:
+ .globl sun4v_svc_clrstatus
+ .type sun4v_svc_clrstatus,#function
+sun4v_svc_clrstatus:
mov HV_FAST_SVC_CLRSTATUS, %o5
ta HV_FAST_TRAP
retl
nop
- .size sun4v_scv_clrstatus, .-sun4v_scv_clrstatus
+ .size sun4v_svc_clrstatus, .-sun4v_svc_clrstatus
+
+ .globl sun4v_mmustat_conf
+ .type sun4v_mmustat_conf,#function
+sun4v_mmustat_conf:
+ mov %o1, %o4
+ mov HV_FAST_MMUSTAT_CONF, %o5
+ ta HV_FAST_TRAP
+ stx %o1, [%o4]
+ retl
+ nop
+ .size sun4v_mmustat_conf, .-sun4v_mmustat_conf
+
+ .globl sun4v_mmustat_info
+ .type sun4v_mmustat_info,#function
+sun4v_mmustat_info:
+ mov %o0, %o4
+ mov HV_FAST_MMUSTAT_INFO, %o5
+ ta HV_FAST_TRAP
+ stx %o1, [%o4]
+ retl
+ nop
+ .size sun4v_mmustat_info, .-sun4v_mmustat_info
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c
index 9246c2cf957..f0e16045fb1 100644
--- a/arch/sparc64/kernel/mdesc.c
+++ b/arch/sparc64/kernel/mdesc.c
@@ -473,6 +473,53 @@ static void __init set_core_ids(void)
}
}
+static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id)
+{
+ int i;
+
+ for (i = 0; i < mp->num_arcs; i++) {
+ struct mdesc_node *t = mp->arcs[i].arc;
+ const u64 *id;
+
+ if (strcmp(mp->arcs[i].name, "back"))
+ continue;
+
+ if (strcmp(t->name, "cpu"))
+ continue;
+
+ id = md_get_property(t, "id", NULL);
+ if (*id < NR_CPUS)
+ cpu_data(*id).proc_id = proc_id;
+ }
+}
+
+static void __init __set_proc_ids(const char *exec_unit_name)
+{
+ struct mdesc_node *mp;
+ int idx;
+
+ idx = 0;
+ md_for_each_node_by_name(mp, exec_unit_name) {
+ const char *type;
+ int len;
+
+ type = md_get_property(mp, "type", &len);
+ if (!find_in_proplist(type, "int", len) &&
+ !find_in_proplist(type, "integer", len))
+ continue;
+
+ mark_proc_ids(mp, idx);
+
+ idx++;
+ }
+}
+
+static void __init set_proc_ids(void)
+{
+ __set_proc_ids("exec_unit");
+ __set_proc_ids("exec-unit");
+}
+
static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def)
{
u64 val;
@@ -574,9 +621,15 @@ static void __init mdesc_fill_in_cpu_data(void)
#endif
c->core_id = 0;
+ c->proc_id = -1;
}
+#ifdef CONFIG_SMP
+ sparc64_multi_core = 1;
+#endif
+
set_core_ids();
+ set_proc_ids();
smp_fill_in_sib_core_maps();
}
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index dad4b3ba705..6f4a5284b0e 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -1781,6 +1781,10 @@ static void __init of_fill_in_cpu_data(void)
}
cpu_data(cpuid).core_id = portid + 1;
+ cpu_data(cpuid).proc_id = portid;
+#ifdef CONFIG_SMP
+ sparc64_multi_core = 1;
+#endif
} else {
cpu_data(cpuid).dcache_size =
of_getintprop_default(dp, "dcache-size", 16 * 1024);
@@ -1799,6 +1803,7 @@ static void __init of_fill_in_cpu_data(void)
of_getintprop_default(dp, "ecache-line-size", 64);
cpu_data(cpuid).core_id = 0;
+ cpu_data(cpuid).proc_id = -1;
}
#ifdef CONFIG_SMP
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index de9b4c13f1c..7490cc670a5 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -513,22 +513,3 @@ void sun_do_break(void)
int serial_console = -1;
int stop_a_enabled = 1;
-
-static int __init topology_init(void)
-{
- int i, err;
-
- err = -ENOMEM;
-
- for_each_possible_cpu(i) {
- struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (p) {
- register_cpu(p, i);
- err = 0;
- }
- }
-
- return err;
-}
-
-subsys_initcall(topology_init);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index c550bba3490..4dcd7d0b60f 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -44,6 +44,8 @@
extern void calibrate_delay(void);
+int sparc64_multi_core __read_mostly;
+
/* Please don't make this stuff initdata!!! --DaveM */
unsigned char boot_cpu_id;
@@ -51,6 +53,8 @@ cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE;
cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly =
{ [0 ... NR_CPUS-1] = CPU_MASK_NONE };
+cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
+ { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
static cpumask_t smp_commenced_mask;
static cpumask_t cpu_callout_map;
@@ -1217,13 +1221,28 @@ void __devinit smp_fill_in_sib_core_maps(void)
unsigned int j;
if (cpu_data(i).core_id == 0) {
- cpu_set(i, cpu_sibling_map[i]);
+ cpu_set(i, cpu_core_map[i]);
continue;
}
for_each_possible_cpu(j) {
if (cpu_data(i).core_id ==
cpu_data(j).core_id)
+ cpu_set(j, cpu_core_map[i]);
+ }
+ }
+
+ for_each_possible_cpu(i) {
+ unsigned int j;
+
+ if (cpu_data(i).proc_id == -1) {
+ cpu_set(i, cpu_sibling_map[i]);
+ continue;
+ }
+
+ for_each_possible_cpu(j) {
+ if (cpu_data(i).proc_id ==
+ cpu_data(j).proc_id)
cpu_set(j, cpu_sibling_map[i]);
}
}
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c
new file mode 100644
index 00000000000..cdb1477af89
--- /dev/null
+++ b/arch/sparc64/kernel/sysfs.c
@@ -0,0 +1,297 @@
+/* sysfs.c: Toplogy sysfs support code for sparc64.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/init.h>
+
+#include <asm/hypervisor.h>
+#include <asm/spitfire.h>
+
+static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64)));
+
+#define SHOW_MMUSTAT_ULONG(NAME) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+ struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \
+ return sprintf(buf, "%lu\n", p->NAME); \
+} \
+static SYSDEV_ATTR(NAME, 0444, show_##NAME, NULL)
+
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_8k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_64k_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_4mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_256mb_tte);
+SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte);
+
+static struct attribute *mmu_stat_attrs[] = {
+ &attr_immu_tsb_hits_ctx0_8k_tte.attr,
+ &attr_immu_tsb_ticks_ctx0_8k_tte.attr,
+ &attr_immu_tsb_hits_ctx0_64k_tte.attr,
+ &attr_immu_tsb_ticks_ctx0_64k_tte.attr,
+ &attr_immu_tsb_hits_ctx0_4mb_tte.attr,
+ &attr_immu_tsb_ticks_ctx0_4mb_tte.attr,
+ &attr_immu_tsb_hits_ctx0_256mb_tte.attr,
+ &attr_immu_tsb_ticks_ctx0_256mb_tte.attr,
+ &attr_immu_tsb_hits_ctxnon0_8k_tte.attr,
+ &attr_immu_tsb_ticks_ctxnon0_8k_tte.attr,
+ &attr_immu_tsb_hits_ctxnon0_64k_tte.attr,
+ &attr_immu_tsb_ticks_ctxnon0_64k_tte.attr,
+ &attr_immu_tsb_hits_ctxnon0_4mb_tte.attr,
+ &attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr,
+ &attr_immu_tsb_hits_ctxnon0_256mb_tte.attr,
+ &attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr,
+ &attr_dmmu_tsb_hits_ctx0_8k_tte.attr,
+ &attr_dmmu_tsb_ticks_ctx0_8k_tte.attr,
+ &attr_dmmu_tsb_hits_ctx0_64k_tte.attr,
+ &attr_dmmu_tsb_ticks_ctx0_64k_tte.attr,
+ &attr_dmmu_tsb_hits_ctx0_4mb_tte.attr,
+ &attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr,
+ &attr_dmmu_tsb_hits_ctx0_256mb_tte.attr,
+ &attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr,
+ &attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr,
+ &attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr,
+ &attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr,
+ &attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr,
+ &attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr,
+ &attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr,
+ &attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr,
+ &attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr,
+ NULL,
+};
+
+static struct attribute_group mmu_stat_group = {
+ .attrs = mmu_stat_attrs,
+ .name = "mmu_stats",
+};
+
+/* XXX convert to rusty's on_one_cpu */
+static unsigned long run_on_cpu(unsigned long cpu,
+ unsigned long (*func)(unsigned long),
+ unsigned long arg)
+{
+ cpumask_t old_affinity = current->cpus_allowed;
+ unsigned long ret;
+
+ /* should return -EINVAL to userspace */
+ if (set_cpus_allowed(current, cpumask_of_cpu(cpu)))
+ return 0;
+
+ ret = func(arg);
+
+ set_cpus_allowed(current, old_affinity);
+
+ return ret;
+}
+
+static unsigned long read_mmustat_enable(unsigned long junk)
+{
+ unsigned long ra = 0;
+
+ sun4v_mmustat_info(&ra);
+
+ return ra != 0;
+}
+
+static unsigned long write_mmustat_enable(unsigned long val)
+{
+ unsigned long ra, orig_ra;
+
+ if (val)
+ ra = __pa(&per_cpu(mmu_stats, smp_processor_id()));
+ else
+ ra = 0UL;
+
+ return sun4v_mmustat_conf(ra, &orig_ra);
+}
+
+static ssize_t show_mmustat_enable(struct sys_device *s, char *buf)
+{
+ unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0);
+ return sprintf(buf, "%lx\n", val);
+}
+
+static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count)
+{
+ unsigned long val, err;
+ int ret = sscanf(buf, "%ld", &val);
+
+ if (ret != 1)
+ return -EINVAL;
+
+ err = run_on_cpu(s->id, write_mmustat_enable, val);
+ if (err)
+ return -EIO;
+
+ return count;
+}
+
+static SYSDEV_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable);
+
+static int mmu_stats_supported;
+
+static int register_mmu_stats(struct sys_device *s)
+{
+ if (!mmu_stats_supported)
+ return 0;
+ sysdev_create_file(s, &attr_mmustat_enable);
+ return sysfs_create_group(&s->kobj, &mmu_stat_group);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_mmu_stats(struct sys_device *s)
+{
+ if (!mmu_stats_supported)
+ return;
+ sysfs_remove_group(&s->kobj, &mmu_stat_group);
+ sysdev_remove_file(s, &attr_mmustat_enable);
+}
+#endif
+
+#define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+ cpuinfo_sparc *c = &cpu_data(dev->id); \
+ return sprintf(buf, "%lu\n", c->MEMBER); \
+}
+
+#define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
+static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+{ \
+ cpuinfo_sparc *c = &cpu_data(dev->id); \
+ return sprintf(buf, "%u\n", c->MEMBER); \
+}
+
+SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick);
+SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val);
+SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size);
+SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size);
+SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size);
+SHOW_CPUDATA_UINT_NAME(l1_icache_line_size, icache_line_size);
+SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size);
+SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size);
+
+static struct sysdev_attribute cpu_core_attrs[] = {
+ _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL),
+ _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL),
+ _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL),
+ _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL),
+ _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL),
+ _SYSDEV_ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL),
+ _SYSDEV_ATTR(l2_cache_size, 0444, show_l2_cache_size, NULL),
+ _SYSDEV_ATTR(l2_cache_line_size, 0444, show_l2_cache_line_size, NULL),
+};
+
+static DEFINE_PER_CPU(struct cpu, cpu_devices);
+
+static void register_cpu_online(unsigned int cpu)
+{
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+ struct sys_device *s = &c->sysdev;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+ sysdev_create_file(s, &cpu_core_attrs[i]);
+
+ register_mmu_stats(s);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void unregister_cpu_online(unsigned int cpu)
+{
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+ struct sys_device *s = &c->sysdev;
+ int i;
+
+ unregister_mmu_stats(s);
+ for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++)
+ sysdev_remove_file(s, &cpu_core_attrs[i]);
+}
+#endif
+
+static int __cpuinit sysfs_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ unsigned int cpu = (unsigned int)(long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ register_cpu_online(cpu);
+ break;
+#ifdef CONFIG_HOTPLUG_CPU
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ unregister_cpu_online(cpu);
+ break;
+#endif
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
+ .notifier_call = sysfs_cpu_notify,
+};
+
+static void __init check_mmu_stats(void)
+{
+ unsigned long dummy1, err;
+
+ if (tlb_type != hypervisor)
+ return;
+
+ err = sun4v_mmustat_info(&dummy1);
+ if (!err)
+ mmu_stats_supported = 1;
+}
+
+static int __init topology_init(void)
+{
+ int cpu;
+
+ check_mmu_stats();
+
+ register_cpu_notifier(&sysfs_cpu_nb);
+
+ for_each_possible_cpu(cpu) {
+ struct cpu *c = &per_cpu(cpu_devices, cpu);
+
+ register_cpu(c, cpu);
+ if (cpu_online(cpu))
+ register_cpu_online(cpu);
+ }
+
+ return 0;
+}
+
+subsys_initcall(topology_init);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 7d893a60f99..b4a8d6030e4 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -8,7 +8,6 @@ menuconfig ATA
depends on BLOCK
depends on !(M32R || M68K) || BROKEN
depends on !SUN4 || BROKEN
- depends on !(SPARC64 && !PCI)
select SCSI
---help---
If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 9b26dda18a3..ac46cc3f6a2 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -47,7 +47,7 @@ targets := promcon_tbl.c
quiet_cmd_conmakehash = CNMKHSH $@
cmd_conmakehash = scripts/conmakehash $< | \
sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \
- -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+ -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@
$(obj)/promcon_tbl.c: $(src)/prom.uni
$(call cmd,conmakehash)
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 1d4e8354b56..3f6c98fad43 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -656,7 +656,7 @@ static int ffb_setcolreg(unsigned regno,
{
u32 value;
- if (regno >= 256)
+ if (regno >= 16)
return 1;
red >>= 8;
@@ -903,7 +903,7 @@ ffb_init_fix(struct fb_info *info)
struct all_info {
struct fb_info info;
struct ffb_par par;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int ffb_init_one(struct of_device *op)
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index 4316c7fe8e2..c3869a96ab5 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -28,7 +28,7 @@ struct s3d_info {
unsigned int depth;
unsigned int fb_size;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int __devinit s3d_get_props(struct s3d_info *sp)
@@ -52,15 +52,14 @@ static int s3d_setcolreg(unsigned regno,
{
u32 value;
- if (regno >= 256)
- return 1;
+ if (regno < 16) {
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
- red >>= 8;
- green >>= 8;
- blue >>= 8;
-
- value = (blue << 24) | (green << 16) | (red << 8);
- ((u32 *)info->pseudo_palette)[regno] = value;
+ value = (blue << 24) | (green << 16) | (red << 8);
+ ((u32 *)info->pseudo_palette)[regno] = value;
+ }
return 0;
}
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index 08880a62bfa..71bf3f1f00b 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -50,7 +50,7 @@ struct e3d_info {
u32 fb8_0_off;
u32 fb8_1_off;
- u32 pseudo_palette[256];
+ u32 pseudo_palette[16];
};
static int __devinit e3d_get_props(struct e3d_info *ep)
@@ -126,7 +126,9 @@ static int e3d_setcolreg(unsigned regno,
blue_8 = blue >> 8;
value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8);
- ((u32 *)info->pseudo_palette)[regno] = value;
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16)
+ ((u32 *)info->pseudo_palette)[regno] = value;
red_10 = red >> 6;
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h
index be303b3eef4..6931af525da 100644
--- a/include/asm-frv/system.h
+++ b/include/asm-frv/system.h
@@ -12,6 +12,7 @@
#ifndef _ASM_SYSTEM_H
#define _ASM_SYSTEM_H
+#include <linux/types.h>
#include <linux/linkage.h>
struct thread_struct;
diff --git a/include/asm-sh/se73180.h b/include/asm-sh/se73180.h
index 3a4acb3e38a..907c062b4c9 100644
--- a/include/asm-sh/se73180.h
+++ b/include/asm-sh/se73180.h
@@ -1,9 +1,7 @@
-#ifndef __ASM_SH_HITACHI_SE73180_H
-#define __ASM_SH_HITACHI_SE73180_H
+#ifndef __ASM_SH_SE73180_H
+#define __ASM_SH_SE73180_H
/*
- * include/asm-sh/se/se73180.h
- *
* Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
*
* SH-Mobile SolutionEngine 73180 support
@@ -62,4 +60,7 @@
#define __IO_PREFIX sh73180se
#include <asm/io_generic.h>
-#endif /* __ASM_SH_HITACHI_SE73180_H */
+/* arch/sh/boards/se/73180/irq.c */
+int shmse_irq_demux(int irq);
+
+#endif /* __ASM_SH_SE73180_H */
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
index 03c385de761..445026fbec3 100644
--- a/include/asm-sparc64/cpudata.h
+++ b/include/asm-sparc64/cpudata.h
@@ -31,7 +31,7 @@ typedef struct {
unsigned int ecache_size;
unsigned int ecache_line_size;
int core_id;
- unsigned int __pad3;
+ int proc_id;
} cpuinfo_sparc;
DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h
index 9329429fb7f..4e21c2f3065 100644
--- a/include/asm-sparc64/dma-mapping.h
+++ b/include/asm-sparc64/dma-mapping.h
@@ -162,6 +162,22 @@ dma_mapping_error(dma_addr_t dma_addr)
#else
struct device;
+struct page;
+struct scatterlist;
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ BUG();
+ return 0;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ BUG();
+ return 0;
+}
static inline void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
@@ -176,6 +192,52 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
BUG();
}
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return 0;
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
static inline void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
@@ -190,6 +252,27 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t siz
BUG();
}
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+ BUG();
+ return 0;
+}
+
#endif /* PCI */
diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h
index 4a43075a061..5c2f9d4b9f0 100644
--- a/include/asm-sparc64/hypervisor.h
+++ b/include/asm-sparc64/hypervisor.h
@@ -2798,6 +2798,11 @@ struct hv_mmu_statistics {
*/
#define HV_FAST_MMUSTAT_INFO 0x103
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra);
+extern unsigned long sun4v_mmustat_info(unsigned long *ra);
+#endif
+
/* NCS crypto services */
/* ncs_request() sub-function numbers */
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index f76e1492add..4fb8c4bfb84 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -33,6 +33,8 @@ extern cpumask_t phys_cpu_present_map;
#define cpu_possible_map phys_cpu_present_map
extern cpumask_t cpu_sibling_map[NR_CPUS];
+extern cpumask_t cpu_core_map[NR_CPUS];
+extern int sparc64_multi_core;
/*
* General functions that each host system must provide.
diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h
index e0d450d600e..290ac75f385 100644
--- a/include/asm-sparc64/topology.h
+++ b/include/asm-sparc64/topology.h
@@ -1,12 +1,17 @@
#ifndef _ASM_SPARC64_TOPOLOGY_H
#define _ASM_SPARC64_TOPOLOGY_H
-#include <asm/spitfire.h>
-#define smt_capable() (tlb_type == hypervisor)
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
+#define topology_core_id(cpu) (cpu_data(cpu).core_id)
+#define topology_core_siblings(cpu) (cpu_core_map[cpu])
+#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define mc_capable() (sparc64_multi_core)
+#define smt_capable() (sparc64_multi_core)
+#endif /* CONFIG_SMP */
#include <asm-generic/topology.h>
-#define topology_core_id(cpu) (cpu_data(cpu).core_id)
-#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#define cpu_coregroup_map(cpu) (cpu_core_map[cpu])
#endif /* _ASM_SPARC64_TOPOLOGY_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index acdfc0549c6..fe590e00db8 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -105,7 +105,11 @@ static int recalc_sigpending_tsk(struct task_struct *t)
set_tsk_thread_flag(t, TIF_SIGPENDING);
return 1;
}
- clear_tsk_thread_flag(t, TIF_SIGPENDING);
+ /*
+ * We must never clear the flag in another thread, or in current
+ * when it's possible the current syscall is returning -ERESTART*.
+ * So we don't clear it here, and only callers who know they should do.
+ */
return 0;
}
@@ -121,7 +125,9 @@ void recalc_sigpending_and_wake(struct task_struct *t)
void recalc_sigpending(void)
{
- recalc_sigpending_tsk(current);
+ if (!recalc_sigpending_tsk(current))
+ clear_thread_flag(TIF_SIGPENDING);
+
}
/* Given the mask, find the first available signal that should be serviced. */
@@ -385,7 +391,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
}
}
}
- recalc_sigpending_tsk(tsk);
+ if (likely(tsk == current))
+ recalc_sigpending();
if (signr && unlikely(sig_kernel_stop(signr))) {
/*
* Set a marker that we have dequeued a stop signal. Our
@@ -1580,8 +1587,9 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info)
/*
* Queued signals ignored us while we were stopped for tracing.
* So check for any that we should take before resuming user mode.
+ * This sets TIF_SIGPENDING, but never clears it.
*/
- recalc_sigpending();
+ recalc_sigpending_tsk(current);
}
void ptrace_notify(int exit_code)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index e216d49624b..e216d49624b 100644..100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl