* [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes
From: Stephen Rothwell @ 2007-10-11 4:58 UTC (permalink / raw)
To: paulus; +Cc: ppc-dev
In-Reply-To: <20071011145726.59bcbc02.sfr@canb.auug.org.au>
Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties). This way viotape.c gets
all the information about the devices from the device tree.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/platforms/iseries/dt.c | 7 --
arch/powerpc/platforms/iseries/vio.c | 149 ++++++++++++++++++++++++++++++----
drivers/char/viotape.c | 124 ++++------------------------
include/asm-powerpc/iseries/vio.h | 41 +++++++++
4 files changed, 192 insertions(+), 129 deletions(-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 84fcee1..2e4ad6b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -73,7 +73,6 @@ static char __initdata device_type_memory[] = "memory";
static char __initdata device_type_serial[] = "serial";
static char __initdata device_type_network[] = "network";
static char __initdata device_type_block[] = "block";
-static char __initdata device_type_byte[] = "byte";
static char __initdata device_type_pci[] = "pci";
static char __initdata device_type_vdevice[] = "vdevice";
static char __initdata device_type_vscsi[] = "vscsi";
@@ -380,12 +379,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
"IBM,iSeries-viodasd", 1);
- reg += HVMAXARCHITECTEDVIRTUALDISKS;
- reg += HVMAXARCHITECTEDVIRTUALCDROMS;
-
- for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
- dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
- "IBM,iSeries-viotape", 1);
dt_end_node(dt);
}
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 08f6884..b4f7433 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -45,6 +45,18 @@
#define FIRST_VIOTAPE (FIRST_VIOCD + NUM_VIOCDS)
#define NUM_VIOTAPES HVMAXARCHITECTEDVIRTUALTAPES
+struct vio_waitevent {
+ struct completion com;
+ int rc;
+ u16 sub_result;
+};
+
+struct vio_resource {
+ char rsrcname[10];
+ char type[4];
+ char model[3];
+};
+
static struct property * __init new_property(const char *name, int length,
const void *value)
{
@@ -123,22 +135,10 @@ static int __init add_raw_property(struct device_node *np, const char *name,
return 1;
}
-struct viocd_waitevent {
- struct completion com;
- int rc;
- u16 sub_result;
-};
-
-struct cdrom_info {
- char rsrcname[10];
- char type[4];
- char model[3];
-};
-
static void __init handle_cd_event(struct HvLpEvent *event)
{
struct viocdlpevent *bevent;
- struct viocd_waitevent *pwe;
+ struct vio_waitevent *pwe;
if (!event)
/* Notification that a partition went away! */
@@ -158,7 +158,7 @@ static void __init handle_cd_event(struct HvLpEvent *event)
switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
case viocdgetinfo:
- pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+ pwe = (struct vio_waitevent *)event->xCorrelationToken;
pwe->rc = event->xRc;
pwe->sub_result = bevent->sub_result;
complete(&pwe->com);
@@ -179,8 +179,8 @@ static void __init get_viocd_info(struct device_node *vio_root)
{
HvLpEvent_Rc hvrc;
u32 unit;
- struct viocd_waitevent we;
- struct cdrom_info *unitinfo;
+ struct vio_waitevent we;
+ struct vio_resource *unitinfo;
dma_addr_t unitinfo_dmaaddr;
int ret;
@@ -286,6 +286,122 @@ static void __init get_viocd_info(struct device_node *vio_root)
viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
}
+/* Handle interrupt events for tape */
+static void __init handle_tape_event(struct HvLpEvent *event)
+{
+ struct vio_waitevent *we;
+ struct viotapelpevent *tevent = (struct viotapelpevent *)event;
+
+ if (event == NULL)
+ /* Notification that a partition went away! */
+ return;
+
+ we = (struct vio_waitevent *)event->xCorrelationToken;
+ switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+ case viotapegetinfo:
+ we->rc = tevent->sub_type_result;
+ complete(&we->com);
+ break;
+ default:
+ printk(KERN_WARNING "handle_tape_event: weird ack\n");
+ }
+}
+
+static void __init get_viotape_info(struct device_node *vio_root)
+{
+ HvLpEvent_Rc hvrc;
+ u32 unit;
+ struct vio_resource *unitinfo;
+ dma_addr_t unitinfo_dmaaddr;
+ size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES;
+ struct vio_waitevent we;
+ int ret;
+
+ ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
+ if (ret) {
+ printk(KERN_WARNING "get_viotape_info: "
+ "error on viopath_open to hostlp %d\n", ret);
+ return;
+ }
+
+ vio_setHandler(viomajorsubtype_tape, handle_tape_event);
+
+ unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC);
+ if (!unitinfo)
+ goto clear_handler;
+
+ memset(unitinfo, 0, len);
+
+ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+ HvLpEvent_Type_VirtualIo,
+ viomajorsubtype_tape | viotapegetinfo,
+ HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+ viopath_sourceinst(viopath_hostLp),
+ viopath_targetinst(viopath_hostLp),
+ (u64)(unsigned long)&we, VIOVERSION << 16,
+ unitinfo_dmaaddr, len, 0, 0);
+ if (hvrc != HvLpEvent_Rc_Good) {
+ printk(KERN_WARNING "get_viotape_info: hv error on op %d\n",
+ (int)hvrc);
+ goto hv_free;
+ }
+
+ wait_for_completion(&we.com);
+
+ for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
+ unitinfo[unit].rsrcname[0]; unit++) {
+ struct device_node *np;
+ char name[64];
+ u32 reg = FIRST_VIOTAPE + unit;
+
+ snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
+ np = new_node(name, vio_root);
+ if (!np)
+ goto hv_free;
+ if (!add_string_property(np, "name", "viotape") ||
+ !add_string_property(np, "device_type", "byte") ||
+ !add_string_property(np, "compatible",
+ "IBM,iSeries-viotape") ||
+ !add_raw_property(np, "reg", sizeof(reg), ®) ||
+ !add_raw_property(np, "linux,unit_address",
+ sizeof(unit), &unit) ||
+ !add_raw_property(np, "linux,vio_rsrcname",
+ sizeof(unitinfo[unit].rsrcname),
+ unitinfo[unit].rsrcname) ||
+ !add_raw_property(np, "linux,vio_type",
+ sizeof(unitinfo[unit].type),
+ unitinfo[unit].type) ||
+ !add_raw_property(np, "linux,vio_model",
+ sizeof(unitinfo[unit].model),
+ unitinfo[unit].model))
+ goto node_free;
+ np->name = of_get_property(np, "name", NULL);
+ np->type = of_get_property(np, "device_type", NULL);
+ of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+ if (vio_root->pde) {
+ struct proc_dir_entry *ent;
+
+ ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+ vio_root->pde);
+ if (ent)
+ proc_device_tree_add_node(np, ent);
+ }
+#endif
+ continue;
+
+ node_free:
+ free_node(np);
+ break;
+ }
+
+ hv_free:
+ iseries_hv_free(len, unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+ vio_clearHandler(viomajorsubtype_tape);
+ viopath_close(viopath_hostLp, viomajorsubtype_tape, 2);
+}
+
static int __init iseries_vio_init(void)
{
struct device_node *vio_root;
@@ -307,6 +423,7 @@ static int __init iseries_vio_init(void)
}
get_viocd_info(vio_root);
+ get_viotape_info(vio_root);
return 0;
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 064c091..f1d60f0 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
#define VIOTAPOP_SETPART 14
#define VIOTAPOP_UNLOAD 15
-struct viotapelpevent {
- struct HvLpEvent event;
- u32 reserved;
- u16 version;
- u16 sub_type_result;
- u16 tape;
- u16 flags;
- u32 token;
- u64 len;
- union {
- struct {
- u32 tape_op;
- u32 count;
- } op;
- struct {
- u32 type;
- u32 resid;
- u32 dsreg;
- u32 gstat;
- u32 erreg;
- u32 file_no;
- u32 block_no;
- } get_status;
- struct {
- u32 block_no;
- } get_pos;
- } u;
-};
-
-enum viotapesubtype {
- viotapeopen = 0x0001,
- viotapeclose = 0x0002,
- viotaperead = 0x0003,
- viotapewrite = 0x0004,
- viotapegetinfo = 0x0005,
- viotapeop = 0x0006,
- viotapegetpos = 0x0007,
- viotapesetpos = 0x0008,
- viotapegetstatus = 0x0009
-};
-
enum viotaperc {
viotape_InvalidRange = 0x0601,
viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
#define VIOT_WRITING 2
/* Our info on the tapes */
-struct tape_descr {
- char rsrcname[10];
- char type[4];
- char model[3];
-};
-
-static struct tape_descr *viotape_unitinfo;
-static dma_addr_t viotape_unitinfo_token;
+static struct {
+ const char *rsrcname;
+ const char *type;
+ const char *model;
+} viotape_unitinfo[VIOTAPE_MAX_TAPE];
static struct mtget viomtget[VIOTAPE_MAX_TAPE];
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
return -err->errno;
}
-/* Get info on all tapes from OS/400 */
-static int get_viotape_info(void)
-{
- HvLpEvent_Rc hvrc;
- int i;
- size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
- struct op_struct *op = get_op_struct();
-
- if (op == NULL)
- return -ENOMEM;
-
- viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
- GFP_ATOMIC);
- if (viotape_unitinfo == NULL) {
- free_op_struct(op);
- return -ENOMEM;
- }
-
- memset(viotape_unitinfo, 0, len);
-
- hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
- HvLpEvent_Type_VirtualIo,
- viomajorsubtype_tape | viotapegetinfo,
- HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
- viopath_sourceinst(viopath_hostLp),
- viopath_targetinst(viopath_hostLp),
- (u64) (unsigned long) op, VIOVERSION << 16,
- viotape_unitinfo_token, len, 0, 0);
- if (hvrc != HvLpEvent_Rc_Good) {
- printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
- (int)hvrc);
- free_op_struct(op);
- return -EIO;
- }
-
- wait_for_completion(&op->com);
-
- free_op_struct(op);
-
- for (i = 0;
- ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
- i++)
- viotape_numdev++;
- return 0;
-}
-
-
/* Write */
static ssize_t viotap_write(struct file *file, const char *buf,
size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
op = (struct op_struct *)event->xCorrelationToken;
switch (tapeminor) {
- case viotapegetinfo:
case viotapeopen:
case viotapeclose:
op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
int i = vdev->unit_address;
int j;
+ struct device_node *node = vdev->dev.archdata.of_node;
- if (i >= viotape_numdev)
+ if (i > VIOTAPE_MAX_TAPE)
+ return -ENODEV;
+ if (!node)
return -ENODEV;
+ if (i >= viotape_numdev)
+ viotape_numdev = i + 1;
+
tape_device[i] = &vdev->dev;
+ viotape_unitinfo[i].rsrcname = of_get_property(node,
+ "linux,vio_rsrcname", NULL);
+ viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
+ NULL);
+ viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
+ NULL);
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
goto unreg_chrdev;
}
- if ((ret = get_viotape_info()) < 0) {
- printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
- goto unreg_class;
- }
-
ret = vio_register_driver(&viotape_driver);
if (ret)
goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
vio_unregister_driver(&viotape_driver);
class_destroy(tape_class);
unregister_chrdev(VIOTAPE_MAJOR, "viotape");
- if (viotape_unitinfo)
- iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
- viotape_unitinfo, viotape_unitinfo_token);
viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
vio_clearHandler(viomajorsubtype_tape);
clear_op_struct_pool();
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index e5a405b..2555dfd 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -75,6 +75,47 @@ enum viocdsubtype {
viocdcheck = 0x0007
};
+struct viotapelpevent {
+ struct HvLpEvent event;
+ u32 reserved;
+ u16 version;
+ u16 sub_type_result;
+ u16 tape;
+ u16 flags;
+ u32 token;
+ u64 len;
+ union {
+ struct {
+ u32 tape_op;
+ u32 count;
+ } op;
+ struct {
+ u32 type;
+ u32 resid;
+ u32 dsreg;
+ u32 gstat;
+ u32 erreg;
+ u32 file_no;
+ u32 block_no;
+ } get_status;
+ struct {
+ u32 block_no;
+ } get_pos;
+ } u;
+};
+
+enum viotapesubtype {
+ viotapeopen = 0x0001,
+ viotapeclose = 0x0002,
+ viotaperead = 0x0003,
+ viotapewrite = 0x0004,
+ viotapegetinfo = 0x0005,
+ viotapeop = 0x0006,
+ viotapegetpos = 0x0007,
+ viotapesetpos = 0x0008,
+ viotapegetstatus = 0x0009
+};
+
/*
* Each subtype can register a handler to process their events.
* The handler must have this interface.
--
1.5.3.4
^ permalink raw reply related
* [PATCH 7/7] [POWERPC] iSeries: move viodasd probing
From: Stephen Rothwell @ 2007-10-11 4:59 UTC (permalink / raw)
To: paulus; +Cc: ppc-dev, Jens Axboe
In-Reply-To: <20071011145831.20c4e691.sfr@canb.auug.org.au>
This way we only have entries in the device tree for disks that actually
exist. A slight complication is that disks may be attached to LPARs
at runtime.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
arch/powerpc/platforms/iseries/dt.c | 6 -
arch/powerpc/platforms/iseries/vio.c | 301 +++++++++++++++++++++++----------
drivers/block/viodasd.c | 77 +++------
include/asm-powerpc/iseries/vio.h | 47 ++++++
4 files changed, 282 insertions(+), 149 deletions(-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 2e4ad6b..4543c4b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -72,7 +72,6 @@ static char __initdata device_type_cpu[] = "cpu";
static char __initdata device_type_memory[] = "memory";
static char __initdata device_type_serial[] = "serial";
static char __initdata device_type_network[] = "network";
-static char __initdata device_type_block[] = "block";
static char __initdata device_type_pci[] = "pci";
static char __initdata device_type_vdevice[] = "vdevice";
static char __initdata device_type_vscsi[] = "vscsi";
@@ -374,11 +373,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
dt_end_node(dt);
}
- reg += HVMAXARCHITECTEDVIRTUALLANS;
-
- for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
- dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
- "IBM,iSeries-viodasd", 1);
dt_end_node(dt);
}
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index b4f7433..d6435b0 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -25,8 +25,10 @@
#include <linux/gfp.h>
#include <linux/completion.h>
#include <linux/proc_fs.h>
+#include <linux/module.h>
#include <asm/firmware.h>
+#include <asm/vio.h>
#include <asm/iseries/vio.h>
#include <asm/iseries/iommu.h>
#include <asm/iseries/hv_types.h>
@@ -57,7 +59,7 @@ struct vio_resource {
char model[3];
};
-static struct property * __init new_property(const char *name, int length,
+static struct property *new_property(const char *name, int length,
const void *value)
{
struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
@@ -78,7 +80,7 @@ static void __init free_property(struct property *np)
kfree(np);
}
-static struct device_node * __init new_node(const char *path,
+static struct device_node *new_node(const char *path,
struct device_node *parent)
{
struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
@@ -97,7 +99,7 @@ static struct device_node * __init new_node(const char *path,
return np;
}
-static void __init free_node(struct device_node *np)
+static void free_node(struct device_node *np)
{
struct property *next;
struct property *prop;
@@ -113,7 +115,7 @@ static void __init free_node(struct device_node *np)
kfree(np);
}
-static int __init add_string_property(struct device_node *np, const char *name,
+static int add_string_property(struct device_node *np, const char *name,
const char *value)
{
struct property *nprop = new_property(name, strlen(value) + 1, value);
@@ -124,7 +126,7 @@ static int __init add_string_property(struct device_node *np, const char *name,
return 1;
}
-static int __init add_raw_property(struct device_node *np, const char *name,
+static int add_raw_property(struct device_node *np, const char *name,
int length, const void *value)
{
struct property *nprop = new_property(name, length, value);
@@ -135,6 +137,201 @@ static int __init add_raw_property(struct device_node *np, const char *name,
return 1;
}
+static struct device_node *do_device_node(struct device_node *parent,
+ const char *name, u32 reg, u32 unit, const char *type,
+ const char *compat, struct vio_resource *res)
+{
+ struct device_node *np;
+ char path[32];
+
+ snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg);
+ np = new_node(path, parent);
+ if (!np)
+ return NULL;
+ if (!add_string_property(np, "name", name) ||
+ !add_string_property(np, "device_type", type) ||
+ !add_string_property(np, "compatible", compat) ||
+ !add_raw_property(np, "reg", sizeof(reg), ®) ||
+ !add_raw_property(np, "linux,unit_address",
+ sizeof(unit), &unit)) {
+ goto node_free;
+ }
+ if (res) {
+ if (!add_raw_property(np, "linux,vio_rsrcname",
+ sizeof(res->rsrcname), res->rsrcname) ||
+ !add_raw_property(np, "linux,vio_type",
+ sizeof(res->type), res->type) ||
+ !add_raw_property(np, "linux,vio_model",
+ sizeof(res->model), res->model))
+ goto node_free;
+ }
+ np->name = of_get_property(np, "name", NULL);
+ np->type = of_get_property(np, "device_type", NULL);
+ of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+ if (parent->pde) {
+ struct proc_dir_entry *ent;
+
+ ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde);
+ if (ent)
+ proc_device_tree_add_node(np, ent);
+ }
+#endif
+ return np;
+
+ node_free:
+ free_node(np);
+ return NULL;
+}
+
+/*
+ * This is here so that we can dynamically add viodasd
+ * devices without exposing all the above infrastructure.
+ */
+struct vio_dev *vio_create_viodasd(u32 unit)
+{
+ struct device_node *vio_root;
+ struct device_node *np;
+ struct vio_dev *vdev = NULL;
+
+ vio_root = of_find_node_by_path("/vdevice");
+ if (!vio_root)
+ return NULL;
+ np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+ "block", "IBM,iSeries-viodasd", NULL);
+ of_node_put(vio_root);
+ if (np) {
+ vdev = vio_register_device_node(np);
+ if (!vdev)
+ free_node(np);
+ }
+ return vdev;
+}
+EXPORT_SYMBOL_GPL(vio_create_viodasd);
+
+static void __init handle_block_event(struct HvLpEvent *event)
+{
+ struct vioblocklpevent *bevent = (struct vioblocklpevent *)event;
+ struct vio_waitevent *pwe;
+
+ if (event == NULL)
+ /* Notification that a partition went away! */
+ return;
+ /* First, we should NEVER get an int here...only acks */
+ if (hvlpevent_is_int(event)) {
+ printk(KERN_WARNING "handle_viod_request: "
+ "Yikes! got an int in viodasd event handler!\n");
+ if (hvlpevent_need_ack(event)) {
+ event->xRc = HvLpEvent_Rc_InvalidSubtype;
+ HvCallEvent_ackLpEvent(event);
+ }
+ return;
+ }
+
+ switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+ case vioblockopen:
+ /*
+ * Handle a response to an open request. We get all the
+ * disk information in the response, so update it. The
+ * correlation token contains a pointer to a waitevent
+ * structure that has a completion in it. update the
+ * return code in the waitevent structure and post the
+ * completion to wake up the guy who sent the request
+ */
+ pwe = (struct vio_waitevent *)event->xCorrelationToken;
+ pwe->rc = event->xRc;
+ pwe->sub_result = bevent->sub_result;
+ complete(&pwe->com);
+ break;
+ case vioblockclose:
+ break;
+ default:
+ printk(KERN_WARNING "handle_viod_request: unexpected subtype!");
+ if (hvlpevent_need_ack(event)) {
+ event->xRc = HvLpEvent_Rc_InvalidSubtype;
+ HvCallEvent_ackLpEvent(event);
+ }
+ }
+}
+
+static void __init probe_disk(struct device_node *vio_root, u32 unit)
+{
+ HvLpEvent_Rc hvrc;
+ struct vio_waitevent we;
+ u16 flags = 0;
+
+retry:
+ init_completion(&we.com);
+
+ /* Send the open event to OS/400 */
+ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+ HvLpEvent_Type_VirtualIo,
+ viomajorsubtype_blockio | vioblockopen,
+ HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+ viopath_sourceinst(viopath_hostLp),
+ viopath_targetinst(viopath_hostLp),
+ (u64)(unsigned long)&we, VIOVERSION << 16,
+ ((u64)unit << 48) | ((u64)flags<< 32),
+ 0, 0, 0);
+ if (hvrc != 0) {
+ printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n",
+ (int)hvrc);
+ return;
+ }
+
+ wait_for_completion(&we.com);
+
+ if (we.rc != 0) {
+ if (flags != 0)
+ return;
+ /* try again with read only flag set */
+ flags = vioblockflags_ro;
+ goto retry;
+ }
+
+ /* Send the close event to OS/400. We DON'T expect a response */
+ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+ HvLpEvent_Type_VirtualIo,
+ viomajorsubtype_blockio | vioblockclose,
+ HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
+ viopath_sourceinst(viopath_hostLp),
+ viopath_targetinst(viopath_hostLp),
+ 0, VIOVERSION << 16,
+ ((u64)unit << 48) | ((u64)flags << 32),
+ 0, 0, 0);
+ if (hvrc != 0) {
+ printk(KERN_WARNING "probe_disk: "
+ "bad rc sending event to OS/400 %d\n", (int)hvrc);
+ return;
+ }
+
+ do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+ "block", "IBM,iSeries-viodasd", NULL);
+}
+
+static void __init get_viodasd_info(struct device_node *vio_root)
+{
+ int rc;
+ u32 unit;
+
+ rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2);
+ if (rc) {
+ printk(KERN_WARNING "get_viodasd_info: "
+ "error opening path to host partition %d\n",
+ viopath_hostLp);
+ return;
+ }
+
+ /* Initialize our request handler */
+ vio_setHandler(viomajorsubtype_blockio, handle_block_event);
+
+ for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++)
+ probe_disk(vio_root, unit);
+
+ vio_clearHandler(viomajorsubtype_blockio);
+ viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2);
+}
+
static void __init handle_cd_event(struct HvLpEvent *event)
{
struct viocdlpevent *bevent;
@@ -233,49 +430,9 @@ static void __init get_viocd_info(struct device_node *vio_root)
for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
unitinfo[unit].rsrcname[0]; unit++) {
- struct device_node *np;
- char name[64];
- u32 reg = FIRST_VIOCD + unit;
-
- snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
- np = new_node(name, vio_root);
- if (!np)
- goto hv_free;
- if (!add_string_property(np, "name", "viocd") ||
- !add_string_property(np, "device_type", "block") ||
- !add_string_property(np, "compatible",
- "IBM,iSeries-viocd") ||
- !add_raw_property(np, "reg", sizeof(reg), ®) ||
- !add_raw_property(np, "linux,unit_address",
- sizeof(unit), &unit) ||
- !add_raw_property(np, "linux,vio_rsrcname",
- sizeof(unitinfo[unit].rsrcname),
- unitinfo[unit].rsrcname) ||
- !add_raw_property(np, "linux,vio_type",
- sizeof(unitinfo[unit].type),
- unitinfo[unit].type) ||
- !add_raw_property(np, "linux,vio_model",
- sizeof(unitinfo[unit].model),
- unitinfo[unit].model))
- goto node_free;
- np->name = of_get_property(np, "name", NULL);
- np->type = of_get_property(np, "device_type", NULL);
- of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
- if (vio_root->pde) {
- struct proc_dir_entry *ent;
-
- ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
- vio_root->pde);
- if (ent)
- proc_device_tree_add_node(np, ent);
- }
-#endif
- continue;
-
- node_free:
- free_node(np);
- break;
+ if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit,
+ "block", "IBM,iSeries-viocd", &unitinfo[unit]))
+ break;
}
hv_free:
@@ -350,49 +507,10 @@ static void __init get_viotape_info(struct device_node *vio_root)
for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
unitinfo[unit].rsrcname[0]; unit++) {
- struct device_node *np;
- char name[64];
- u32 reg = FIRST_VIOTAPE + unit;
-
- snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
- np = new_node(name, vio_root);
- if (!np)
- goto hv_free;
- if (!add_string_property(np, "name", "viotape") ||
- !add_string_property(np, "device_type", "byte") ||
- !add_string_property(np, "compatible",
- "IBM,iSeries-viotape") ||
- !add_raw_property(np, "reg", sizeof(reg), ®) ||
- !add_raw_property(np, "linux,unit_address",
- sizeof(unit), &unit) ||
- !add_raw_property(np, "linux,vio_rsrcname",
- sizeof(unitinfo[unit].rsrcname),
- unitinfo[unit].rsrcname) ||
- !add_raw_property(np, "linux,vio_type",
- sizeof(unitinfo[unit].type),
- unitinfo[unit].type) ||
- !add_raw_property(np, "linux,vio_model",
- sizeof(unitinfo[unit].model),
- unitinfo[unit].model))
- goto node_free;
- np->name = of_get_property(np, "name", NULL);
- np->type = of_get_property(np, "device_type", NULL);
- of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
- if (vio_root->pde) {
- struct proc_dir_entry *ent;
-
- ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
- vio_root->pde);
- if (ent)
- proc_device_tree_add_node(np, ent);
- }
-#endif
- continue;
-
- node_free:
- free_node(np);
- break;
+ if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit,
+ unit, "byte", "IBM,iSeries-viotape",
+ &unitinfo[unit]))
+ break;
}
hv_free:
@@ -422,6 +540,7 @@ static int __init iseries_vio_init(void)
goto put_node;
}
+ get_viodasd_info(vio_root);
get_viocd_info(vio_root);
get_viotape_info(vio_root);
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index af3969a..e824b67 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -74,53 +74,9 @@ enum {
static DEFINE_SPINLOCK(viodasd_spinlock);
#define VIOMAXREQ 16
-#define VIOMAXBLOCKDMA 12
#define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0])
-struct open_data {
- u64 disk_size;
- u16 max_disk;
- u16 cylinders;
- u16 tracks;
- u16 sectors;
- u16 bytes_per_sector;
-};
-
-struct rw_data {
- u64 offset;
- struct {
- u32 token;
- u32 reserved;
- u64 len;
- } dma_info[VIOMAXBLOCKDMA];
-};
-
-struct vioblocklpevent {
- struct HvLpEvent event;
- u32 reserved;
- u16 version;
- u16 sub_result;
- u16 disk;
- u16 flags;
- union {
- struct open_data open_data;
- struct rw_data rw_data;
- u64 changed;
- } u;
-};
-
-#define vioblockflags_ro 0x0001
-
-enum vioblocksubtype {
- vioblockopen = 0x0001,
- vioblockclose = 0x0002,
- vioblockread = 0x0003,
- vioblockwrite = 0x0004,
- vioblockflush = 0x0005,
- vioblockcheck = 0x0007
-};
-
struct viodasd_waitevent {
struct completion com;
int rc;
@@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q)
* Probe a single disk and fill in the viodasd_device structure
* for it.
*/
-static void probe_disk(struct viodasd_device *d)
+static int probe_disk(struct viodasd_device *d)
{
HvLpEvent_Rc hvrc;
struct viodasd_waitevent we;
@@ -453,14 +409,14 @@ retry:
0, 0, 0);
if (hvrc != 0) {
printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
- return;
+ return 0;
}
wait_for_completion(&we.com);
if (we.rc != 0) {
if (flags != 0)
- return;
+ return 0;
/* try again with read only flag set */
flags = vioblockflags_ro;
goto retry;
@@ -490,15 +446,32 @@ retry:
if (hvrc != 0) {
printk(VIOD_KERN_WARNING
"bad rc sending event to OS/400 %d\n", (int)hvrc);
- return;
+ return 0;
}
+
+ if (d->dev == NULL) {
+ /* this is when we reprobe for new disks */
+ if (vio_create_viodasd(dev_no) == NULL) {
+ printk(VIOD_KERN_WARNING
+ "cannot allocate virtual device for disk %d\n",
+ dev_no);
+ return 0;
+ }
+ /*
+ * The vio_create_viodasd will have recursed into this
+ * routine with d->dev set to the new vio device and
+ * will finish the setup of the disk below.
+ */
+ return 1;
+ }
+
/* create the request queue for the disk */
spin_lock_init(&d->q_lock);
q = blk_init_queue(do_viodasd_request, &d->q_lock);
if (q == NULL) {
printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
dev_no);
- return;
+ return 0;
}
g = alloc_disk(1 << PARTITION_SHIFT);
if (g == NULL) {
@@ -506,7 +479,7 @@ retry:
"cannot allocate disk structure for disk %d\n",
dev_no);
blk_cleanup_queue(q);
- return;
+ return 0;
}
d->disk = g;
@@ -538,6 +511,7 @@ retry:
/* register us in the global list */
add_disk(g);
+ return 1;
}
/* returns the total number of scatterlist elements converted */
@@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
d->dev = &vdev->dev;
- probe_disk(d);
- if (d->disk == NULL)
+ if (!probe_disk(d))
return -ENODEV;
return 0;
}
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 2555dfd..f9ac0d0 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,51 @@
*/
#define VIO_MAX_SUBTYPES 8
+#define VIOMAXBLOCKDMA 12
+
+struct open_data {
+ u64 disk_size;
+ u16 max_disk;
+ u16 cylinders;
+ u16 tracks;
+ u16 sectors;
+ u16 bytes_per_sector;
+};
+
+struct rw_data {
+ u64 offset;
+ struct {
+ u32 token;
+ u32 reserved;
+ u64 len;
+ } dma_info[VIOMAXBLOCKDMA];
+};
+
+struct vioblocklpevent {
+ struct HvLpEvent event;
+ u32 reserved;
+ u16 version;
+ u16 sub_result;
+ u16 disk;
+ u16 flags;
+ union {
+ struct open_data open_data;
+ struct rw_data rw_data;
+ u64 changed;
+ } u;
+};
+
+#define vioblockflags_ro 0x0001
+
+enum vioblocksubtype {
+ vioblockopen = 0x0001,
+ vioblockclose = 0x0002,
+ vioblockread = 0x0003,
+ vioblockwrite = 0x0004,
+ vioblockflush = 0x0005,
+ vioblockcheck = 0x0007
+};
+
struct viocdlpevent {
struct HvLpEvent event;
u32 reserved;
@@ -133,6 +178,8 @@ extern void vio_set_hostlp(void);
extern void *vio_get_event_buffer(int subtype);
extern void vio_free_event_buffer(int subtype, void *buffer);
+extern struct vio_dev *vio_create_viodasd(u32 unit);
+
extern HvLpIndex viopath_hostLp;
extern HvLpIndex viopath_ourLp;
--
1.5.3.4
^ permalink raw reply related
* Re: [PATCH] Device tree bindings for Xilinx devices
From: David Gibson @ 2007-10-11 5:08 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40710102158r5d488d3kae3d02177625da1e@mail.gmail.com>
On Wed, Oct 10, 2007 at 10:58:25PM -0600, Grant Likely wrote:
> On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > On Wed, Oct 10, 2007 at 10:18:50PM -0600, Grant Likely wrote:
> > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> > > > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > > > We've used 'cell-index' for similar purposes on other 4xx.
> > > > >
> > > > > Unfortunately, 'cell' has been used in the sense of a logic cell in an
> > > > > SoC. In the case of the SystemACE, it is an external chip.
> > > > >
> > > > > What about "device-number"?
> > > >
> > > > Ok, I misunderstood. If it's not on chip, what significance does this
> > > > serial number have? Where would a driver need it?
> > >
> > > If there were 2 systemace devices on board; one attached to a CF slot
> > > labeled "1" and the other to one labeled "2". :-) Same problem as
> > > lining up serial device files to physical port numbers.
> > >
> > > The driver doesn't technically need it, but the information does need
> > > to flow through to the creation of logically numbered device files.
> >
> > Ah. Then, I'm afraid it doesn't belong in the core binding.
> >
> > Preferably, you should just figure out something without help of this
> > property - plenty of other things have to figure out device names
> > without assistance like this.
>
> I'm not too stuck on the method used, but I do think it is appropriate
> to encode this kind of data in the device tree in some form...
> However, for this particular device I'm probably just borrowing
> trouble. I'll drop the property.
>
> My main concern is that I don't like the implicit numbering that
> occurs simply based on the order of devices in the device tree. If
> the probe algorithm ever changes to parse in reverse order or
> something reorders the tree, then the device numbers also change. :-(
Way of the future, apparently, everything's supposed to use udev to
give things logical names. No, I'm not thrilled at the prospect
either.
> I'd rather be explicit. In fact I've already been bitten by this
> where the mpc5200 has 6 PSC, each of which can be configured as a
> serial port. However, I've got access to 3 different boards; each of
> which has the logical port numbers 100% unrelated to the 'cell'
> number.
In any case, this can't really belong in a *device* binding. Because
the numbering has to cross devices of the same basic type, but
different implementations. Where "basic type" is based on how device
names are allocated, and is thus inherently Linux specific.
> > If you really must you could do this in analogy with the
> > "linux,network-index" property - but this would be, as that is, an
> > ugly hack, and should be recognized as such
> >
> > Segher's suggestion of using OF-style aliases for this is a fairly
> > good one, actually. I just need to get to implementing it...
>
> /me needs to look up what that look like and how I would use it. My
> knowledge of OF is sadly lacking.
Short version by example:
/ {
/* ... */
aliases {
hd = "/pci@f0000000/sata@f4000000/....";
enet0 = "/soc/ethernet@c000";
enet1 = "/soc/ethernet@d000";
enet2 = "/pci@f0000000/isa/ethernet@i480"
ttya = "/soc/serial@e000";
ttyb = "/pci/isa/serail@3f8";
}
}
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* [PATCH] [POWERPC] move of_platform_driver initialisations: arch/powerpc
From: Stephen Rothwell @ 2007-10-11 5:19 UTC (permalink / raw)
To: paulus
Cc: Olof Johansson, ppc-dev, Arnd Bergmann, Maxim Shchetynin,
Christian Krafft
We no longer initialise the name and owner fields of the
of_platform_driver, but use the fields of the embedded device_driver's
name field instead.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/platforms/pasemi/gpio_mdio.c | 4 +++-
arch/powerpc/sysdev/axonram.c | 8 +++++---
arch/powerpc/sysdev/pmi.c | 6 ++++--
3 files changed, 12 insertions(+), 6 deletions(-)
This patch depends on my "Prepare to remove of_platform_driver name"
patch.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index c91a335..dae9f65 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -320,10 +320,12 @@ static struct of_device_id gpio_mdio_match[] =
static struct of_platform_driver gpio_mdio_driver =
{
- .name = "gpio-mdio-bitbang",
.match_table = gpio_mdio_match,
.probe = gpio_mdio_probe,
.remove = gpio_mdio_remove,
+ .driver = {
+ .name = "gpio-mdio-bitbang",
+ },
};
int gpio_mdio_init(void)
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index ab037a3..4d3ba63 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -324,11 +324,13 @@ static struct of_device_id axon_ram_device_id[] = {
};
static struct of_platform_driver axon_ram_driver = {
- .owner = THIS_MODULE,
- .name = AXON_RAM_MODULE_NAME,
.match_table = axon_ram_device_id,
.probe = axon_ram_probe,
- .remove = axon_ram_remove
+ .remove = axon_ram_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = AXON_RAM_MODULE_NAME,
+ },
};
/**
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index 2f91b55..20edd1e 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -205,10 +205,12 @@ static int pmi_of_remove(struct of_device *dev)
}
static struct of_platform_driver pmi_of_platform_driver = {
- .name = "pmi",
.match_table = pmi_match,
.probe = pmi_of_probe,
- .remove = pmi_of_remove
+ .remove = pmi_of_remove,
+ .driver = {
+ .name = "pmi",
+ },
};
static int __init pmi_module_init(void)
--
1.5.3.4
^ permalink raw reply related
* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11 5:25 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011145332.e3638c2e.sfr@canb.auug.org.au>
Hi Stephen,
On Thu, Oct 11, 2007 at 02:53:32PM +1000, Stephen Rothwell wrote:
> It was only being used to carry around dma_iommu_ops and vio_iommu_table
> which we can use directly instead. This also means that vio_bus_device
> doesn't need to refer to them either.
>
> diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
> index fd631d4..eaf7f69 100644
> --- a/arch/powerpc/kernel/vio.c
> +++ b/arch/powerpc/kernel/vio.c
> @@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device = { /* fake "parent" device */
> };
>
> #ifdef CONFIG_PPC_ISERIES
> -struct device *iSeries_vio_dev = &vio_bus_device.dev;
> -EXPORT_SYMBOL(iSeries_vio_dev);
> -
> static struct iommu_table veth_iommu_table;
> -static struct iommu_table vio_iommu_table;
> +struct iommu_table vio_iommu_table;
>
> static void __init iommu_vio_init(void)
> {
> @@ -66,8 +63,6 @@ static void __init iommu_vio_init(void)
> printk("Virtual Bus VETH TCE table failed.\n");
> if (!iommu_init_table(&vio_iommu_table, -1))
> printk("Virtual Bus VIO TCE table failed.\n");
> - vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
> - vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
> }
> #else
> static void __init iommu_vio_init(void)
> diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
> index 3b6a966..3281f10 100644
> --- a/arch/powerpc/platforms/iseries/iommu.c
> +++ b/arch/powerpc/platforms/iseries/iommu.c
> @@ -28,6 +28,7 @@
> #include <linux/dma-mapping.h>
> #include <linux/list.h>
> #include <linux/pci.h>
> +#include <linux/module.h>
>
> #include <asm/iommu.h>
> #include <asm/tce.h>
> @@ -36,6 +37,7 @@
> #include <asm/prom.h>
> #include <asm/pci-bridge.h>
> #include <asm/iseries/hv_call_xm.h>
> +#include <asm/iseries/hv_call_event.h>
> #include <asm/iseries/iommu.h>
>
> static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
> @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
> }
> #endif
>
> +extern struct iommu_table vio_iommu_table;
This looks like it really should go in a header file
instead. include/asm-powerpc/vio.h perhaps?
-Olof
^ permalink raw reply
* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11 5:27 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011052535.GA578@lixom.net>
On Thu, Oct 11, 2007 at 12:25:35AM -0500, Olof Johansson wrote:
> Hi Stephen,
>
> > @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
> > }
> > #endif
> >
> > +extern struct iommu_table vio_iommu_table;
>
> This looks like it really should go in a header file
> instead. include/asm-powerpc/vio.h perhaps?
Oh nevermind, I just noticed the variable got moved in the next
patch. Twice the review work!
-Olof
^ permalink raw reply
* Re: [PATCH] [POWERPC] move of_platform_driver initialisations: arch/powerpc
From: Olof Johansson @ 2007-10-11 5:30 UTC (permalink / raw)
To: Stephen Rothwell
Cc: Maxim Shchetynin, ppc-dev, paulus, Arnd Bergmann,
Christian Krafft
In-Reply-To: <20071011151903.efa8fdb8.sfr@canb.auug.org.au>
On Thu, Oct 11, 2007 at 03:19:03PM +1000, Stephen Rothwell wrote:
> We no longer initialise the name and owner fields of the
> of_platform_driver, but use the fields of the embedded device_driver's
> name field instead.
>
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Olof Johansson <olof@lixom.net>
-Olof
^ permalink raw reply
* Re: [PATCH] Device tree bindings for Xilinx devices
From: Grant Likely @ 2007-10-11 5:27 UTC (permalink / raw)
To: Grant Likely, Josh Boyer, linuxppc-dev
In-Reply-To: <20071011050850.GI14873@localhost.localdomain>
On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > My main concern is that I don't like the implicit numbering that
> > occurs simply based on the order of devices in the device tree. If
> > the probe algorithm ever changes to parse in reverse order or
> > something reorders the tree, then the device numbers also change. :-(
>
> Way of the future, apparently, everything's supposed to use udev to
> give things logical names. No, I'm not thrilled at the prospect
> either.
...
So in the OF aliases approach, would udev need to read the aliases
node when assigning names to devices?
>
> > I'd rather be explicit. In fact I've already been bitten by this
> > where the mpc5200 has 6 PSC, each of which can be configured as a
> > serial port. However, I've got access to 3 different boards; each of
> > which has the logical port numbers 100% unrelated to the 'cell'
> > number.
>
> In any case, this can't really belong in a *device* binding. Because
> the numbering has to cross devices of the same basic type, but
> different implementations. Where "basic type" is based on how device
> names are allocated, and is thus inherently Linux specific.
Okay, that makes sense.
> > > Segher's suggestion of using OF-style aliases for this is a fairly
> > > good one, actually. I just need to get to implementing it...
> >
> > /me needs to look up what that look like and how I would use it. My
> > knowledge of OF is sadly lacking.
>
> Short version by example:
> / {
> /* ... */
> aliases {
> hd = "/pci@f0000000/sata@f4000000/....";
> enet0 = "/soc/ethernet@c000";
> enet1 = "/soc/ethernet@d000";
> enet2 = "/pci@f0000000/isa/ethernet@i480"
> ttya = "/soc/serial@e000";
> ttyb = "/pci/isa/serail@3f8";
> }
> }
Ah, my plan worked... I got you to teach me about OF aliases and I
have to do any work myself. :-)
Hmm, yes that would provide the information nicely. As long as the
data is in the tree, I'm pretty happy.
Cheers,
g.
>
> --
> David Gibson | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
> | _way_ _around_!
> http://www.ozlabs.org/~dgibson
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Stephen Rothwell @ 2007-10-11 5:29 UTC (permalink / raw)
To: Olof Johansson; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011052731.GB578@lixom.net>
[-- Attachment #1: Type: text/plain, Size: 337 bytes --]
Hi Olof,
On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> Oh nevermind, I just noticed the variable got moved in the next
> patch. Twice the review work!
Thanks for the review in any case.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11 5:55 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011152949.4a78ec1b.sfr@canb.auug.org.au>
On Thu, Oct 11, 2007 at 03:29:49PM +1000, Stephen Rothwell wrote:
> Hi Olof,
>
> On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
> >
> > Oh nevermind, I just noticed the variable got moved in the next
> > patch. Twice the review work!
>
> Thanks for the review in any case.
No problem. It's hard to split up changes like that anyway, I don't
blame you.
Rest of the patches look good to me. I had another couple of comments
but they were fixed by the end of the series too. :-)
-Olof
^ permalink raw reply
* Re: [PATCH v2] powerpc: don't enable cpu hotplug on mpic-based pseries
From: Paul Mackerras @ 2007-10-11 5:52 UTC (permalink / raw)
To: Olof Johansson
Cc: Stephen Rothwell, Greg KH, Greg KH, linux-kernel, Chris Wedgwood,
linuxppc-dev, tgall.foo, Thomas Gleixner, Linus Torvalds, stable
In-Reply-To: <20071010003824.GA8477@lixom.net>
Olof Johansson writes:
> Don't allow cpu hotplug on systems lacking XICS interrupt controller,
> since current code is hardcoded for it.
...
> + for (np = NULL; (np = of_find_node_by_name(np,
> + "interrupt-controller"));) {
Looks like for_each_node_by_name would be nicer here.
If you agree, I'll hand-edit your patch to do that and apply it. Of
course, ultimately we should implement the necessary mpic bits to
support cpu hotplug.
Paul.
^ permalink raw reply
* Re: [PATCH v2] powerpc: don't enable cpu hotplug on mpic-based pseries
From: Olof Johansson @ 2007-10-11 5:59 UTC (permalink / raw)
To: Paul Mackerras
Cc: Stephen Rothwell, Greg KH, Greg KH, linux-kernel, Chris Wedgwood,
linuxppc-dev, tgall.foo, Thomas Gleixner, Linus Torvalds, stable
In-Reply-To: <18189.47620.466515.645055@cargo.ozlabs.ibm.com>
On Thu, Oct 11, 2007 at 03:52:04PM +1000, Paul Mackerras wrote:
> Olof Johansson writes:
>
> > Don't allow cpu hotplug on systems lacking XICS interrupt controller,
> > since current code is hardcoded for it.
> ...
> > + for (np = NULL; (np = of_find_node_by_name(np,
> > + "interrupt-controller"));) {
>
> Looks like for_each_node_by_name would be nicer here.
>
> If you agree, I'll hand-edit your patch to do that and apply it.
Go for it, I just stole that out of the detection code. That
could be changed accordingly as well at some point (I'm guessing
for_each_node_by_name didn't exist when that was written).
> Of course, ultimately we should implement the necessary mpic bits to
> support cpu hotplug.
Yep. I'll leave that to people who have hardware access. :-)
Thanks,
-Olof
^ permalink raw reply
* Re: [PATCH 2/3] [POWERPC] Add AMCC Kilauea eval board support to platforms/40x
From: Stefan Roese @ 2007-10-11 6:06 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Olof Johansson
In-Reply-To: <1192045466.5534.60.camel@localhost.localdomain>
On Wednesday 10 October 2007, Josh Boyer wrote:
> > > Do you really need config options for 405EP/EX? I don't seem them used
> > > anywhere else in the code (and it's also contradictory to the whole new
> > > multiplatform way of looking at stuff :).
> > >
> > > I know the 405/440 is still somewhat #ifdef:ed on the cpu here and
> > > there, but since this doesn't add any such code I don't see a need for
> > > the config options?
> >
> > Yes, I'm still used to needing these defines from arch/ppc (for example
> > for the 4xx EMAC driver). But its possible, that we really don't need it
> > at all in arch/powerpc with all the device tree information. Not sure
> > though.
> >
> > Josh, what do you think? Should I remove the 405EX define completely?
>
> If it's not needed, it can go. As Olof said, it doesn't appear to be
> used anywhere in the code so I think it's fine.
OK, I'll remove it. If we later see that we need it, we can always add it
again.
> One question I do have is if 405EX and 405EP need any of the 405GP
> errata config options selected. I would like to think those don't apply
> because the hardware is fixed, but I haven't checked to be sure.
Yes, the 2 405 errata's IBM405_ERR51 and IBM405_ERR77 do not apply to "newer"
405 cores. Only 405GP (and 405CR I assume) are affected.
Best regards,
Stefan
^ permalink raw reply
* [patch 0/2] add Altivec/VMX state to coredumps
From: markn @ 2007-10-11 7:15 UTC (permalink / raw)
To: linuxppc-dev
--
Here's the new and improved patch to add Altivec/VMX state into the coredump.
It's now two patches:
* the first patch makes the note type of the state dumped by
elf_core_copy_task_xfpregs() a #define and adds the appropriate #defines so
that archs that support SSE still have their note type as NT_PRXFPREG
* the second patch actually adds the Altivec/VMX state to the coredumps and
uses a note type of NT_PPC_VMX that's #defined as 0x100. Thus SPE could use
a note type of NT_PPC_SPE and 0x101, for example.
The second patch is essentially the same as the single patch that was posted on
2007-09-25, but with the addition of the new NT_PPC_VMX note type.
^ permalink raw reply
* [patch 1/2] Replace NT_PRXFPREG with ELF_CORE_XFPREG_TYPE #define
From: markn @ 2007-10-11 7:15 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20071011071558.676463639@au1.ibm.com>
Replace NT_PRXFPREG with ELF_CORE_XFPREG_TYPE in the coredump code which
allows for more flexibility in the note type for the state of 'extended
floating point' implementations in coredumps. New note types can now be
added with an appropriate #define.
#define ELF_CORE_XFPREG_TYPE to be NT_PRXFPREG in all current users so
there's are no change in behaviour.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/ia64/ia32/elfcore32.h | 1 +
arch/x86_64/ia32/ia32_binfmt.c | 1 +
fs/binfmt_elf.c | 4 ++--
include/asm-i386/elf.h | 1 +
4 files changed, 5 insertions(+), 2 deletions(-)
Index: linux/arch/ia64/ia32/elfcore32.h
===================================================================
--- linux.orig/arch/ia64/ia32/elfcore32.h
+++ linux/arch/ia64/ia32/elfcore32.h
@@ -117,6 +117,7 @@ elf_core_copy_task_fpregs(struct task_st
}
#define ELF_CORE_COPY_XFPREGS 1
+#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
static inline int
elf_core_copy_task_xfpregs(struct task_struct *tsk, elf_fpxregset_t *xfpu)
{
Index: linux/arch/x86_64/ia32/ia32_binfmt.c
===================================================================
--- linux.orig/arch/x86_64/ia32/ia32_binfmt.c
+++ linux/arch/x86_64/ia32/ia32_binfmt.c
@@ -188,6 +188,7 @@ elf_core_copy_task_fpregs(struct task_st
}
#define ELF_CORE_COPY_XFPREGS 1
+#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
static inline int
elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
{
Index: linux/fs/binfmt_elf.c
===================================================================
--- linux.orig/fs/binfmt_elf.c
+++ linux/fs/binfmt_elf.c
@@ -1446,8 +1446,8 @@ static int elf_dump_thread_status(long s
#ifdef ELF_CORE_COPY_XFPREGS
if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
- fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
- &t->xfpu);
+ fill_note(&t->notes[2], "LINUX", ELF_CORE_XFPREG_TYPE,
+ sizeof(t->xfpu), &t->xfpu);
t->num_notes++;
sz += notesize(&t->notes[2]);
}
Index: linux/include/asm-i386/elf.h
===================================================================
--- linux.orig/include/asm-i386/elf.h
+++ linux/include/asm-i386/elf.h
@@ -129,6 +129,7 @@ extern int dump_task_extended_fpu (struc
#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
#define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
+#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
#define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
--
^ permalink raw reply
* [patch 2/2] add Altivec/VMX state to coredumps
From: markn @ 2007-10-11 7:16 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20071011071558.676463639@au1.ibm.com>
Update dump_task_altivec() (that has so far never been put to use)
so that it dumps the Altivec/VMX registers (VR[0] - VR[31], VSCR
and VRSAVE) in the same format as the ptrace get_vrregs() and add
the appropriate glue typedef and #defines to make it work.
A new note type of NT_PPC_VMX was chosen to be 0x100 (arbitrarily)
because it allows the low range values to be used for more generic
purposes and 0x100 seems an adequate starting point for PowerPC
extensions.
Signed-off-by: Mark Nelson <markn@au1.ibm.com>
---
arch/powerpc/kernel/process.c | 28 +++++++++++++++++++++++++---
include/asm-powerpc/elf.h | 8 ++++++++
include/linux/elf.h | 1 +
3 files changed, 34 insertions(+), 3 deletions(-)
Index: linux/arch/powerpc/kernel/process.c
===================================================================
--- linux.orig/arch/powerpc/kernel/process.c
+++ linux/arch/powerpc/kernel/process.c
@@ -149,10 +149,32 @@ void flush_altivec_to_thread(struct task
}
}
-int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+int dump_task_altivec(struct task_struct *tsk, elf_vrregset_t *vrregs)
{
- flush_altivec_to_thread(current);
- memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs));
+ /* ELF_NVRREG includes the VSCR and VRSAVE which we need to save
+ * separately, see below */
+ const int nregs = ELF_NVRREG - 2;
+ elf_vrreg_t *reg;
+ u32 *dest;
+
+ if (tsk == current)
+ flush_altivec_to_thread(tsk);
+
+ reg = (elf_vrreg_t *)vrregs;
+
+ /* copy the 32 vr registers */
+ memcpy(reg, &tsk->thread.vr[0], nregs * sizeof(*reg));
+ reg += nregs;
+
+ /* copy the vscr */
+ memcpy(reg, &tsk->thread.vscr, sizeof(*reg));
+ reg++;
+
+ /* vrsave is stored in the high 32bit slot of the final 128bits */
+ memset(reg, 0, sizeof(*reg));
+ dest = (u32 *)reg;
+ *dest = tsk->thread.vrsave;
+
return 1;
}
#endif /* CONFIG_ALTIVEC */
Index: linux/include/asm-powerpc/elf.h
===================================================================
--- linux.orig/include/asm-powerpc/elf.h
+++ linux/include/asm-powerpc/elf.h
@@ -212,6 +212,14 @@ static inline int dump_task_regs(struct
extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+typedef elf_vrregset_t elf_fpxregset_t;
+
+#ifdef CONFIG_ALTIVEC
+extern int dump_task_altivec(struct task_struct *, elf_vrregset_t *vrregs);
+#define ELF_CORE_COPY_XFPREGS(tsk, regs) dump_task_altivec(tsk, regs)
+#define ELF_CORE_XFPREG_TYPE NT_PPC_VMX
+#endif
+
#endif /* __KERNEL__ */
/* ELF_HWCAP yields a mask that user programs can use to figure out what
Index: linux/include/linux/elf.h
===================================================================
--- linux.orig/include/linux/elf.h
+++ linux/include/linux/elf.h
@@ -355,6 +355,7 @@ typedef struct elf64_shdr {
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
/* Note header in a PT_NOTE section */
--
^ permalink raw reply
* RE: [PATCH 4/9] add platform support for MPC837x MDS board
From: Li Yang-r58472 @ 2007-10-11 7:28 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev, paulus
In-Reply-To: <20071011110546.99239e24.sfr@canb.auug.org.au>
> -----Original Message-----
> From: Stephen Rothwell [mailto:sfr@canb.auug.org.au]=20
> Sent: Thursday, October 11, 2007 9:06 AM
> To: Li Yang-r58472
> Cc: galak@kernel.crashing.org; paulus@samba.org;=20
> linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 4/9] add platform support for MPC837x MDS board
>=20
> On Wed, 10 Oct 2007 18:06:39 +0800 Li Yang=20
> <leoli@freescale.com> wrote:
> >
> > +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
> >
> > +#include <asm/of_platform.h>
>=20
> You actually neeed linux/of.h (for of_ routines) and=20
> asm/prom.h (for of_flat_dt_is_compatible).
Thanks for the comments. Updated version on the way.
- Leo
^ permalink raw reply
* [PATCH v2] Fix regression. Make hot unlplug of CPU0 work again.
From: Tony Breeds @ 2007-10-11 7:30 UTC (permalink / raw)
To: Milton Miller, Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <200710051716.l95HG1cV019434@sullivan.realtime.net>
Early in the 2.6.23 cycle we broke the ability to offline cpu0
(7ccb4a662462616f6be5053e26b79580e02f1529). This patch fixes that by
ensuring that the (xics) default irq server, will not be 0 when taking
cpu0 offline.
Also catches a use of irq, when virq should be used (I think that's the
last one).
This patch also include the fix from Milton which makes JS21 work
aswell. In the commit message for that patch Milton writes:
xics_set_affinity no longer looks at the cpu_mask arg, instead
get_irq_server reads it from the irq descriptor.
Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Milton also says in his patch:
> A more complete fix might be to pass the cpu_mask struct to get_irq_server,
> but kernel/irq/manage.c currently sets the descriptor first.
arch/powerpc/platforms/pseries/xics.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index f0b5ff1..217ae5d 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -837,6 +837,15 @@ void xics_migrate_irqs_away(void)
/* Allow IPIs again... */
xics_set_cpu_priority(cpu, DEFAULT_PRIORITY);
+ /* It would be bad to migrate any IRQs to the CPU we're taking down */
+ if (default_server == cpu) {
+ unsigned int new_server = first_cpu(cpu_online_map);
+
+ default_server = get_hard_smp_processor_id(new_server);
+ printk(KERN_WARNING "%s: default server was %d, reset to %d\n",
+ __func__, cpu, default_server);
+ }
+
for_each_irq(virq) {
struct irq_desc *desc;
int xics_status[2];
@@ -881,8 +890,8 @@ void xics_migrate_irqs_away(void)
virq, cpu);
/* Reset affinity to all cpus */
+ irq_desc[virq].affinity = CPU_MASK_ALL;
desc->chip->set_affinity(virq, CPU_MASK_ALL);
- irq_desc[irq].affinity = CPU_MASK_ALL;
unlock:
spin_unlock_irqrestore(&desc->lock, flags);
}
Yours Tony
linux.conf.au http://linux.conf.au/ || http://lca2008.linux.org.au/
Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!
^ permalink raw reply related
* port gnome
From: Bai Shuwei @ 2007-10-11 8:22 UTC (permalink / raw)
To: linuxppc-embedded, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 339 bytes --]
all, hi
I want to port the GNOME or KDE to AMCC PowerPC 440EP board. I want to
know whether it will run and whether the monitor work if I use PCI to
connect the monitor card? Thank you very much!
Buroc
--
Add: Tianshui South Road 222, Lanzhou, P.R.China
Tel: +86-931-8912025
Zip Code: 730000
Email: baishuwei@gmail.com, buroc@126.com
[-- Attachment #2: Type: text/html, Size: 516 bytes --]
^ permalink raw reply
* Re: port gnome
From: Benjamin Herrenschmidt @ 2007-10-11 8:32 UTC (permalink / raw)
To: Bai Shuwei; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <f3566d60710110122q23a0c49bkf0b8e8fd4f66b1e9@mail.gmail.com>
On Thu, 2007-10-11 at 16:22 +0800, Bai Shuwei wrote:
>
> all, hi
> I want to port the GNOME or KDE to AMCC PowerPC 440EP board. I want
> to know whether it will run and whether the monitor work if I use PCI
> to connect the monitor card? Thank you very much!
Gnome and KDE themselves should just work...
The problem is to get a video card working. The main issue is to
soft-boot it with some kind of x86 emulator such as x86emu. Once
that's done, the second main problem is that 440 tend to have
PCI memory space above 32bits, which totally defeats broken X
hacks through /dev/mem.
There's a way to work around the later by doing a kernel tweak to
create a "window" in /dev/mem that gets remapped to the appropriate
PCI space, but you still need to fake the card base address for
X ... pretty hard overall (doable though).
Ben.
^ permalink raw reply
* Kconfig selects non-existent IBM_NEW_EMAC_ZMII
From: Robert P. J. Day @ 2007-10-11 8:29 UTC (permalink / raw)
To: Linux PPC Mailing List
just FYI, from arch/powerpc/platforms/4xx/Kconfig:
...
config 440GP
bool
select IBM_NEW_EMAC_ZMII
...
there is no such Kconfig variable IBM_NEW_EMAC_ZMII.
rday
--
========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry
Waterloo, Ontario, CANADA
http://crashcourse.ca
========================================================================
^ permalink raw reply
* Re: [PATCH v2] Fix regression. Make hot unlplug of CPU0 work again.
From: Michael Neuling @ 2007-10-11 8:37 UTC (permalink / raw)
To: Tony Breeds; +Cc: linuxppc-dev, Paul Mackerras, Milton Miller
In-Reply-To: <20071011073040.GD9814@bakeyournoodle.com>
In message <20071011073040.GD9814@bakeyournoodle.com> you wrote:
>
> Early in the 2.6.23 cycle we broke the ability to offline cpu0
> (7ccb4a662462616f6be5053e26b79580e02f1529). This patch fixes that by
> ensuring that the (xics) default irq server, will not be 0 when taking
> cpu0 offline.
>
> Also catches a use of irq, when virq should be used (I think that's the
> last one).
>
> This patch also include the fix from Milton which makes JS21 work
> aswell. In the commit message for that patch Milton writes:
> xics_set_affinity no longer looks at the cpu_mask arg, instead
> get_irq_server reads it from the irq descriptor.
This doesn't fix the problem for me.
If I offline CPU0, then online it again, it's fine, but doing the same
for CPU1 kills the machine.
Mikey
>
> Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
> Signed-off-by: Milton Miller <miltonm@bga.com>
>
> ---
> Milton also says in his patch:
> > A more complete fix might be to pass the cpu_mask struct to get_irq_server,
> > but kernel/irq/manage.c currently sets the descriptor first.
>
> arch/powerpc/platforms/pseries/xics.c | 11 ++++++++++-
> 1 files changed, 10 insertions(+), 1 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/p
series/xics.c
> index f0b5ff1..217ae5d 100644
> --- a/arch/powerpc/platforms/pseries/xics.c
> +++ b/arch/powerpc/platforms/pseries/xics.c
> @@ -837,6 +837,15 @@ void xics_migrate_irqs_away(void)
> /* Allow IPIs again... */
> xics_set_cpu_priority(cpu, DEFAULT_PRIORITY);
>
> + /* It would be bad to migrate any IRQs to the CPU we're taking down */
> + if (default_server == cpu) {
> + unsigned int new_server = first_cpu(cpu_online_map);
> +
> + default_server = get_hard_smp_processor_id(new_server);
> + printk(KERN_WARNING "%s: default server was %d, reset to %d\n",
> + __func__, cpu, default_server);
> + }
> +
> for_each_irq(virq) {
> struct irq_desc *desc;
> int xics_status[2];
> @@ -881,8 +890,8 @@ void xics_migrate_irqs_away(void)
> virq, cpu);
>
> /* Reset affinity to all cpus */
> + irq_desc[virq].affinity = CPU_MASK_ALL;
> desc->chip->set_affinity(virq, CPU_MASK_ALL);
> - irq_desc[irq].affinity = CPU_MASK_ALL;
> unlock:
> spin_unlock_irqrestore(&desc->lock, flags);
> }
>
> Yours Tony
>
> linux.conf.au http://linux.conf.au/ || http://lca2008.linux.org.au/
> Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [PATCH 3/3] [POWERPC] Kilauea DTS
From: Stefan Roese @ 2007-10-11 8:49 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1192047714.5534.81.camel@localhost.localdomain>
On Wednesday 10 October 2007, Josh Boyer wrote:
> On Mon, 2007-10-08 at 11:10 +0200, Stefan Roese wrote:
> > Signed-off-by: Stefan Roese <sr@denx.de>
>
> Looks pretty good. Just a couple of questions.
>
> > ---
> > arch/powerpc/boot/dts/kilauea.dts | 253
> > +++++++++++++++++++++++++++++++++++++ 1 files changed, 253 insertions(+),
> > 0 deletions(-)
> > create mode 100644 arch/powerpc/boot/dts/kilauea.dts
> >
> > diff --git a/arch/powerpc/boot/dts/kilauea.dts
> > b/arch/powerpc/boot/dts/kilauea.dts new file mode 100644
> > index 0000000..4683174
> > --- /dev/null
> > +++ b/arch/powerpc/boot/dts/kilauea.dts
> > @@ -0,0 +1,253 @@
> > +/*
> > + * Device Tree Source for AMCC Kilauea (405EX)
> > + *
> > + * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2. This program is licensed "as is" without
> > + * any warranty of any kind, whether express or implied.
> > + */
> > +
> > +/ {
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + model = "amcc,kilauea";
> > + compatible = "amcc,kilauea";
> > + dcr-parent = <&/cpus/PowerPC,405EX@0>;
> > +
> > + cpus {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + PowerPC,405EX@0 {
> > + device_type = "cpu";
> > + reg = <0>;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
>
> Filled in by U-Boot itself? Or by a cuboot wrapper? (which I can't find
> in the patches.)
By U-Boot itself. I have a U-Boot patch in the queue to add device tree
support for 4xx. Therefor I don't plan adding a cuboot wrapper for Kilauea.
> > + timebase-frequency = <0>; /* Filled in by U-Boot */
> > + i-cache-line-size = <20>;
> > + d-cache-line-size = <20>;
> > + i-cache-size = <4000>; /* 16 kB */
> > + d-cache-size = <4000>; /* 16 kB */
> > + dcr-controller;
> > + dcr-access-method = "native";
> > + };
> > + };
> > +
> > + memory {
> > + device_type = "memory";
> > + reg = <0 0>; /* Filled in by U-Boot */
> > + };
> > +
> > + UIC0: interrupt-controller {
> > + compatible = "ibm,uic-405ex", "ibm,uic";
> > + interrupt-controller;
> > + cell-index = <0>;
> > + dcr-reg = <0c0 009>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + #interrupt-cells = <2>;
> > + };
> > +
> > + UIC1: interrupt-controller1 {
> > + compatible = "ibm,uic-405ex","ibm,uic";
> > + interrupt-controller;
> > + cell-index = <1>;
> > + dcr-reg = <0d0 009>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + #interrupt-cells = <2>;
> > + interrupts = <1e 4 1f 4>; /* cascade */
> > + interrupt-parent = <&UIC0>;
> > + };
> > +
> > + UIC2: interrupt-controller2 {
> > + compatible = "ibm,uic-405ex","ibm,uic";
> > + interrupt-controller;
> > + cell-index = <2>;
> > + dcr-reg = <0e0 009>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + #interrupt-cells = <2>;
> > + interrupts = <1c 4 1d 4>; /* cascade */
> > + interrupt-parent = <&UIC0>;
> > + };
> > +
> > + plb {
> > + compatible = "ibm,plb-405ex", "ibm,plb4";
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + ranges;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
> > +
> > + SDRAM0: memory-controller {
> > + compatible = "ibm,sdram-405ex";
> > + dcr-reg = <010 2>;
> > + };
> > +
> > + MAL0: mcmal {
> > + compatible = "ibm,mcmal-405ex", "ibm,mcmal2";
> > + dcr-reg = <180 62>;
> > + num-tx-chans = <2>;
> > + num-rx-chans = <2>;
> > + interrupt-parent = <&MAL0>;
> > + interrupts = <0 1 2 3 4>;
> > + #interrupt-cells = <1>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
> > + /*RXEOB*/ 1 &UIC0 b 4
> > + /*SERR*/ 2 &UIC1 0 4
> > + /*TXDE*/ 3 &UIC1 1 4
> > + /*RXDE*/ 4 &UIC1 2 4>;
> > + interrupt-map-mask = <ffffffff>;
> > + };
> > +
> > + POB0: opb {
> > + compatible = "ibm,opb-405ex", "ibm,opb";
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + ranges = <ef600000 ef600000 a00000>;
> > + dcr-reg = <0a0 5>;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
> > +
> > + EBC0: ebc {
> > + compatible = "ibm,ebc-405ex", "ibm,ebc";
> > + dcr-reg = <012 2>;
> > + #address-cells = <2>;
> > + #size-cells = <1>;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
> > + interrupts = <5 1>;
>
> This interrupt is really rising edge? Just double checking.
Yes, it is rising edge. I have to admit though, that I'm not sure if this
interrupt will ever be used at all.
> > + interrupt-parent = <&UIC1>;
> > +
> > + nor_flash@0,0 {
>
> You have no ranges property for the ebc parent node. Is if filled in by
> U-Boot? If so, please add a comment because otherwise I don't see how
> this mapping will work.
Yes, it's filled in by U-Boot too. I'll add a comment here.
> > + compatible = "amd,s29gl256n", "cfi-flash";
> > + bank-width = <2>;
> > + reg = <0 000000 4000000>;
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + partition@0 {
> > + label = "Kernel";
> > + reg = <0 180000>;
> > + };
> > + partition@180000 {
> > + label = "ramdisk";
> > + reg = <180000 200000>;
> > + };
> > + partition@380000 {
> > + label = "file system";
> > + reg = <380000 3aa0000>;
> > + };
> > + partition@3e20000 {
> > + label = "kozio";
> > + reg = <3e20000 140000>;
> > + };
> > + partition@3f60000 {
> > + label = "env";
> > + reg = <3f60000 40000>;
> > + };
> > + partition@3fa0000 {
> > + label = "u-boot";
> > + reg = <3fa0000 60000>;
> > + };
> > + };
> > + };
> > +
> > + UART0: serial@ef600200 {
> > + device_type = "serial";
> > + compatible = "ns16550";
> > + reg = <ef600200 8>;
> > + virtual-reg = <ef600200>;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
> > + current-speed = <0>;
> > + interrupt-parent = <&UIC0>;
> > + interrupts = <1a 4>;
> > + };
> > +
> > + UART1: serial@ef600300 {
> > + device_type = "serial";
> > + compatible = "ns16550";
> > + reg = <ef600300 8>;
> > + virtual-reg = <ef600300>;
> > + clock-frequency = <0>; /* Filled in by U-Boot */
> > + current-speed = <0>;
> > + interrupt-parent = <&UIC0>;
> > + interrupts = <1 4>;
> > + };
> > +
> > + IIC0: i2c@ef600400 {
> > + device_type = "i2c";
> > + compatible = "ibm,iic-405ex", "ibm,iic";
> > + reg = <ef600400 14>;
> > + interrupt-parent = <&UIC0>;
> > + interrupts = <2 4>;
> > + };
> > +
> > + IIC1: i2c@ef600500 {
> > + device_type = "i2c";
> > + compatible = "ibm,iic-405ex", "ibm,iic";
> > + reg = <ef600500 14>;
> > + interrupt-parent = <&UIC0>;
> > + interrupts = <7 4>;
> > + };
> > +
> > +
> > + RGMII0: emac-rgmii@ef600b00 {
> > + device_type = "rgmii-interface";
> > + compatible = "ibm,rgmii-405ex", "ibm,rgmii";
> > + reg = <ef600b00 104>;
> > + };
> > +
> > + EMAC0: ethernet@ef600900 {
> > + linux,network-index = <0>;
> > + device_type = "network";
> > + compatible = "ibm,emac-405ex", "ibm,emac4";
> > + interrupt-parent = <&EMAC0>;
> > + interrupts = <0 1>;
> > + #interrupt-cells = <1>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + interrupt-map = </*Status*/ 0 &UIC0 18 4
> > + /*Wake*/ 1 &UIC1 1d 4>;
> > + reg = <ef600900 70>;
> > + local-mac-address = [000000000000];
>
> Does U-Boot (or the wrapper) poke these values as well?
Yes, I'll add a comment here too.
> > + mal-device = <&MAL0>;
> > + mal-tx-channel = <0>;
> > + mal-rx-channel = <0>;
> > + cell-index = <0>;
> > + max-frame-size = <5dc>;
> > + rx-fifo-size = <1000>;
> > + tx-fifo-size = <800>;
> > + phy-mode = "rgmii";
> > + phy-map = <00000000>;
> > + rgmii-device = <&RGMII0>;
> > + rgmii-channel = <0>;
> > + };
> > +
> > + EMAC1: ethernet@ef600a00 {
> > + linux,network-index = <1>;
> > + device_type = "network";
> > + compatible = "ibm,emac-405ex", "ibm,emac4";
> > + interrupt-parent = <&EMAC1>;
> > + interrupts = <0 1>;
> > + #interrupt-cells = <1>;
> > + #address-cells = <0>;
> > + #size-cells = <0>;
> > + interrupt-map = </*Status*/ 0 &UIC0 19 4
> > + /*Wake*/ 1 &UIC1 1f 4>;
> > + reg = <ef600a00 70>;
> > + local-mac-address = [000000000000];
> > + mal-device = <&MAL0>;
> > + mal-tx-channel = <1>;
> > + mal-rx-channel = <1>;
> > + cell-index = <1>;
> > + max-frame-size = <5dc>;
> > + rx-fifo-size = <1000>;
> > + tx-fifo-size = <800>;
> > + phy-mode = "rgmii";
> > + phy-map = <00000000>;
> > + rgmii-device = <&RGMII0>;
> > + rgmii-channel = <1>;
> > + };
> > + };
> > + };
>
> No chosen node?
No. U-Boot will provide all needed information here.
Thanks.
Best regards,
Stefan
^ permalink raw reply
* [PATCH 3/9 v2] add Freescale SerDes PHY support
From: Li Yang @ 2007-10-11 9:53 UTC (permalink / raw)
To: galak, paulus, linuxppc-dev; +Cc: Li Yang
The SerDes(serializer/deserializer) PHY block is a new SoC block used
in Freescale chips to support multiple serial interfaces, such as PCI
Express, SGMII, SATA.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/platforms/Kconfig | 4 +
arch/powerpc/sysdev/Makefile | 1 +
arch/powerpc/sysdev/fsl_serdes.c | 170 ++++++++++++++++++++++++++++++++++++++
arch/powerpc/sysdev/fsl_serdes.h | 36 ++++++++
4 files changed, 211 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/sysdev/fsl_serdes.c
create mode 100644 arch/powerpc/sysdev/fsl_serdes.h
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 19d4628..e89f803 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -291,4 +291,8 @@ config FSL_ULI1575
Freescale reference boards. The boards all use the ULI in pretty
much the same way.
+config FSL_SERDES
+ bool
+ default n
+
endmenu
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 08ce31e..315aa36 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -19,6 +19,7 @@ mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += $(mv64x60-y) mv64x60_pic.o mv64x60_dev.o
obj-$(CONFIG_RTC_DRV_CMOS) += rtc_cmos_setup.o
obj-$(CONFIG_AXON_RAM) += axonram.o
+obj-$(CONFIG_FSL_SERDES) += fsl_serdes.o
# contains only the suspend handler for time
ifeq ($(CONFIG_RTC_CLASS),)
diff --git a/arch/powerpc/sysdev/fsl_serdes.c b/arch/powerpc/sysdev/fsl_serdes.c
new file mode 100644
index 0000000..8a04395
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_serdes.c
@@ -0,0 +1,170 @@
+/*
+ * arch/powerpc/sysdev/fsl_serdes.c
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ *
+ * Freescale SerDes initialization routines
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+
+#include "fsl_serdes.h"
+
+static int __init setup_serdes(struct device_node *np)
+{
+ void __iomem *regs;
+ const void *prot;
+ const unsigned int *freq;
+ struct resource res;
+ u32 tmp, rfcks;
+
+ of_address_to_resource(np, 0, &res);
+ regs = ioremap(res.start, res.end - res.start + 1);
+
+ prot = of_get_property(np, "protocol", NULL);
+ if (!prot)
+ return -EINVAL;
+ freq = of_get_property(np, "clock", NULL);
+ switch (*freq) {
+ case 100:
+ rfcks = FSL_SRDSCR4_RFCKS_100;
+ break;
+ case 125:
+ rfcks = FSL_SRDSCR4_RFCKS_125;
+ break;
+ case 150:
+ rfcks = FSL_SRDSCR4_RFCKS_150;
+ break;
+ default:
+ printk(KERN_ERR "SerDes: Wrong frequency\n");
+ return -EINVAL;
+ }
+
+ /* Use default prescale and counter */
+
+ /* 1.0V corevdd */
+ if (of_get_property(np, "vdd-1v", NULL)) {
+ /* DPPE/DPPA = 0 */
+ tmp = in_be32(regs + FSL_SRDSCR0_OFFS);
+ tmp &= ~FSL_SRDSCR0_DPP_1V2;
+ out_be32(regs + FSL_SRDSCR0_OFFS, tmp);
+
+ /* VDD = 0 */
+ tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+ tmp &= ~FSL_SRDSCR2_VDD_1V2;
+ out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+ }
+
+ /* protocol specific configuration */
+ if (!strcmp(prot, "sata")) {
+ /* Set and clear reset bits */
+ tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS);
+ tmp |= FSL_SRDSRSTCTL_SATA_RESET;
+ out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+ mdelay(1);
+ tmp &= ~FSL_SRDSRSTCTL_SATA_RESET;
+ out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+
+ /* Configure SRDSCR1 */
+ tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+ tmp &= ~FSL_SRDSCR1_PLLBW;
+ out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+ /* Configure SRDSCR2 */
+ tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+ tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+ tmp |= FSL_SRDSCR2_SEIC_SATA;
+ out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+ /* Configure SRDSCR3 */
+ tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA |
+ FSL_SRDSCR3_SDFM_SATA_PEX |
+ FSL_SRDSCR3_SDTXL_SATA;
+ out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
+
+ /* Configure SRDSCR4 */
+ tmp = rfcks | FSL_SRDSCR4_PROT_SATA;
+ out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+
+ } else if (!strcmp(prot, "pcie")) {
+ /* Configure SRDSCR1 */
+ tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+ tmp |= FSL_SRDSCR1_PLLBW;
+ out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+ /* Configure SRDSCR2 */
+ tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+ tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+ tmp |= FSL_SRDSCR2_SEIC_PEX;
+ out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+ /* Configure SRDSCR3 */
+ tmp = FSL_SRDSCR3_SDFM_SATA_PEX;
+ out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
+
+ /* Configure SRDSCR4 */
+ tmp = rfcks | FSL_SRDSCR4_PROT_PEX;
+ if (of_get_property(np, "pcie-x2", NULL))
+ tmp |= FSL_SRDSCR4_PLANE_X2;
+ out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+
+ } else if (!strcmp(prot, "sgmii")) {
+ /* Configure SRDSCR1 */
+ tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+ tmp &= ~FSL_SRDSCR1_PLLBW;
+ out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+ /* Configure SRDSCR2 */
+ tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+ tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+ tmp |= FSL_SRDSCR2_SEIC_SGMII;
+ out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+ /* Configure SRDSCR3 */
+ out_be32(regs + FSL_SRDSCR3_OFFS, 0);
+
+ /* Configure SRDSCR4 */
+ tmp = rfcks | FSL_SRDSCR4_PROT_SGMII;
+ out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+
+ } else {
+ printk(KERN_ERR "SerDes: Wrong protocol\n");
+ return -EINVAL;
+ }
+
+ /* Do a software reset */
+ tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS);
+ tmp |= FSL_SRDSRSTCTL_RST;
+ out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+
+ printk(KERN_INFO "Freescale SerDes at %8x initialized\n", res.start);
+
+ return 0;
+}
+
+static int __init fsl_serdes_init(void) {
+ struct device_node *np;
+
+ for (np = NULL; (np = of_find_compatible_node(np, NULL, "fsl,serdes")) != NULL;)
+ setup_serdes(np);
+
+ return 0;
+}
+
+arch_initcall(fsl_serdes_init);
diff --git a/arch/powerpc/sysdev/fsl_serdes.h b/arch/powerpc/sysdev/fsl_serdes.h
new file mode 100644
index 0000000..d4e5570
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_serdes.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/* SerDes registers */
+#define FSL_SRDSCR0_OFFS 0x0
+#define FSL_SRDSCR0_DPP_1V2 0x00008800
+#define FSL_SRDSCR1_OFFS 0x4
+#define FSL_SRDSCR1_PLLBW 0x00000040
+#define FSL_SRDSCR2_OFFS 0x8
+#define FSL_SRDSCR2_VDD_1V2 0x00800000
+#define FSL_SRDSCR2_SEIC_MASK 0x00001c1c
+#define FSL_SRDSCR2_SEIC_SATA 0x00001414
+#define FSL_SRDSCR2_SEIC_PEX 0x00001010
+#define FSL_SRDSCR2_SEIC_SGMII 0x00000101
+#define FSL_SRDSCR3_OFFS 0xc
+#define FSL_SRDSCR3_KFR_SATA 0x10100000
+#define FSL_SRDSCR3_KPH_SATA 0x04040000
+#define FSL_SRDSCR3_SDFM_SATA_PEX 0x01010000
+#define FSL_SRDSCR3_SDTXL_SATA 0x00000505
+#define FSL_SRDSCR4_OFFS 0x10
+#define FSL_SRDSCR4_PROT_SATA 0x00000808
+#define FSL_SRDSCR4_PROT_PEX 0x00000101
+#define FSL_SRDSCR4_PROT_SGMII 0x00000505
+#define FSL_SRDSCR4_PLANE_X2 0x01000000
+#define FSL_SRDSCR4_RFCKS_100 0x00000000
+#define FSL_SRDSCR4_RFCKS_125 0x10000000
+#define FSL_SRDSCR4_RFCKS_150 0x30000000
+#define FSL_SRDSRSTCTL_OFFS 0x20
+#define FSL_SRDSRSTCTL_RST 0x80000000
+#define FSL_SRDSRSTCTL_SATA_RESET 0xf
--
1.5.3.2.104.g41ef
^ permalink raw reply related
* [PATCH 4/9 v2] add platform support for MPC837x MDS board
From: Li Yang @ 2007-10-11 9:54 UTC (permalink / raw)
To: galak, paulus, linuxppc-dev; +Cc: Li Yang
The MPC837x MDS is a new member of Freescale MDS reference system.
Signed-off-by: Li Yang <leoli@freescale.com>
---
arch/powerpc/platforms/83xx/Kconfig | 12 ++++
arch/powerpc/platforms/83xx/Makefile | 1 +
arch/powerpc/platforms/83xx/mpc837x_mds.c | 102 +++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 0 deletions(-)
create mode 100644 arch/powerpc/platforms/83xx/mpc837x_mds.c
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index ec305f1..0c61e7a 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -50,6 +50,11 @@ config MPC836x_MDS
help
This option enables support for the MPC836x MDS Processor Board.
+config MPC837x_MDS
+ bool "Freescale MPC837x MDS"
+ select DEFAULT_UIMAGE
+ help
+ This option enables support for the MPC837x MDS Processor Board.
endchoice
config PPC_MPC831x
@@ -75,3 +80,10 @@ config PPC_MPC836x
select PPC_UDBG_16550
select PPC_INDIRECT_PCI
default y if MPC836x_MDS
+
+config PPC_MPC837x
+ bool
+ select PPC_UDBG_16550
+ select PPC_INDIRECT_PCI
+ select FSL_SERDES
+ default y if MPC837x_MDS
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 5a98f88..df46629 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o
obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o
+obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
new file mode 100644
index 0000000..4342173
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -0,0 +1,103 @@
+/*
+ * arch/powerpc/platforms/83xx/mpc837x_mds.c
+ *
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * MPC837x MDS board specific routines
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/pci.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/time.h>
+#include <asm/ipic.h>
+#include <asm/udbg.h>
+
+#include "mpc83xx.h"
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+/* ************************************************************************
+ *
+ * Setup the architecture
+ *
+ */
+static void __init mpc837x_mds_setup_arch(void)
+{
+#ifdef CONFIG_PCI
+ struct device_node *np;
+#endif
+
+ if (ppc_md.progress)
+ ppc_md.progress("mpc837x_mds_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+ for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+ mpc83xx_add_bridge(np);
+#endif
+}
+
+static struct of_device_id mpc837x_ids[] = {
+ { .type = "soc", },
+ { .compatible = "soc", },
+ {},
+};
+
+static int __init mpc837x_declare_of_platform_devices(void)
+{
+ if (!machine_is(mpc837x_mds))
+ return 0;
+
+ /* Publish of_device */
+ of_platform_bus_probe(NULL, mpc837x_ids, NULL);
+
+ return 0;
+}
+device_initcall(mpc837x_declare_of_platform_devices);
+
+static void __init mpc837x_mds_init_IRQ(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
+ if (!np)
+ return;
+
+ ipic_init(np, 0);
+
+ /* Initialize the default interrupt mapping priorities,
+ * in case the boot rom changed something on us.
+ */
+ ipic_set_default_priority();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init mpc837x_mds_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ return of_flat_dt_is_compatible(root, "fsl,mpc837xmds");
+}
+
+define_machine(mpc837x_mds) {
+ .name = "MPC837x MDS",
+ .probe = mpc837x_mds_probe,
+ .setup_arch = mpc837x_mds_setup_arch,
+ .init_IRQ = mpc837x_mds_init_IRQ,
+ .get_irq = ipic_get_irq,
+ .restart = mpc83xx_restart,
+ .time_init = mpc83xx_time_init,
+ .calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
+};
--
1.5.3.2.104.g41ef
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox