linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [patch 00/11] Cell patches for 2.6.27
@ 2008-07-04 19:05 arnd
  2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
                   ` (10 more replies)
  0 siblings, 11 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt; +Cc: linuxppc-dev, cbe-oss-dev

Hi Paul and Ben,

These are the cell related patches I would like to see in
2.6.27. If there are no further comments, please pull into
powerpc-next from

master.kernel.org/pub/scm/linux/kernel/git/arnd/cell-2.6.git cell-next

-- 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-07  5:12   ` Benjamin Herrenschmidt
  2008-07-07  5:24   ` [patch 01/11] " Stephen Rothwell
  2008-07-04 19:05 ` [patch 02/11] powerpc/axonram: use only one block device major number arnd
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: linuxppc-dev, cbe-oss-dev, Christian Krafft

This patch adds support for the power button on future IBM cell blades.
It actually doesn't shut down the machine. Instead it exposes an
input device /dev/input/event0 to userspace which sends KEY_POWER
if power button has been pressed.
haldaemon actually recognizes the button, so a plattform independent acpid
replacement should handle it correctly.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/platforms/cell/pervasive.c |   70 ++++++++++++++++++++++++++++++-
 1 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index 8a3631c..e5bd08c 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -24,8 +24,10 @@
 #undef DEBUG
 
 #include <linux/interrupt.h>
+#include <linux/input.h>
 #include <linux/irq.h>
 #include <linux/percpu.h>
+#include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/kallsyms.h>
 
@@ -40,6 +42,9 @@
 
 static int sysreset_hack;
 
+static struct input_dev *button_dev;
+static struct platform_device *button_pdev;
+
 static void cbe_power_save(void)
 {
 	unsigned long ctrl, thread_switch_control;
@@ -105,10 +110,21 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
 		 */
 		if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
 			pmd = cbe_get_cpu_pmd_regs(cpu);
-			if (in_be64(&pmd->ras_esc_0) & 0xffff) {
+			if (in_be64(&pmd->ras_esc_0) & 0x0000ffff) {
 				out_be64(&pmd->ras_esc_0, 0);
 				return 0;
 			}
+			if (in_be64(&pmd->ras_esc_0) & 0x00010000) {
+				out_be64(&pmd->ras_esc_0, 0);
+				if (!button_dev)
+					return 0;
+
+				input_report_key(button_dev, KEY_POWER, 1);
+				input_sync(button_dev);
+				input_report_key(button_dev, KEY_POWER, 0);
+				input_sync(button_dev);
+				return 1;
+			}
 		}
 		break;
 #ifdef CONFIG_CBE_RAS
@@ -155,3 +171,55 @@ void __init cbe_pervasive_init(void)
 	ppc_md.power_save = cbe_power_save;
 	ppc_md.system_reset_exception = cbe_system_reset_exception;
 }
+
+static int __init cbe_power_button_init(void)
+{
+	int ret;
+	struct input_dev *dev;
+
+	if (!sysreset_hack)
+		return 0;
+
+	dev = input_allocate_device();
+        if (!dev) {
+		ret = -ENOMEM;
+                printk(KERN_ERR "%s: Not enough memory\n", __func__);
+                goto out;
+        }
+
+	set_bit(EV_KEY, dev->evbit);
+	set_bit(KEY_POWER, dev->keybit);
+
+	dev->name = "Power Button";
+	dev->id.bustype = BUS_HOST;
+
+	/* this makes the button look like an acpi power button
+	 * no clue whether anyone relies on that though */
+	dev->id.product = 0x02;
+	dev->phys = "LNXPWRBN/button/input0";
+
+	button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
+	if (IS_ERR(button_pdev)) {
+		ret = PTR_ERR(button_pdev);
+		goto out_free_input;
+	}
+
+	dev->dev.parent = &button_pdev->dev;
+
+	ret = input_register_device(dev);
+	if (ret) {
+                printk(KERN_ERR "%s: Failed to register device\n", __func__);
+		goto out_free_pdev;
+        }
+
+	button_dev = dev;
+	return ret;
+
+out_free_pdev:
+	platform_device_unregister(button_pdev);
+out_free_input:
+	input_free_device(dev);
+out:
+	return ret;
+}
+device_initcall(cbe_power_button_init);
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 02/11] powerpc/axonram: use only one block device major number
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
  2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 03/11] powerpc/axonram: enable partitioning of the Axons DDR2 DIMMs arnd
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Maxim Shchetynin, linuxppc-dev, cbe-oss-dev

Axonram module registers one block device for each DDR2 DIMM found
on a system. This means that each DDR2 DIMM becomes its own block device
major number. This patch lets axonram module to register the only one
block device for all DDR2 DIMMs which also spares kernel resources.

Signed-off-by: Maxim Shchetynin <maxim@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/sysdev/axonram.c |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 7f59188..9b639ed 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -57,6 +57,8 @@
 #define AXON_RAM_SECTOR_SIZE		1 << AXON_RAM_SECTOR_SHIFT
 #define AXON_RAM_IRQ_FLAGS		IRQF_SHARED | IRQF_TRIGGER_RISING
 
+static int azfs_major, azfs_minor;
+
 struct axon_ram_bank {
 	struct of_device	*device;
 	struct gendisk		*disk;
@@ -227,19 +229,14 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
 		goto failed;
 	}
 
-	bank->disk->first_minor = 0;
+	bank->disk->major = azfs_major;
+	bank->disk->first_minor = azfs_minor;
 	bank->disk->fops = &axon_ram_devops;
 	bank->disk->private_data = bank;
 	bank->disk->driverfs_dev = &device->dev;
 
 	sprintf(bank->disk->disk_name, "%s%d",
 			AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
-	bank->disk->major = register_blkdev(0, bank->disk->disk_name);
-	if (bank->disk->major < 0) {
-		dev_err(&device->dev, "Cannot register block device\n");
-		rc = -EFAULT;
-		goto failed;
-	}
 
 	bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
 	if (bank->disk->queue == NULL) {
@@ -276,6 +273,8 @@ axon_ram_probe(struct of_device *device, const struct of_device_id *device_id)
 		goto failed;
 	}
 
+	azfs_minor += bank->disk->minors;
+
 	return 0;
 
 failed:
@@ -310,7 +309,6 @@ axon_ram_remove(struct of_device *device)
 
 	device_remove_file(&device->dev, &dev_attr_ecc);
 	free_irq(bank->irq_id, device);
-	unregister_blkdev(bank->disk->major, bank->disk->disk_name);
 	del_gendisk(bank->disk);
 	iounmap((void __iomem *) bank->io_addr);
 	kfree(bank);
@@ -341,6 +339,14 @@ static struct of_platform_driver axon_ram_driver = {
 static int __init
 axon_ram_init(void)
 {
+	azfs_major = register_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
+	if (azfs_major < 0) {
+		printk(KERN_ERR "%s cannot become block device major number\n",
+				AXON_RAM_MODULE_NAME);
+		return -EFAULT;
+	}
+	azfs_minor = 0;
+
 	return of_register_platform_driver(&axon_ram_driver);
 }
 
@@ -351,6 +357,7 @@ static void __exit
 axon_ram_exit(void)
 {
 	of_unregister_platform_driver(&axon_ram_driver);
+	unregister_blkdev(azfs_major, AXON_RAM_DEVICE_NAME);
 }
 
 module_init(axon_ram_init);
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 03/11] powerpc/axonram: enable partitioning of the Axons DDR2 DIMMs
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
  2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
  2008-07-04 19:05 ` [patch 02/11] powerpc/axonram: use only one block device major number arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info arnd
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Maxim Shchetynin, linuxppc-dev, cbe-oss-dev

DDR2 memory DIMMs on the Axon could be accessed only as one partition
when using file system drivers which are using the direct_access() method.
This patch enables for such file system drivers to access Axon's DDR2 memory
even if it is splitted in several partitions.

Signed-off-by: Maxim Shchetynin <maxim@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/sysdev/axonram.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 9b639ed..9e105cb 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -150,7 +150,10 @@ axon_ram_direct_access(struct block_device *device, sector_t sector,
 	struct axon_ram_bank *bank = device->bd_disk->private_data;
 	loff_t offset;
 
-	offset = sector << AXON_RAM_SECTOR_SHIFT;
+	offset = sector;
+	if (device->bd_part != NULL)
+		offset += device->bd_part->start_sect;
+	offset <<= AXON_RAM_SECTOR_SHIFT;
 	if (offset >= bank->size) {
 		dev_err(&bank->device->dev, "Access outside of address space\n");
 		return -ERANGE;
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (2 preceding siblings ...)
  2008-07-04 19:05 ` [patch 03/11] powerpc/axonram: enable partitioning of the Axons DDR2 DIMMs arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-07  5:19   ` Benjamin Herrenschmidt
  2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: linuxppc-dev, cbe-oss-dev, Christian Krafft

As nr_active counter includes also spus waiting for syscalls to return
we need a seperate counter that only counts spus that are currently running
on spu side. This counter shall be used by a cpufreq governor that targets
a frequency dependent from the number of running spus.

From: Maxim Shchetynin <maxim@de.ibm.com>
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
---
 arch/powerpc/platforms/cell/spufs/sched.c |    6 ++++++
 include/asm-powerpc/spu.h                 |    1 +
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index e929e70..be77910 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -993,6 +993,7 @@ void spuctx_switch_state(struct spu_context *ctx,
 	struct timespec ts;
 	struct spu *spu;
 	enum spu_utilization_state old_state;
+	int node;
 
 	ktime_get_ts(&ts);
 	curtime = timespec_to_ns(&ts);
@@ -1014,6 +1015,11 @@ void spuctx_switch_state(struct spu_context *ctx,
 		spu->stats.times[old_state] += delta;
 		spu->stats.util_state = new_state;
 		spu->stats.tstamp = curtime;
+		node = spu->node;
+		if (old_state == SPU_UTIL_USER)
+			atomic_dec(&cbe_spu_info[node].busy_spus);
+		if (new_state == SPU_UTIL_USER);
+			atomic_inc(&cbe_spu_info[node].busy_spus);
 	}
 }
 
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index 99348c1..8b2eb04 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -191,6 +191,7 @@ struct cbe_spu_info {
 	struct list_head spus;
 	int n_spus;
 	int nr_active;
+	atomic_t busy_spus;
 	atomic_t reserved_spus;
 };
 
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (3 preceding siblings ...)
  2008-07-04 19:05 ` [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-07  5:21   ` Benjamin Herrenschmidt
                     ` (2 more replies)
  2008-07-04 19:05 ` [patch 06/11] powerpc: Add struct iommu_table argument to iommu_map_sg() arnd
                   ` (5 subsequent siblings)
  10 siblings, 3 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: linuxppc-dev, cbe-oss-dev, Christian Krafft

This patch adds a cpufreq governor that takes the number of running spus
into account. It's very similar to the ondemand governor, but not as complex.
Instead of hacking spu load into the ondemand governor it might be easier to
have cpufreq accepting multiple governors per cpu in future.
Don't know if this is the right way, but it would keep the governors simple.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>
---
 arch/powerpc/platforms/cell/Kconfig            |   10 ++
 arch/powerpc/platforms/cell/Makefile           |    1 +
 arch/powerpc/platforms/cell/cbe_spu_governor.c |  183 ++++++++++++++++++++++++
 3 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/cell/cbe_spu_governor.c

diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3959fcf..2dfff9f 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -107,6 +107,16 @@ config CBE_CPUFREQ_PMI
 	  processor will not only be able to run at lower speed,
 	  but also at lower core voltage.
 
+config CBE_CPUFREQ_SPU_GOVERNOR
+	tristate "CBE frequency scaling based on SPU usage"
+	depends on SPU_FS
+	select CBE_CPUFREQ
+	default m
+	help
+	  This governor checks for spu usage to adjust the cpu frequency.
+	  If no spu is running on a given cpu, that cpu will be throttled to
+	  the minimal possible frequency.
+
 endmenu
 
 config OPROFILE_CELL
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index c2a7e4e..8be5158 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_CBE_THERM)			+= cbe_thermal.o
 obj-$(CONFIG_CBE_CPUFREQ_PMI)		+= cbe_cpufreq_pmi.o
 obj-$(CONFIG_CBE_CPUFREQ)		+= cbe-cpufreq.o
 cbe-cpufreq-y				+= cbe_cpufreq_pervasive.o cbe_cpufreq.o
+obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR)	+= cbe_spu_governor.o
 
 ifeq ($(CONFIG_SMP),y)
 obj-$(CONFIG_PPC_CELL_NATIVE)		+= smp.o
diff --git a/arch/powerpc/platforms/cell/cbe_spu_governor.c b/arch/powerpc/platforms/cell/cbe_spu_governor.c
new file mode 100644
index 0000000..7e63009
--- /dev/null
+++ b/arch/powerpc/platforms/cell/cbe_spu_governor.c
@@ -0,0 +1,183 @@
+/*
+ * spu aware cpufreq governor for the cell processor
+ *
+ * (C) Copyright IBM Corporation 2006-2008
+ *
+ * Author: Christian Krafft <krafft@de.ibm.com>
+ *
+ * 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, or (at your option)
+ * any later version.
+ *
+ * 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. See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ */
+
+#include <linux/cpufreq.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+#include <asm/machdep.h>
+#include <asm/spu.h>
+
+#define POLL_TIME	100000		/* in us */
+#define EXP		753		/* exp(-1) in fixed-point */
+
+struct spu_gov_info_struct {
+	unsigned long busy_spus;	/* fixed-point */
+	struct cpufreq_policy *policy;
+	struct delayed_work work;
+	unsigned int poll_int;		/* us */
+};
+static DEFINE_PER_CPU(struct spu_gov_info_struct, spu_gov_info);
+
+static struct workqueue_struct *kspugov_wq;
+
+static int calc_freq(struct spu_gov_info_struct *info)
+{
+	int cpu;
+	int busy_spus;
+
+	cpu = info->policy->cpu;
+	busy_spus = atomic_read(&cbe_spu_info[cpu_to_node(cpu)].busy_spus);
+
+	CALC_LOAD(info->busy_spus, EXP, busy_spus * FIXED_1);
+	pr_debug(KERN_ERR "cpu %d: busy_spus=%d, info->busy_spus=%d\n", cpu, busy_spus, info->busy_spus);
+
+	return info->policy->max * info->busy_spus / FIXED_1;
+}
+
+static void spu_gov_work(struct work_struct *work)
+{
+	struct spu_gov_info_struct *info;
+	int delay;
+	unsigned long target_freq;
+
+	info = container_of(work, struct spu_gov_info_struct, work.work);
+
+	/* after cancel_delayed_work_sync we unset info->policy */
+	BUG_ON(info->policy == NULL);
+
+	target_freq = calc_freq(info);
+	__cpufreq_driver_target(info->policy, target_freq, CPUFREQ_RELATION_H);
+
+	delay = usecs_to_jiffies(info->poll_int);
+	queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
+}
+
+static void spu_gov_init_work(struct spu_gov_info_struct *info)
+{
+	int delay = usecs_to_jiffies(info->poll_int);
+	INIT_DELAYED_WORK_DEFERRABLE(&info->work, spu_gov_work);
+	queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
+}
+
+static void spu_gov_cancel_work(struct spu_gov_info_struct *info)
+{
+	cancel_delayed_work_sync(&info->work);
+}
+
+static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
+{
+	unsigned int cpu = policy->cpu;
+	struct spu_gov_info_struct *info, *affected_info;
+	int i;
+	int ret = 0;
+
+	info = &per_cpu(spu_gov_info, cpu);
+
+	switch (event) {
+	case CPUFREQ_GOV_START:
+		if (!cpu_online(cpu)) {
+			printk(KERN_ERR "cpu %d is not online\n", cpu);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!policy->cur) {
+			printk(KERN_ERR "no cpu specified in policy\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		/* initialize spu_gov_info for all affected cpus */
+		for_each_cpu_mask(i, policy->cpus) {
+			affected_info = &per_cpu(spu_gov_info, i);
+			affected_info->policy = policy;
+		}
+
+		info->poll_int = POLL_TIME;
+
+		/* setup timer */
+		spu_gov_init_work(info);
+
+		break;
+
+	case CPUFREQ_GOV_STOP:
+		/* cancel timer */
+		spu_gov_cancel_work(info);
+
+		/* clean spu_gov_info for all affected cpus */
+		for_each_cpu_mask (i, policy->cpus) {
+			info = &per_cpu(spu_gov_info, i);
+			info->policy = NULL;
+		}
+
+		break;
+	}
+
+	return ret;
+}
+
+static struct cpufreq_governor spu_governor = {
+	.name = "spu_governor",
+	.governor = spu_gov_govern,
+	.owner = THIS_MODULE,
+};
+
+/*
+ * module init and destoy
+ */
+
+static int __init spu_gov_init(void)
+{
+	int ret;
+
+	kspugov_wq = create_workqueue("kspugov");
+	if (!kspugov_wq) {
+		printk(KERN_ERR "creation of kspugov failed\n");
+		ret = -EFAULT;
+		goto out;
+	}
+
+	ret = cpufreq_register_governor(&spu_governor);
+	if (ret) {
+		printk(KERN_ERR "registration of governor failed\n");
+		destroy_workqueue(kspugov_wq);
+		goto out;
+	}
+out:
+	return ret;
+}
+
+static void __exit spu_gov_exit(void)
+{
+	cpufreq_unregister_governor(&spu_governor);
+	destroy_workqueue(kspugov_wq);
+}
+
+
+module_init(spu_gov_init);
+module_exit(spu_gov_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
+
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 06/11] powerpc: Add struct iommu_table argument to iommu_map_sg()
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (4 preceding siblings ...)
  2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces arnd
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Make iommu_map_sg take a struct iommu_table. It did so before commit
740c3ce66700640a6e6136ff679b067e92125794 (iommu sg merging: ppc: make
iommu respect the segment size limits).

This stops the function looking in the archdata.dma_data for the iommu
table because in the future it will be called with a device that has
no table there.

This also has the nice side effect of making iommu_map_sg() match the
other map functions.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/kernel/dma_64.c |    2 +-
 arch/powerpc/kernel/iommu.c  |    7 +++----
 include/asm-powerpc/iommu.h  |    6 +++---
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 3a317cb..7397445 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -68,7 +68,7 @@ static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
 static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
 			    int nelems, enum dma_data_direction direction)
 {
-	return iommu_map_sg(dev, sglist, nelems,
+	return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
 			    device_to_mask(dev), direction);
 }
 
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 0c66366..ccf00fe 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -267,11 +267,10 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 	spin_unlock_irqrestore(&(tbl->it_lock), flags);
 }
 
-int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
-		 int nelems, unsigned long mask,
-		 enum dma_data_direction direction)
+int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+		 struct scatterlist *sglist, int nelems,
+		 unsigned long mask, enum dma_data_direction direction)
 {
-	struct iommu_table *tbl = dev->archdata.dma_data;
 	dma_addr_t dma_next = 0, dma_addr;
 	unsigned long flags;
 	struct scatterlist *s, *outs, *segstart;
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 852e15f..65f6682 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -79,9 +79,9 @@ extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
 					    int nid);
 
-extern int iommu_map_sg(struct device *dev, struct scatterlist *sglist,
-			int nelems, unsigned long mask,
-			enum dma_data_direction direction);
+extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+			struct scatterlist *sglist, int nelems,
+			unsigned long mask, enum dma_data_direction direction);
 extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 			   int nelems, enum dma_data_direction direction);
 
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (5 preceding siblings ...)
  2008-07-04 19:05 ` [patch 06/11] powerpc: Add struct iommu_table argument to iommu_map_sg() arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-07  5:27   ` Benjamin Herrenschmidt
  2008-07-04 19:05 ` [patch 08/11] powerpc/dma: use the struct dma_attrs in iommu code arnd
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Update powerpc to use the new dma_*map*_attrs() interfaces. In doing so
update struct dma_mapping_ops to accept a struct dma_attrs and propagate
these changes through to all users of the code (generic IOMMU and the
64bit DMA code, and the iseries and ps3 platform code).

The old dma_*map_*() interfaces are reimplemented as calls to the
corresponding new interfaces.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/Kconfig                    |    1 +
 arch/powerpc/kernel/dma_64.c            |   34 ++++++---
 arch/powerpc/kernel/ibmebus.c           |   12 ++-
 arch/powerpc/kernel/iommu.c             |   11 ++-
 arch/powerpc/platforms/iseries/iommu.c  |    4 +-
 arch/powerpc/platforms/ps3/system-bus.c |   17 +++--
 include/asm-powerpc/dma-mapping.h       |  116 +++++++++++++++++++++++--------
 include/asm-powerpc/iommu.h             |   12 ++-
 8 files changed, 144 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f2a0f50..462c86a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -110,6 +110,7 @@ config PPC
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
 	select HAVE_LMB
+	select HAVE_DMA_ATTRS
 
 config EARLY_PRINTK
 	bool
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 7397445..3ae0c35 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -50,32 +50,38 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size,
  */
 static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
 				       size_t size,
-				       enum dma_data_direction direction)
+				       enum dma_data_direction direction,
+				       struct dma_attrs *attrs)
 {
 	return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size,
-			        device_to_mask(dev), direction);
+				device_to_mask(dev), direction, attrs);
 }
 
 
 static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
 				   size_t size,
-				   enum dma_data_direction direction)
+				   enum dma_data_direction direction,
+				   struct dma_attrs *attrs)
 {
-	iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
+	iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction,
+			   attrs);
 }
 
 
 static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
-			    int nelems, enum dma_data_direction direction)
+			    int nelems, enum dma_data_direction direction,
+			    struct dma_attrs *attrs)
 {
 	return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
-			    device_to_mask(dev), direction);
+			    device_to_mask(dev), direction, attrs);
 }
 
 static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
+		int nelems, enum dma_data_direction direction,
+		struct dma_attrs *attrs)
 {
-	iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
+	iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction,
+		       attrs);
 }
 
 /* We support DMA to/from any memory page via the iommu */
@@ -148,19 +154,22 @@ static void dma_direct_free_coherent(struct device *dev, size_t size,
 
 static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
 					size_t size,
-					enum dma_data_direction direction)
+					enum dma_data_direction direction,
+					struct dma_attrs *attrs)
 {
 	return virt_to_abs(ptr) + get_dma_direct_offset(dev);
 }
 
 static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
 				    size_t size,
-				    enum dma_data_direction direction)
+				    enum dma_data_direction direction,
+				    struct dma_attrs *attrs)
 {
 }
 
 static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
-			     int nents, enum dma_data_direction direction)
+			     int nents, enum dma_data_direction direction,
+			     struct dma_attrs *attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -174,7 +183,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
 }
 
 static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction)
+				int nents, enum dma_data_direction direction,
+				struct dma_attrs *attrs)
 {
 }
 
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 9971159..e3b1fcd 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -82,7 +82,8 @@ static void ibmebus_free_coherent(struct device *dev,
 static dma_addr_t ibmebus_map_single(struct device *dev,
 				     void *ptr,
 				     size_t size,
-				     enum dma_data_direction direction)
+				     enum dma_data_direction direction,
+				     struct dma_attrs *attrs)
 {
 	return (dma_addr_t)(ptr);
 }
@@ -90,14 +91,16 @@ static dma_addr_t ibmebus_map_single(struct device *dev,
 static void ibmebus_unmap_single(struct device *dev,
 				 dma_addr_t dma_addr,
 				 size_t size,
-				 enum dma_data_direction direction)
+				 enum dma_data_direction direction,
+				 struct dma_attrs *attrs)
 {
 	return;
 }
 
 static int ibmebus_map_sg(struct device *dev,
 			  struct scatterlist *sgl,
-			  int nents, enum dma_data_direction direction)
+			  int nents, enum dma_data_direction direction,
+			  struct dma_attrs *attrs)
 {
 	struct scatterlist *sg;
 	int i;
@@ -112,7 +115,8 @@ static int ibmebus_map_sg(struct device *dev,
 
 static void ibmebus_unmap_sg(struct device *dev,
 			     struct scatterlist *sg,
-			     int nents, enum dma_data_direction direction)
+			     int nents, enum dma_data_direction direction,
+			     struct dma_attrs *attrs)
 {
 	return;
 }
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index ccf00fe..8c68ee9 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -269,7 +269,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 
 int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 		 struct scatterlist *sglist, int nelems,
-		 unsigned long mask, enum dma_data_direction direction)
+		 unsigned long mask, enum dma_data_direction direction,
+		 struct dma_attrs *attrs)
 {
 	dma_addr_t dma_next = 0, dma_addr;
 	unsigned long flags;
@@ -411,7 +412,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 
 
 void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
+		int nelems, enum dma_data_direction direction,
+		struct dma_attrs *attrs)
 {
 	struct scatterlist *sg;
 	unsigned long flags;
@@ -553,7 +555,7 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
  */
 dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
 			    void *vaddr, size_t size, unsigned long mask,
-			    enum dma_data_direction direction)
+		enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 	dma_addr_t dma_handle = DMA_ERROR_CODE;
 	unsigned long uaddr;
@@ -586,7 +588,8 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
 }
 
 void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction direction)
+		size_t size, enum dma_data_direction direction,
+		struct dma_attrs *attrs)
 {
 	unsigned int npages;
 
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 11fa3c7..ab5d868 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -214,13 +214,13 @@ dma_addr_t iseries_hv_map(void *vaddr, size_t size,
 			enum dma_data_direction direction)
 {
 	return iommu_map_single(NULL, &vio_iommu_table, vaddr, size,
-				DMA_32BIT_MASK, direction);
+				DMA_32BIT_MASK, direction, NULL);
 }
 
 void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
 			enum dma_data_direction direction)
 {
-	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
+	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL);
 }
 
 void __init iommu_vio_init(void)
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 43c493f..526cf14 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -550,7 +550,7 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
  */
 
 static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
-	enum dma_data_direction direction)
+	enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 	int result;
@@ -570,7 +570,8 @@ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
 
 static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
 				      size_t size,
-				      enum dma_data_direction direction)
+				      enum dma_data_direction direction,
+				      struct dma_attrs *attrs)
 {
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 	int result;
@@ -603,7 +604,7 @@ static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
 }
 
 static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
-	size_t size, enum dma_data_direction direction)
+	size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
 	int result;
@@ -617,7 +618,7 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
 }
 
 static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
-	int nents, enum dma_data_direction direction)
+	int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 #if defined(CONFIG_PS3_DYNAMIC_DMA)
 	BUG_ON("do");
@@ -646,14 +647,15 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
 
 static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
 			   int nents,
-			   enum dma_data_direction direction)
+			   enum dma_data_direction direction,
+			   struct dma_attrs *attrs)
 {
 	BUG();
 	return 0;
 }
 
 static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
-	int nents, enum dma_data_direction direction)
+	int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
 #if defined(CONFIG_PS3_DYNAMIC_DMA)
 	BUG_ON("do");
@@ -661,7 +663,8 @@ static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
 }
 
 static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
-			    int nents, enum dma_data_direction direction)
+			    int nents, enum dma_data_direction direction,
+			    struct dma_attrs *attrs)
 {
 	BUG();
 }
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index bbefb69..de13950 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -13,6 +13,7 @@
 /* need struct page definitions */
 #include <linux/mm.h>
 #include <linux/scatterlist.h>
+#include <linux/dma-attrs.h>
 #include <asm/io.h>
 
 #define DMA_ERROR_CODE		(~(dma_addr_t)0x0)
@@ -53,13 +54,17 @@ struct dma_mapping_ops {
 	void		(*free_coherent)(struct device *dev, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 	dma_addr_t	(*map_single)(struct device *dev, void *ptr,
-				size_t size, enum dma_data_direction direction);
+				size_t size, enum dma_data_direction direction,
+				struct dma_attrs *attrs);
 	void		(*unmap_single)(struct device *dev, dma_addr_t dma_addr,
-				size_t size, enum dma_data_direction direction);
+				size_t size, enum dma_data_direction direction,
+				struct dma_attrs *attrs);
 	int		(*map_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction);
+				int nents, enum dma_data_direction direction,
+				struct dma_attrs *attrs);
 	void		(*unmap_sg)(struct device *dev, struct scatterlist *sg,
-				int nents, enum dma_data_direction direction);
+				int nents, enum dma_data_direction direction,
+				struct dma_attrs *attrs);
 	int		(*dma_supported)(struct device *dev, u64 mask);
 	int		(*set_dma_mask)(struct device *dev, u64 dma_mask);
 };
@@ -109,6 +114,77 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
 	return 0;
 }
 
+static inline dma_addr_t dma_map_single_attrs(struct device *dev,
+					      void *cpu_addr,
+					      size_t size,
+					      enum dma_data_direction direction,
+					      struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	return dma_ops->map_single(dev, cpu_addr, size, direction, attrs);
+}
+
+static inline void dma_unmap_single_attrs(struct device *dev,
+					  dma_addr_t dma_addr,
+					  size_t size,
+					  enum dma_data_direction direction,
+					  struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
+}
+
+static inline dma_addr_t dma_map_page_attrs(struct device *dev,
+					    struct page *page,
+					    unsigned long offset, size_t size,
+					    enum dma_data_direction direction,
+					    struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	return dma_ops->map_single(dev, page_address(page) + offset, size,
+			direction, attrs);
+}
+
+static inline void dma_unmap_page_attrs(struct device *dev,
+					dma_addr_t dma_address,
+					size_t size,
+					enum dma_data_direction direction,
+					struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
+}
+
+static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
+				   int nents, enum dma_data_direction direction,
+				   struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	return dma_ops->map_sg(dev, sg, nents, direction, attrs);
+}
+
+static inline void dma_unmap_sg_attrs(struct device *dev,
+				      struct scatterlist *sg,
+				      int nhwentries,
+				      enum dma_data_direction direction,
+				      struct dma_attrs *attrs)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	BUG_ON(!dma_ops);
+	dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
+}
+
 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
 				       dma_addr_t *dma_handle, gfp_t flag)
 {
@@ -131,63 +207,43 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
 					size_t size,
 					enum dma_data_direction direction)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	return dma_ops->map_single(dev, cpu_addr, size, direction);
+	return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL);
 }
 
 static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
 				    size_t size,
 				    enum dma_data_direction direction)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	dma_ops->unmap_single(dev, dma_addr, size, direction);
+	dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL);
 }
 
 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)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	return dma_ops->map_single(dev, page_address(page) + offset, size,
-			direction);
+	return dma_map_page_attrs(dev, page, offset, size, direction, NULL);
 }
 
 static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
 				  size_t size,
 				  enum dma_data_direction direction)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	dma_ops->unmap_single(dev, dma_address, size, direction);
+	dma_unmap_page_attrs(dev, dma_address, size, direction, NULL);
 }
 
 static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
 			     int nents, enum dma_data_direction direction)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	return dma_ops->map_sg(dev, sg, nents, direction);
+	return dma_map_sg_attrs(dev, sg, nents, direction, NULL);
 }
 
 static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
 				int nhwentries,
 				enum dma_data_direction direction)
 {
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	BUG_ON(!dma_ops);
-	dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+	dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
 }
 
-
 /*
  * Available generic sets of operations
  */
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 65f6682..51ecfef 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -81,9 +81,11 @@ extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
 
 extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 			struct scatterlist *sglist, int nelems,
-			unsigned long mask, enum dma_data_direction direction);
+			unsigned long mask, enum dma_data_direction direction,
+			struct dma_attrs *attrs);
 extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
-			   int nelems, enum dma_data_direction direction);
+			   int nelems, enum dma_data_direction direction,
+			   struct dma_attrs *attrs);
 
 extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
 				  size_t size, dma_addr_t *dma_handle,
@@ -92,9 +94,11 @@ extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
 				void *vaddr, dma_addr_t dma_handle);
 extern dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
 				   void *vaddr, size_t size, unsigned long mask,
-				   enum dma_data_direction direction);
+				   enum dma_data_direction direction,
+				   struct dma_attrs *attrs);
 extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
-			       size_t size, enum dma_data_direction direction);
+			       size_t size, enum dma_data_direction direction,
+			       struct dma_attrs *attrs);
 
 extern void iommu_init_early_pSeries(void);
 extern void iommu_init_early_iSeries(void);
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 08/11] powerpc/dma: use the struct dma_attrs in iommu code
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (6 preceding siblings ...)
  2008-07-04 19:05 ` [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 09/11] powerpc/cell: cell_dma_dev_setup_iommu() return the iommu table arnd
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Update iommu_alloc() to take the struct dma_attrs and pass them on to
tce_build(). This change propagates down to the tce_build functions of
all the platforms.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/kernel/iommu.c            |   13 ++++++++-----
 arch/powerpc/platforms/cell/iommu.c    |    5 +++--
 arch/powerpc/platforms/iseries/iommu.c |    3 ++-
 arch/powerpc/platforms/pasemi/iommu.c  |    3 ++-
 arch/powerpc/platforms/pseries/iommu.c |   14 +++++++++-----
 arch/powerpc/sysdev/dart_iommu.c       |    3 ++-
 include/asm-powerpc/machdep.h          |    3 ++-
 7 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 8c68ee9..2385f68 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -186,7 +186,8 @@ static unsigned long iommu_range_alloc(struct device *dev,
 static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
 			      void *page, unsigned int npages,
 			      enum dma_data_direction direction,
-			      unsigned long mask, unsigned int align_order)
+			      unsigned long mask, unsigned int align_order,
+			      struct dma_attrs *attrs)
 {
 	unsigned long entry, flags;
 	dma_addr_t ret = DMA_ERROR_CODE;
@@ -205,7 +206,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
 
 	/* Put the TCEs in the HW table */
 	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK,
-			 direction);
+			 direction, attrs);
 
 
 	/* Flush/invalidate TLB caches if necessary */
@@ -336,7 +337,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 			    npages, entry, dma_addr);
 
 		/* Insert into HW table */
-		ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction);
+		ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK,
+				 direction, attrs);
 
 		/* If we are in an open segment, try merging */
 		if (segstart != s) {
@@ -573,7 +575,8 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
 			align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
 
 		dma_handle = iommu_alloc(dev, tbl, vaddr, npages, direction,
-					 mask >> IOMMU_PAGE_SHIFT, align);
+					 mask >> IOMMU_PAGE_SHIFT, align,
+					 attrs);
 		if (dma_handle == DMA_ERROR_CODE) {
 			if (printk_ratelimit())  {
 				printk(KERN_INFO "iommu_alloc failed, "
@@ -642,7 +645,7 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
 	nio_pages = size >> IOMMU_PAGE_SHIFT;
 	io_order = get_iommu_order(size);
 	mapping = iommu_alloc(dev, tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
-			      mask >> IOMMU_PAGE_SHIFT, io_order);
+			      mask >> IOMMU_PAGE_SHIFT, io_order, NULL);
 	if (mapping == DMA_ERROR_CODE) {
 		free_pages((unsigned long)ret, order);
 		return NULL;
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 45646b2..b4fe598 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -173,7 +173,8 @@ static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte,
 }
 
 static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
-		unsigned long uaddr, enum dma_data_direction direction)
+		unsigned long uaddr, enum dma_data_direction direction,
+		struct dma_attrs *attrs)
 {
 	int i;
 	unsigned long *io_pte, base_pte;
@@ -519,7 +520,7 @@ cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
 
 	__set_bit(0, window->table.it_map);
 	tce_build_cell(&window->table, window->table.it_offset, 1,
-		       (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
+		       (unsigned long)iommu->pad_page, DMA_TO_DEVICE, NULL);
 	window->table.it_hint = window->table.it_blocksize;
 
 	return window;
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index ab5d868..bc818e4 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -42,7 +42,8 @@
 #include <asm/iseries/iommu.h>
 
 static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
-		unsigned long uaddr, enum dma_data_direction direction)
+		unsigned long uaddr, enum dma_data_direction direction,
+		struct dma_attrs *attrs)
 {
 	u64 rc;
 	u64 tce, rpn;
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 86967bd..70541b7 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -85,7 +85,8 @@ static int iommu_table_iobmap_inited;
 
 static void iobmap_build(struct iommu_table *tbl, long index,
 			 long npages, unsigned long uaddr,
-			 enum dma_data_direction direction)
+			 enum dma_data_direction direction,
+			 struct dma_attrs *attrs)
 {
 	u32 *ip;
 	u32 rpn;
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 9a12908..5377dd4 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -50,7 +50,8 @@
 
 static void tce_build_pSeries(struct iommu_table *tbl, long index,
 			      long npages, unsigned long uaddr,
-			      enum dma_data_direction direction)
+			      enum dma_data_direction direction,
+			      struct dma_attrs *attrs)
 {
 	u64 proto_tce;
 	u64 *tcep;
@@ -95,7 +96,8 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 
 static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				long npages, unsigned long uaddr,
-				enum dma_data_direction direction)
+				enum dma_data_direction direction,
+				struct dma_attrs *attrs)
 {
 	u64 rc;
 	u64 proto_tce, tce;
@@ -127,7 +129,8 @@ static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
 
 static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 				     long npages, unsigned long uaddr,
-				     enum dma_data_direction direction)
+				     enum dma_data_direction direction,
+				     struct dma_attrs *attrs)
 {
 	u64 rc;
 	u64 proto_tce;
@@ -136,7 +139,8 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 	long l, limit;
 
 	if (npages == 1) {
-		tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction);
+		tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+				    direction, attrs);
 		return;
 	}
 
@@ -150,7 +154,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 		/* If allocation fails, fall back to the loop implementation */
 		if (!tcep) {
 			tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
-					    direction);
+					    direction, attrs);
 			return;
 		}
 		__get_cpu_var(tce_page) = tcep;
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 005c2ec..de8c8b5 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -149,7 +149,8 @@ static void dart_flush(struct iommu_table *tbl)
 
 static void dart_build(struct iommu_table *tbl, long index,
 		       long npages, unsigned long uaddr,
-		       enum dma_data_direction direction)
+		       enum dma_data_direction direction,
+		       struct dma_attrs *attrs)
 {
 	unsigned int *dp;
 	unsigned int rpn;
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 9899226..1233d73 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -80,7 +80,8 @@ struct machdep_calls {
 				     long index,
 				     long npages,
 				     unsigned long uaddr,
-				     enum dma_data_direction direction);
+				     enum dma_data_direction direction,
+				     struct dma_attrs *attrs);
 	void		(*tce_free)(struct iommu_table *tbl,
 				    long index,
 				    long npages);
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 09/11] powerpc/cell: cell_dma_dev_setup_iommu() return the iommu table
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (7 preceding siblings ...)
  2008-07-04 19:05 ` [patch 08/11] powerpc/dma: use the struct dma_attrs in iommu code arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 10/11] powerpc: move device_to_mask() to dma-mapping.h arnd
  2008-07-04 19:05 ` [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code arnd
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Make cell_dma_dev_setup_iommu() return a pointer to the struct iommu_table
(or NULL if no table can be found) rather than putting this pointer into
dev->archdata.dma_data (let the caller do that), and rename this function
to cell_get_iommu_table() to reflect this change.

This will allow us to get the iommu table for a device that doesn't have
the table in the archdata.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/platforms/cell/iommu.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index b4fe598..3b70784 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -541,7 +541,7 @@ static unsigned long cell_dma_direct_offset;
 static unsigned long dma_iommu_fixed_base;
 struct dma_mapping_ops dma_iommu_fixed_ops;
 
-static void cell_dma_dev_setup_iommu(struct device *dev)
+static struct iommu_table *cell_get_iommu_table(struct device *dev)
 {
 	struct iommu_window *window;
 	struct cbe_iommu *iommu;
@@ -556,11 +556,11 @@ static void cell_dma_dev_setup_iommu(struct device *dev)
 		printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
 		       archdata->of_node ? archdata->of_node->full_name : "?",
 		       archdata->numa_node);
-		return;
+		return NULL;
 	}
 	window = list_entry(iommu->windows.next, struct iommu_window, list);
 
-	archdata->dma_data = &window->table;
+	return &window->table;
 }
 
 static void cell_dma_dev_setup_fixed(struct device *dev);
@@ -573,7 +573,7 @@ static void cell_dma_dev_setup(struct device *dev)
 	if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
 		cell_dma_dev_setup_fixed(dev);
 	else if (get_pci_dma_ops() == &dma_iommu_ops)
-		cell_dma_dev_setup_iommu(dev);
+		archdata->dma_data = cell_get_iommu_table(dev);
 	else if (get_pci_dma_ops() == &dma_direct_ops)
 		archdata->dma_data = (void *)cell_dma_direct_offset;
 	else
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 10/11] powerpc: move device_to_mask() to dma-mapping.h
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (8 preceding siblings ...)
  2008-07-04 19:05 ` [patch 09/11] powerpc/cell: cell_dma_dev_setup_iommu() return the iommu table arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-04 19:05 ` [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code arnd
  10 siblings, 0 replies; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Move device_to_mask() to dma-mapping.h because we need to use it from
outside dma_64.c in a later patch.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/powerpc/kernel/dma_64.c      |    9 ---------
 include/asm-powerpc/dma-mapping.h |    9 +++++++++
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 3ae0c35..ae5708e 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -15,15 +15,6 @@
  * Generic iommu implementation
  */
 
-static inline unsigned long device_to_mask(struct device *dev)
-{
-	if (dev->dma_mask && *dev->dma_mask)
-		return *dev->dma_mask;
-	/* Assume devices without mask can take 32 bit addresses */
-	return 0xfffffffful;
-}
-
-
 /* Allocates a contiguous real buffer and creates mappings over it.
  * Returns the virtual address of the buffer and sets dma_handle
  * to the dma address (mapping) of the first page.
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index de13950..74c5497 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -45,6 +45,15 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
 #endif /* ! CONFIG_NOT_COHERENT_CACHE */
 
 #ifdef CONFIG_PPC64
+
+static inline unsigned long device_to_mask(struct device *dev)
+{
+	if (dev->dma_mask && *dev->dma_mask)
+		return *dev->dma_mask;
+	/* Assume devices without mask can take 32 bit addresses */
+	return 0xfffffffful;
+}
+
 /*
  * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
  */
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
                   ` (9 preceding siblings ...)
  2008-07-04 19:05 ` [patch 10/11] powerpc: move device_to_mask() to dma-mapping.h arnd
@ 2008-07-04 19:05 ` arnd
  2008-07-05  5:43   ` [Cbe-oss-dev] " Michael Ellerman
  10 siblings, 1 reply; 45+ messages in thread
From: arnd @ 2008-07-04 19:05 UTC (permalink / raw)
  To: Paul Mackerras, Benjamin Herrenschmidt
  Cc: Mark Nelson, linuxppc-dev, cbe-oss-dev

Introduce a new dma attriblue DMA_ATTR_STRONG_ORDERING to use strong ordering
on DMA mappings in the Cell processor. Add the code to the Cell's IOMMU
implementation to use this.

The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
(for both the dynamic and fixed mappings) which enforces strong ordering of
both reads and writes. This patch makes the default behaviour weak ordering
(the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
new DMA_ATTR_STRONG_ORDERING needs to be used.

Dynamic mappings can be weakly or strongly ordered on an individual basis
but the fixed mapping is always weakly ordered.

Signed-off-by: Mark Nelson <markn@au1.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 Documentation/DMA-attributes.txt    |   12 +++++
 arch/powerpc/platforms/cell/iommu.c |   93 ++++++++++++++++++++++++++++++++---
 include/linux/dma-attrs.h           |    1 +
 3 files changed, 99 insertions(+), 7 deletions(-)

diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt
index 6d772f8..f2d2800 100644
--- a/Documentation/DMA-attributes.txt
+++ b/Documentation/DMA-attributes.txt
@@ -22,3 +22,15 @@ ready and available in memory.  The DMA of the "completion indication"
 could race with data DMA.  Mapping the memory used for completion
 indications with DMA_ATTR_WRITE_BARRIER would prevent the race.
 
+
+DMA_ATTR_STRONG_ORDERING
+----------------------
+
+DMA_ATTR_STRONG_ORDERING specifies that previous reads and writes are
+performed in the order in which they're received by the IOMMU; thus
+reads and writes may not pass each other.
+
+Platforms that are strongly ordered by default will ignore this new
+attribute but platforms that are weakly ordered by default should not
+ignore this new attribute. Instead, they should return an error if a
+strongly ordered mapping cannot be used when one is requested.
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 3b70784..7f6ed20 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -194,11 +194,13 @@ static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
 	const unsigned long prot = 0xc48;
 	base_pte =
 		((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R))
-		| IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask);
+		| IOPTE_M | (window->ioid & IOPTE_IOID_Mask);
 #else
-	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW |
+	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M |
 		(window->ioid & IOPTE_IOID_Mask);
 #endif
+	if (unlikely(dma_get_attr(DMA_ATTR_STRONG_ORDERING, attrs)))
+		base_pte |= IOPTE_SO_RW;
 
 	io_pte = (unsigned long *)tbl->it_base + (index - tbl->it_offset);
 
@@ -539,7 +541,6 @@ static struct cbe_iommu *cell_iommu_for_node(int nid)
 static unsigned long cell_dma_direct_offset;
 
 static unsigned long dma_iommu_fixed_base;
-struct dma_mapping_ops dma_iommu_fixed_ops;
 
 static struct iommu_table *cell_get_iommu_table(struct device *dev)
 {
@@ -563,6 +564,85 @@ static struct iommu_table *cell_get_iommu_table(struct device *dev)
 	return &window->table;
 }
 
+static void *dma_fixed_alloc_coherent(struct device *dev, size_t size,
+				      dma_addr_t *dma_handle, gfp_t flag)
+{
+	return dma_direct_ops.alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static void dma_fixed_free_coherent(struct device *dev, size_t size,
+				    void *vaddr, dma_addr_t dma_handle)
+{
+	dma_direct_ops.free_coherent(dev, size, vaddr, dma_handle);
+}
+
+static dma_addr_t dma_fixed_map_single(struct device *dev, void *ptr,
+				       size_t size,
+				       enum dma_data_direction direction,
+				       struct dma_attrs *attrs)
+{
+	if (dma_get_attr(DMA_ATTR_STRONG_ORDERING, attrs))
+		return iommu_map_single(dev, cell_get_iommu_table(dev), ptr,
+					size, device_to_mask(dev), direction,
+					attrs);
+	else
+		return dma_direct_ops.map_single(dev, ptr, size, direction,
+						 attrs);
+}
+
+static void dma_fixed_unmap_single(struct device *dev, dma_addr_t dma_addr,
+				   size_t size,
+				   enum dma_data_direction direction,
+				   struct dma_attrs *attrs)
+{
+	if (dma_get_attr(DMA_ATTR_STRONG_ORDERING, attrs))
+		iommu_unmap_single(cell_get_iommu_table(dev), dma_addr, size,
+				   direction, attrs);
+	else
+		dma_direct_ops.unmap_single(dev, dma_addr, size, direction,
+					    attrs);
+}
+
+static int dma_fixed_map_sg(struct device *dev, struct scatterlist *sg,
+			   int nents, enum dma_data_direction direction,
+			   struct dma_attrs *attrs)
+{
+	if (dma_get_attr(DMA_ATTR_STRONG_ORDERING, attrs))
+		return iommu_map_sg(dev, cell_get_iommu_table(dev), sg, nents,
+				    device_to_mask(dev), direction, attrs);
+	else
+		return dma_direct_ops.map_sg(dev, sg, nents, direction, attrs);
+}
+
+static void dma_fixed_unmap_sg(struct device *dev, struct scatterlist *sg,
+			       int nents, enum dma_data_direction direction,
+			       struct dma_attrs *attrs)
+{
+	if (dma_get_attr(DMA_ATTR_STRONG_ORDERING, attrs))
+		iommu_unmap_sg(cell_get_iommu_table(dev), sg, nents, direction,
+			       attrs);
+	else
+		dma_direct_ops.unmap_sg(dev, sg, nents, direction, attrs);
+}
+
+static int dma_fixed_dma_supported(struct device *dev, u64 mask)
+{
+	return mask == DMA_64BIT_MASK;
+}
+
+static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask);
+
+struct dma_mapping_ops dma_iommu_fixed_ops = {
+	.alloc_coherent = dma_fixed_alloc_coherent,
+	.free_coherent  = dma_fixed_free_coherent,
+	.map_single     = dma_fixed_map_single,
+	.unmap_single   = dma_fixed_unmap_single,
+	.map_sg         = dma_fixed_map_sg,
+	.unmap_sg       = dma_fixed_unmap_sg,
+	.dma_supported  = dma_fixed_dma_supported,
+	.set_dma_mask   = dma_set_mask_and_switch,
+};
+
 static void cell_dma_dev_setup_fixed(struct device *dev);
 
 static void cell_dma_dev_setup(struct device *dev)
@@ -919,9 +999,11 @@ static void cell_iommu_setup_fixed_ptab(struct cbe_iommu *iommu,
 
 	pr_debug("iommu: mapping 0x%lx pages from 0x%lx\n", fsize, fbase);
 
-	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW
+	base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M
 		    | (cell_iommu_get_ioid(np) & IOPTE_IOID_Mask);
 
+	pr_info("IOMMU: Using weak ordering for fixed mapping\n");
+
 	for (uaddr = 0; uaddr < fsize; uaddr += (1 << 24)) {
 		/* Don't touch the dynamic region */
 		ioaddr = uaddr + fbase;
@@ -1037,9 +1119,6 @@ static int __init cell_iommu_fixed_mapping_init(void)
 		cell_iommu_setup_window(iommu, np, dbase, dsize, 0);
 	}
 
-	dma_iommu_fixed_ops = dma_direct_ops;
-	dma_iommu_fixed_ops.set_dma_mask = dma_set_mask_and_switch;
-
 	dma_iommu_ops.set_dma_mask = dma_set_mask_and_switch;
 	set_pci_dma_ops(&dma_iommu_ops);
 
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
index 1677e2b..600fea7 100644
--- a/include/linux/dma-attrs.h
+++ b/include/linux/dma-attrs.h
@@ -12,6 +12,7 @@
  */
 enum dma_attr {
 	DMA_ATTR_WRITE_BARRIER,
+	DMA_ATTR_STRONG_ORDERING,
 	DMA_ATTR_MAX,
 };
 
-- 
1.5.4.3

-- 

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-04 19:05 ` [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code arnd
@ 2008-07-05  5:43   ` Michael Ellerman
  2008-07-05  6:28     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 45+ messages in thread
From: Michael Ellerman @ 2008-07-05  5:43 UTC (permalink / raw)
  To: arnd; +Cc: Paul Mackerras, cbe-oss-dev, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 907 bytes --]

On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:

> Introduce a new dma attriblue DMA_ATTR_STRONG_ORDERING to use strong ordering
> on DMA mappings in the Cell processor. Add the code to the Cell's IOMMU
> implementation to use this.
> 
> The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> (for both the dynamic and fixed mappings) which enforces strong ordering of
> both reads and writes. This patch makes the default behaviour weak ordering
> (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> new DMA_ATTR_STRONG_ORDERING needs to be used.

We're sure that's safe?

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-05  5:43   ` [Cbe-oss-dev] " Michael Ellerman
@ 2008-07-05  6:28     ` Benjamin Herrenschmidt
  2008-07-05 21:51       ` Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-05  6:28 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, arnd

On Sat, 2008-07-05 at 15:43 +1000, Michael Ellerman wrote:
> > The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> > (for both the dynamic and fixed mappings) which enforces strong ordering of
> > both reads and writes. This patch makes the default behaviour weak ordering
> > (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> > new DMA_ATTR_STRONG_ORDERING needs to be used.
> 
> We're sure that's safe?

I'd say it's not...

Ben.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-05  6:28     ` Benjamin Herrenschmidt
@ 2008-07-05 21:51       ` Arnd Bergmann
  2008-07-05 22:20         ` Benjamin Herrenschmidt
  2008-07-07  0:00         ` Michael Ellerman
  0 siblings, 2 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-05 21:51 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev

On Saturday 05 July 2008, Benjamin Herrenschmidt wrote:
> On Sat, 2008-07-05 at 15:43 +1000, Michael Ellerman wrote:
> > > The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> > > (for both the dynamic and fixed mappings) which enforces strong ordering of
> > > both reads and writes. This patch makes the default behaviour weak ordering
> > > (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> > > new DMA_ATTR_STRONG_ORDERING needs to be used.
> > 
> > We're sure that's safe?
> 
> I'd say it's not...

It turned out that the firmware sets up the south bridge to never set the 'S'
bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
existing cell hardware.

This weak ordering gives the same ordering guarantees as the default ordering
for DMA on other PowerPC machines. Setting strong ordering on both the host
bridge *and* the page table will give further ordering guarantees, i.e.
it will make sure that no DMA requests on the bus can ever overtake each
other.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-05 21:51       ` Arnd Bergmann
@ 2008-07-05 22:20         ` Benjamin Herrenschmidt
  2008-07-06 15:15           ` Arnd Bergmann
  2008-07-07  0:00         ` Michael Ellerman
  1 sibling, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-05 22:20 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev

On Sat, 2008-07-05 at 23:51 +0200, Arnd Bergmann wrote:
> 
> It turned out that the firmware sets up the south bridge to never set the 'S'
> bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
> existing cell hardware.
> 
> This weak ordering gives the same ordering guarantees as the default ordering
> for DMA on other PowerPC machines. Setting strong ordering on both the host
> bridge *and* the page table will give further ordering guarantees, i.e.
> it will make sure that no DMA requests on the bus can ever overtake each
> other

I need to look closely at what the various bridge settings are. Drivers
do expect DMA requests from one device to stay in order, at least up to
what's defined in the PCI spec, which is pretty much fully ordered
unless those devices set the PCIe (or X) relaxed ordering attribute.
However, AFAIK, Axon doesn't convey that sort of ordering attributes
from incoming transactions between the PCIe segment and the PLB5.

Ben.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-05 22:20         ` Benjamin Herrenschmidt
@ 2008-07-06 15:15           ` Arnd Bergmann
  0 siblings, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-06 15:15 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev

On Sunday 06 July 2008, Benjamin Herrenschmidt wrote:
> I need to look closely at what the various bridge settings are. Drivers
> do expect DMA requests from one device to stay in order, at least up to
> what's defined in the PCI spec, which is pretty much fully ordered
> unless those devices set the PCIe (or X) relaxed ordering attribute.
> However, AFAIK, Axon doesn't convey that sort of ordering attributes
> from incoming transactions between the PCIe segment and the PLB5.

Yes, it would be very helpful if you can look into this a bit more.
The Axon specification is particularly confusing in this regard and
even though everyone I have asked so far told us that it's totally
fine, an extra person with more insight in the complete picture looking
into this would be good.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-05 21:51       ` Arnd Bergmann
  2008-07-05 22:20         ` Benjamin Herrenschmidt
@ 2008-07-07  0:00         ` Michael Ellerman
  2008-07-07  9:01           ` Arnd Bergmann
  1 sibling, 1 reply; 45+ messages in thread
From: Michael Ellerman @ 2008-07-07  0:00 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Paul Mackerras, cbe-oss-dev, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1243 bytes --]

On Sat, 2008-07-05 at 23:51 +0200, Arnd Bergmann wrote:
> On Saturday 05 July 2008, Benjamin Herrenschmidt wrote:
> > On Sat, 2008-07-05 at 15:43 +1000, Michael Ellerman wrote:
> > > > The current Cell IOMMU implementation sets the IOPTE_SO_RW bits in all IOTPEs
> > > > (for both the dynamic and fixed mappings) which enforces strong ordering of
> > > > both reads and writes. This patch makes the default behaviour weak ordering
> > > > (the IOPTE_SO_RW bits not set) and to request a strongly ordered mapping the
> > > > new DMA_ATTR_STRONG_ORDERING needs to be used.
> > > 
> > > We're sure that's safe?
> > 
> > I'd say it's not...
> 
> It turned out that the firmware sets up the south bridge to never set the 'S'
> bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
> existing cell hardware.

It seems strange to me that the southbridge is allowed to override the
setting in the IOMMU page table, but if that's what the doc says ..

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
@ 2008-07-07  5:12   ` Benjamin Herrenschmidt
  2008-07-07  9:23     ` Christian Krafft
  2008-07-07  5:24   ` [patch 01/11] " Stephen Rothwell
  1 sibling, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-07  5:12 UTC (permalink / raw)
  To: arnd; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Christian Krafft

On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> plain text document attachment
> (0001-powerpc-cell-add-support-for-power-button-of-future.patch)
> This patch adds support for the power button on future IBM cell blades.
> It actually doesn't shut down the machine. Instead it exposes an
> input device /dev/input/event0 to userspace which sends KEY_POWER
> if power button has been pressed.
> haldaemon actually recognizes the button, so a plattform independent acpid
> replacement should handle it correctly.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---

And what if CONFIG_INPUT=n or m ?

Cheers,
Ben.

>  arch/powerpc/platforms/cell/pervasive.c |   70 ++++++++++++++++++++++++++++++-
>  1 files changed, 69 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
> index 8a3631c..e5bd08c 100644
> --- a/arch/powerpc/platforms/cell/pervasive.c
> +++ b/arch/powerpc/platforms/cell/pervasive.c
> @@ -24,8 +24,10 @@
>  #undef DEBUG
>  
>  #include <linux/interrupt.h>
> +#include <linux/input.h>
>  #include <linux/irq.h>
>  #include <linux/percpu.h>
> +#include <linux/platform_device.h>
>  #include <linux/types.h>
>  #include <linux/kallsyms.h>
>  
> @@ -40,6 +42,9 @@
>  
>  static int sysreset_hack;
>  
> +static struct input_dev *button_dev;
> +static struct platform_device *button_pdev;
> +
>  static void cbe_power_save(void)
>  {
>  	unsigned long ctrl, thread_switch_control;
> @@ -105,10 +110,21 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
>  		 */
>  		if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
>  			pmd = cbe_get_cpu_pmd_regs(cpu);
> -			if (in_be64(&pmd->ras_esc_0) & 0xffff) {
> +			if (in_be64(&pmd->ras_esc_0) & 0x0000ffff) {
>  				out_be64(&pmd->ras_esc_0, 0);
>  				return 0;
>  			}
> +			if (in_be64(&pmd->ras_esc_0) & 0x00010000) {
> +				out_be64(&pmd->ras_esc_0, 0);
> +				if (!button_dev)
> +					return 0;
> +
> +				input_report_key(button_dev, KEY_POWER, 1);
> +				input_sync(button_dev);
> +				input_report_key(button_dev, KEY_POWER, 0);
> +				input_sync(button_dev);
> +				return 1;
> +			}
>  		}
>  		break;
>  #ifdef CONFIG_CBE_RAS
> @@ -155,3 +171,55 @@ void __init cbe_pervasive_init(void)
>  	ppc_md.power_save = cbe_power_save;
>  	ppc_md.system_reset_exception = cbe_system_reset_exception;
>  }
> +
> +static int __init cbe_power_button_init(void)
> +{
> +	int ret;
> +	struct input_dev *dev;
> +
> +	if (!sysreset_hack)
> +		return 0;
> +
> +	dev = input_allocate_device();
> +        if (!dev) {
> +		ret = -ENOMEM;
> +                printk(KERN_ERR "%s: Not enough memory\n", __func__);
> +                goto out;
> +        }
> +
> +	set_bit(EV_KEY, dev->evbit);
> +	set_bit(KEY_POWER, dev->keybit);
> +
> +	dev->name = "Power Button";
> +	dev->id.bustype = BUS_HOST;
> +
> +	/* this makes the button look like an acpi power button
> +	 * no clue whether anyone relies on that though */
> +	dev->id.product = 0x02;
> +	dev->phys = "LNXPWRBN/button/input0";
> +
> +	button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
> +	if (IS_ERR(button_pdev)) {
> +		ret = PTR_ERR(button_pdev);
> +		goto out_free_input;
> +	}
> +
> +	dev->dev.parent = &button_pdev->dev;
> +
> +	ret = input_register_device(dev);
> +	if (ret) {
> +                printk(KERN_ERR "%s: Failed to register device\n", __func__);
> +		goto out_free_pdev;
> +        }
> +
> +	button_dev = dev;
> +	return ret;
> +
> +out_free_pdev:
> +	platform_device_unregister(button_pdev);
> +out_free_input:
> +	input_free_device(dev);
> +out:
> +	return ret;
> +}
> +device_initcall(cbe_power_button_init);
> -- 
> 1.5.4.3
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info
  2008-07-04 19:05 ` [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info arnd
@ 2008-07-07  5:19   ` Benjamin Herrenschmidt
  2008-07-07  5:30     ` Stephen Rothwell
  0 siblings, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-07  5:19 UTC (permalink / raw)
  To: arnd; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Christian Krafft

On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> plain text document attachment
> (0004-powerpc-spufs-add-atomic-busy_spus-counter-to-struc.patch)
> As nr_active counter includes also spus waiting for syscalls to return
> we need a seperate counter that only counts spus that are currently running
> on spu side. This counter shall be used by a cpufreq governor that targets
> a frequency dependent from the number of running spus.
> 
> From: Maxim Shchetynin <maxim@de.ibm.com>
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>

This needs your S-O-B, Arnd, and should go via jk.

Cheers,
Ben.

> ---
>  arch/powerpc/platforms/cell/spufs/sched.c |    6 ++++++
>  include/asm-powerpc/spu.h                 |    1 +
>  2 files changed, 7 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
> index e929e70..be77910 100644
> --- a/arch/powerpc/platforms/cell/spufs/sched.c
> +++ b/arch/powerpc/platforms/cell/spufs/sched.c
> @@ -993,6 +993,7 @@ void spuctx_switch_state(struct spu_context *ctx,
>  	struct timespec ts;
>  	struct spu *spu;
>  	enum spu_utilization_state old_state;
> +	int node;
>  
>  	ktime_get_ts(&ts);
>  	curtime = timespec_to_ns(&ts);
> @@ -1014,6 +1015,11 @@ void spuctx_switch_state(struct spu_context *ctx,
>  		spu->stats.times[old_state] += delta;
>  		spu->stats.util_state = new_state;
>  		spu->stats.tstamp = curtime;
> +		node = spu->node;
> +		if (old_state == SPU_UTIL_USER)
> +			atomic_dec(&cbe_spu_info[node].busy_spus);
> +		if (new_state == SPU_UTIL_USER);
> +			atomic_inc(&cbe_spu_info[node].busy_spus);
>  	}
>  }
>  
> diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
> index 99348c1..8b2eb04 100644
> --- a/include/asm-powerpc/spu.h
> +++ b/include/asm-powerpc/spu.h
> @@ -191,6 +191,7 @@ struct cbe_spu_info {
>  	struct list_head spus;
>  	int n_spus;
>  	int nr_active;
> +	atomic_t busy_spus;
>  	atomic_t reserved_spus;
>  };
>  
> -- 
> 1.5.4.3
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
@ 2008-07-07  5:21   ` Benjamin Herrenschmidt
  2008-07-07  5:32     ` Stephen Rothwell
  2008-07-07  9:01     ` [Cbe-oss-dev] " Arnd Bergmann
  2008-07-07  6:24   ` Stephen Rothwell
  2008-07-07 19:56   ` Geoff Levand
  2 siblings, 2 replies; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-07  5:21 UTC (permalink / raw)
  To: arnd; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, Christian Krafft

On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> plain text document attachment
> (0005-powerpc-cell-add-spu-aware-cpufreq-governor.patch)
> This patch adds a cpufreq governor that takes the number of running spus
> into account. It's very similar to the ondemand governor, but not as complex.
> Instead of hacking spu load into the ondemand governor it might be easier to
> have cpufreq accepting multiple governors per cpu in future.
> Don't know if this is the right way, but it would keep the governors simple.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Arnd, your S-O-B ?

Also, there's the question of whether this should also go in
drivers/cpufreq or not and should be reviewed by the cpufreq
maintainer (whoever that is), no ?

Cheers,
Ben.

> ---
>  arch/powerpc/platforms/cell/Kconfig            |   10 ++
>  arch/powerpc/platforms/cell/Makefile           |    1 +
>  arch/powerpc/platforms/cell/cbe_spu_governor.c |  183 ++++++++++++++++++++++++
>  3 files changed, 194 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/platforms/cell/cbe_spu_governor.c
> 
> diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
> index 3959fcf..2dfff9f 100644
> --- a/arch/powerpc/platforms/cell/Kconfig
> +++ b/arch/powerpc/platforms/cell/Kconfig
> @@ -107,6 +107,16 @@ config CBE_CPUFREQ_PMI
>  	  processor will not only be able to run at lower speed,
>  	  but also at lower core voltage.
>  
> +config CBE_CPUFREQ_SPU_GOVERNOR
> +	tristate "CBE frequency scaling based on SPU usage"
> +	depends on SPU_FS
> +	select CBE_CPUFREQ
> +	default m
> +	help
> +	  This governor checks for spu usage to adjust the cpu frequency.
> +	  If no spu is running on a given cpu, that cpu will be throttled to
> +	  the minimal possible frequency.
> +
>  endmenu
>  
>  config OPROFILE_CELL
> diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
> index c2a7e4e..8be5158 100644
> --- a/arch/powerpc/platforms/cell/Makefile
> +++ b/arch/powerpc/platforms/cell/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_CBE_THERM)			+= cbe_thermal.o
>  obj-$(CONFIG_CBE_CPUFREQ_PMI)		+= cbe_cpufreq_pmi.o
>  obj-$(CONFIG_CBE_CPUFREQ)		+= cbe-cpufreq.o
>  cbe-cpufreq-y				+= cbe_cpufreq_pervasive.o cbe_cpufreq.o
> +obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR)	+= cbe_spu_governor.o
>  
>  ifeq ($(CONFIG_SMP),y)
>  obj-$(CONFIG_PPC_CELL_NATIVE)		+= smp.o
> diff --git a/arch/powerpc/platforms/cell/cbe_spu_governor.c b/arch/powerpc/platforms/cell/cbe_spu_governor.c
> new file mode 100644
> index 0000000..7e63009
> --- /dev/null
> +++ b/arch/powerpc/platforms/cell/cbe_spu_governor.c
> @@ -0,0 +1,183 @@
> +/*
> + * spu aware cpufreq governor for the cell processor
> + *
> + * (C) Copyright IBM Corporation 2006-2008
> + *
> + * Author: Christian Krafft <krafft@de.ibm.com>
> + *
> + * 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, or (at your option)
> + * any later version.
> + *
> + * 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. See the
> + * GNU General Public License for more details.
> + *
> + * 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.
> + */
> +
> +#include <linux/cpufreq.h>
> +#include <linux/sched.h>
> +#include <linux/timer.h>
> +#include <linux/workqueue.h>
> +#include <asm/atomic.h>
> +#include <asm/machdep.h>
> +#include <asm/spu.h>
> +
> +#define POLL_TIME	100000		/* in us */
> +#define EXP		753		/* exp(-1) in fixed-point */
> +
> +struct spu_gov_info_struct {
> +	unsigned long busy_spus;	/* fixed-point */
> +	struct cpufreq_policy *policy;
> +	struct delayed_work work;
> +	unsigned int poll_int;		/* us */
> +};
> +static DEFINE_PER_CPU(struct spu_gov_info_struct, spu_gov_info);
> +
> +static struct workqueue_struct *kspugov_wq;
> +
> +static int calc_freq(struct spu_gov_info_struct *info)
> +{
> +	int cpu;
> +	int busy_spus;
> +
> +	cpu = info->policy->cpu;
> +	busy_spus = atomic_read(&cbe_spu_info[cpu_to_node(cpu)].busy_spus);
> +
> +	CALC_LOAD(info->busy_spus, EXP, busy_spus * FIXED_1);
> +	pr_debug(KERN_ERR "cpu %d: busy_spus=%d, info->busy_spus=%d\n", cpu, busy_spus, info->busy_spus);
> +
> +	return info->policy->max * info->busy_spus / FIXED_1;
> +}
> +
> +static void spu_gov_work(struct work_struct *work)
> +{
> +	struct spu_gov_info_struct *info;
> +	int delay;
> +	unsigned long target_freq;
> +
> +	info = container_of(work, struct spu_gov_info_struct, work.work);
> +
> +	/* after cancel_delayed_work_sync we unset info->policy */
> +	BUG_ON(info->policy == NULL);
> +
> +	target_freq = calc_freq(info);
> +	__cpufreq_driver_target(info->policy, target_freq, CPUFREQ_RELATION_H);
> +
> +	delay = usecs_to_jiffies(info->poll_int);
> +	queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
> +}
> +
> +static void spu_gov_init_work(struct spu_gov_info_struct *info)
> +{
> +	int delay = usecs_to_jiffies(info->poll_int);
> +	INIT_DELAYED_WORK_DEFERRABLE(&info->work, spu_gov_work);
> +	queue_delayed_work_on(info->policy->cpu, kspugov_wq, &info->work, delay);
> +}
> +
> +static void spu_gov_cancel_work(struct spu_gov_info_struct *info)
> +{
> +	cancel_delayed_work_sync(&info->work);
> +}
> +
> +static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
> +{
> +	unsigned int cpu = policy->cpu;
> +	struct spu_gov_info_struct *info, *affected_info;
> +	int i;
> +	int ret = 0;
> +
> +	info = &per_cpu(spu_gov_info, cpu);
> +
> +	switch (event) {
> +	case CPUFREQ_GOV_START:
> +		if (!cpu_online(cpu)) {
> +			printk(KERN_ERR "cpu %d is not online\n", cpu);
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		if (!policy->cur) {
> +			printk(KERN_ERR "no cpu specified in policy\n");
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		/* initialize spu_gov_info for all affected cpus */
> +		for_each_cpu_mask(i, policy->cpus) {
> +			affected_info = &per_cpu(spu_gov_info, i);
> +			affected_info->policy = policy;
> +		}
> +
> +		info->poll_int = POLL_TIME;
> +
> +		/* setup timer */
> +		spu_gov_init_work(info);
> +
> +		break;
> +
> +	case CPUFREQ_GOV_STOP:
> +		/* cancel timer */
> +		spu_gov_cancel_work(info);
> +
> +		/* clean spu_gov_info for all affected cpus */
> +		for_each_cpu_mask (i, policy->cpus) {
> +			info = &per_cpu(spu_gov_info, i);
> +			info->policy = NULL;
> +		}
> +
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static struct cpufreq_governor spu_governor = {
> +	.name = "spu_governor",
> +	.governor = spu_gov_govern,
> +	.owner = THIS_MODULE,
> +};
> +
> +/*
> + * module init and destoy
> + */
> +
> +static int __init spu_gov_init(void)
> +{
> +	int ret;
> +
> +	kspugov_wq = create_workqueue("kspugov");
> +	if (!kspugov_wq) {
> +		printk(KERN_ERR "creation of kspugov failed\n");
> +		ret = -EFAULT;
> +		goto out;
> +	}
> +
> +	ret = cpufreq_register_governor(&spu_governor);
> +	if (ret) {
> +		printk(KERN_ERR "registration of governor failed\n");
> +		destroy_workqueue(kspugov_wq);
> +		goto out;
> +	}
> +out:
> +	return ret;
> +}
> +
> +static void __exit spu_gov_exit(void)
> +{
> +	cpufreq_unregister_governor(&spu_governor);
> +	destroy_workqueue(kspugov_wq);
> +}
> +
> +
> +module_init(spu_gov_init);
> +module_exit(spu_gov_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
> +
> -- 
> 1.5.4.3
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
  2008-07-07  5:12   ` Benjamin Herrenschmidt
@ 2008-07-07  5:24   ` Stephen Rothwell
  2008-07-07  8:40     ` [Cbe-oss-dev] " Arnd Bergmann
  1 sibling, 1 reply; 45+ messages in thread
From: Stephen Rothwell @ 2008-07-07  5:24 UTC (permalink / raw)
  To: arnd; +Cc: Paul Mackerras, cbe-oss-dev, Christian Krafft, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 1896 bytes --]

Hi Arnd,

On Fri, 04 Jul 2008 21:05:36 +0200 arnd@arndb.de wrote:
>
> This patch adds support for the power button on future IBM cell blades.
> It actually doesn't shut down the machine. Instead it exposes an
> input device /dev/input/event0 to userspace which sends KEY_POWER
> if power button has been pressed.
> haldaemon actually recognizes the button, so a plattform independent acpid
> replacement should handle it correctly.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Was this written by you or Christian?

> @@ -105,10 +110,21 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
>  		 */
>  		if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
>  			pmd = cbe_get_cpu_pmd_regs(cpu);
> -			if (in_be64(&pmd->ras_esc_0) & 0xffff) {
> +			if (in_be64(&pmd->ras_esc_0) & 0x0000ffff) {
>  				out_be64(&pmd->ras_esc_0, 0);
>  				return 0;
>  			}
> +			if (in_be64(&pmd->ras_esc_0) & 0x00010000) {

Do we really want to read that register twice?  (Just asking, I don't
know how the hardware works ...)  Also, do we want to recognise this bit
even if some lower order bits are set?  (this code won't)

> +static int __init cbe_power_button_init(void)
> +{
> +	int ret;
> +	struct input_dev *dev;
> +
> +	if (!sysreset_hack)
> +		return 0;
> +
> +	dev = input_allocate_device();
> +        if (!dev) {
> +		ret = -ENOMEM;
> +                printk(KERN_ERR "%s: Not enough memory\n", __func__);
> +                goto out;
> +        }

Some white space damage here.

> +	ret = input_register_device(dev);
> +	if (ret) {
> +                printk(KERN_ERR "%s: Failed to register device\n", __func__);
> +		goto out_free_pdev;
> +        }

And here.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces
  2008-07-04 19:05 ` [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces arnd
@ 2008-07-07  5:27   ` Benjamin Herrenschmidt
  2008-07-07 19:15     ` Geoff Levand
  0 siblings, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-07  5:27 UTC (permalink / raw)
  To: Geoff Levand; +Cc: Mark Nelson, linuxppc-dev, Paul Mackerras, cbe-oss-dev

On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> plain text document attachment
> (0007-powerpc-dma-implement-new-dma_-map-_attrs-interfa.patch)
> Update powerpc to use the new dma_*map*_attrs() interfaces. In doing so
> update struct dma_mapping_ops to accept a struct dma_attrs and propagate
> these changes through to all users of the code (generic IOMMU and the
> 64bit DMA code, and the iseries and ps3 platform code).
> 
> The old dma_*map_*() interfaces are reimplemented as calls to the
> corresponding new interfaces.

Geoff, I think the PS3 bits in this patch are ok but I'd like
you to double-check and send your ack if you think they are.

Cheers,
Ben.

> Signed-off-by: Mark Nelson <markn@au1.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
>  arch/powerpc/Kconfig                    |    1 +
>  arch/powerpc/kernel/dma_64.c            |   34 ++++++---
>  arch/powerpc/kernel/ibmebus.c           |   12 ++-
>  arch/powerpc/kernel/iommu.c             |   11 ++-
>  arch/powerpc/platforms/iseries/iommu.c  |    4 +-
>  arch/powerpc/platforms/ps3/system-bus.c |   17 +++--
>  include/asm-powerpc/dma-mapping.h       |  116 +++++++++++++++++++++++--------
>  include/asm-powerpc/iommu.h             |   12 ++-
>  8 files changed, 144 insertions(+), 63 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index f2a0f50..462c86a 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -110,6 +110,7 @@ config PPC
>  	select HAVE_KPROBES
>  	select HAVE_KRETPROBES
>  	select HAVE_LMB
> +	select HAVE_DMA_ATTRS
>  
>  config EARLY_PRINTK
>  	bool
> diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
> index 7397445..3ae0c35 100644
> --- a/arch/powerpc/kernel/dma_64.c
> +++ b/arch/powerpc/kernel/dma_64.c
> @@ -50,32 +50,38 @@ static void dma_iommu_free_coherent(struct device *dev, size_t size,
>   */
>  static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
>  				       size_t size,
> -				       enum dma_data_direction direction)
> +				       enum dma_data_direction direction,
> +				       struct dma_attrs *attrs)
>  {
>  	return iommu_map_single(dev, dev->archdata.dma_data, vaddr, size,
> -			        device_to_mask(dev), direction);
> +				device_to_mask(dev), direction, attrs);
>  }
>  
> 
>  static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
>  				   size_t size,
> -				   enum dma_data_direction direction)
> +				   enum dma_data_direction direction,
> +				   struct dma_attrs *attrs)
>  {
> -	iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
> +	iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction,
> +			   attrs);
>  }
>  
> 
>  static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
> -			    int nelems, enum dma_data_direction direction)
> +			    int nelems, enum dma_data_direction direction,
> +			    struct dma_attrs *attrs)
>  {
>  	return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems,
> -			    device_to_mask(dev), direction);
> +			    device_to_mask(dev), direction, attrs);
>  }
>  
>  static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
> -		int nelems, enum dma_data_direction direction)
> +		int nelems, enum dma_data_direction direction,
> +		struct dma_attrs *attrs)
>  {
> -	iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
> +	iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction,
> +		       attrs);
>  }
>  
>  /* We support DMA to/from any memory page via the iommu */
> @@ -148,19 +154,22 @@ static void dma_direct_free_coherent(struct device *dev, size_t size,
>  
>  static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
>  					size_t size,
> -					enum dma_data_direction direction)
> +					enum dma_data_direction direction,
> +					struct dma_attrs *attrs)
>  {
>  	return virt_to_abs(ptr) + get_dma_direct_offset(dev);
>  }
>  
>  static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
>  				    size_t size,
> -				    enum dma_data_direction direction)
> +				    enum dma_data_direction direction,
> +				    struct dma_attrs *attrs)
>  {
>  }
>  
>  static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
> -			     int nents, enum dma_data_direction direction)
> +			     int nents, enum dma_data_direction direction,
> +			     struct dma_attrs *attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -174,7 +183,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
>  }
>  
>  static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
> -				int nents, enum dma_data_direction direction)
> +				int nents, enum dma_data_direction direction,
> +				struct dma_attrs *attrs)
>  {
>  }
>  
> diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
> index 9971159..e3b1fcd 100644
> --- a/arch/powerpc/kernel/ibmebus.c
> +++ b/arch/powerpc/kernel/ibmebus.c
> @@ -82,7 +82,8 @@ static void ibmebus_free_coherent(struct device *dev,
>  static dma_addr_t ibmebus_map_single(struct device *dev,
>  				     void *ptr,
>  				     size_t size,
> -				     enum dma_data_direction direction)
> +				     enum dma_data_direction direction,
> +				     struct dma_attrs *attrs)
>  {
>  	return (dma_addr_t)(ptr);
>  }
> @@ -90,14 +91,16 @@ static dma_addr_t ibmebus_map_single(struct device *dev,
>  static void ibmebus_unmap_single(struct device *dev,
>  				 dma_addr_t dma_addr,
>  				 size_t size,
> -				 enum dma_data_direction direction)
> +				 enum dma_data_direction direction,
> +				 struct dma_attrs *attrs)
>  {
>  	return;
>  }
>  
>  static int ibmebus_map_sg(struct device *dev,
>  			  struct scatterlist *sgl,
> -			  int nents, enum dma_data_direction direction)
> +			  int nents, enum dma_data_direction direction,
> +			  struct dma_attrs *attrs)
>  {
>  	struct scatterlist *sg;
>  	int i;
> @@ -112,7 +115,8 @@ static int ibmebus_map_sg(struct device *dev,
>  
>  static void ibmebus_unmap_sg(struct device *dev,
>  			     struct scatterlist *sg,
> -			     int nents, enum dma_data_direction direction)
> +			     int nents, enum dma_data_direction direction,
> +			     struct dma_attrs *attrs)
>  {
>  	return;
>  }
> diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
> index ccf00fe..8c68ee9 100644
> --- a/arch/powerpc/kernel/iommu.c
> +++ b/arch/powerpc/kernel/iommu.c
> @@ -269,7 +269,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
>  
>  int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
>  		 struct scatterlist *sglist, int nelems,
> -		 unsigned long mask, enum dma_data_direction direction)
> +		 unsigned long mask, enum dma_data_direction direction,
> +		 struct dma_attrs *attrs)
>  {
>  	dma_addr_t dma_next = 0, dma_addr;
>  	unsigned long flags;
> @@ -411,7 +412,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
>  
> 
>  void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
> -		int nelems, enum dma_data_direction direction)
> +		int nelems, enum dma_data_direction direction,
> +		struct dma_attrs *attrs)
>  {
>  	struct scatterlist *sg;
>  	unsigned long flags;
> @@ -553,7 +555,7 @@ void iommu_free_table(struct iommu_table *tbl, const char *node_name)
>   */
>  dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
>  			    void *vaddr, size_t size, unsigned long mask,
> -			    enum dma_data_direction direction)
> +		enum dma_data_direction direction, struct dma_attrs *attrs)
>  {
>  	dma_addr_t dma_handle = DMA_ERROR_CODE;
>  	unsigned long uaddr;
> @@ -586,7 +588,8 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
>  }
>  
>  void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
> -		size_t size, enum dma_data_direction direction)
> +		size_t size, enum dma_data_direction direction,
> +		struct dma_attrs *attrs)
>  {
>  	unsigned int npages;
>  
> diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
> index 11fa3c7..ab5d868 100644
> --- a/arch/powerpc/platforms/iseries/iommu.c
> +++ b/arch/powerpc/platforms/iseries/iommu.c
> @@ -214,13 +214,13 @@ dma_addr_t iseries_hv_map(void *vaddr, size_t size,
>  			enum dma_data_direction direction)
>  {
>  	return iommu_map_single(NULL, &vio_iommu_table, vaddr, size,
> -				DMA_32BIT_MASK, direction);
> +				DMA_32BIT_MASK, direction, NULL);
>  }
>  
>  void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
>  			enum dma_data_direction direction)
>  {
> -	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
> +	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction, NULL);
>  }
>  
>  void __init iommu_vio_init(void)
> diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
> index 43c493f..526cf14 100644
> --- a/arch/powerpc/platforms/ps3/system-bus.c
> +++ b/arch/powerpc/platforms/ps3/system-bus.c
> @@ -550,7 +550,7 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
>   */
>  
>  static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
> -	enum dma_data_direction direction)
> +	enum dma_data_direction direction, struct dma_attrs *attrs)
>  {
>  	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
>  	int result;
> @@ -570,7 +570,8 @@ static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
>  
>  static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
>  				      size_t size,
> -				      enum dma_data_direction direction)
> +				      enum dma_data_direction direction,
> +				      struct dma_attrs *attrs)
>  {
>  	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
>  	int result;
> @@ -603,7 +604,7 @@ static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr,
>  }
>  
>  static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
> -	size_t size, enum dma_data_direction direction)
> +	size_t size, enum dma_data_direction direction, struct dma_attrs *attrs)
>  {
>  	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
>  	int result;
> @@ -617,7 +618,7 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
>  }
>  
>  static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
> -	int nents, enum dma_data_direction direction)
> +	int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
>  {
>  #if defined(CONFIG_PS3_DYNAMIC_DMA)
>  	BUG_ON("do");
> @@ -646,14 +647,15 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
>  
>  static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg,
>  			   int nents,
> -			   enum dma_data_direction direction)
> +			   enum dma_data_direction direction,
> +			   struct dma_attrs *attrs)
>  {
>  	BUG();
>  	return 0;
>  }
>  
>  static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
> -	int nents, enum dma_data_direction direction)
> +	int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
>  {
>  #if defined(CONFIG_PS3_DYNAMIC_DMA)
>  	BUG_ON("do");
> @@ -661,7 +663,8 @@ static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
>  }
>  
>  static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
> -			    int nents, enum dma_data_direction direction)
> +			    int nents, enum dma_data_direction direction,
> +			    struct dma_attrs *attrs)
>  {
>  	BUG();
>  }
> diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
> index bbefb69..de13950 100644
> --- a/include/asm-powerpc/dma-mapping.h
> +++ b/include/asm-powerpc/dma-mapping.h
> @@ -13,6 +13,7 @@
>  /* need struct page definitions */
>  #include <linux/mm.h>
>  #include <linux/scatterlist.h>
> +#include <linux/dma-attrs.h>
>  #include <asm/io.h>
>  
>  #define DMA_ERROR_CODE		(~(dma_addr_t)0x0)
> @@ -53,13 +54,17 @@ struct dma_mapping_ops {
>  	void		(*free_coherent)(struct device *dev, size_t size,
>  				void *vaddr, dma_addr_t dma_handle);
>  	dma_addr_t	(*map_single)(struct device *dev, void *ptr,
> -				size_t size, enum dma_data_direction direction);
> +				size_t size, enum dma_data_direction direction,
> +				struct dma_attrs *attrs);
>  	void		(*unmap_single)(struct device *dev, dma_addr_t dma_addr,
> -				size_t size, enum dma_data_direction direction);
> +				size_t size, enum dma_data_direction direction,
> +				struct dma_attrs *attrs);
>  	int		(*map_sg)(struct device *dev, struct scatterlist *sg,
> -				int nents, enum dma_data_direction direction);
> +				int nents, enum dma_data_direction direction,
> +				struct dma_attrs *attrs);
>  	void		(*unmap_sg)(struct device *dev, struct scatterlist *sg,
> -				int nents, enum dma_data_direction direction);
> +				int nents, enum dma_data_direction direction,
> +				struct dma_attrs *attrs);
>  	int		(*dma_supported)(struct device *dev, u64 mask);
>  	int		(*set_dma_mask)(struct device *dev, u64 dma_mask);
>  };
> @@ -109,6 +114,77 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask)
>  	return 0;
>  }
>  
> +static inline dma_addr_t dma_map_single_attrs(struct device *dev,
> +					      void *cpu_addr,
> +					      size_t size,
> +					      enum dma_data_direction direction,
> +					      struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	return dma_ops->map_single(dev, cpu_addr, size, direction, attrs);
> +}
> +
> +static inline void dma_unmap_single_attrs(struct device *dev,
> +					  dma_addr_t dma_addr,
> +					  size_t size,
> +					  enum dma_data_direction direction,
> +					  struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	dma_ops->unmap_single(dev, dma_addr, size, direction, attrs);
> +}
> +
> +static inline dma_addr_t dma_map_page_attrs(struct device *dev,
> +					    struct page *page,
> +					    unsigned long offset, size_t size,
> +					    enum dma_data_direction direction,
> +					    struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	return dma_ops->map_single(dev, page_address(page) + offset, size,
> +			direction, attrs);
> +}
> +
> +static inline void dma_unmap_page_attrs(struct device *dev,
> +					dma_addr_t dma_address,
> +					size_t size,
> +					enum dma_data_direction direction,
> +					struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	dma_ops->unmap_single(dev, dma_address, size, direction, attrs);
> +}
> +
> +static inline int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
> +				   int nents, enum dma_data_direction direction,
> +				   struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	return dma_ops->map_sg(dev, sg, nents, direction, attrs);
> +}
> +
> +static inline void dma_unmap_sg_attrs(struct device *dev,
> +				      struct scatterlist *sg,
> +				      int nhwentries,
> +				      enum dma_data_direction direction,
> +				      struct dma_attrs *attrs)
> +{
> +	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> +
> +	BUG_ON(!dma_ops);
> +	dma_ops->unmap_sg(dev, sg, nhwentries, direction, attrs);
> +}
> +
>  static inline void *dma_alloc_coherent(struct device *dev, size_t size,
>  				       dma_addr_t *dma_handle, gfp_t flag)
>  {
> @@ -131,63 +207,43 @@ static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
>  					size_t size,
>  					enum dma_data_direction direction)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	return dma_ops->map_single(dev, cpu_addr, size, direction);
> +	return dma_map_single_attrs(dev, cpu_addr, size, direction, NULL);
>  }
>  
>  static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
>  				    size_t size,
>  				    enum dma_data_direction direction)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	dma_ops->unmap_single(dev, dma_addr, size, direction);
> +	dma_unmap_single_attrs(dev, dma_addr, size, direction, NULL);
>  }
>  
>  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)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	return dma_ops->map_single(dev, page_address(page) + offset, size,
> -			direction);
> +	return dma_map_page_attrs(dev, page, offset, size, direction, NULL);
>  }
>  
>  static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
>  				  size_t size,
>  				  enum dma_data_direction direction)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	dma_ops->unmap_single(dev, dma_address, size, direction);
> +	dma_unmap_page_attrs(dev, dma_address, size, direction, NULL);
>  }
>  
>  static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
>  			     int nents, enum dma_data_direction direction)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	return dma_ops->map_sg(dev, sg, nents, direction);
> +	return dma_map_sg_attrs(dev, sg, nents, direction, NULL);
>  }
>  
>  static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
>  				int nhwentries,
>  				enum dma_data_direction direction)
>  {
> -	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
> -
> -	BUG_ON(!dma_ops);
> -	dma_ops->unmap_sg(dev, sg, nhwentries, direction);
> +	dma_unmap_sg_attrs(dev, sg, nhwentries, direction, NULL);
>  }
>  
> -
>  /*
>   * Available generic sets of operations
>   */
> diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
> index 65f6682..51ecfef 100644
> --- a/include/asm-powerpc/iommu.h
> +++ b/include/asm-powerpc/iommu.h
> @@ -81,9 +81,11 @@ extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
>  
>  extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
>  			struct scatterlist *sglist, int nelems,
> -			unsigned long mask, enum dma_data_direction direction);
> +			unsigned long mask, enum dma_data_direction direction,
> +			struct dma_attrs *attrs);
>  extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
> -			   int nelems, enum dma_data_direction direction);
> +			   int nelems, enum dma_data_direction direction,
> +			   struct dma_attrs *attrs);
>  
>  extern void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl,
>  				  size_t size, dma_addr_t *dma_handle,
> @@ -92,9 +94,11 @@ extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
>  				void *vaddr, dma_addr_t dma_handle);
>  extern dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
>  				   void *vaddr, size_t size, unsigned long mask,
> -				   enum dma_data_direction direction);
> +				   enum dma_data_direction direction,
> +				   struct dma_attrs *attrs);
>  extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
> -			       size_t size, enum dma_data_direction direction);
> +			       size_t size, enum dma_data_direction direction,
> +			       struct dma_attrs *attrs);
>  
>  extern void iommu_init_early_pSeries(void);
>  extern void iommu_init_early_iSeries(void);
> -- 
> 1.5.4.3
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info
  2008-07-07  5:19   ` Benjamin Herrenschmidt
@ 2008-07-07  5:30     ` Stephen Rothwell
  2008-07-07  8:50       ` [Cbe-oss-dev] " Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Stephen Rothwell @ 2008-07-07  5:30 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, arnd, Christian Krafft

[-- Attachment #1: Type: text/plain, Size: 916 bytes --]

On Mon, 07 Jul 2008 15:19:01 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> > plain text document attachment
> > (0004-powerpc-spufs-add-atomic-busy_spus-counter-to-struc.patch)
> > As nr_active counter includes also spus waiting for syscalls to return
> > we need a seperate counter that only counts spus that are currently running
> > on spu side. This counter shall be used by a cpufreq governor that targets
> > a frequency dependent from the number of running spus.
> > 
> > From: Maxim Shchetynin <maxim@de.ibm.com>
> > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> 
> This needs your S-O-B, Arnd, and should go via jk.

And the From line should be the first so the Author is correctly
attributed.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07  5:21   ` Benjamin Herrenschmidt
@ 2008-07-07  5:32     ` Stephen Rothwell
  2008-07-07  9:01     ` [Cbe-oss-dev] " Arnd Bergmann
  1 sibling, 0 replies; 45+ messages in thread
From: Stephen Rothwell @ 2008-07-07  5:32 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, arnd, Christian Krafft

[-- Attachment #1: Type: text/plain, Size: 944 bytes --]

On Mon, 07 Jul 2008 15:21:59 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> > plain text document attachment
> > (0005-powerpc-cell-add-spu-aware-cpufreq-governor.patch)

We probably don't need to know that :-)

> > This patch adds a cpufreq governor that takes the number of running spus
> > into account. It's very similar to the ondemand governor, but not as complex.
> > Instead of hacking spu load into the ondemand governor it might be easier to
> > have cpufreq accepting multiple governors per cpu in future.
> > Don't know if this is the right way, but it would keep the governors simple.
> > 
> > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> 
> Arnd, your S-O-B ?

And a leading From line if it was written by Christian.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
  2008-07-07  5:21   ` Benjamin Herrenschmidt
@ 2008-07-07  6:24   ` Stephen Rothwell
  2008-07-07  8:58     ` [Cbe-oss-dev] " Arnd Bergmann
  2008-07-07 14:59     ` Arnd Bergmann
  2008-07-07 19:56   ` Geoff Levand
  2 siblings, 2 replies; 45+ messages in thread
From: Stephen Rothwell @ 2008-07-07  6:24 UTC (permalink / raw)
  To: arnd; +Cc: Paul Mackerras, cbe-oss-dev, Christian Krafft, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 990 bytes --]

Just a couple of trivial things.

On Fri, 04 Jul 2008 21:05:40 +0200 arnd@arndb.de wrote:
>
> + * (C) Copyright IBM Corporation 2006-2008
      ^^^
You should use ©.

> +#define POLL_TIME	100000		/* in us */
                                              ^
How about μ ?

> +struct spu_gov_info_struct {
> +	unsigned long busy_spus;	/* fixed-point */
> +	struct cpufreq_policy *policy;
> +	struct delayed_work work;
> +	unsigned int poll_int;		/* us */

And again.

> +static int calc_freq(struct spu_gov_info_struct *info)
> +{
> +	int cpu;
> +	int busy_spus;
> +
> +	cpu = info->policy->cpu;
> +	busy_spus = atomic_read(&cbe_spu_info[cpu_to_node(cpu)].busy_spus);
> +
> +	CALC_LOAD(info->busy_spus, EXP, busy_spus * FIXED_1);
> +	pr_debug(KERN_ERR "cpu %d: busy_spus=%d, info->busy_spus=%d\n", cpu, busy_spus, info->busy_spus);

Split this line.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-07  5:24   ` [patch 01/11] " Stephen Rothwell
@ 2008-07-07  8:40     ` Arnd Bergmann
  0 siblings, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07  8:40 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Stephen Rothwell, Christian Krafft, linuxppc-dev

On Monday 07 July 2008, Stephen Rothwell wrote:

> > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> 
> Was this written by you or Christian?

It's from Christian. For some reason, the author is reflected correctly
in my git tree, but git-format-patch/quilt-mail must have lost that
information. I need to check my scripts.
 
> > @@ -105,10 +110,21 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
> >  		 */
> >  		if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
> >  			pmd = cbe_get_cpu_pmd_regs(cpu);
> > -			if (in_be64(&pmd->ras_esc_0) & 0xffff) {
> > +			if (in_be64(&pmd->ras_esc_0) & 0x0000ffff) {
> >  				out_be64(&pmd->ras_esc_0, 0);
> >  				return 0;
> >  			}
> > +			if (in_be64(&pmd->ras_esc_0) & 0x00010000) {
> 
> Do we really want to read that register twice?  (Just asking, I don't
> know how the hardware works ...)  Also, do we want to recognise this bit
> even if some lower order bits are set?  (this code won't)

It would probably be cleaner to read it just once, but it's safe to
read it multiple times. It only gets written by the BMC when a button
gets pressed.

The lower bits are for system-reset, i.e. for entering xmon or kdump,
while the higher bits are for soft power off, and we certainly don't want
to trigger a soft powerp off at the same time as an xmon entry.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info
  2008-07-07  5:30     ` Stephen Rothwell
@ 2008-07-07  8:50       ` Arnd Bergmann
  0 siblings, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07  8:50 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: linuxppc-dev, Stephen Rothwell, Jeremy Kerr

On Monday 07 July 2008, Stephen Rothwell wrote:
> 
> > > From: Maxim Shchetynin <maxim@de.ibm.com>
> > > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> > 
> > This needs your S-O-B, Arnd, and should go via jk.

I noticed the missing S-O-B already after I had sent it, and corrected
it in the git.

Since this patch is a prerequisite for patch 5/11, I'd like to keep them
in order. Jeremy, can you add your Acked-by?

> And the From line should be the first so the Author is correctly
> attributed.

Right, this one again got missing in quilt-mail.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07  6:24   ` Stephen Rothwell
@ 2008-07-07  8:58     ` Arnd Bergmann
  2008-07-07 14:59     ` Arnd Bergmann
  1 sibling, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07  8:58 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Christian Krafft, Stephen Rothwell, linuxppc-dev

On Monday 07 July 2008, Stephen Rothwell wrote:
> > +
> > +=A0=A0=A0=A0=A0CALC_LOAD(info->busy_spus, EXP, busy_spus * FIXED_1);
> > +=A0=A0=A0=A0=A0pr_debug(KERN_ERR "cpu %d: busy_spus=3D%d, info->busy_s=
pus=3D%d\n", cpu, busy_spus, info->busy_spus);
>=20
> Split this line.

Right, also: leave out the KERN_ERR in pr_debug, and use %ld for info->busy=
_spus.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07  5:21   ` Benjamin Herrenschmidt
  2008-07-07  5:32     ` Stephen Rothwell
@ 2008-07-07  9:01     ` Arnd Bergmann
  1 sibling, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07  9:01 UTC (permalink / raw)
  To: cbe-oss-dev, benh; +Cc: linuxppc-dev

On Monday 07 July 2008, Benjamin Herrenschmidt wrote:
> Also, there's the question of whether this should also go in
> drivers/cpufreq or not and should be reviewed by the cpufreq
> maintainer (whoever that is), no ?

Good point. Let's see if Dave Jones has a few cycles for a review
of this.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code
  2008-07-07  0:00         ` Michael Ellerman
@ 2008-07-07  9:01           ` Arnd Bergmann
  0 siblings, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07  9:01 UTC (permalink / raw)
  To: michael; +Cc: Paul Mackerras, cbe-oss-dev, linuxppc-dev

On Monday 07 July 2008, Michael Ellerman wrote:
> 
> > It turned out that the firmware sets up the south bridge to never set the 'S'
> > bit on incoming transactions, which overrides the IOPTE_SO_RW bits, on all
> > existing cell hardware.
> 
> It seems strange to me that the southbridge is allowed to override the
> setting in the IOMMU page table, but if that's what the doc says ..

That's what I thought at first as well, but it actually makes sense:
If the bridge knows that a data packet has been reordered already
by the originator or one of its own busses, there is no point in
enforcing strong ordering at the IOMMU again.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-07  5:12   ` Benjamin Herrenschmidt
@ 2008-07-07  9:23     ` Christian Krafft
       [not found]       ` <20080707184756.16e52677@linux.ibm.com>
  0 siblings, 1 reply; 45+ messages in thread
From: Christian Krafft @ 2008-07-07  9:23 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev, Paul Mackerras, cbe-oss-dev, arnd

On Mon, 07 Jul 2008 15:12:23 +1000
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:

> On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
> > plain text document attachment
> > (0001-powerpc-cell-add-support-for-power-button-of-future.patch)
> > This patch adds support for the power button on future IBM cell blades.
> > It actually doesn't shut down the machine. Instead it exposes an
> > input device /dev/input/event0 to userspace which sends KEY_POWER
> > if power button has been pressed.
> > haldaemon actually recognizes the button, so a plattform independent acpid
> > replacement should handle it correctly.
> > 
> > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > ---
> 
> And what if CONFIG_INPUT=n or m ?
> 
> Cheers,
> Ben.
> 

hm, good point.
Only wrapping with ifdefs will not fix the CONFIG_INPUT=m case.
Have to think about it again, will send an update ...

Cheers,
ck

-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
Linux Kernel Development
IBM Systems & Technology Group
Phone: +49-07031-16-2032

IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaetsfuehung:		Herbert Kircher
Sitz der Gesellschaft:		Boelingen
Registergericht:		Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07  6:24   ` Stephen Rothwell
  2008-07-07  8:58     ` [Cbe-oss-dev] " Arnd Bergmann
@ 2008-07-07 14:59     ` Arnd Bergmann
  2008-07-07 15:35       ` Josh Boyer
  1 sibling, 1 reply; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07 14:59 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Stephen Rothwell, linuxppc-dev

T24gTW9uZGF5IDA3IEp1bHkgMjAwOCwgU3RlcGhlbiBSb3Rod2VsbCB3cm90ZToKPiA+ICsjZGVm
aW5lIFBPTExfVElNRcKgwqDCoMKgMTAwMDAwwqDCoMKgwqDCoMKgwqDCoMKgwqAvKiBpbiB1cyAq
Lwo+IMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKgIMKg
IMKgIMKgIMKgIMKgIMKgIF4KPiBIb3cgYWJvdXQgzrwgPwoKTm90IHN1cmUsIGhvdyBhYm91dCDC
tSBpbnN0ZWFkPyA7LSkKCglBcm5kIDw+PAo=

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07 14:59     ` Arnd Bergmann
@ 2008-07-07 15:35       ` Josh Boyer
  2008-07-07 21:15         ` Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Josh Boyer @ 2008-07-07 15:35 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Stephen Rothwell, cbe-oss-dev, linuxppc-dev

On Mon, 2008-07-07 at 16:59 +0200, Arnd Bergmann wrote:
> On Monday 07 July 2008, Stephen Rothwell wrote:
> > > +#define POLL_TIME    100000          /* in us */
> >                                               ^
> > How about μ ?
> 
> Not sure, how about µ instead? ;-)

Erm... don't get it.  You have identical characters here.

josh

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 01/02] powerpc/cell: cleanup sysreset_hack for IBM cell blades
       [not found]       ` <20080707184756.16e52677@linux.ibm.com>
@ 2008-07-07 16:54         ` Christian Krafft
  2008-07-07 16:56         ` [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future " Christian Krafft
  1 sibling, 0 replies; 45+ messages in thread
From: Christian Krafft @ 2008-07-07 16:54 UTC (permalink / raw)
  To: Christian Krafft; +Cc: cbe-oss-dev, arnd, linuxppc-dev

From: Christian Krafft <krafft@de.ibm.com>

This patch adds a config option for the sysreset_hack used for
IBM Cell blades. The code is moves from pervasive.c into ras.c and
gets it's own init method.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/arch/powerpc/platforms/cell/pervasive.c
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/pervasive.c
+++ linux.git/arch/powerpc/platforms/cell/pervasive.c
@@ -38,8 +38,6 @@
 
 #include "pervasive.h"
 
-static int sysreset_hack;
-
 static void cbe_power_save(void)
 {
 	unsigned long ctrl, thread_switch_control;
@@ -87,9 +85,6 @@ static void cbe_power_save(void)
 
 static int cbe_system_reset_exception(struct pt_regs *regs)
 {
-	int cpu;
-	struct cbe_pmd_regs __iomem *pmd;
-
 	switch (regs->msr & SRR1_WAKEMASK) {
 	case SRR1_WAKEEE:
 		do_IRQ(regs);
@@ -98,19 +93,7 @@ static int cbe_system_reset_exception(st
 		timer_interrupt(regs);
 		break;
 	case SRR1_WAKEMT:
-		/*
-		 * The BMC can inject user triggered system reset exceptions,
-		 * but cannot set the system reset reason in srr1,
-		 * so check an extra register here.
-		 */
-		if (sysreset_hack && (cpu = smp_processor_id()) == 0) {
-			pmd = cbe_get_cpu_pmd_regs(cpu);
-			if (in_be64(&pmd->ras_esc_0) & 0xffff) {
-				out_be64(&pmd->ras_esc_0, 0);
-				return 0;
-			}
-		}
-		break;
+		return cbe_sysreset_hack();
 #ifdef CONFIG_CBE_RAS
 	case SRR1_WAKESYSERR:
 		cbe_system_error_exception(regs);
@@ -134,8 +117,6 @@ void __init cbe_pervasive_init(void)
 	if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
 		return;
 
-	sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
-
 	for_each_possible_cpu(cpu) {
 		struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
 		if (!regs)
@@ -144,12 +125,6 @@ void __init cbe_pervasive_init(void)
 		 /* Enable Pause(0) control bit */
 		out_be64(&regs->pmcr, in_be64(&regs->pmcr) |
 					    CBE_PMD_PAUSE_ZERO_CONTROL);
-
-		/* Enable JTAG system-reset hack */
-		if (sysreset_hack)
-			out_be32(&regs->fir_mode_reg,
-				in_be32(&regs->fir_mode_reg) |
-				CBE_PMD_FIR_MODE_M8);
 	}
 
 	ppc_md.power_save = cbe_power_save;
Index: linux.git/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/Kconfig
+++ linux.git/arch/powerpc/platforms/cell/Kconfig
@@ -83,6 +83,14 @@ config CBE_RAS
 	depends on PPC_CELL_NATIVE
 	default y
 
+config PPC_IBM_CELL_BLADE_BUTTONS
+	bool "IBM Cell Blade Buttons"
+	depends on CBE_RAS && PPC_IBM_CELL_BLADE
+	default y
+	help
+	  Support Buttons on IBM Cell blades. This adds a method to
+	  trigger system reset via front panel pinhole button.
+
 config CBE_THERM
 	tristate "CBE thermal support"
 	default m
Index: linux.git/arch/powerpc/platforms/cell/pervasive.h
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/pervasive.h
+++ linux.git/arch/powerpc/platforms/cell/pervasive.h
@@ -30,4 +30,13 @@ extern void cbe_system_error_exception(s
 extern void cbe_maintenance_exception(struct pt_regs *regs);
 extern void cbe_thermal_exception(struct pt_regs *regs);
 
+#ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
+extern int cbe_sysreset_hack(void);
+#else
+static inline int cbe_sysreset_hack(void)
+{
+	return 1;
+}
+#endif /* CONFIG_PPC_IBM_CELL_BLADE_BUTTONS */
+
 #endif
Index: linux.git/arch/powerpc/platforms/cell/ras.c
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/ras.c
+++ linux.git/arch/powerpc/platforms/cell/ras.c
@@ -230,6 +230,50 @@ static struct notifier_block cbe_ptcal_r
 	.notifier_call = cbe_ptcal_notify_reboot
 };
 
+#ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
+static int sysreset_hack;
+
+static int __init cbe_sysreset_init(void)
+{
+	struct cbe_pmd_regs __iomem *regs;
+
+	sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
+	if (!sysreset_hack)
+		return 0;
+
+	/* Enable JTAG system-reset hack */
+	regs = cbe_get_cpu_pmd_regs(0);
+	if (regs)
+		out_be32(&regs->fir_mode_reg,
+			in_be32(&regs->fir_mode_reg) |
+			CBE_PMD_FIR_MODE_M8);
+
+	return 0;
+}
+device_initcall(cbe_sysreset_init);
+
+int cbe_sysreset_hack(void)
+{
+	struct cbe_pmd_regs __iomem *regs;
+
+	/*
+	 * The BMC can inject user triggered system reset exceptions,
+	 * but cannot set the system reset reason in srr1,
+	 * so check an extra register here.
+	 */
+	if (sysreset_hack && (smp_processor_id() == 0)) {
+		regs = cbe_get_cpu_pmd_regs(0);
+		if (!regs)
+			return 0;
+		if (in_be64(&regs->ras_esc_0) & 0x0000ffff) {
+			out_be64(&regs->ras_esc_0, 0);
+			return 0;
+		}
+	}
+	return 1;
+}
+#endif /* CONFIG_PPC_IBM_CELL_BLADE_BUTTONS */
+
 int __init cbe_ptcal_init(void)
 {
 	int ret;

-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
Linux Kernel Development
IBM Systems & Technology Group
Phone: +49-07031-16-2032

IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaetsfuehung:		Herbert Kircher
Sitz der Gesellschaft:		Boelingen
Registergericht:		Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future IBM cell blades
       [not found]       ` <20080707184756.16e52677@linux.ibm.com>
  2008-07-07 16:54         ` [Cbe-oss-dev] [patch 01/02] powerpc/cell: cleanup sysreset_hack for " Christian Krafft
@ 2008-07-07 16:56         ` Christian Krafft
  2008-07-09  3:35           ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 45+ messages in thread
From: Christian Krafft @ 2008-07-07 16:56 UTC (permalink / raw)
  To: Christian Krafft; +Cc: cbe-oss-dev, arnd, linuxppc-dev

From: Christian Krafft <krafft@de.ibm.com>

This patch adds support for the power button on future IBM cell blades.
It actually doesn't shut down the machine. Instead it exposes an
input device /dev/input/event0 to userspace which sends KEY_POWER
if power button has been pressed.
haldaemon actually recognizes the button, so a plattform independent acpid
replacement should handle it correctly.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Index: linux.git/arch/powerpc/platforms/cell/Kconfig
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/Kconfig
+++ linux.git/arch/powerpc/platforms/cell/Kconfig
@@ -87,9 +87,12 @@ config PPC_IBM_CELL_BLADE_BUTTONS
 	bool "IBM Cell Blade Buttons"
 	depends on CBE_RAS && PPC_IBM_CELL_BLADE
 	default y
+	select INPUT
+	select INPUT_EVDEV
 	help
 	  Support Buttons on IBM Cell blades. This adds a method to
-	  trigger system reset via front panel pinhole button.
+	  trigger system reset via front panel pinhole button and
+	  an input device for the power button.
 
 config CBE_THERM
 	tristate "CBE thermal support"
Index: linux.git/arch/powerpc/platforms/cell/ras.c
===================================================================
--- linux.git.orig/arch/powerpc/platforms/cell/ras.c
+++ linux.git/arch/powerpc/platforms/cell/ras.c
@@ -14,6 +14,11 @@
 #include <linux/smp.h>
 #include <linux/reboot.h>
 
+#ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#endif /* CONFIG_PPC_IBM_CELL_BLADE_BUTTONS */
+
 #include <asm/reg.h>
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -232,31 +237,76 @@ static struct notifier_block cbe_ptcal_r
 
 #ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
 static int sysreset_hack;
+static struct input_dev *button_dev;
+static struct platform_device *button_pdev;
 
 static int __init cbe_sysreset_init(void)
 {
+	int ret = 0;
+	struct input_dev *dev;
 	struct cbe_pmd_regs __iomem *regs;
 
 	sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
 	if (!sysreset_hack)
-		return 0;
+		goto out;
 
 	regs = cbe_get_cpu_pmd_regs(0);
 	if (!regs)
-		return 0;
+		goto out;
 
 	/* Enable JTAG system-reset hack */
 	out_be32(&regs->fir_mode_reg,
 		in_be32(&regs->fir_mode_reg) |
 		CBE_PMD_FIR_MODE_M8);
 
-	return 0;
+	dev = input_allocate_device();
+	if (!dev) {
+		ret = -ENOMEM;
+		printk(KERN_ERR "%s: Not enough memory\n", __func__);
+		goto out;
+	}
+
+	set_bit(EV_KEY, dev->evbit);
+	set_bit(KEY_POWER, dev->keybit);
+
+	dev->name = "Power Button";
+	dev->id.bustype = BUS_HOST;
+
+	/* this makes the button look like an acpi power button
+	 * no clue whether anyone relies on that though */
+	dev->id.product = 0x02;
+	dev->phys = "LNXPWRBN/button/input0";
+
+	button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
+	if (IS_ERR(button_pdev)) {
+		ret = PTR_ERR(button_pdev);
+		goto out_free_input;
+	}
+
+	dev->dev.parent = &button_pdev->dev;
+ 	ret = input_register_device(dev);
+
+	if (ret) {
+		printk(KERN_ERR "%s: Failed to register device\n", __func__);
+		goto out_free_pdev;
+	}
+
+	button_dev = dev;
+	goto out;
+
+out_free_pdev:
+	platform_device_unregister(button_pdev);
+out_free_input:
+	input_free_device(dev);
+out:
+	return ret;
 }
 device_initcall(cbe_sysreset_init);
 
 int cbe_sysreset_hack(void)
 {
 	struct cbe_pmd_regs __iomem *regs;
+	u64 status;
 
 	/*
 	 * The BMC can inject user triggered system reset exceptions,
@@ -267,10 +317,20 @@ int cbe_sysreset_hack(void)
 		regs = cbe_get_cpu_pmd_regs(0);
 		if (!regs)
 			return 0;
-		if (in_be64(&regs->ras_esc_0) & 0x0000ffff) {
+		status = in_be64(&regs->ras_esc_0);
+		if (status & 0x0000ffff) {
 			out_be64(&regs->ras_esc_0, 0);
 			return 0;
 		}
+		if (status & 0x00010000) {
+			out_be64(&regs->ras_esc_0, 0);
+			if (!button_dev)
+				return 0;
+			input_report_key(button_dev, KEY_POWER, 1);
+			input_sync(button_dev);
+			input_report_key(button_dev, KEY_POWER, 0);
+			input_sync(button_dev);
+		}
 	}
 	return 1;
 }

-- 
Mit freundlichen Gruessen,
kind regards,

Christian Krafft
Linux Kernel Development
IBM Systems & Technology Group
Phone: +49-07031-16-2032

IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats:	Martin Jetter
Geschaetsfuehung:		Herbert Kircher
Sitz der Gesellschaft:		Boelingen
Registergericht:		Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces
  2008-07-07  5:27   ` Benjamin Herrenschmidt
@ 2008-07-07 19:15     ` Geoff Levand
  0 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2008-07-07 19:15 UTC (permalink / raw)
  To: benh; +Cc: Mark Nelson, linuxppc-dev, Paul Mackerras, cbe-oss-dev

Benjamin Herrenschmidt wrote:
> On Fri, 2008-07-04 at 21:05 +0200, arnd@arndb.de wrote:
>> plain text document attachment
>> (0007-powerpc-dma-implement-new-dma_-map-_attrs-interfa.patch)
>> Update powerpc to use the new dma_*map*_attrs() interfaces. In doing so
>> update struct dma_mapping_ops to accept a struct dma_attrs and propagate
>> these changes through to all users of the code (generic IOMMU and the
>> 64bit DMA code, and the iseries and ps3 platform code).
>> 
>> The old dma_*map_*() interfaces are reimplemented as calls to the
>> corresponding new interfaces.
> 
> Geoff, I think the PS3 bits in this patch are ok but I'd like
> you to double-check and send your ack if you think they are.


I tested on PS3 with ps3_defconfig, and it works OK.

Acked-by: Geoff Levand <geoffrey.levand@am.sony.com>


>> Signed-off-by: Mark Nelson <markn@au1.ibm.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> ---
>>  arch/powerpc/Kconfig                    |    1 +
>>  arch/powerpc/kernel/dma_64.c            |   34 ++++++---
>>  arch/powerpc/kernel/ibmebus.c           |   12 ++-
>>  arch/powerpc/kernel/iommu.c             |   11 ++-
>>  arch/powerpc/platforms/iseries/iommu.c  |    4 +-
>>  arch/powerpc/platforms/ps3/system-bus.c |   17 +++--
>>  include/asm-powerpc/dma-mapping.h       |  116 +++++++++++++++++++++++--------
>>  include/asm-powerpc/iommu.h             |   12 ++-
>>  8 files changed, 144 insertions(+), 63 deletions(-)

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
  2008-07-07  5:21   ` Benjamin Herrenschmidt
  2008-07-07  6:24   ` Stephen Rothwell
@ 2008-07-07 19:56   ` Geoff Levand
  2 siblings, 0 replies; 45+ messages in thread
From: Geoff Levand @ 2008-07-07 19:56 UTC (permalink / raw)
  To: arnd; +Cc: Paul Mackerras, cbe-oss-dev, Christian Krafft, linuxppc-dev

arnd@arndb.de wrote:
> This patch adds a cpufreq governor that takes the number of running spus
> into account. It's very similar to the ondemand governor, but not as complex.
> Instead of hacking spu load into the ondemand governor it might be easier to
> have cpufreq accepting multiple governors per cpu in future.
> Don't know if this is the right way, but it would keep the governors simple.

I tried your current cell-2.6.git #cell_next branch with ps3_defconfig and
get these. ps3_defconfig has

 CONFIG_CBE_CPUFREQ=m
 CONFIG_CBE_CPUFREQ_SPU_GOVERNOR=m

I'm not sure if this patch is the one that introduced the problem though.
I guess we need to make an adjustment in the Kconfig.  I'll be away the
rest of this week, and will look at it next week if you don't.

-Geoff

cell-2.6/arch/powerpc/platforms/cell/cbe_spu_governor.c: In function 'calc_freq':
cell-2.6/arch/powerpc/platforms/cell/cbe_spu_governor.c:53: warning: format '%d' expects type 'int', but argument 4 has type 'long unsigned int'

ERROR: ".cpufreq_register_governor" [arch/powerpc/platforms/cell/cbe_spu_governor.ko] undefined!
ERROR: ".__cpufreq_driver_target" [arch/powerpc/platforms/cell/cbe_spu_governor.ko] undefined!
ERROR: ".cpufreq_unregister_governor" [arch/powerpc/platforms/cell/cbe_spu_governor.ko] undefined!
ERROR: ".cpufreq_frequency_table_target" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_register_driver" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_frequency_table_verify" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_frequency_table_get_attr" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_notify_transition" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_frequency_table_cpuinfo" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cbe_get_cpu_mic_tm_regs" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cbe_get_cpu_pmd_regs" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_unregister_driver" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!
ERROR: ".cpufreq_frequency_table_put_attr" [arch/powerpc/platforms/cell/cbe-cpufreq.ko] undefined!

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07 15:35       ` Josh Boyer
@ 2008-07-07 21:15         ` Arnd Bergmann
  2008-07-07 21:17           ` Josh Boyer
  0 siblings, 1 reply; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-07 21:15 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Stephen Rothwell, linuxppc-dev

On Monday 07 July 2008, Josh Boyer wrote:
> 0% probability of being spam.
>=20
> Full report:
> No, score=3D-2.6 required=3D5.0 tests=3DAWL,BAYES_00 autolearn=3Dham vers=
ion=3D3.2.4 =C2=A0
> On Mon, 2008-07-07 at 16:59 +0200, Arnd Bergmann wrote:
> > On Monday 07 July 2008, Stephen Rothwell wrote:
> > > > +#define POLL_TIME =C2=A0 =C2=A0100000 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0/* in us */
> > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 ^
> > > How about =CE=BC ?
> >=20
> > Not sure, how about =C2=B5 instead? ;-)
>=20
> Erm... don't get it. =C2=A0You have identical characters here.

That depends on the tool you use to look at it.

Stephen wrote a Unicode character U+03BC from the Greek alphabet part of
unicode, I wrote unicode character U+00B5 from the Latin-1 code page.
In my mail client, latin-1 characters get rendered in the default font,
but it has to change the font for less common scripts.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07 21:15         ` Arnd Bergmann
@ 2008-07-07 21:17           ` Josh Boyer
  2008-07-08  2:40             ` Stephen Rothwell
  0 siblings, 1 reply; 45+ messages in thread
From: Josh Boyer @ 2008-07-07 21:17 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Stephen Rothwell, cbe-oss-dev, linuxppc-dev

On Mon, 2008-07-07 at 23:15 +0200, Arnd Bergmann wrote:
> On Monday 07 July 2008, Josh Boyer wrote:
> > 0% probability of being spam.
> > 
> > Full report:
> > No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.4  
> > On Mon, 2008-07-07 at 16:59 +0200, Arnd Bergmann wrote:
> > > On Monday 07 July 2008, Stephen Rothwell wrote:
> > > > > +#define POLL_TIME    100000          /* in us */
> > > >                                               ^
> > > > How about μ ?
> > > 
> > > Not sure, how about µ instead? ;-)
> > 
> > Erm... don't get it.  You have identical characters here.
> 
> That depends on the tool you use to look at it.
> 
> Stephen wrote a Unicode character U+03BC from the Greek alphabet part of
> unicode, I wrote unicode character U+00B5 from the Latin-1 code page.
> In my mail client, latin-1 characters get rendered in the default font,
> but it has to change the font for less common scripts.

I thought Unicode was supposed to _improve_ stuff like that... ;)

josh

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 05/11] powerpc/cell: add spu aware cpufreq governor
  2008-07-07 21:17           ` Josh Boyer
@ 2008-07-08  2:40             ` Stephen Rothwell
  0 siblings, 0 replies; 45+ messages in thread
From: Stephen Rothwell @ 2008-07-08  2:40 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev, cbe-oss-dev, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 1269 bytes --]

On Mon, 07 Jul 2008 17:17:57 -0400 Josh Boyer <jwboyer@gmail.com> wrote:
>
> On Mon, 2008-07-07 at 23:15 +0200, Arnd Bergmann wrote:
> > On Monday 07 July 2008, Josh Boyer wrote:
> > > 
> > > On Mon, 2008-07-07 at 16:59 +0200, Arnd Bergmann wrote:
> > > > On Monday 07 July 2008, Stephen Rothwell wrote:
> > > > > > +#define POLL_TIME    100000          /* in us */
> > > > >                                               ^
> > > > > How about μ ?
> > > > 
> > > > Not sure, how about µ instead? ;-)
> > > 
> > > Erm... don't get it.  You have identical characters here.
> > 
> > That depends on the tool you use to look at it.
> > 
> > Stephen wrote a Unicode character U+03BC from the Greek alphabet part of
> > unicode, I wrote unicode character U+00B5 from the Latin-1 code page.
> > In my mail client, latin-1 characters get rendered in the default font,
> > but it has to change the font for less common scripts.
> 
> I thought Unicode was supposed to _improve_ stuff like that... ;)

In fact, Arnd was right, I used the Greek letter mu (μ) while he chose the
micro sign (µ).  So, the lartter (Unicode 0x00B5) it should be.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-07 16:56         ` [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future " Christian Krafft
@ 2008-07-09  3:35           ` Benjamin Herrenschmidt
  2008-07-09 13:15             ` Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-09  3:35 UTC (permalink / raw)
  To: Christian Krafft; +Cc: linuxppc-dev, cbe-oss-dev, arnd, Christian Krafft

On Mon, 2008-07-07 at 18:56 +0200, Christian Krafft wrote:
> From: Christian Krafft <krafft@de.ibm.com>
> 
> This patch adds support for the power button on future IBM cell blades.
> It actually doesn't shut down the machine. Instead it exposes an
> input device /dev/input/event0 to userspace which sends KEY_POWER
> if power button has been pressed.
> haldaemon actually recognizes the button, so a plattform independent acpid
> replacement should handle it correctly.
> 
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>

Sorry Christian, i'm still not too happy with this one.

There are two issues at hand here:

 - The use of SELECT, that will be frowned on unfortunately.

 - I'm not too sure it's very safe the way you do it. If I understand
correctly, you can get called for that sysreset at -any- time, including
when interrupts are off right ?

That means potentially, code that has interrupts off will be interrupted
by input_report/input_sync, which is really bad (may corrupt the input
layer internal list management for example).

You could solve both things with a little trick: Have the platform code
just basically set a global flag when the button was pressed and have a
module that depends on INPUT & INPUT_DEV poll for it (slowly pls) and do
the input report.

Ben.

> Index: linux.git/arch/powerpc/platforms/cell/Kconfig
> ===================================================================
> --- linux.git.orig/arch/powerpc/platforms/cell/Kconfig
> +++ linux.git/arch/powerpc/platforms/cell/Kconfig
> @@ -87,9 +87,12 @@ config PPC_IBM_CELL_BLADE_BUTTONS
>  	bool "IBM Cell Blade Buttons"
>  	depends on CBE_RAS && PPC_IBM_CELL_BLADE
>  	default y
> +	select INPUT
> +	select INPUT_EVDEV
>  	help
>  	  Support Buttons on IBM Cell blades. This adds a method to
> -	  trigger system reset via front panel pinhole button.
> +	  trigger system reset via front panel pinhole button and
> +	  an input device for the power button.
>  
>  config CBE_THERM
>  	tristate "CBE thermal support"
> Index: linux.git/arch/powerpc/platforms/cell/ras.c
> ===================================================================
> --- linux.git.orig/arch/powerpc/platforms/cell/ras.c
> +++ linux.git/arch/powerpc/platforms/cell/ras.c
> @@ -14,6 +14,11 @@
>  #include <linux/smp.h>
>  #include <linux/reboot.h>
>  
> +#ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
> +#include <linux/input.h>
> +#include <linux/platform_device.h>
> +#endif /* CONFIG_PPC_IBM_CELL_BLADE_BUTTONS */
> +
>  #include <asm/reg.h>
>  #include <asm/io.h>
>  #include <asm/prom.h>
> @@ -232,31 +237,76 @@ static struct notifier_block cbe_ptcal_r
>  
>  #ifdef CONFIG_PPC_IBM_CELL_BLADE_BUTTONS
>  static int sysreset_hack;
> +static struct input_dev *button_dev;
> +static struct platform_device *button_pdev;
>  
>  static int __init cbe_sysreset_init(void)
>  {
> +	int ret = 0;
> +	struct input_dev *dev;
>  	struct cbe_pmd_regs __iomem *regs;
>  
>  	sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0");
>  	if (!sysreset_hack)
> -		return 0;
> +		goto out;
>  
>  	regs = cbe_get_cpu_pmd_regs(0);
>  	if (!regs)
> -		return 0;
> +		goto out;
>  
>  	/* Enable JTAG system-reset hack */
>  	out_be32(&regs->fir_mode_reg,
>  		in_be32(&regs->fir_mode_reg) |
>  		CBE_PMD_FIR_MODE_M8);
>  
> -	return 0;
> +	dev = input_allocate_device();
> +	if (!dev) {
> +		ret = -ENOMEM;
> +		printk(KERN_ERR "%s: Not enough memory\n", __func__);
> +		goto out;
> +	}
> +
> +	set_bit(EV_KEY, dev->evbit);
> +	set_bit(KEY_POWER, dev->keybit);
> +
> +	dev->name = "Power Button";
> +	dev->id.bustype = BUS_HOST;
> +
> +	/* this makes the button look like an acpi power button
> +	 * no clue whether anyone relies on that though */
> +	dev->id.product = 0x02;
> +	dev->phys = "LNXPWRBN/button/input0";
> +
> +	button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
> +	if (IS_ERR(button_pdev)) {
> +		ret = PTR_ERR(button_pdev);
> +		goto out_free_input;
> +	}
> +
> +	dev->dev.parent = &button_pdev->dev;
> + 	ret = input_register_device(dev);
> +
> +	if (ret) {
> +		printk(KERN_ERR "%s: Failed to register device\n", __func__);
> +		goto out_free_pdev;
> +	}
> +
> +	button_dev = dev;
> +	goto out;
> +
> +out_free_pdev:
> +	platform_device_unregister(button_pdev);
> +out_free_input:
> +	input_free_device(dev);
> +out:
> +	return ret;
>  }
>  device_initcall(cbe_sysreset_init);
>  
>  int cbe_sysreset_hack(void)
>  {
>  	struct cbe_pmd_regs __iomem *regs;
> +	u64 status;
>  
>  	/*
>  	 * The BMC can inject user triggered system reset exceptions,
> @@ -267,10 +317,20 @@ int cbe_sysreset_hack(void)
>  		regs = cbe_get_cpu_pmd_regs(0);
>  		if (!regs)
>  			return 0;
> -		if (in_be64(&regs->ras_esc_0) & 0x0000ffff) {
> +		status = in_be64(&regs->ras_esc_0);
> +		if (status & 0x0000ffff) {
>  			out_be64(&regs->ras_esc_0, 0);
>  			return 0;
>  		}
> +		if (status & 0x00010000) {
> +			out_be64(&regs->ras_esc_0, 0);
> +			if (!button_dev)
> +				return 0;
> +			input_report_key(button_dev, KEY_POWER, 1);
> +			input_sync(button_dev);
> +			input_report_key(button_dev, KEY_POWER, 0);
> +			input_sync(button_dev);
> +		}
>  	}
>  	return 1;
>  }
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-09  3:35           ` Benjamin Herrenschmidt
@ 2008-07-09 13:15             ` Arnd Bergmann
  2008-07-09 20:45               ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-09 13:15 UTC (permalink / raw)
  To: cbe-oss-dev, benh; +Cc: Christian Krafft, Christian Krafft, linuxppc-dev

On Wednesday 09 July 2008, Benjamin Herrenschmidt wrote:
> Sorry Christian, i'm still not too happy with this one.
>=20
> There are two issues at hand here:
>=20
> =A0- The use of SELECT, that will be frowned on unfortunately.

Ok, this should be easy to fix, by making it depend on INPUT
instead, like the ACPI power button does. It's modeled after
that anyway.

> =A0- I'm not too sure it's very safe the way you do it. If I understand
> correctly, you can get called for that sysreset at -any- time, including
> when interrupts are off right ?

Yes, that sounds like a problem.

> That means potentially, code that has interrupts off will be interrupted
> by input_report/input_sync, which is really bad (may corrupt the input
> layer internal list management for example).

I can't think of a case where this can realistically hit us (the blades
don't have any other input devices normally), but of course you are
right that it's broken anyway.

> You could solve both things with a little trick: Have the platform code
> just basically set a global flag when the button was pressed and have a
> module that depends on INPUT & INPUT_DEV poll for it (slowly pls) and do
> the input report.

Ugly, but doable, yes. I wonder if there is a way that we can trigger some
interrupt from system_reset_exception context in order to get around the
polling though. tasklets and workqueues unfortunately won't do us any good
here because they also depend on disabling interrupts.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-09 13:15             ` Arnd Bergmann
@ 2008-07-09 20:45               ` Benjamin Herrenschmidt
  2008-07-10 14:34                 ` Arnd Bergmann
  0 siblings, 1 reply; 45+ messages in thread
From: Benjamin Herrenschmidt @ 2008-07-09 20:45 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Christian Krafft, Christian Krafft, cbe-oss-dev, linuxppc-dev

On Wed, 2008-07-09 at 15:15 +0200, Arnd Bergmann wrote:
> Ugly, but doable, yes. I wonder if there is a way that we can trigger some
> interrupt from system_reset_exception context in order to get around the
> polling though. tasklets and workqueues unfortunately won't do us any good
> here because they also depend on disabling interrupts.

You can trigger a DEC interrupt at any time but you don't have
a nice hook to catch it. You can probably trigger an IPI to yourself
using a special call to the iic, do we have any available number ?

Ben.

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future IBM cell blades
  2008-07-09 20:45               ` Benjamin Herrenschmidt
@ 2008-07-10 14:34                 ` Arnd Bergmann
  0 siblings, 0 replies; 45+ messages in thread
From: Arnd Bergmann @ 2008-07-10 14:34 UTC (permalink / raw)
  To: linuxppc-dev, benh; +Cc: Christian Krafft, cbe-oss-dev, Christian Krafft

On Wednesday 09 July 2008, Benjamin Herrenschmidt wrote:
> On Wed, 2008-07-09 at 15:15 +0200, Arnd Bergmann wrote:
> > Ugly, but doable, yes. I wonder if there is a way that we can trigger some
> > interrupt from system_reset_exception context in order to get around the
> > polling though. tasklets and workqueues unfortunately won't do us any good
> > here because they also depend on disabling interrupts.
> 
> You can trigger a DEC interrupt at any time but you don't have
> a nice hook to catch it. You can probably trigger an IPI to yourself
> using a special call to the iic, do we have any available number ?

Yes, we are only using 4 out of 15 possible IPIs. Probably worth a try,
but it might not be cleaner than your suggested solution.

	Arnd <><

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2008-07-10 14:34 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-04 19:05 [patch 00/11] Cell patches for 2.6.27 arnd
2008-07-04 19:05 ` [patch 01/11] powerpc/cell: add support for power button of future IBM cell blades arnd
2008-07-07  5:12   ` Benjamin Herrenschmidt
2008-07-07  9:23     ` Christian Krafft
     [not found]       ` <20080707184756.16e52677@linux.ibm.com>
2008-07-07 16:54         ` [Cbe-oss-dev] [patch 01/02] powerpc/cell: cleanup sysreset_hack for " Christian Krafft
2008-07-07 16:56         ` [Cbe-oss-dev] [patch 02/02] powerpc/cell: add support for power button of future " Christian Krafft
2008-07-09  3:35           ` Benjamin Herrenschmidt
2008-07-09 13:15             ` Arnd Bergmann
2008-07-09 20:45               ` Benjamin Herrenschmidt
2008-07-10 14:34                 ` Arnd Bergmann
2008-07-07  5:24   ` [patch 01/11] " Stephen Rothwell
2008-07-07  8:40     ` [Cbe-oss-dev] " Arnd Bergmann
2008-07-04 19:05 ` [patch 02/11] powerpc/axonram: use only one block device major number arnd
2008-07-04 19:05 ` [patch 03/11] powerpc/axonram: enable partitioning of the Axons DDR2 DIMMs arnd
2008-07-04 19:05 ` [patch 04/11] powerpc/spufs: add atomic busy_spus counter to struct cbe_spu_info arnd
2008-07-07  5:19   ` Benjamin Herrenschmidt
2008-07-07  5:30     ` Stephen Rothwell
2008-07-07  8:50       ` [Cbe-oss-dev] " Arnd Bergmann
2008-07-04 19:05 ` [patch 05/11] powerpc/cell: add spu aware cpufreq governor arnd
2008-07-07  5:21   ` Benjamin Herrenschmidt
2008-07-07  5:32     ` Stephen Rothwell
2008-07-07  9:01     ` [Cbe-oss-dev] " Arnd Bergmann
2008-07-07  6:24   ` Stephen Rothwell
2008-07-07  8:58     ` [Cbe-oss-dev] " Arnd Bergmann
2008-07-07 14:59     ` Arnd Bergmann
2008-07-07 15:35       ` Josh Boyer
2008-07-07 21:15         ` Arnd Bergmann
2008-07-07 21:17           ` Josh Boyer
2008-07-08  2:40             ` Stephen Rothwell
2008-07-07 19:56   ` Geoff Levand
2008-07-04 19:05 ` [patch 06/11] powerpc: Add struct iommu_table argument to iommu_map_sg() arnd
2008-07-04 19:05 ` [patch 07/11] powerpc/dma: implement new dma_*map*_attrs() interfaces arnd
2008-07-07  5:27   ` Benjamin Herrenschmidt
2008-07-07 19:15     ` Geoff Levand
2008-07-04 19:05 ` [patch 08/11] powerpc/dma: use the struct dma_attrs in iommu code arnd
2008-07-04 19:05 ` [patch 09/11] powerpc/cell: cell_dma_dev_setup_iommu() return the iommu table arnd
2008-07-04 19:05 ` [patch 10/11] powerpc: move device_to_mask() to dma-mapping.h arnd
2008-07-04 19:05 ` [patch 11/11] powerpc/cell: Add DMA_ATTR_STRONG_ORDERING dma attribute and use in IOMMU code arnd
2008-07-05  5:43   ` [Cbe-oss-dev] " Michael Ellerman
2008-07-05  6:28     ` Benjamin Herrenschmidt
2008-07-05 21:51       ` Arnd Bergmann
2008-07-05 22:20         ` Benjamin Herrenschmidt
2008-07-06 15:15           ` Arnd Bergmann
2008-07-07  0:00         ` Michael Ellerman
2008-07-07  9:01           ` Arnd Bergmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).