* [PATCH 01/10] cell: add cbe_node_to_cpu function
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 02/10] cbe_thermal: clean up computation of temperature Arnd Bergmann
` (8 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
This patch adds code to deal with conversion of
logical cpu to cbe nodes. It removes code that
assummed there were two logical CPUs per CBE.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_regs.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_regs.c
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_regs.c
@@ -38,8 +38,13 @@ static struct cbe_thread_map
{
struct device_node *cpu_node;
struct cbe_regs_map *regs;
+ unsigned int thread_id;
+ unsigned int cbe_id;
} cbe_thread_map[NR_CPUS];
+static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = CPU_MASK_NONE };
+static cpumask_t cbe_first_online_cpu = CPU_MASK_NONE;
+
static struct cbe_regs_map *cbe_find_map(struct device_node *np)
{
int i;
@@ -130,31 +135,40 @@ struct cbe_mic_tm_regs __iomem *cbe_get_
}
EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs);
-/* FIXME
- * This is little more than a stub at the moment. It should be
- * fleshed out so that it works for both SMT and non-SMT, no
- * matter if the passed cpu is odd or even.
- * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1.
- * For SMT disabled, returns 0 for all cpus.
- */
u32 cbe_get_hw_thread_id(int cpu)
{
- return (cpu & 1);
+ return cbe_thread_map[cpu].thread_id;
}
EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id);
+u32 cbe_cpu_to_node(int cpu)
+{
+ return cbe_thread_map[cpu].cbe_id;
+}
+EXPORT_SYMBOL_GPL(cbe_cpu_to_node);
+
+u32 cbe_node_to_cpu(int node)
+{
+ return find_first_bit( (unsigned long *) &cbe_local_mask[node], sizeof(cpumask_t));
+}
+EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
+
void __init cbe_regs_init(void)
{
int i;
+ unsigned int thread_id;
struct device_node *cpu;
/* Build local fast map of CPUs */
- for_each_possible_cpu(i)
- cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL);
+ for_each_possible_cpu(i) {
+ cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id);
+ cbe_thread_map[i].thread_id = thread_id;
+ }
/* Find maps for each device tree CPU */
for_each_node_by_type(cpu, "cpu") {
- struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
+ struct cbe_regs_map *map;
+ unsigned int cbe_id;
/* That hack must die die die ! */
const struct address_prop {
@@ -162,6 +176,8 @@ void __init cbe_regs_init(void)
unsigned int len;
} __attribute__((packed)) *prop;
+ cbe_id = cbe_regs_map_count++;
+ map = &cbe_regs_maps[cbe_id];
if (cbe_regs_map_count > MAX_CBE) {
printk(KERN_ERR "cbe_regs: More BE chips than supported"
@@ -170,9 +186,18 @@ void __init cbe_regs_init(void)
return;
}
map->cpu_node = cpu;
- for_each_possible_cpu(i)
- if (cbe_thread_map[i].cpu_node == cpu)
- cbe_thread_map[i].regs = map;
+
+ for_each_possible_cpu(i) {
+ struct cbe_thread_map *thread = &cbe_thread_map[i];
+
+ if (thread->cpu_node == cpu) {
+ thread->regs = map;
+ thread->cbe_id = cbe_id;
+ cpu_set(i, cbe_local_mask[cbe_id]);
+ if(thread->thread_id == 0)
+ cpu_set(i, cbe_first_online_cpu);
+ }
+ }
prop = of_get_property(cpu, "pervasive", NULL);
if (prop != NULL)
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_regs.h
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_regs.h
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_regs.h
@@ -255,6 +255,11 @@ struct cbe_mic_tm_regs {
extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
+/* some utility functions to deal with SMT */
+extern u32 cbe_get_hw_thread_id(int cpu);
+extern u32 cbe_cpu_to_node(int cpu);
+extern u32 cbe_node_to_cpu(int node);
+
/* Init this module early */
extern void cbe_regs_init(void);
Index: linux-2.6/arch/powerpc/oprofile/op_model_cell.c
===================================================================
--- linux-2.6.orig/arch/powerpc/oprofile/op_model_cell.c
+++ linux-2.6/arch/powerpc/oprofile/op_model_cell.c
@@ -37,6 +37,7 @@
#include <asm/system.h>
#include "../platforms/cell/interrupt.h"
+#include "../platforms/cell/cbe_regs.h"
#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */
#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying
Index: linux-2.6/include/asm-powerpc/cell-pmu.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/cell-pmu.h
+++ linux-2.6/include/asm-powerpc/cell-pmu.h
@@ -97,11 +97,6 @@ extern void cbe_disable_pm_interrupts(u3
extern u32 cbe_get_and_clear_pm_interrupts(u32 cpu);
extern void cbe_sync_irq(int node);
-/* Utility functions, macros */
-extern u32 cbe_get_hw_thread_id(int cpu);
-
-#define cbe_cpu_to_node(cpu) ((cpu) >> 1)
-
#define CBE_COUNT_SUPERVISOR_MODE 0
#define CBE_COUNT_HYPERVISOR_MODE 1
#define CBE_COUNT_PROBLEM_MODE 2
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 02/10] cbe_thermal: clean up computation of temperature
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
2007-04-23 19:35 ` [PATCH 01/10] cell: add cbe_node_to_cpu function Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 03/10] cbe_thermal: add throttling attributes to cpu and spu nodes Arnd Bergmann
` (7 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
This patch introduces a little function for transforming
register values into temperature.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_thermal.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_thermal.c
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -31,6 +31,11 @@
#include "cbe_regs.h"
#include "spu_priv1_mmio.h"
+static inline u8 reg_to_temp(u8 reg_value)
+{
+ return ((reg_value & 0x3f) << 1) + 65;
+}
+
static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev)
{
struct spu *spu;
@@ -58,20 +63,14 @@ static u8 spu_read_register_value(struct
static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf)
{
- int value;
+ u8 value;
struct cbe_pmd_regs __iomem *pmd_regs;
pmd_regs = get_pmd_regs(sysdev);
value = spu_read_register_value(sysdev, &pmd_regs->ts_ctsr1);
- /* clear all other bits */
- value &= 0x3F;
- /* temp is stored in steps of 2 degrees */
- value *= 2;
- /* base temp is 65 degrees */
- value += 65;
- return sprintf(buf, "%d\n", (int) value);
+ return sprintf(buf, "%d\n", reg_to_temp(value));
}
static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
@@ -82,16 +81,9 @@ static ssize_t ppe_show_temp(struct sys_
pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id);
value = in_be64(&pmd_regs->ts_ctsr2);
- /* access the corresponding byte */
- value >>= pos;
- /* clear all other bits */
- value &= 0x3F;
- /* temp is stored in steps of 2 degrees */
- value *= 2;
- /* base temp is 65 degrees */
- value += 65;
+ value = (value >> pos) & 0x3f;
- return sprintf(buf, "%d\n", (int) value);
+ return sprintf(buf, "%d\n", reg_to_temp(value));
}
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 03/10] cbe_thermal: add throttling attributes to cpu and spu nodes
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
2007-04-23 19:35 ` [PATCH 01/10] cell: add cbe_node_to_cpu function Arnd Bergmann
2007-04-23 19:35 ` [PATCH 02/10] cbe_thermal: clean up computation of temperature Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 04/10] cell: use pmi in cpufreq driver Arnd Bergmann
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
This patch adds some attributes the cpu and spu nodes:
/sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_begin
/sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_end
/sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_full_stop
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_thermal.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_thermal.c
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -1,6 +1,31 @@
/*
* thermal support for the cell processor
*
+ * This module adds some sysfs attributes to cpu and spu nodes.
+ * Base for measurements are the digital thermal sensors (DTS)
+ * located on the chip.
+ * The accuracy is 2 degrees, starting from 65 up to 125 degrees celsius
+ * The attributes can be found under
+ * /sys/devices/system/cpu/cpuX/thermal
+ * /sys/devices/system/spu/spuX/thermal
+ *
+ * The following attributes are added for each node:
+ * temperature:
+ * contains the current temperature measured by the DTS
+ * throttle_begin:
+ * throttling begins when temperature is greater or equal to
+ * throttle_begin. Setting this value to 125 prevents throttling.
+ * throttle_end:
+ * throttling is being ceased, if the temperature is lower than
+ * throttle_end. Due to a delay between applying throttling and
+ * a reduced temperature this value should be less than throttle_begin.
+ * A value equal to throttle_begin provides only a very little hysteresis.
+ * throttle_full_stop:
+ * If the temperatrue is greater or equal to throttle_full_stop,
+ * full throttling is applied to the cpu or spu. This value should be
+ * greater than throttle_begin and throttle_end. Setting this value to
+ * 65 prevents the unit from running code at all.
+ *
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
*
* Author: Christian Krafft <krafft@de.ibm.com>
@@ -31,9 +56,24 @@
#include "cbe_regs.h"
#include "spu_priv1_mmio.h"
+#define TEMP_MIN 65
+#define TEMP_MAX 125
+
+#define SYSDEV_PREFIX_ATTR(_prefix,_name,_mode) \
+struct sysdev_attribute attr_ ## _prefix ## _ ## _name = { \
+ .attr = { .name = __stringify(_name), .mode = _mode }, \
+ .show = _prefix ## _show_ ## _name, \
+ .store = _prefix ## _store_ ## _name, \
+};
+
static inline u8 reg_to_temp(u8 reg_value)
{
- return ((reg_value & 0x3f) << 1) + 65;
+ return ((reg_value & 0x3f) << 1) + TEMP_MIN;
+}
+
+static inline u8 temp_to_reg(u8 temp)
+{
+ return ((temp - TEMP_MIN) >> 1) & 0x3f;
}
static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev)
@@ -73,6 +113,73 @@ static ssize_t spu_show_temp(struct sys_
return sprintf(buf, "%d\n", reg_to_temp(value));
}
+static ssize_t show_throttle(struct cbe_pmd_regs __iomem *pmd_regs, char *buf, int pos)
+{
+ u64 value;
+
+ value = in_be64(&pmd_regs->tm_tpr.val);
+ /* access the corresponding byte */
+ value >>= pos;
+ value &= 0x3F;
+
+ return sprintf(buf, "%d\n", reg_to_temp(value));
+}
+
+static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char *buf, size_t size, int pos)
+{
+ u64 reg_value;
+ int temp;
+ u64 new_value;
+ int ret;
+
+ ret = sscanf(buf, "%u", &temp);
+
+ if (ret != 1 || temp < TEMP_MIN || temp > TEMP_MAX)
+ return -EINVAL;
+
+ new_value = temp_to_reg(temp);
+
+ reg_value = in_be64(&pmd_regs->tm_tpr.val);
+
+ /* zero out bits for new value */
+ reg_value &= ~(0xffull << pos);
+ /* set bits to new value */
+ reg_value |= new_value << pos;
+
+ out_be64(&pmd_regs->tm_tpr.val, reg_value);
+ return size;
+}
+
+static ssize_t spu_show_throttle_end(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(get_pmd_regs(sysdev), buf, 0);
+}
+
+static ssize_t spu_show_throttle_begin(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(get_pmd_regs(sysdev), buf, 8);
+}
+
+static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(get_pmd_regs(sysdev), buf, 16);
+}
+
+static ssize_t spu_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(get_pmd_regs(sysdev), buf, size, 0);
+}
+
+static ssize_t spu_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(get_pmd_regs(sysdev), buf, size, 8);
+}
+
+static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(get_pmd_regs(sysdev), buf, size, 16);
+}
+
static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
{
struct cbe_pmd_regs __iomem *pmd_regs;
@@ -100,13 +207,52 @@ static ssize_t ppe_show_temp1(struct sys
return ppe_show_temp(sysdev, buf, 0);
}
+static ssize_t ppe_show_throttle_end(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 32);
+}
+
+static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 40);
+}
+
+static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+{
+ return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 48);
+}
+
+static ssize_t ppe_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 32);
+}
+
+static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 40);
+}
+
+static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+{
+ return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 48);
+}
+
+
static struct sysdev_attribute attr_spu_temperature = {
.attr = {.name = "temperature", .mode = 0400 },
.show = spu_show_temp,
};
+static SYSDEV_PREFIX_ATTR(spu, throttle_end, 0600);
+static SYSDEV_PREFIX_ATTR(spu, throttle_begin, 0600);
+static SYSDEV_PREFIX_ATTR(spu, throttle_full_stop, 0600);
+
+
static struct attribute *spu_attributes[] = {
&attr_spu_temperature.attr,
+ &attr_spu_throttle_end.attr,
+ &attr_spu_throttle_begin.attr,
+ &attr_spu_throttle_full_stop.attr,
NULL,
};
@@ -125,9 +271,16 @@ static struct sysdev_attribute attr_ppe_
.show = ppe_show_temp1,
};
+static SYSDEV_PREFIX_ATTR(ppe, throttle_end, 0600);
+static SYSDEV_PREFIX_ATTR(ppe, throttle_begin, 0600);
+static SYSDEV_PREFIX_ATTR(ppe, throttle_full_stop, 0600);
+
static struct attribute *ppe_attributes[] = {
&attr_ppe_temperature0.attr,
&attr_ppe_temperature1.attr,
+ &attr_ppe_throttle_end.attr,
+ &attr_ppe_throttle_begin.attr,
+ &attr_ppe_throttle_full_stop.attr,
NULL,
};
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 04/10] cell: use pmi in cpufreq driver
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (2 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 03/10] cbe_thermal: add throttling attributes to cpu and spu nodes Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 05/10] add check for initialized driver data to pmi driver Arnd Bergmann
` (5 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
The new PMI driver was added in order to support
cpufreq on blades that require the frequency to
be controlled by the service processor, so use it
on those.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_cpufreq.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -28,6 +28,8 @@
#include <asm/processor.h>
#include <asm/prom.h>
#include <asm/time.h>
+#include <asm/pmi.h>
+#include <asm/of_platform.h>
#include "cbe_regs.h"
@@ -68,6 +70,38 @@ static u64 MIC_Slow_Next_Timer_table[] =
* hardware specific functions
*/
+static struct of_device *pmi_dev;
+
+static int set_pmode_pmi(int cpu, unsigned int pmode)
+{
+ int ret;
+ pmi_message_t pmi_msg;
+#ifdef DEBUG
+ u64 time;
+#endif
+
+ pmi_msg.type = PMI_TYPE_FREQ_CHANGE;
+ pmi_msg.data1 = cbe_cpu_to_node(cpu);
+ pmi_msg.data2 = pmode;
+
+#ifdef DEBUG
+ time = (u64) get_cycles();
+#endif
+
+ pmi_send_message(pmi_dev, pmi_msg);
+ ret = pmi_msg.data2;
+
+ pr_debug("PMI returned slow mode %d\n", ret);
+
+#ifdef DEBUG
+ time = (u64) get_cycles() - time; /* actual cycles (not cpu cycles!) */
+ time = 1000000000 * time / CLOCK_TICK_RATE; /* time in ns (10^-9) */
+ pr_debug("had to wait %lu ns for a transition\n", time);
+#endif
+ return ret;
+}
+
+
static int get_pmode(int cpu)
{
int ret;
@@ -79,7 +113,7 @@ static int get_pmode(int cpu)
return ret;
}
-static int set_pmode(int cpu, unsigned int pmode)
+static int set_pmode_reg(int cpu, unsigned int pmode)
{
struct cbe_pmd_regs __iomem *pmd_regs;
struct cbe_mic_tm_regs __iomem *mic_tm_regs;
@@ -120,6 +154,39 @@ static int set_pmode(int cpu, unsigned i
return 0;
}
+static int set_pmode(int cpu, unsigned int slow_mode) {
+ if(pmi_dev)
+ return set_pmode_pmi(cpu, slow_mode);
+ else
+ return set_pmode_reg(cpu, slow_mode);
+}
+
+static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg)
+{
+ struct cpufreq_policy policy;
+ u8 cpu;
+ u8 cbe_pmode_new;
+
+ BUG_ON (pmi_msg.type != PMI_TYPE_FREQ_CHANGE);
+
+ cpu = cbe_node_to_cpu(pmi_msg.data1);
+ cbe_pmode_new = pmi_msg.data2;
+
+ cpufreq_get_policy(&policy, cpu);
+
+ policy.max = min(policy.max, cbe_freqs[cbe_pmode_new].frequency);
+ policy.min = min(policy.min, policy.max);
+
+ pr_debug("cbe_handle_pmi: new policy.min=%d policy.max=%d\n", policy.min, policy.max);
+ cpufreq_set_policy(&policy);
+}
+
+static struct pmi_handler cbe_pmi_handler = {
+ .type = PMI_TYPE_FREQ_CHANGE,
+ .handle_pmi_message = cbe_cpufreq_handle_pmi,
+};
+
+
/*
* cpufreq functions
*/
@@ -234,11 +301,23 @@ static struct cpufreq_driver cbe_cpufreq
static int __init cbe_cpufreq_init(void)
{
+ struct device_node *np;
+
+ np = of_find_node_by_type(NULL, "ibm,pmi");
+
+ pmi_dev = of_find_device_by_node(np);
+
+ if (pmi_dev)
+ pmi_register_handler(pmi_dev, &cbe_pmi_handler);
+
return cpufreq_register_driver(&cbe_cpufreq_driver);
}
static void __exit cbe_cpufreq_exit(void)
{
+ if(pmi_dev)
+ pmi_unregister_handler(pmi_dev, &cbe_pmi_handler);
+
cpufreq_unregister_driver(&cbe_cpufreq_driver);
}
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 05/10] add check for initialized driver data to pmi driver
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (3 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 04/10] cell: use pmi in cpufreq driver Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 06/10] pmi probe device by device-type Arnd Bergmann
` (4 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
This patch adds a check for the private driver data to be initialized.
The bug showed up, as the caller found a pmi device by it's type.
Whereas the pmi driver probes for the type and the name.
Since the name was not as the driver expected, it did not initialize.
A more relaxed probing will be supplied with an extra patch, too.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/sysdev/pmi.c
===================================================================
--- linux-2.6.orig/arch/powerpc/sysdev/pmi.c
+++ linux-2.6/arch/powerpc/sysdev/pmi.c
@@ -279,6 +279,9 @@ void pmi_register_handler(struct of_devi
struct pmi_data *data;
data = device->dev.driver_data;
+ if (!data)
+ return;
+
spin_lock(&data->handler_spinlock);
list_add_tail(&handler->node, &data->handler);
spin_unlock(&data->handler_spinlock);
@@ -289,10 +292,12 @@ void pmi_unregister_handler(struct of_de
struct pmi_handler *handler)
{
struct pmi_data *data;
+ data = device->dev.driver_data;
- pr_debug("pmi: unregistering handler %p\n", handler);
+ if (!data)
+ return;
- data = device->dev.driver_data;
+ pr_debug("pmi: unregistering handler %p\n", handler);
spin_lock(&data->handler_spinlock);
list_del(&handler->node);
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 06/10] pmi probe device by device-type
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (4 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 05/10] add check for initialized driver data to pmi driver Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 07/10] add of_iomap function Arnd Bergmann
` (3 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
At the moment the pmi device driver is probing for devices with
a given type and a given name. As there may be devices of
the same type but with a different name, probing should be
done also for device type only.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/sysdev/pmi.c
===================================================================
--- linux-2.6.orig/arch/powerpc/sysdev/pmi.c
+++ linux-2.6/arch/powerpc/sysdev/pmi.c
@@ -118,6 +118,7 @@ out:
static struct of_device_id pmi_match[] = {
{ .type = "ibm,pmi", .name = "ibm,pmi" },
+ { .type = "ibm,pmi" },
{},
};
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 07/10] add of_iomap function
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (5 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 06/10] pmi probe device by device-type Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-24 1:35 ` Benjamin Herrenschmidt
2007-04-23 19:35 ` [PATCH 08/10] cell: add support for proper device-tree Arnd Bergmann
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
The of_iomap function maps memory for a given
device_node and returns a pointer to that memory.
This is used at some places, so it makes sense to
a seperate function.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/sysdev/pmi.c
===================================================================
--- linux-2.6.orig/arch/powerpc/sysdev/pmi.c
+++ linux-2.6/arch/powerpc/sysdev/pmi.c
@@ -33,7 +33,7 @@
#include <asm/of_platform.h>
#include <asm/io.h>
#include <asm/pmi.h>
-
+#include <asm/prom.h>
struct pmi_data {
struct list_head handler;
@@ -49,21 +49,6 @@ struct pmi_data {
};
-
-static void __iomem *of_iomap(struct device_node *np)
-{
- struct resource res;
-
- if (of_address_to_resource(np, 0, &res))
- return NULL;
-
- pr_debug("Resource start: 0x%lx\n", res.start);
- pr_debug("Resource end: 0x%lx\n", res.end);
-
- return ioremap(res.start, 1 + res.end - res.start);
-}
-
-
static int pmi_irq_handler(int irq, void *dev_id)
{
struct pmi_data *data;
@@ -154,7 +139,7 @@ static int pmi_of_probe(struct of_device
goto out;
}
- data->pmi_reg = of_iomap(np);
+ data->pmi_reg = of_iomap(np, 0);
if (!data->pmi_reg) {
printk(KERN_ERR "pmi: invalid register address.\n");
rc = -EFAULT;
Index: linux-2.6/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/prom.h
+++ linux-2.6/include/asm-powerpc/prom.h
@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <asm/irq.h>
#include <asm/atomic.h>
+#include <asm/io.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
@@ -355,6 +356,16 @@ static inline int of_irq_to_resource(str
return irq;
}
+static inline void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
--
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 07/10] add of_iomap function
2007-04-23 19:35 ` [PATCH 07/10] add of_iomap function Arnd Bergmann
@ 2007-04-24 1:35 ` Benjamin Herrenschmidt
2007-04-24 15:32 ` [PATCH] powerpc: uninline " Christian Krafft
0 siblings, 1 reply; 19+ messages in thread
From: Benjamin Herrenschmidt @ 2007-04-24 1:35 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann, Christian Krafft
On Mon, 2007-04-23 at 21:35 +0200, Arnd Bergmann wrote:
> plain text document attachment (powerpc-add-of_remap.diff)
> From: Christian Krafft <krafft@de.ibm.com>
>
> The of_iomap function maps memory for a given
> device_node and returns a pointer to that memory.
> This is used at some places, so it makes sense to
> a seperate function.
No point in inlining it imho.
Ben.
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
>
> Index: linux-2.6/arch/powerpc/sysdev/pmi.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/sysdev/pmi.c
> +++ linux-2.6/arch/powerpc/sysdev/pmi.c
> @@ -33,7 +33,7 @@
> #include <asm/of_platform.h>
> #include <asm/io.h>
> #include <asm/pmi.h>
> -
> +#include <asm/prom.h>
>
> struct pmi_data {
> struct list_head handler;
> @@ -49,21 +49,6 @@ struct pmi_data {
> };
>
>
> -
> -static void __iomem *of_iomap(struct device_node *np)
> -{
> - struct resource res;
> -
> - if (of_address_to_resource(np, 0, &res))
> - return NULL;
> -
> - pr_debug("Resource start: 0x%lx\n", res.start);
> - pr_debug("Resource end: 0x%lx\n", res.end);
> -
> - return ioremap(res.start, 1 + res.end - res.start);
> -}
> -
> -
> static int pmi_irq_handler(int irq, void *dev_id)
> {
> struct pmi_data *data;
> @@ -154,7 +139,7 @@ static int pmi_of_probe(struct of_device
> goto out;
> }
>
> - data->pmi_reg = of_iomap(np);
> + data->pmi_reg = of_iomap(np, 0);
> if (!data->pmi_reg) {
> printk(KERN_ERR "pmi: invalid register address.\n");
> rc = -EFAULT;
> Index: linux-2.6/include/asm-powerpc/prom.h
> ===================================================================
> --- linux-2.6.orig/include/asm-powerpc/prom.h
> +++ linux-2.6/include/asm-powerpc/prom.h
> @@ -20,6 +20,7 @@
> #include <linux/platform_device.h>
> #include <asm/irq.h>
> #include <asm/atomic.h>
> +#include <asm/io.h>
>
> /* Definitions used by the flattened device tree */
> #define OF_DT_HEADER 0xd00dfeed /* marker */
> @@ -355,6 +356,16 @@ static inline int of_irq_to_resource(str
> return irq;
> }
>
> +static inline void __iomem *of_iomap(struct device_node *np, int index)
> +{
> + struct resource res;
> +
> + if (of_address_to_resource(np, index, &res))
> + return NULL;
> +
> + return ioremap(res.start, 1 + res.end - res.start);
> +}
> +
>
> #endif /* __KERNEL__ */
> #endif /* _POWERPC_PROM_H */
>
> --
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH] powerpc: uninline of_iomap function
2007-04-24 1:35 ` Benjamin Herrenschmidt
@ 2007-04-24 15:32 ` Christian Krafft
2007-04-24 17:27 ` Arnd Bergmann
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Christian Krafft @ 2007-04-24 15:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann, Arnd Bergmann
[-- Attachment #1: Type: text/plain, Size: 2218 bytes --]
From: Christian Krafft <krafft@de.ibm.com>
There is no big reason to have that function inlined.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Index: linux-2.6.21-rc4/arch/powerpc/kernel/prom_parse.c
===================================================================
--- linux-2.6.21-rc4.orig/arch/powerpc/kernel/prom_parse.c
+++ linux-2.6.21-rc4/arch/powerpc/kernel/prom_parse.c
@@ -1042,3 +1042,15 @@ const void *of_get_mac_address(struct de
}
EXPORT_SYMBOL(of_get_mac_address);
+void __iomem *of_iomap(struct device_node *np, int index)
+{
+ struct resource res;
+
+ if (of_address_to_resource(np, index, &res))
+ return NULL;
+
+ return ioremap(res.start, 1 + res.end - res.start);
+}
+EXPORT_SYMBOL(of_iomap);
+
+
Index: linux-2.6.21-rc4/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.21-rc4.orig/include/asm-powerpc/prom.h
+++ linux-2.6.21-rc4/include/asm-powerpc/prom.h
@@ -19,7 +19,6 @@
#include <linux/proc_fs.h>
#include <linux/platform_device.h>
#include <asm/atomic.h>
-#include <asm/io.h>
/* Definitions used by the flattened device tree */
#define OF_DT_HEADER 0xd00dfeed /* marker */
@@ -352,16 +351,14 @@ static inline int of_irq_to_resource(str
return irq;
}
-static inline void __iomem *of_iomap(struct device_node *np, int index)
-{
- struct resource res;
-
- if (of_address_to_resource(np, index, &res))
- return NULL;
-
- return ioremap(res.start, 1 + res.end - res.start);
-}
-
+/**
+ * of_iomap - Maps the memory mapped IO for a given device_node
+ * @device: the device whose io range will be mapped
+ * @index: index of the io range
+ *
+ * Returns a pointer to the mapped memory
+ */
+extern void __iomem *of_iomap(struct device_node *device, int index);
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
--
Mit freundlichen Gruessen,
kind regards,
Christian Krafft
IBM Systems & Technology Group,
Linux Kernel Development
IT Specialist
Vorsitzender des Aufsichtsrats: Johann Weihen
Geschaeftsfuehrung: Herbert Kircher
Sitz der Gesellschaft: Boeblingen
Registriergericht: Amtsgericht Stuttgart, HRB 243294
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH] powerpc: uninline of_iomap function
2007-04-24 15:32 ` [PATCH] powerpc: uninline " Christian Krafft
@ 2007-04-24 17:27 ` Arnd Bergmann
2007-04-24 22:35 ` Benjamin Herrenschmidt
2007-04-25 0:31 ` Paul Mackerras
2 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-24 17:27 UTC (permalink / raw)
To: Christian Krafft; +Cc: Paul Mackerras, linuxppc-dev
On Tuesday 24 April 2007, Christian Krafft wrote:
> From: Christian Krafft <krafft@de.ibm.com>
> There is no big reason to have that function inlined.
>
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] powerpc: uninline of_iomap function
2007-04-24 15:32 ` [PATCH] powerpc: uninline " Christian Krafft
2007-04-24 17:27 ` Arnd Bergmann
@ 2007-04-24 22:35 ` Benjamin Herrenschmidt
2007-04-25 0:31 ` Paul Mackerras
2 siblings, 0 replies; 19+ messages in thread
From: Benjamin Herrenschmidt @ 2007-04-24 22:35 UTC (permalink / raw)
To: Christian Krafft
Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann, Arnd Bergmann
On Tue, 2007-04-24 at 17:32 +0200, Christian Krafft wrote:
> From: Christian Krafft <krafft@de.ibm.com>
> There is no big reason to have that function inlined.
>
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Index: linux-2.6.21-rc4/arch/powerpc/kernel/prom_parse.c
> ===================================================================
> --- linux-2.6.21-rc4.orig/arch/powerpc/kernel/prom_parse.c
> +++ linux-2.6.21-rc4/arch/powerpc/kernel/prom_parse.c
> @@ -1042,3 +1042,15 @@ const void *of_get_mac_address(struct de
> }
> EXPORT_SYMBOL(of_get_mac_address);
>
> +void __iomem *of_iomap(struct device_node *np, int index)
> +{
> + struct resource res;
> +
> + if (of_address_to_resource(np, index, &res))
> + return NULL;
> +
> + return ioremap(res.start, 1 + res.end - res.start);
> +}
> +EXPORT_SYMBOL(of_iomap);
> +
> +
> Index: linux-2.6.21-rc4/include/asm-powerpc/prom.h
> ===================================================================
> --- linux-2.6.21-rc4.orig/include/asm-powerpc/prom.h
> +++ linux-2.6.21-rc4/include/asm-powerpc/prom.h
> @@ -19,7 +19,6 @@
> #include <linux/proc_fs.h>
> #include <linux/platform_device.h>
> #include <asm/atomic.h>
> -#include <asm/io.h>
>
> /* Definitions used by the flattened device tree */
> #define OF_DT_HEADER 0xd00dfeed /* marker */
> @@ -352,16 +351,14 @@ static inline int of_irq_to_resource(str
> return irq;
> }
>
> -static inline void __iomem *of_iomap(struct device_node *np, int index)
> -{
> - struct resource res;
> -
> - if (of_address_to_resource(np, index, &res))
> - return NULL;
> -
> - return ioremap(res.start, 1 + res.end - res.start);
> -}
> -
> +/**
> + * of_iomap - Maps the memory mapped IO for a given device_node
> + * @device: the device whose io range will be mapped
> + * @index: index of the io range
> + *
> + * Returns a pointer to the mapped memory
> + */
> +extern void __iomem *of_iomap(struct device_node *device, int index);
>
> #endif /* __KERNEL__ */
> #endif /* _POWERPC_PROM_H */
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH] powerpc: uninline of_iomap function
2007-04-24 15:32 ` [PATCH] powerpc: uninline " Christian Krafft
2007-04-24 17:27 ` Arnd Bergmann
2007-04-24 22:35 ` Benjamin Herrenschmidt
@ 2007-04-25 0:31 ` Paul Mackerras
2007-04-25 2:15 ` Paul Mackerras
2 siblings, 1 reply; 19+ messages in thread
From: Paul Mackerras @ 2007-04-25 0:31 UTC (permalink / raw)
To: Christian Krafft; +Cc: Arnd Bergmann, Arnd Bergmann, linuxppc-dev
Christian Krafft writes:
> @@ -1042,3 +1042,15 @@ const void *of_get_mac_address(struct de
> }
> EXPORT_SYMBOL(of_get_mac_address);
>
> +void __iomem *of_iomap(struct device_node *np, int index)
> +{
> + struct resource res;
>
> + if (of_address_to_resource(np, index, &res))
> + return NULL;
>
> + return ioremap(res.start, 1 + res.end - res.start);
> +}
> +EXPORT_SYMBOL(of_iomap);
Looks like your mailer mangled the patch - could you resend it with a
different mailer or with different settings of your mailer?
Paul.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 08/10] cell: add support for proper device-tree
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (6 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 07/10] add of_iomap function Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 23:16 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 09/10] cell: enable RTAS-based PTCAL for Cell XDR memory Arnd Bergmann
2007-04-23 19:35 ` [PATCH 10/10] update cell_defconfig Arnd Bergmann
9 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann, Christian Krafft
From: Christian Krafft <krafft@de.ibm.com>
This patch adds support for a proper device-tree.
A porper device-tree on cell contains be nodes
for each CBE containg nodes for SPEs and all the
other special devices on it.
Ofcourse oldschool devicetree is still supported.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/platforms/cell/cbe_regs.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/cbe_regs.c
+++ linux-2.6/arch/powerpc/platforms/cell/cbe_regs.c
@@ -14,6 +14,8 @@
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/ptrace.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
#include "cbe_regs.h"
@@ -27,6 +29,7 @@
static struct cbe_regs_map
{
struct device_node *cpu_node;
+ struct device_node *be_node;
struct cbe_pmd_regs __iomem *pmd_regs;
struct cbe_iic_regs __iomem *iic_regs;
struct cbe_mic_tm_regs __iomem *mic_tm_regs;
@@ -37,6 +40,7 @@ static int cbe_regs_map_count;
static struct cbe_thread_map
{
struct device_node *cpu_node;
+ struct device_node *be_node;
struct cbe_regs_map *regs;
unsigned int thread_id;
unsigned int cbe_id;
@@ -50,22 +54,29 @@ static struct cbe_regs_map *cbe_find_map
int i;
struct device_node *tmp_np;
- if (strcasecmp(np->type, "spe") == 0) {
- if (np->data == NULL) {
- /* walk up path until cpu node was found */
- tmp_np = np->parent;
- while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0)
- tmp_np = tmp_np->parent;
+ if (strcasecmp(np->type, "spe")) {
+ for (i = 0; i < cbe_regs_map_count; i++)
+ if (cbe_regs_maps[i].cpu_node == np ||
+ cbe_regs_maps[i].be_node == np)
+ return &cbe_regs_maps[i];
+ return NULL;
+ }
- np->data = cbe_find_map(tmp_np);
- }
+ if (np->data)
return np->data;
- }
- for (i = 0; i < cbe_regs_map_count; i++)
- if (cbe_regs_maps[i].cpu_node == np)
- return &cbe_regs_maps[i];
- return NULL;
+ /* walk up path until cpu or be node was found */
+ tmp_np = np;
+ do {
+ tmp_np = tmp_np->parent;
+ /* on a correct devicetree we wont get up to root */
+ BUG_ON(!tmp_np);
+ } while (strcasecmp(tmp_np->type, "cpu") &&
+ strcasecmp(tmp_np->type, "be"));
+
+ np->data = cbe_find_map(tmp_np);
+
+ return np->data;
}
struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np)
@@ -153,6 +164,67 @@ u32 cbe_node_to_cpu(int node)
}
EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
+static struct device_node *cbe_get_be_node(int cpu_id)
+{
+ struct device_node *np;
+
+ for_each_node_by_type (np, "be") {
+ int len,i;
+ const phandle *cpu_handle;
+
+ cpu_handle = of_get_property(np, "cpus", &len);
+
+ for (i=0; i<len; i++)
+ if (of_find_node_by_phandle(cpu_handle[i]) == of_get_cpu_node(cpu_id, NULL))
+ return np;
+ }
+
+ return NULL;
+}
+
+void __init cbe_fill_regs_map(struct cbe_regs_map *map)
+{
+ if(map->be_node) {
+ struct device_node *be, *np;
+
+ be = map->be_node;
+
+ for_each_node_by_type(np, "pervasive")
+ if (of_get_parent(np) == be)
+ map->pmd_regs = of_iomap(np, 0);
+
+ for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller")
+ if (of_get_parent(np) == be)
+ map->iic_regs = of_iomap(np, 2);
+
+ for_each_node_by_type(np, "mic-tm")
+ if (of_get_parent(np) == be)
+ map->mic_tm_regs = of_iomap(np, 0);
+ } else {
+ struct device_node *cpu;
+ /* That hack must die die die ! */
+ const struct address_prop {
+ unsigned long address;
+ unsigned int len;
+ } __attribute__((packed)) *prop;
+
+ cpu = map->cpu_node;
+
+ prop = of_get_property(cpu, "pervasive", NULL);
+ if (prop != NULL)
+ map->pmd_regs = ioremap(prop->address, prop->len);
+
+ prop = of_get_property(cpu, "iic", NULL);
+ if (prop != NULL)
+ map->iic_regs = ioremap(prop->address, prop->len);
+
+ prop = of_get_property(cpu, "mic-tm", NULL);
+ if (prop != NULL)
+ map->mic_tm_regs = ioremap(prop->address, prop->len);
+ }
+}
+
+
void __init cbe_regs_init(void)
{
int i;
@@ -162,6 +234,7 @@ void __init cbe_regs_init(void)
/* Build local fast map of CPUs */
for_each_possible_cpu(i) {
cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id);
+ cbe_thread_map[i].be_node = cbe_get_be_node(i);
cbe_thread_map[i].thread_id = thread_id;
}
@@ -170,12 +243,6 @@ void __init cbe_regs_init(void)
struct cbe_regs_map *map;
unsigned int cbe_id;
- /* That hack must die die die ! */
- const struct address_prop {
- unsigned long address;
- unsigned int len;
- } __attribute__((packed)) *prop;
-
cbe_id = cbe_regs_map_count++;
map = &cbe_regs_maps[cbe_id];
@@ -193,23 +260,14 @@ void __init cbe_regs_init(void)
if (thread->cpu_node == cpu) {
thread->regs = map;
thread->cbe_id = cbe_id;
+ map->be_node = thread->be_node;
cpu_set(i, cbe_local_mask[cbe_id]);
if(thread->thread_id == 0)
cpu_set(i, cbe_first_online_cpu);
}
}
- prop = of_get_property(cpu, "pervasive", NULL);
- if (prop != NULL)
- map->pmd_regs = ioremap(prop->address, prop->len);
-
- prop = of_get_property(cpu, "iic", NULL);
- if (prop != NULL)
- map->iic_regs = ioremap(prop->address, prop->len);
-
- prop = of_get_property(cpu, "mic-tm", NULL);
- if (prop != NULL)
- map->mic_tm_regs = ioremap(prop->address, prop->len);
+ cbe_fill_regs_map(map);
}
}
--
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH 08/10] cell: add support for proper device-tree
2007-04-23 19:35 ` [PATCH 08/10] cell: add support for proper device-tree Arnd Bergmann
@ 2007-04-23 23:16 ` Arnd Bergmann
2007-04-24 1:48 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 23:16 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Christian Krafft, paulus, David Woodhouse
On Monday 23 April 2007, Arnd Bergmann wrote:
> From: Christian Krafft <krafft@de.ibm.com>
>
> This patch adds support for a proper device-tree.
> A porper device-tree on cell contains be nodes
> for each CBE containg nodes for SPEs and all the
> other special devices on it.
> Ofcourse oldschool devicetree is still supported.
>
> Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Christian, I only now saw that there is this rather important
patch left, it never stood out as something for 2.6.21 and now
it's too late for that.
This might explain why people could not boot some hardware
with Fedora 7.
Should we try to get this in as a hotfix?
Arnd <><
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 08/10] cell: add support for proper device-tree
2007-04-23 23:16 ` Arnd Bergmann
@ 2007-04-24 1:48 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 19+ messages in thread
From: Benjamin Herrenschmidt @ 2007-04-24 1:48 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, paulus, David Woodhouse, Christian Krafft
On Tue, 2007-04-24 at 01:16 +0200, Arnd Bergmann wrote:
> On Monday 23 April 2007, Arnd Bergmann wrote:
> > From: Christian Krafft <krafft@de.ibm.com>
> >
> > This patch adds support for a proper device-tree.
> > A porper device-tree on cell contains be nodes
> > for each CBE containg nodes for SPEs and all the
> > other special devices on it.
> > Ofcourse oldschool devicetree is still supported.
> >
> > Signed-off-by: Christian Krafft <krafft@de.ibm.com>
> > Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
>
> Christian, I only now saw that there is this rather important
> patch left, it never stood out as something for 2.6.21 and now
> it's too late for that.
> This might explain why people could not boot some hardware
> with Fedora 7.
>
> Should we try to get this in as a hotfix?
Please do.
Ben.
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 09/10] cell: enable RTAS-based PTCAL for Cell XDR memory
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (7 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 08/10] cell: add support for proper device-tree Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
2007-04-23 19:35 ` [PATCH 10/10] update cell_defconfig Arnd Bergmann
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev, Arnd Bergmann
From: Jeremy Kerr <jk@ozlabs.org>
Enable Periodic Recalibration (PTCAL) support for Cell XDR memory,
using the new ibm,cbe-start-ptcal and ibm,cbe-stop-ptcal RTAS calls.
Tested on QS20 and QS21 (by Thomas Huth). It seems that SLOF has
problems disabling, at least on QS20; this patch should only be
used once these problems have been addressed.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
Update: Updated with Michael's feedback, expanded comment.
Index: linux-2.6/arch/powerpc/platforms/cell/ras.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/ras.c
+++ linux-2.6/arch/powerpc/platforms/cell/ras.c
@@ -3,11 +3,13 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/smp.h>
+#include <linux/reboot.h>
#include <asm/reg.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/machdep.h>
+#include <asm/rtas.h>
#include "ras.h"
#include "cbe_regs.h"
@@ -82,6 +84,164 @@ static int cbe_machine_check_handler(str
return 0;
}
+struct ptcal_area {
+ struct list_head list;
+ int nid;
+ int order;
+ struct page *pages;
+};
+
+static LIST_HEAD(ptcal_list);
+
+static int ptcal_start_tok, ptcal_stop_tok;
+
+static int __init cbe_ptcal_enable_on_node(int nid, int order)
+{
+ struct ptcal_area *area;
+ int ret = -ENOMEM;
+ unsigned long addr;
+
+#ifdef CONFIG_CRASH_DUMP
+ rtas_call(ptcal_stop_tok, 1, 1, NULL, nid);
+#endif
+
+ area = kmalloc(sizeof(*area), GFP_KERNEL);
+ if (!area)
+ goto out_err;
+
+ area->nid = nid;
+ area->order = order;
+ area->pages = alloc_pages_node(area->nid, GFP_KERNEL, area->order);
+
+ if (!area->pages)
+ goto out_free_area;
+
+ addr = __pa(page_address(area->pages));
+
+ ret = -EIO;
+ if (rtas_call(ptcal_start_tok, 3, 1, NULL, area->nid,
+ (unsigned int)(addr >> 32),
+ (unsigned int)(addr & 0xffffffff))) {
+ printk(KERN_ERR "%s: error enabling PTCAL on node %d!\n",
+ __FUNCTION__, nid);
+ goto out_free_pages;
+ }
+
+ list_add(&area->list, &ptcal_list);
+
+ return 0;
+
+out_free_pages:
+ __free_pages(area->pages, area->order);
+out_free_area:
+ kfree(area);
+out_err:
+ return ret;
+}
+
+static int __init cbe_ptcal_enable(void)
+{
+ const u32 *size;
+ struct device_node *np;
+ int order, found_mic = 0;
+
+ np = of_find_node_by_path("/rtas");
+ if (!np)
+ return -ENODEV;
+
+ size = get_property(np, "ibm,cbe-ptcal-size", NULL);
+ if (!size)
+ return -ENODEV;
+
+ pr_debug("%s: enabling PTCAL, size = 0x%x\n", __FUNCTION__, *size);
+ order = get_order(*size);
+ of_node_put(np);
+
+ /* support for malta device trees, with be@/mic@ nodes */
+ for_each_node_by_type(np, "mic-tm") {
+ cbe_ptcal_enable_on_node(of_node_to_nid(np), order);
+ found_mic = 1;
+ }
+
+ if (found_mic)
+ return 0;
+
+ /* support for older device tree - use cpu nodes */
+ for_each_node_by_type(np, "cpu") {
+ const u32 *nid = get_property(np, "node-id", NULL);
+ if (!nid) {
+ printk(KERN_ERR "%s: node %s is missing node-id?\n",
+ __FUNCTION__, np->full_name);
+ continue;
+ }
+ cbe_ptcal_enable_on_node(*nid, order);
+ found_mic = 1;
+ }
+
+ return found_mic ? 0 : -ENODEV;
+}
+
+static int cbe_ptcal_disable(void)
+{
+ struct ptcal_area *area, *tmp;
+ int ret = 0;
+
+ pr_debug("%s: disabling PTCAL\n", __FUNCTION__);
+
+ list_for_each_entry_safe(area, tmp, &ptcal_list, list) {
+ /* disable ptcal on this node */
+ if (rtas_call(ptcal_stop_tok, 1, 1, NULL, area->nid)) {
+ printk(KERN_ERR "%s: error disabling PTCAL "
+ "on node %d!\n", __FUNCTION__,
+ area->nid);
+ ret = -EIO;
+ continue;
+ }
+
+ /* ensure we can access the PTCAL area */
+ memset(page_address(area->pages), 0,
+ 1 << (area->order + PAGE_SHIFT));
+
+ /* clean up */
+ list_del(&area->list);
+ __free_pages(area->pages, area->order);
+ kfree(area);
+ }
+
+ return ret;
+}
+
+static int cbe_ptcal_notify_reboot(struct notifier_block *nb,
+ unsigned long code, void *data)
+{
+ return cbe_ptcal_disable();
+}
+
+static struct notifier_block cbe_ptcal_reboot_notifier = {
+ .notifier_call = cbe_ptcal_notify_reboot
+};
+
+int __init cbe_ptcal_init(void)
+{
+ int ret;
+ ptcal_start_tok = rtas_token("ibm,cbe-start-ptcal");
+ ptcal_stop_tok = rtas_token("ibm,cbe-stop-ptcal");
+
+ if (ptcal_start_tok == RTAS_UNKNOWN_SERVICE
+ || ptcal_stop_tok == RTAS_UNKNOWN_SERVICE)
+ return -ENODEV;
+
+ ret = register_reboot_notifier(&cbe_ptcal_reboot_notifier);
+ if (ret) {
+ printk(KERN_ERR "Can't disable PTCAL, so not enabling\n");
+ return ret;
+ }
+
+ return cbe_ptcal_enable();
+}
+
+arch_initcall(cbe_ptcal_init);
+
void __init cbe_ras_init(void)
{
unsigned long hid0;
--
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 10/10] update cell_defconfig
2007-04-23 19:35 [PATCH 00/10] non-spufs updates for cell platforms Arnd Bergmann
` (8 preceding siblings ...)
2007-04-23 19:35 ` [PATCH 09/10] cell: enable RTAS-based PTCAL for Cell XDR memory Arnd Bergmann
@ 2007-04-23 19:35 ` Arnd Bergmann
9 siblings, 0 replies; 19+ messages in thread
From: Arnd Bergmann @ 2007-04-23 19:35 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Arnd Bergmann, linuxppc-dev
Sync with the Kconfig changes, and enable some options for celleb
Cc: Ishizaki Kou <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Jens Osterkamp <jens@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Index: linux-2.6/arch/powerpc/configs/cell_defconfig
===================================================================
--- linux-2.6.orig/arch/powerpc/configs/cell_defconfig
+++ linux-2.6/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc3
-# Fri Mar 9 23:34:53 2007
+# Linux kernel version: 2.6.21-rc6
+# Mon Apr 23 20:46:48 2007
#
CONFIG_PPC64=y
CONFIG_64BIT=y
@@ -139,11 +139,31 @@ CONFIG_PPC_MULTIPLATFORM=y
# CONFIG_PPC_PMAC is not set
# CONFIG_PPC_MAPLE is not set
# CONFIG_PPC_PASEMI is not set
+CONFIG_PPC_CELLEB=y
+CONFIG_PPC_PS3=y
+
+#
+# PS3 Platform Options
+#
+# CONFIG_PS3_ADVANCED is not set
+CONFIG_PS3_HTAB_SIZE=20
+# CONFIG_PS3_DYNAMIC_DMA is not set
+CONFIG_PS3_USE_LPAR_ADDR=y
+CONFIG_PS3_VUART=y
+CONFIG_PS3_PS3AV=y
+CONFIG_PS3_SYS_MANAGER=y
CONFIG_PPC_CELL=y
CONFIG_PPC_CELL_NATIVE=y
CONFIG_PPC_IBM_CELL_BLADE=y
-CONFIG_PPC_PS3=y
-CONFIG_PPC_CELLEB=y
+
+#
+# Cell Broadband Engine options
+#
+CONFIG_SPU_FS=m
+CONFIG_SPU_BASE=y
+CONFIG_CBE_RAS=y
+CONFIG_CBE_THERM=m
+CONFIG_CBE_CPUFREQ=m
CONFIG_PPC_NATIVE=y
CONFIG_UDBG_RTAS_CONSOLE=y
CONFIG_PPC_UDBG_BEAT=y
@@ -175,26 +195,6 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_MPIC=y
#
-# Cell Broadband Engine options
-#
-CONFIG_SPU_FS=m
-CONFIG_SPU_BASE=y
-CONFIG_CBE_RAS=y
-CONFIG_CBE_THERM=m
-CONFIG_CBE_CPUFREQ=m
-
-#
-# PS3 Platform Options
-#
-# CONFIG_PS3_ADVANCED is not set
-CONFIG_PS3_HTAB_SIZE=20
-# CONFIG_PS3_DYNAMIC_DMA is not set
-CONFIG_PS3_USE_LPAR_ADDR=y
-CONFIG_PS3_VUART=y
-CONFIG_PS3_PS3AV=y
-CONFIG_PS3_SYS_MANAGER=y
-
-#
# Kernel options
#
# CONFIG_HZ_100 is not set
@@ -534,7 +534,6 @@ CONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_AEC62XX=y
# CONFIG_BLK_DEV_ALI15X3 is not set
@@ -561,11 +560,10 @@ CONFIG_BLK_DEV_SIIMAGE=y
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
-CONFIG_BLK_DEV_IDE_CELLEB=y
+CONFIG_BLK_DEV_CELLEB=y
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -937,7 +935,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_HVC_DRIVER=y
CONFIG_HVC_RTAS=y
-# CONFIG_HVC_BEAT is not set
+CONFIG_HVC_BEAT=y
#
# IPMI
@@ -1482,6 +1480,8 @@ CONFIG_NLS_ISO8859_15=m
# Distributed Lock Manager
#
# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
#
# Library routines
@@ -1540,6 +1540,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_DEBUGGER=y
CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
--
^ permalink raw reply [flat|nested] 19+ messages in thread