* [patch 05/16] PS3: Add repository polling loop to work around timing bug
From: Geoff Levand @ 2008-01-18 20:30 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20080118202612.422185192@am.sony.com>
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
PS3: Add repository polling loop to work around timing bug
On some firmware versions (e.g. 1.90), the storage device may not show up
in the repository immediately after receiving the notification message.
Add a small polling loop to make sure we don't miss it.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/device-init.c | 46 ++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 13 deletions(-)
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -489,6 +489,38 @@ static int ps3_register_repository_devic
return result;
}
+static void ps3_find_and_add_device(u64 bus_id, u64 dev_id)
+{
+ struct ps3_repository_device repo;
+ int res;
+ unsigned int retries;
+ unsigned long rem;
+
+ /*
+ * On some firmware versions (e.g. 1.90), the device may not show up
+ * in the repository immediately
+ */
+ for (retries = 0; retries < 10; retries++) {
+ res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id);
+ if (!res)
+ goto found;
+
+ rem = msleep_interruptible(100);
+ if (rem)
+ break;
+ }
+ pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__,
+ bus_id, dev_id);
+ return;
+
+found:
+ if (retries)
+ pr_debug("%s:%u: device %lu:%lu found after %u retries\n",
+ __func__, __LINE__, bus_id, dev_id, retries);
+
+ ps3_register_repository_device(&repo);
+ return;
+}
#define PS3_NOTIFICATION_DEV_ID ULONG_MAX
#define PS3_NOTIFICATION_INTERRUPT_ID 0
@@ -600,7 +632,6 @@ static struct task_struct *probe_task;
static int ps3_probe_thread(void *data)
{
struct ps3_notification_device dev;
- struct ps3_repository_device repo;
int res;
unsigned int irq;
u64 lpar;
@@ -682,18 +713,7 @@ static int ps3_probe_thread(void *data)
continue;
}
- res = ps3_repository_find_device_by_id(&repo, dev.sbd.bus_id,
- notify_event->dev_id);
- if (res) {
- pr_warning("%s:%u: device %lu:%lu not found\n",
- __func__, __LINE__, dev.sbd.bus_id,
- notify_event->dev_id);
- continue;
- }
-
- pr_debug("%s:%u: device %lu:%lu found\n", __func__, __LINE__,
- dev.sbd.bus_id, notify_event->dev_id);
- ps3_register_repository_device(&repo);
+ ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id);
} while (!kthread_should_stop());
--
^ permalink raw reply
* [patch 02/16] PS3: Make bus_id and dev_id u64
From: Geoff Levand @ 2008-01-18 20:30 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20080118202612.422185192@am.sony.com>
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Change the PS3 bus_id and dev_id from type unsigned int to u64. These
IDs are 64-bit in the repository, and the special storage notification
device has a device ID of ULONG_MAX.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/device-init.c | 4 ++--
arch/powerpc/platforms/ps3/mm.c | 8 ++++----
arch/powerpc/platforms/ps3/platform.h | 12 ++++++------
arch/powerpc/platforms/ps3/repository.c | 21 ++++++++-------------
arch/powerpc/platforms/ps3/system-bus.c | 14 +++++++-------
drivers/net/ps3_gelic_net.c | 4 ++--
include/asm-powerpc/ps3.h | 4 ++--
7 files changed, 31 insertions(+), 36 deletions(-)
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -297,7 +297,7 @@ static int ps3_storage_wait_for_device(c
u64 dev_port;
} *notify_event;
- pr_debug(" -> %s:%u: (%u:%u:%u)\n", __func__, __LINE__, repo->bus_id,
+ pr_debug(" -> %s:%u: (%lu:%lu:%u)\n", __func__, __LINE__, repo->bus_id,
repo->dev_id, repo->dev_type);
buf = kzalloc(512, GFP_KERNEL);
@@ -384,7 +384,7 @@ static int ps3_storage_wait_for_device(c
if (notify_event->dev_id == repo->dev_id &&
notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
- pr_debug("%s:%u: no access: dev_id %u\n", __func__,
+ pr_debug("%s:%u: no access: dev_id %lu\n", __func__,
__LINE__, repo->dev_id);
break;
}
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -359,7 +359,7 @@ static unsigned long dma_sb_lpar_to_bus(
static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r,
const char *func, int line)
{
- DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
+ DBG("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id,
r->dev->dev_id);
DBG("%s:%d: page_size %u\n", func, line, r->page_size);
DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
@@ -394,7 +394,7 @@ struct dma_chunk {
static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
int line)
{
- DBG("%s:%d: r.dev %u:%u\n", func, line,
+ DBG("%s:%d: r.dev %lu:%lu\n", func, line,
c->region->dev->bus_id, c->region->dev->dev_id);
DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
@@ -658,7 +658,7 @@ static int dma_sb_region_create(struct p
BUG_ON(!r);
if (!r->dev->bus_id) {
- pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+ pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
r->dev->bus_id, r->dev->dev_id);
return 0;
}
@@ -724,7 +724,7 @@ static int dma_sb_region_free(struct ps3
BUG_ON(!r);
if (!r->dev->bus_id) {
- pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+ pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__,
r->dev->bus_id, r->dev->dev_id);
return 0;
}
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -95,7 +95,7 @@ enum ps3_dev_type {
int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
u64 *value);
-int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id);
+int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id);
int ps3_repository_read_bus_type(unsigned int bus_index,
enum ps3_bus_type *bus_type);
int ps3_repository_read_bus_num_dev(unsigned int bus_index,
@@ -119,7 +119,7 @@ enum ps3_reg_type {
int ps3_repository_read_dev_str(unsigned int bus_index,
unsigned int dev_index, const char *dev_str, u64 *value);
int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
- unsigned int *dev_id);
+ u64 *dev_id);
int ps3_repository_read_dev_type(unsigned int bus_index,
unsigned int dev_index, enum ps3_dev_type *dev_type);
int ps3_repository_read_dev_intr(unsigned int bus_index,
@@ -138,12 +138,12 @@ int ps3_repository_read_dev_reg(unsigned
/* repository bus enumerators */
struct ps3_repository_device {
- enum ps3_bus_type bus_type;
unsigned int bus_index;
- unsigned int bus_id;
- enum ps3_dev_type dev_type;
unsigned int dev_index;
- unsigned int dev_id;
+ enum ps3_bus_type bus_type;
+ enum ps3_dev_type dev_type;
+ u64 bus_id;
+ u64 dev_id;
};
static inline struct ps3_repository_device *ps3_repository_bump_device(
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -168,18 +168,15 @@ int ps3_repository_read_bus_str(unsigned
value, 0);
}
-int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
+int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id)
{
int result;
- u64 v1;
- u64 v2; /* unused */
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
make_field("id", 0),
0, 0,
- &v1, &v2);
- *bus_id = v1;
+ bus_id, NULL);
return result;
}
@@ -225,18 +222,16 @@ int ps3_repository_read_dev_str(unsigned
}
int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
- unsigned int *dev_id)
+ u64 *dev_id)
{
int result;
- u64 v1;
result = read_node(PS3_LPAR_ID_PME,
make_first_field("bus", bus_index),
make_field("dev", dev_index),
make_field("id", 0),
0,
- &v1, 0);
- *dev_id = v1;
+ dev_id, 0);
return result;
}
@@ -332,7 +327,7 @@ int ps3_repository_find_device(struct ps
return result;
}
- pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n",
+ pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n",
__func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
num_dev);
@@ -387,7 +382,7 @@ int ps3_repository_find_device(struct ps
return result;
}
- pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n",
+ pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n",
__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
*repo = tmp;
@@ -1034,7 +1029,7 @@ static int dump_device_info(struct ps3_r
continue;
}
- pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
+ pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__,
__LINE__, repo->bus_index, repo->dev_index,
repo->dev_type, repo->dev_id);
@@ -1091,7 +1086,7 @@ int ps3_repository_dump_bus_info(void)
continue;
}
- pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
+ pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
__func__, __LINE__, repo.bus_index, repo.bus_type,
repo.bus_id, num_dev);
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -42,8 +42,8 @@ struct {
int gpu;
} static usage_hack;
-static int ps3_is_device(struct ps3_system_bus_device *dev,
- unsigned int bus_id, unsigned int dev_id)
+static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id,
+ u64 dev_id)
{
return dev->bus_id == bus_id && dev->dev_id == dev_id;
}
@@ -182,8 +182,8 @@ int ps3_open_hv_device(struct ps3_system
case PS3_MATCH_ID_SYSTEM_MANAGER:
pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
__LINE__, dev->match_id);
- pr_debug("%s:%d: bus_id: %u\n", __func__,
- __LINE__, dev->bus_id);
+ pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
+ dev->bus_id);
BUG();
return -EINVAL;
@@ -220,8 +220,8 @@ int ps3_close_hv_device(struct ps3_syste
case PS3_MATCH_ID_SYSTEM_MANAGER:
pr_debug("%s:%d: unsupported match_id: %u\n", __func__,
__LINE__, dev->match_id);
- pr_debug("%s:%d: bus_id: %u\n", __func__,
- __LINE__, dev->bus_id);
+ pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__,
+ dev->bus_id);
BUG();
return -EINVAL;
@@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(ps3_close_hv_device);
static void _dump_mmio_region(const struct ps3_mmio_region* r,
const char* func, int line)
{
- pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id,
+ pr_debug("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id,
r->dev->dev_id);
pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
pr_debug("%s:%d: len %lxh\n", func, line, r->len);
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -58,11 +58,11 @@ static inline struct device *ctodev(stru
{
return &card->dev->core;
}
-static inline unsigned int bus_id(struct gelic_net_card *card)
+static inline u64 bus_id(struct gelic_net_card *card)
{
return card->dev->bus_id;
}
-static inline unsigned int dev_id(struct gelic_net_card *card)
+static inline u64 dev_id(struct gelic_net_card *card)
{
return card->dev->dev_id;
}
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -344,8 +344,8 @@ struct ps3_system_bus_device {
enum ps3_match_id match_id;
enum ps3_system_bus_device_type dev_type;
- unsigned int bus_id; /* SB */
- unsigned int dev_id; /* SB */
+ u64 bus_id; /* SB */
+ u64 dev_id; /* SB */
unsigned int interrupt_id; /* SB */
struct ps3_dma_region *d_region; /* SB, IOC0 */
struct ps3_mmio_region *m_region; /* SB, IOC0*/
--
^ permalink raw reply
* [patch 04/16] PS3: Use the HVs storage device notification mechanism properly
From: Geoff Levand @ 2008-01-18 20:30 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20080118202612.422185192@am.sony.com>
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
The PS3 hypervisor has a storage device notification mechanism to wait until a
storage device is ready. Unfortunately the storage device probing code used
this mechanism in an incorrect way, needing a polling loop and handling of
devices that are not yet ready.
This change corrects this by:
- First waiting for the reception of an asynchronous notification that a new
storage device became ready,
- Then looking up the storage device in the device repository.
On shutdown, the storage probe thread is stopped and the storage notification
device is closed using a reboot notifier.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/device-init.c | 422 ++++++++++++++++---------------
arch/powerpc/platforms/ps3/platform.h | 2
arch/powerpc/platforms/ps3/repository.c | 29 --
3 files changed, 221 insertions(+), 232 deletions(-)
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/init.h>
+#include <linux/reboot.h>
#include <asm/firmware.h>
#include <asm/lv1call.h>
@@ -238,166 +239,6 @@ static int __init ps3_setup_vuart_device
return result;
}
-static int ps3stor_wait_for_completion(u64 dev_id, u64 tag,
- unsigned int timeout)
-{
- int result = -1;
- unsigned int retries = 0;
- u64 status;
-
- for (retries = 0; retries < timeout; retries++) {
- result = lv1_storage_check_async_status(dev_id, tag, &status);
- if (!result)
- break;
-
- msleep(1);
- }
-
- if (result)
- pr_debug("%s:%u: check_async_status: %s, status %lx\n",
- __func__, __LINE__, ps3_result(result), status);
-
- return result;
-}
-
-/**
- * ps3_storage_wait_for_device - Wait for a storage device to become ready.
- * @repo: The repository device to wait for.
- *
- * Uses the hypervisor's storage device notification mechanism to wait until
- * a storage device is ready. The device notification mechanism uses a
- * psuedo device (id = -1) to asynchronously notify the guest when storage
- * devices become ready. The notification device has a block size of 512
- * bytes.
- */
-
-static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo)
-{
- int error = -ENODEV;
- int result;
- const u64 notification_dev_id = (u64)-1LL;
- const unsigned int timeout = HZ;
- u64 lpar;
- u64 tag;
- void *buf;
- enum ps3_notify_type {
- notify_device_ready = 0,
- notify_region_probe = 1,
- notify_region_update = 2,
- };
- struct {
- u64 operation_code; /* must be zero */
- u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
- } *notify_cmd;
- struct {
- u64 event_type; /* enum ps3_notify_type */
- u64 bus_id;
- u64 dev_id;
- u64 dev_type;
- u64 dev_port;
- } *notify_event;
-
- pr_debug(" -> %s:%u: (%lu:%lu:%u)\n", __func__, __LINE__, repo->bus_id,
- repo->dev_id, repo->dev_type);
-
- buf = kzalloc(512, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- lpar = ps3_mm_phys_to_lpar(__pa(buf));
- notify_cmd = buf;
- notify_event = buf;
-
- result = lv1_open_device(repo->bus_id, notification_dev_id, 0);
- if (result) {
- printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__,
- __LINE__, ps3_result(result));
- goto fail_free;
- }
-
- /* Setup and write the request for device notification. */
-
- notify_cmd->operation_code = 0; /* must be zero */
- notify_cmd->event_mask = 1UL << notify_region_probe;
-
- result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar,
- &tag);
- if (result) {
- printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__,
- ps3_result(result));
- goto fail_close;
- }
-
- /* Wait for the write completion */
-
- result = ps3stor_wait_for_completion(notification_dev_id, tag,
- timeout);
- if (result) {
- printk(KERN_ERR "%s:%u: write not completed %s\n", __func__,
- __LINE__, ps3_result(result));
- goto fail_close;
- }
-
- /* Loop here processing the requested notification events. */
-
- while (1) {
- memset(notify_event, 0, sizeof(*notify_event));
-
- result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0,
- lpar, &tag);
- if (result) {
- printk(KERN_ERR "%s:%u: write failed %s\n", __func__,
- __LINE__, ps3_result(result));
- break;
- }
-
- result = ps3stor_wait_for_completion(notification_dev_id, tag,
- timeout);
- if (result) {
- printk(KERN_ERR "%s:%u: read not completed %s\n",
- __func__, __LINE__, ps3_result(result));
- break;
- }
-
- pr_debug("%s:%d: notify event (%u:%u:%u): event_type 0x%lx, "
- "port %lu\n", __func__, __LINE__, repo->bus_index,
- repo->dev_index, repo->dev_type,
- notify_event->event_type, notify_event->dev_port);
-
- if (notify_event->event_type != notify_region_probe ||
- notify_event->bus_id != repo->bus_id) {
- pr_debug("%s:%u: bad notify_event: event %lu, "
- "dev_id %lu, dev_type %lu\n",
- __func__, __LINE__, notify_event->event_type,
- notify_event->dev_id, notify_event->dev_type);
- break;
- }
-
- if (notify_event->dev_id == repo->dev_id &&
- notify_event->dev_type == repo->dev_type) {
- pr_debug("%s:%u: device ready (%u:%u:%u)\n", __func__,
- __LINE__, repo->bus_index, repo->dev_index,
- repo->dev_type);
- error = 0;
- break;
- }
-
- if (notify_event->dev_id == repo->dev_id &&
- notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) {
- pr_debug("%s:%u: no access: dev_id %lu\n", __func__,
- __LINE__, repo->dev_id);
- break;
- }
- }
-
-fail_close:
- lv1_close_device(repo->bus_id, notification_dev_id);
-fail_free:
- kfree(buf);
- pr_debug(" <- %s:%u\n", __func__, __LINE__);
- return error;
-}
-
static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
enum ps3_match_id match_id)
{
@@ -449,16 +290,6 @@ static int ps3_setup_storage_dev(const s
goto fail_find_interrupt;
}
- /* FIXME: Arrange to only do this on a 'cold' boot */
-
- result = ps3_storage_wait_for_device(repo);
- if (result) {
- printk(KERN_ERR "%s:%u: storage_notification failed %d\n",
- __func__, __LINE__, result);
- result = -ENODEV;
- goto fail_probe_notification;
- }
-
for (i = 0; i < num_regions; i++) {
unsigned int id;
u64 start, size;
@@ -494,7 +325,6 @@ static int ps3_setup_storage_dev(const s
fail_device_register:
fail_read_region:
-fail_probe_notification:
fail_find_interrupt:
kfree(p);
fail_malloc:
@@ -659,62 +489,248 @@ static int ps3_register_repository_devic
return result;
}
+
+#define PS3_NOTIFICATION_DEV_ID ULONG_MAX
+#define PS3_NOTIFICATION_INTERRUPT_ID 0
+
+struct ps3_notification_device {
+ struct ps3_system_bus_device sbd;
+ spinlock_t lock;
+ u64 tag;
+ u64 lv1_status;
+ struct completion done;
+};
+
+enum ps3_notify_type {
+ notify_device_ready = 0,
+ notify_region_probe = 1,
+ notify_region_update = 2,
+};
+
+struct ps3_notify_cmd {
+ u64 operation_code; /* must be zero */
+ u64 event_mask; /* OR of 1UL << enum ps3_notify_type */
+};
+
+struct ps3_notify_event {
+ u64 event_type; /* enum ps3_notify_type */
+ u64 bus_id;
+ u64 dev_id;
+ u64 dev_type;
+ u64 dev_port;
+};
+
+static irqreturn_t ps3_notification_interrupt(int irq, void *data)
+{
+ struct ps3_notification_device *dev = data;
+ int res;
+ u64 tag, status;
+
+ spin_lock(&dev->lock);
+ res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag,
+ &status);
+ if (tag != dev->tag)
+ pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n",
+ __func__, __LINE__, tag, dev->tag);
+
+ if (res) {
+ pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res,
+ status);
+ } else {
+ pr_debug("%s:%u: completed, status 0x%lx\n", __func__,
+ __LINE__, status);
+ dev->lv1_status = status;
+ complete(&dev->done);
+ }
+ spin_unlock(&dev->lock);
+ return IRQ_HANDLED;
+}
+
+static int ps3_notification_read_write(struct ps3_notification_device *dev,
+ u64 lpar, int write)
+{
+ const char *op = write ? "write" : "read";
+ unsigned long flags;
+ int res;
+
+ init_completion(&dev->done);
+ spin_lock_irqsave(&dev->lock, flags);
+ res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
+ &dev->tag)
+ : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar,
+ &dev->tag);
+ spin_unlock_irqrestore(&dev->lock, flags);
+ if (res) {
+ pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res);
+ return -EPERM;
+ }
+ pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op);
+
+ res = wait_event_interruptible(dev->done.wait,
+ dev->done.done || kthread_should_stop());
+ if (kthread_should_stop())
+ res = -EINTR;
+ if (res) {
+ pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op);
+ return res;
+ }
+
+ if (dev->lv1_status) {
+ pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__,
+ __LINE__, op, dev->lv1_status);
+ return -EIO;
+ }
+ pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op);
+
+ return 0;
+}
+
+static struct task_struct *probe_task;
+
/**
* ps3_probe_thread - Background repository probing at system startup.
*
* This implementation only supports background probing on a single bus.
+ * It uses the hypervisor's storage device notification mechanism to wait until
+ * a storage device is ready. The device notification mechanism uses a
+ * pseudo device to asynchronously notify the guest when storage devices become
+ * ready. The notification device has a block size of 512 bytes.
*/
static int ps3_probe_thread(void *data)
{
- struct ps3_repository_device *repo = data;
- int result;
- unsigned int ms = 250;
+ struct ps3_notification_device dev;
+ struct ps3_repository_device repo;
+ int res;
+ unsigned int irq;
+ u64 lpar;
+ void *buf;
+ struct ps3_notify_cmd *notify_cmd;
+ struct ps3_notify_event *notify_event;
pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
- do {
- try_to_freeze();
+ buf = kzalloc(512, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
- pr_debug("%s:%u: probing...\n", __func__, __LINE__);
+ lpar = ps3_mm_phys_to_lpar(__pa(buf));
+ notify_cmd = buf;
+ notify_event = buf;
- do {
- result = ps3_repository_find_device(repo);
+ /* dummy system bus device */
+ dev.sbd.bus_id = (u64)data;
+ dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
+ dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
+
+ res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0);
+ if (res) {
+ pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
+ __LINE__, ps3_result(res));
+ goto fail_free;
+ }
- if (result == -ENODEV)
- pr_debug("%s:%u: nothing new\n", __func__,
- __LINE__);
- else if (result)
- pr_debug("%s:%u: find device error.\n",
- __func__, __LINE__);
- else {
- pr_debug("%s:%u: found device (%u:%u:%u)\n",
- __func__, __LINE__, repo->bus_index,
- repo->dev_index, repo->dev_type);
- ps3_register_repository_device(repo);
- ps3_repository_bump_device(repo);
- ms = 250;
- }
- } while (!result);
+ res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY,
+ &irq);
+ if (res) {
+ pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
+ __func__, __LINE__, res);
+ goto fail_close_device;
+ }
+
+ spin_lock_init(&dev.lock);
+
+ res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED,
+ "ps3_notification", &dev);
+ if (res) {
+ pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
+ res);
+ goto fail_sb_event_receive_port_destroy;
+ }
- pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
+ /* Setup and write the request for device notification. */
+ notify_cmd->operation_code = 0; /* must be zero */
+ notify_cmd->event_mask = 1UL << notify_region_probe;
- if ( ms > 60000)
+ res = ps3_notification_read_write(&dev, lpar, 1);
+ if (res)
+ goto fail_free_irq;
+
+ /* Loop here processing the requested notification events. */
+ do {
+ try_to_freeze();
+
+ memset(notify_event, 0, sizeof(*notify_event));
+
+ res = ps3_notification_read_write(&dev, lpar, 0);
+ if (res)
break;
- msleep_interruptible(ms);
+ pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu"
+ " type %lu port %lu\n", __func__, __LINE__,
+ notify_event->event_type, notify_event->bus_id,
+ notify_event->dev_id, notify_event->dev_type,
+ notify_event->dev_port);
- /* An exponential backoff. */
- ms <<= 1;
+ if (notify_event->event_type != notify_region_probe ||
+ notify_event->bus_id != dev.sbd.bus_id) {
+ pr_warning("%s:%u: bad notify_event: event %lu, "
+ "dev_id %lu, dev_type %lu\n",
+ __func__, __LINE__, notify_event->event_type,
+ notify_event->dev_id,
+ notify_event->dev_type);
+ continue;
+ }
+
+ res = ps3_repository_find_device_by_id(&repo, dev.sbd.bus_id,
+ notify_event->dev_id);
+ if (res) {
+ pr_warning("%s:%u: device %lu:%lu not found\n",
+ __func__, __LINE__, dev.sbd.bus_id,
+ notify_event->dev_id);
+ continue;
+ }
+
+ pr_debug("%s:%u: device %lu:%lu found\n", __func__, __LINE__,
+ dev.sbd.bus_id, notify_event->dev_id);
+ ps3_register_repository_device(&repo);
} while (!kthread_should_stop());
+fail_free_irq:
+ free_irq(irq, &dev);
+fail_sb_event_receive_port_destroy:
+ ps3_sb_event_receive_port_destroy(&dev.sbd, irq);
+fail_close_device:
+ lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id);
+fail_free:
+ kfree(buf);
+
+ probe_task = NULL;
+
pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
return 0;
}
/**
+ * ps3_stop_probe_thread - Stops the background probe thread.
+ *
+ */
+
+static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code,
+ void *data)
+{
+ if (probe_task)
+ kthread_stop(probe_task);
+ return 0;
+}
+
+static struct notifier_block nb = {
+ .notifier_call = ps3_stop_probe_thread
+};
+
+/**
* ps3_start_probe_thread - Starts the background probe thread.
*
*/
@@ -723,7 +739,7 @@ static int __init ps3_start_probe_thread
{
int result;
struct task_struct *task;
- static struct ps3_repository_device repo; /* must be static */
+ struct ps3_repository_device repo;
pr_debug(" -> %s:%d\n", __func__, __LINE__);
@@ -746,7 +762,8 @@ static int __init ps3_start_probe_thread
return -ENODEV;
}
- task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
+ task = kthread_run(ps3_probe_thread, (void *)repo.bus_id,
+ "ps3-probe-%u", bus_type);
if (IS_ERR(task)) {
result = PTR_ERR(task);
@@ -755,6 +772,9 @@ static int __init ps3_start_probe_thread
return result;
}
+ probe_task = task;
+ register_reboot_notifier(&nb);
+
pr_debug(" <- %s:%d\n", __func__, __LINE__);
return 0;
}
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -89,8 +89,6 @@ enum ps3_dev_type {
PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */
PS3_DEV_TYPE_SB_GPIO = 6,
PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */
- PS3_DEV_TYPE_STOR_DUMMY = 32,
- PS3_DEV_TYPE_NOACCESS = 255,
};
int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -344,35 +344,6 @@ int ps3_repository_find_device(struct ps
return result;
}
- if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) {
- /*
- * A storage device may show up in the repository before the
- * hypervisor has finished probing its type and regions
- */
- unsigned int num_regions;
-
- if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) {
- pr_debug("%s:%u storage device not ready\n", __func__,
- __LINE__);
- return -ENODEV;
- }
-
- result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index,
- tmp.dev_index,
- &num_regions);
- if (result) {
- pr_debug("%s:%d read_stor_dev_num_regions failed\n",
- __func__, __LINE__);
- return result;
- }
-
- if (!num_regions) {
- pr_debug("%s:%u storage device has no regions yet\n",
- __func__, __LINE__);
- return -ENODEV;
- }
- }
-
result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index,
&tmp.dev_id);
--
^ permalink raw reply
* [patch 03/16] PS3: Add ps3_repository_find_device_by_id()
From: Geoff Levand @ 2008-01-18 20:30 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev
In-Reply-To: <20080118202612.422185192@am.sony.com>
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
The storage probe feature of the PS3 hypervisor returns device IDs. Add
the corresponding repository routine ps3_repository_find_device_by_id()
which can be used to retrieve the device info from the repository.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/platform.h | 2
arch/powerpc/platforms/ps3/repository.c | 77 ++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -153,6 +153,8 @@ static inline struct ps3_repository_devi
return repo;
}
int ps3_repository_find_device(struct ps3_repository_device *repo);
+int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
+ u64 bus_id, u64 dev_id);
int ps3_repository_find_devices(enum ps3_bus_type bus_type,
int (*callback)(const struct ps3_repository_device *repo));
int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -389,6 +389,83 @@ int ps3_repository_find_device(struct ps
return 0;
}
+int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
+ u64 bus_id, u64 dev_id)
+{
+ int result = -ENODEV;
+ struct ps3_repository_device tmp;
+ unsigned int num_dev;
+
+ pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__,
+ bus_id, dev_id);
+
+ for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
+ result = ps3_repository_read_bus_id(tmp.bus_index,
+ &tmp.bus_id);
+ if (result) {
+ pr_debug("%s:%u read_bus_id(%u) failed\n", __func__,
+ __LINE__, tmp.bus_index);
+ return result;
+ }
+
+ if (tmp.bus_id == bus_id)
+ goto found_bus;
+
+ pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__,
+ tmp.bus_id);
+ }
+ pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
+ return result;
+
+found_bus:
+ result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
+ if (result) {
+ pr_debug("%s:%u read_bus_type(%u) failed\n", __func__,
+ __LINE__, tmp.bus_index);
+ return result;
+ }
+
+ result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
+ if (result) {
+ pr_debug("%s:%u read_bus_num_dev failed\n", __func__,
+ __LINE__);
+ return result;
+ }
+
+ for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) {
+ result = ps3_repository_read_dev_id(tmp.bus_index,
+ tmp.dev_index,
+ &tmp.dev_id);
+ if (result) {
+ pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__,
+ __LINE__, tmp.bus_index, tmp.dev_index);
+ return result;
+ }
+
+ if (tmp.dev_id == dev_id)
+ goto found_dev;
+
+ pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__,
+ tmp.dev_id);
+ }
+ pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__);
+ return result;
+
+found_dev:
+ result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
+ &tmp.dev_type);
+ if (result) {
+ pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__);
+ return result;
+ }
+
+ pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n",
+ __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
+ tmp.dev_index, tmp.bus_id, tmp.dev_id);
+ *repo = tmp;
+ return 0;
+}
+
int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
int (*callback)(const struct ps3_repository_device *repo))
{
--
^ permalink raw reply
* RE: Adding new driver in Linux 2.6 - read fails with -1
From: Jenkins, Clive @ 2008-01-18 20:15 UTC (permalink / raw)
To: Ramkumar J; +Cc: linuxppc-embedded
In-Reply-To: <4f8c3030801180428k51645960sf0e1765f82eae1d8@mail.gmail.com>
> From: Ramkumar J [mailto:ramkumarj2000@gmail.com]=20
> Sent: 18 January 2008 12:29
> To: Jenkins, Clive
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: Adding new driver in Linux 2.6 - read fails with -1
> [...]
>=20
> Hi,
>=20
> Thanks a lot for replying. I will try using the perror() function and
> modify the busy-loop through wait-for functions. Also, the way I have
> accessed the memory mapped IO, is to ioremap() the physical address
> and then use readl() functions. Is this correct.=20
>=20
> Following is the link to the driver file,
> http://www.geocities.com/ramkumarj_2000/impulse-stream.c
> http://www.geocities.com/ramkumarj_2000/1.txt as impulse-stream.h
>
> This is intermediate layer and part of my application space,
> http://www.geocities.com/ramkumarj_2000/co_stream_linux.c
>=20
> The application is,
> http://www.geocities.com/ramkumarj_2000/HelloWorld.c
> http://www.geocities.com/ramkumarj_2000/HelloWorld_sw.c
>=20
> Logs at,
> http://www.geocities.com/ramkumarj_2000/logs.txt
> http://www.geocities.com/ramkumarj_2000/kernellog.txt
>=20
> My apologies for the dirty code. To add some background, it starts
> from the main() in HelloWorld.c and it proceeds calling the
> hear_hello() in HelloWorld_sw.c . The co_stream_* functions are
> defined in intermediate layer co_stream_linux.c and co_stream_open
> is defined to nothing in one header file. The open and ioctl call
> ( modified a little in the driver now for debugging) map from
> co_stream_attach.=20
> co_stream_read is read and co_stream_write is the write to driver.
=20
> Though the logs indicate the call of release function before the
> read, I m not quite sure about this as the read not being called
> have failed to get inside the kernel messages.
I still can't see everything because the header files are not shown.
But anyway, it is getting too complex. I think you need to cut the code
down to the mininum that causes the error if you want help from the
list.
A couple of hints regarding the driver's read method:
1. If you really want to copy different data sizes into the same
variable
then use a union.
2. *(char*)buffer=3Dx puts x where buffer points to; I think you wanted
to put x into the variable buffer: *(char*)&buffer =3D x, but this is
not very clear -- better to use a union.
3. copy_{to,from)_user() return values that should be checked. Always
check function return values (except maybe printf and printk), and
display all error information.
Clive
^ permalink raw reply
* [patch 00/16] PS3 patch collection for 2.6.25
From: Geoff Levand @ 2008-01-18 20:29 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Paul,
I collected together all the unapplied PS3 patches into a series
and re-based them to your for-2.6.25 branch.
Patches #14 and #15 are new, but just code cleanups. All other patches
have already been reviewed on the ML and have no outstanding comments
or requests.
Please apply for 2.6.25. If you like, I can re-base or breakup the
series as you like.
-Geoff
[01/16] POWERPC: Add Cell SPRN bookmark register
[02/16] PS3: Make bus_id and dev_id u64
[03/16] PS3: Add ps3_repository_find_device_by_id()
[04/16] PS3: Use the HVs storage device notification mechanism properly
[05/16] PS3: Add repository polling loop to work around timing bug
[06/16] PS3: Kill unused ps3_repository_bump_device()
[07/16] PS3: Refactor ps3_repository_find_device()
[08/16] PS3: Checkpatch cleanups for drivers/ps3/ps3-sys-manager.c
[09/16] PS3: Checkpatch cleanups for drivers/ps3/ps3-vuart.c
[10/16] PS3: Checkpatch cleanups for arch/powerpc/platforms/ps3/repository.c
[11/16] PS3: Add logical performance monitor repository routines
[12/16] PS3: Add logical performance monitor device support
[13/16] PS3: Add logical performance monitor driver support
[14/16] PS3: Vuart change semaphore to mutex
[15/16] PS3: Revove use lpar address workaround
[16/16] PS3: Update ps3_defconfig
--
^ permalink raw reply
* l2cr missing from /proc
From: Bob Brose @ 2008-01-18 18:53 UTC (permalink / raw)
To: linuxppc-dev
Why is l2cr missing from the /proc filesystem in recent 2.6 kernels?
Is it a bug or design decision?
It wasn't necessary since one could set it via a kernel arg however
now that I'm trying to turn on cache in a 7455 and setting l3cr isn't
supported from the command line I was wondering if l3cr was in /proc
as well but has also gone missing (since I see l3cr code in the kernel
source).
^ permalink raw reply
* Re: [PATCH/RFCv2] [POWERPC] Add support for freescale watchdog to CPM serial driver.
From: Alan Cox @ 2008-01-18 18:39 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev, linux-kernel
In-Reply-To: <478F4AE3.5090803@scram.de>
On Thu, 17 Jan 2008 13:32:35 +0100
Jochen Friedrich <jochen@scram.de> wrote:
> If a freescale watchdog device node is present, reset the watchdog
> while waiting for serial input.
Why ? We normally rely on user space for watchdog management as only the
fact user space is behaving really proves a box is happy ?
Alan
^ permalink raw reply
* Re: crash in kmem_cache_init
From: Christoph Lameter @ 2008-01-18 18:51 UTC (permalink / raw)
To: Olaf Hering
Cc: Mel Gorman, linuxppc-dev, Pekka Enberg, linux-kernel, Linux MM
In-Reply-To: <20080117211511.GA25320@aepfle.de>
On Thu, 17 Jan 2008, Olaf Hering wrote:
> Normal 892928 -> 892928
> Movable zone start PFN for each node
> early_node_map[1] active PFN ranges
> 1: 0 -> 892928
> Could not find start_pfn for node 0
We only have a single node that is node 1? And then we initialize nodes 0
to 3?
> Memory: 3496633k/3571712k available (6188k kernel code, 75080k reserved, 1324k data, 1220k bss, 304k init)
> cache_grow(2778) swapper(0):c0,j4294937299 cachep c0000000006a4fb8 nodeid 0 l3 c0000000005fddf0
> cache_grow(2778) swapper(0):c0,j4294937299 cachep c0000000006a4fb8 nodeid 1 l3 c0000000005fddf0
> cache_grow(2778) swapper(0):c0,j4294937299 cachep c0000000006a4fb8 nodeid 2 l3 c0000000005fddf0
> cache_grow(2778) swapper(0):c0,j4294937299 cachep c0000000006a4fb8 nodeid 3 l3 c0000000005fddf0
???
^ permalink raw reply
* Re: crash in kmem_cache_init
From: Christoph Lameter @ 2008-01-18 18:42 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, Pekka Enberg, linux-kernel, Linux MM
In-Reply-To: <20080118065621.GA27495@aepfle.de>
On Fri, 18 Jan 2008, Olaf Hering wrote:
> calls cache_grow with nodeid 0
> > [c00000000075bbd0] [c0000000000f82d0] .cache_alloc_refill+0x234/0x2c0
> calls cache_grow with nodeid 0
> > [c00000000075bbe0] [c0000000000f7f38] .____cache_alloc_node+0x17c/0x1e8
>
> calls cache_grow with nodeid 1
> > [c00000000075bbe0] [c0000000000f7d68] .fallback_alloc+0x1a0/0x1f4
Hmmm... fallback_alloc should not be called during bootstrap.
^ permalink raw reply
* Re: crash in kmem_cache_init
From: Christoph Lameter @ 2008-01-18 18:47 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, Pekka Enberg, linux-kernel, Linux MM
In-Reply-To: <20080117211511.GA25320@aepfle.de>
On Thu, 17 Jan 2008, Olaf Hering wrote:
> early_node_map[1] active PFN ranges
> 1: 0 -> 892928
> Could not find start_pfn for node 0
Corrupted min_pfn?
^ permalink raw reply
* Re: [PATCH/RFCv2] [POWERPC] Add support for freescale watchdog to CPM serial driver.
From: Jochen Friedrich @ 2008-01-18 18:47 UTC (permalink / raw)
To: Alan Cox; +Cc: Scott Wood, linuxppc-dev, linux-kernel
In-Reply-To: <20080118183905.2d5d8474@lxorguk.ukuu.org.uk>
Hi Alan,
>> If a freescale watchdog device node is present, reset the watchdog
>> while waiting for serial input.
>
> Why ? We normally rely on user space for watchdog management as only the
> fact user space is behaving really proves a box is happy ?
This is in the boot wrapper code, not in the linux kernel.
Thanks,
Jochen
^ permalink raw reply
* Re: MPIC ISU
From: vb @ 2008-01-18 18:44 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-embedded
In-Reply-To: <57351E05-13DE-48F0-B0E5-28AADEF288A1@kernel.crashing.org>
Kumar,
thank you for your reply!
On Jan 18, 2008 7:54 AM, Kumar Gala <galak@kernel.crashing.org> wrote:
>
> >
> > What is it, at the very least - what does ISU stand for?
> >
> > I would really appreciate any hints,
>
> Interrupt service unit. I believe its an IBM concept.
>
> For 8245 can you look at what the linkstation port is doing and mimic
> that. I believe its an 8245 or 8241 so it should be close to what you
> need.
>
what platform is linkstation and what kernel version can I find it in?
TIA,
/vb
> mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY |
> MPIC_WANTS_RESET, 4, 32, " EPIC ");
> BUG_ON(mpic == NULL);
>
> /* PCI IRQs */
> mpic_assign_isu(mpic, 0, paddr + 0x10200);
>
> /* I2C */
> mpic_assign_isu(mpic, 1, paddr + 0x11000);
>
> /* ttyS0, ttyS1 */
> mpic_assign_isu(mpic, 2, paddr + 0x11100);
>
> mpic_init(mpic);
>
> - k
>
^ permalink raw reply
* Re: Problems with PCI on 8280
From: Scott Wood @ 2008-01-18 17:07 UTC (permalink / raw)
To: Rune Torgersen; +Cc: linuxppc-dev
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B039BA0D8@ismail.innsys.innovsys.com>
On Thu, Jan 17, 2008 at 06:27:46PM -0600, Rune Torgersen wrote:
> BTW. there is a bug in the inbound window size calculation. The mem_log2
> variable sould be the shift value, not 1<< shift. and on the next line the
> window size mask sould be anded with 0x000f_ffff before or'ed with
> 0xa000_0000
D'oh. Thanks for spotting it!
-Scott
^ permalink raw reply
* Re: 2.6.24-rc8-mm1: powerpc oopses
From: Matt Mackall @ 2008-01-18 17:33 UTC (permalink / raw)
To: Mariusz Kozlowski; +Cc: linuxppc-dev, Andrew Morton, paulus, linux-kernel
In-Reply-To: <200801181823.07718.m.kozlowski@tuxland.pl>
On Fri, 2008-01-18 at 18:23 +0100, Mariusz Kozlowski wrote:
> Hello,
>
> > > Do we need `offset' at all?
> >
> > Looks like no.
> >
> > I wonder if there's a good argument for adding a pte_offset_val() which
> > would let us do:
> >
> > pteval = pte_offset_val(pmd, addr);
> >
> > and shrink the map/unmap window and overhead here and possibly
> > elsewhere?
> >
> > Anyway, updated but still untested patch now with revealing comment:
>
> I patched the ppc32 kernel with this and run tests on /proc.
> This patch helps. No more BUGs and oopses :)
Thanks, Andrew's already queued it up.
--
Mathematics is the supreme nostalgia of our time.
^ permalink raw reply
* Re: [PATCH/RFCv2] [POWERPC] Add support for freescale watchdog to CPM serial driver.
From: Jochen Friedrich @ 2008-01-18 17:33 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Stephen Rothwell, linux-kernel
In-Reply-To: <4790DC33.2070104@freescale.com>
Scott Wood schrieb:
>> +void watchdog_poke(void)
>> +{
>> + if (wdt) {
>> + out_be16(&wdt->swsrr, 0x556c);
>> + out_be16(&wdt->swsrr, 0xaa39);
>> + }
>> +}
>
> This should be a function pointer, to allow for other watchdog types.
Thanks for the comments. Stephen Rothwell also asked if the filename watchdog.c is too generic.
I think the pq watchdog is easy enough to keep it in the generic watchdog.c file, but the
function pointer definitely is the way to go. I'll resubmit.
Thanks,
Jochen
^ permalink raw reply
* Re: 2.6.24-rc8-mm1: powerpc oopses
From: Mariusz Kozlowski @ 2008-01-18 17:23 UTC (permalink / raw)
To: Matt Mackall; +Cc: linuxppc-dev, Andrew Morton, paulus, linux-kernel
In-Reply-To: <1200617237.3839.32.camel@cinder.waste.org>
Hello,
> > Do we need `offset' at all?
>
> Looks like no.
>
> I wonder if there's a good argument for adding a pte_offset_val() which
> would let us do:
>
> pteval = pte_offset_val(pmd, addr);
>
> and shrink the map/unmap window and overhead here and possibly
> elsewhere?
>
> Anyway, updated but still untested patch now with revealing comment:
I patched the ppc32 kernel with this and run tests on /proc.
This patch helps. No more BUGs and oopses :)
Thanks,
Mariusz
> diff -r 5595adaea70f fs/proc/task_mmu.c
> --- a/fs/proc/task_mmu.c Thu Jan 17 13:26:54 2008 -0600
> +++ b/fs/proc/task_mmu.c Thu Jan 17 18:45:57 2008 -0600
> @@ -584,18 +585,19 @@
> pte_t *pte;
> int err = 0;
>
> - pte = pte_offset_map(pmd, addr);
> - for (; addr != end; pte++, addr += PAGE_SIZE) {
> + for (; addr != end; addr += PAGE_SIZE) {
> u64 pfn = PM_NOT_PRESENT;
> + pte = pte_offset_map(pmd, addr);
> if (is_swap_pte(*pte))
> pfn = swap_pte_to_pagemap_entry(*pte);
> else if (pte_present(*pte))
> pfn = pte_pfn(*pte);
> + /* unmap so we're not in atomic when we copy to userspace */
> + pte_unmap(pte);
> err = add_to_pagemap(addr, pfn, pm);
> if (err)
> return err;
> }
> - pte_unmap(pte - 1);
>
> cond_resched();
^ permalink raw reply
* [RFC/PATCH 2/2] [POWERPC] Efika: prune fixups and make them more carefull
From: Grant Likely @ 2008-01-18 17:05 UTC (permalink / raw)
To: linuxppc-dev, jrigby, matt, tnt
In-Reply-To: <20080118170324.10592.47360.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Prune back Efika fixups to only include changes that are actually required
to get a working system. Most of the drivers can accept the compatible
properties, even if they don't match the what is recommented in the generic
names recommended practice document.
This patch also adds extra checks so that fixups are not performed blindly.
Instead, the code first verifies that the device tree is faulty before
making any changes. This way, if the Efika firmware is updated to fix
these issues, then the fixups will no longer get applied.
At this point; here is the list of fixups needed for the efika:
1. If the device_type property on the root node is 'chrp', then Linux won't
boot. Change device_type to 'efika' to avoid this condition
2. Add full interrupt list to the bestcomm node. In actual fact, the
bestcomm interrupts property is technically correct, it just doesn't
expose the same granularity as the device driver expects. All other
5200 device trees provide a separate irq number for each bestcomm
channel. Rather than hack the driver, it's simpler to fix it up
3. /builtin/sound node is missing an interrupts property
4. /builtin/ethernet node is missing a phy-handle property and the
device driver doesn't know what to do without one.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/kernel/prom_init.c | 149 +++++++++++++++++++++------------------
1 files changed, 79 insertions(+), 70 deletions(-)
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 5d89a21..5ab4c84 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2142,82 +2142,34 @@ static void __init fixup_device_tree_pmac(void)
#endif
#ifdef CONFIG_PPC_EFIKA
-/* The current fw of the Efika has a device tree needs quite a few
- * fixups to be compliant with the mpc52xx bindings. It's currently
- * unknown if it will ever be compliant (come on bPlan ...) so we do fixups.
- * NOTE that we (barely) tolerate it because the EFIKA was out before
- * the bindings were finished, for any new boards -> RTFM ! */
-
-struct subst_entry {
- char *path;
- char *property;
- void *value;
- int value_len;
-};
-
-static void __init fixup_device_tree_efika(void)
+/*
+ * The MPC5200 FEC driver requires an phy-handle property to tell it how
+ * to talk to the phy. If the phy-handle property is missing, then this
+ * function is called to add the appropriate nodes and link it to the
+ * ethernet node.
+ */
+static void __init fixup_device_tree_efika_add_phy(void)
{
- /* Substitution table */
- #define prop_cstr(x) x, sizeof(x)
- int prop_sound_irq[3] = { 2, 2, 0 };
- int prop_bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
- 3,4,0, 3,5,0, 3,6,0, 3,7,0,
- 3,8,0, 3,9,0, 3,10,0, 3,11,0,
- 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
- struct subst_entry efika_subst_table[] = {
- { "/", "device_type", prop_cstr("efika") },
- { "/builtin", "device_type", prop_cstr("soc") },
- { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), },
- { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") },
- { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) },
- { "/builtin/ethernet", "compatible", prop_cstr("mpc5200b-fec\0mpc5200-fec") },
- { "/builtin/pic", "compatible", prop_cstr("mpc5200b-pic\0mpc5200-pic") },
- { "/builtin/serial", "compatible", prop_cstr("mpc5200b-psc-uart\0mpc5200-psc-uart") },
- { "/builtin/sound", "compatible", prop_cstr("mpc5200b-psc-ac97\0mpc5200-psc-ac97") },
- { "/builtin/sound", "interrupts", prop_sound_irq, sizeof(prop_sound_irq) },
- { "/builtin/sram", "compatible", prop_cstr("mpc5200b-sram\0mpc5200-sram") },
- { "/builtin/sram", "device_type", prop_cstr("sram") },
- {}
- };
- #undef prop_cstr
-
- /* Vars */
u32 node;
char prop[64];
- int rv, i;
+ int rv;
- /* Check if we're really running on a EFIKA */
- node = call_prom("finddevice", 1, 1, ADDR("/"));
+ /* Check if /builtin/ethernet exists - bail if it doesn't */
+ node = call_prom("finddevice", 1, 1, ADDR("/builtin/ethernet"));
if (!PHANDLE_VALID(node))
return;
- rv = prom_getprop(node, "model", prop, sizeof(prop));
- if (rv == PROM_ERROR)
- return;
- if (strcmp(prop, "EFIKA5K2"))
+ /* Check if the phy-handle property exists - bail if it does */
+ rv = prom_getprop(node, "phy-handle", prop, sizeof(prop));
+ if (!rv)
return;
- prom_printf("Applying EFIKA device tree fixups\n");
-
- /* Process substitution table */
- for (i=0; efika_subst_table[i].path; i++) {
- struct subst_entry *se = &efika_subst_table[i];
-
- node = call_prom("finddevice", 1, 1, ADDR(se->path));
- if (!PHANDLE_VALID(node)) {
- prom_printf("fixup_device_tree_efika: ",
- "skipped entry %x - not found\n", i);
- continue;
- }
-
- rv = prom_setprop(node, se->path, se->property,
- se->value, se->value_len );
- if (rv == PROM_ERROR)
- prom_printf("fixup_device_tree_efika: ",
- "skipped entry %x - setprop error\n", i);
- }
+ /*
+ * At this point the ethernet device doesn't have a phy described.
+ * Now we need to add the missing phy node and linkage
+ */
- /* Make sure ethernet mdio bus node exists */
+ /* Check for an MDIO bus node - if missing then create one */
node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio"));
if (!PHANDLE_VALID(node)) {
prom_printf("Adding Ethernet MDIO node\n");
@@ -2226,8 +2178,8 @@ static void __init fixup_device_tree_efika(void)
" new-device"
" 1 encode-int s\" #address-cells\" property"
" 0 encode-int s\" #size-cells\" property"
- " s\" mdio\" 2dup device-name device-type"
- " s\" mpc5200b-fec-phy\" encode-string"
+ " s\" mdio\" device-name"
+ " s\" fsl,mpc5200b-mdio\" encode-string"
" s\" compatible\" property"
" 0xf0003000 0x400 reg"
" 0x2 encode-int"
@@ -2237,8 +2189,10 @@ static void __init fixup_device_tree_efika(void)
" finish-device");
};
- /* Make sure ethernet phy device node exist */
- node = call_prom("finddevice", 1, 1, ADDR("/builtin/mdio/ethernet-phy"));
+ /* Check for a PHY device node - if missing then create one and
+ * give it's phandle to the ethernet node */
+ node = call_prom("finddevice", 1, 1,
+ ADDR("/builtin/mdio/ethernet-phy"));
if (!PHANDLE_VALID(node)) {
prom_printf("Adding Ethernet PHY node\n");
call_prom("interpret", 1, 1,
@@ -2254,7 +2208,62 @@ static void __init fixup_device_tree_efika(void)
" s\" phy-handle\" property"
" device-end");
}
+}
+
+static void __init fixup_device_tree_efika(void)
+{
+ int sound_irq[3] = { 2, 2, 0 };
+ int bcomm_irq[3*16] = { 3,0,0, 3,1,0, 3,2,0, 3,3,0,
+ 3,4,0, 3,5,0, 3,6,0, 3,7,0,
+ 3,8,0, 3,9,0, 3,10,0, 3,11,0,
+ 3,12,0, 3,13,0, 3,14,0, 3,15,0 };
+ u32 node;
+ char prop[64];
+ int rv, len;
+
+ /* Check if we're really running on a EFIKA */
+ node = call_prom("finddevice", 1, 1, ADDR("/"));
+ if (!PHANDLE_VALID(node))
+ return;
+
+ rv = prom_getprop(node, "model", prop, sizeof(prop));
+ if (rv == PROM_ERROR)
+ return;
+ if (strcmp(prop, "EFIKA5K2"))
+ return;
+
+ prom_printf("Applying EFIKA device tree fixups\n");
+
+ /* Claiming to be 'chrp' is death */
+ node = call_prom("finddevice", 1, 1, ADDR("/"));
+ rv = prom_getprop(node, "device_type", prop, sizeof(prop));
+ if (rv != PROM_ERROR && (strcmp(prop, "chrp") == 0))
+ prom_setprop(node, "/", "device_type", "efika", sizeof("efika"));
+
+ /* Fixup bestcomm interrupts property */
+ node = call_prom("finddevice", 1, 1, ADDR("/builtin/bestcomm"));
+ if (PHANDLE_VALID(node)) {
+ len = prom_getproplen(node, "interrupts");
+ if (len == 12) {
+ prom_printf("Fixing bestcomm interrupts property\n");
+ prom_setprop(node, "/builtin/bestcom", "interrupts",
+ bcomm_irq, sizeof(bcomm_irq));
+ }
+ }
+
+ /* Fixup sound interrupts property */
+ node = call_prom("finddevice", 1, 1, ADDR("/builtin/sound"));
+ if (PHANDLE_VALID(node)) {
+ rv = prom_getprop(node, "interrupts", prop, sizeof(prop));
+ if (rv == PROM_ERROR) {
+ prom_printf("Adding sound interrupts property\n");
+ prom_setprop(node, "/builtin/sound", "interrupts",
+ sound_irq, sizeof(sound_irq));
+ }
+ }
+ /* Make sure ethernet phy-handle property exists */
+ fixup_device_tree_efika_add_phy();
}
#else
#define fixup_device_tree_efika()
^ permalink raw reply related
* [RFC/PATCH 1/2] [POWERPC] mpc5200: normalize compatible property bindings
From: Grant Likely @ 2008-01-18 17:04 UTC (permalink / raw)
To: linuxppc-dev, jrigby, matt, tnt
In-Reply-To: <20080118170324.10592.47360.stgit@trillian.secretlab.ca>
From: Grant Likely <grant.likely@secretlab.ca>
Update MPC5200 drivers to also look for compatible properties in the
form "fsl,mpc5200-*" to better conform to open firmware generic names
recommended practice as published here:
http://www.openfirmware.org/1275/practice/gnames/gnamv14a.html
This patch should *not* break compatibility with older device trees
which do not use the 'fsl,' prefix. The drivers will still bind against
the older names also.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
arch/powerpc/platforms/52xx/lite5200.c | 14 +++++++-
arch/powerpc/platforms/52xx/lite5200_pm.c | 8 ++++-
arch/powerpc/platforms/52xx/mpc52xx_common.c | 43 ++++++++++++++++----------
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 9 ++++-
arch/powerpc/platforms/52xx/mpc52xx_pic.c | 14 +++++++-
arch/powerpc/platforms/52xx/mpc52xx_pm.c | 8 ++++-
arch/powerpc/sysdev/bestcomm/bestcomm.c | 13 +++++---
drivers/ata/pata_mpc52xx.c | 6 +---
drivers/net/fec_mpc52xx.c | 6 +---
drivers/net/fec_mpc52xx_phy.c | 8 ++---
drivers/serial/mpc52xx_uart.c | 4 ++
drivers/spi/mpc52xx_psc_spi.c | 5 ++-
drivers/usb/host/ohci-ppc-of.c | 2 +
13 files changed, 94 insertions(+), 46 deletions(-)
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 5a8d190..f8ba5f2 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -44,9 +44,14 @@ lite5200_fix_clock_config(void)
{
struct device_node *np;
struct mpc52xx_cdm __iomem *cdm;
+ struct of_device_id cdm_ids[] = {
+ { .compatible = "fsl,mpc5200-cdm", },
+ { .compatible = "mpc5200-cdm", },
+ {}
+ };
/* Map zones */
- np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm");
+ np = of_find_matching_node(NULL, cdm_ids);
cdm = of_iomap(np, 0);
of_node_put(np);
if (!cdm) {
@@ -79,9 +84,14 @@ lite5200_fix_port_config(void)
{
struct device_node *np;
struct mpc52xx_gpio __iomem *gpio;
+ struct of_device_id gpio_ids[] = {
+ { .compatible = "fsl,mpc5200-gpio", },
+ { .compatible = "mpc5200-gpio", },
+ {}
+ };
u32 port_config;
- np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio");
+ np = of_find_matching_node(NULL, gpio_ids);
gpio = of_iomap(np, 0);
of_node_put(np);
if (!gpio) {
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index c3ada1e..1679662 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -43,6 +43,12 @@ static int lite5200_pm_set_target(suspend_state_t state)
static int lite5200_pm_prepare(void)
{
struct device_node *np;
+ struct of_device_id immr_ids[] = {
+ { .compatible = "fsl,mpc5200-immr", },
+ { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
+ { .type = "builtin", .compatible = "mpc5200", }, /* efika */
+ {}
+ };
/* deep sleep? let mpc52xx code handle that */
if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
@@ -52,7 +58,7 @@ static int lite5200_pm_prepare(void)
return -EINVAL;
/* map registers */
- np = of_find_compatible_node(NULL, NULL, "mpc5200");
+ np = of_find_matching_node(NULL, immr_ids);
mbar = of_iomap(np, 0);
of_node_put(np);
if (!mbar) {
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 6695593..0211890 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -64,8 +64,13 @@ mpc5200_setup_xlb_arbiter(void)
{
struct device_node *np;
struct mpc52xx_xlb __iomem *xlb;
+ struct of_device_id xlb_ids[] = {
+ { .compatible = "fsl,mpc5200-xlb", },
+ { .compatible = "mpc5200-xlb", },
+ {}
+ };
- np = of_find_compatible_node(NULL, NULL, "mpc5200-xlb");
+ np = of_find_matching_node(NULL, xlb_ids);
xlb = of_iomap(np, 0);
of_node_put(np);
if (!xlb) {
@@ -88,6 +93,9 @@ mpc5200_setup_xlb_arbiter(void)
iounmap(xlb);
}
+/*
+ * Match table used by mpc52xx_declare_of_platform_devices
+ */
static struct of_device_id mpc52xx_bus_ids[] __initdata= {
{ .compatible = "fsl,mpc5200-immr", },
{ .compatible = "fsl,lpb", },
@@ -95,9 +103,14 @@ static struct of_device_id mpc52xx_bus_ids[] __initdata= {
/* depreciated matches; shouldn't be used in new device trees */
{ .type = "builtin", .compatible = "mpc5200", }, /* efika */
{ .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
- {},
+ {}
};
+/**
+ * mpc52xx_declare_of_platform_devices: register internal devices and children
+ * of the localplus bus to the of_platform
+ * bus.
+ */
void __init
mpc52xx_declare_of_platform_devices(void)
{
@@ -107,33 +120,31 @@ mpc52xx_declare_of_platform_devices(void)
"Error while probing of_platform bus\n");
}
+/*
+ * match tables used by mpc52xx_map_wdt()
+ */
+static struct of_device_id mpc52xx_gpt_ids[] __initdata = {
+ { .compatible = "fsl,mpc5200-gpt", },
+ { .compatible = "mpc5200-gpt", }, /* old */
+ {}
+};
+
void __init
mpc52xx_map_wdt(void)
{
- const void *has_wdt;
struct device_node *np;
-
/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
* possibly from a interrupt context. wdt is only implement
* on a gpt0, so check has-wdt property before mapping.
*/
- for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
- has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
- if (has_wdt) {
+ for_each_matching_node(np, mpc52xx_gpt_ids) {
+ if (of_get_property(np, "fsl,has-wdt", NULL) ||
+ of_get_property(np, "has-wdt", NULL)) {
mpc52xx_wdt = of_iomap(np, 0);
of_node_put(np);
return;
}
}
- for_each_compatible_node(np, NULL, "mpc5200-gpt") {
- has_wdt = of_get_property(np, "has-wdt", NULL);
- if (has_wdt) {
- mpc52xx_wdt = of_iomap(np, 0);
- of_node_put(np);
- return;
- }
-
- }
}
void
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 4b79398..0e71722 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -410,10 +410,13 @@ mpc52xx_add_bridge(struct device_node *node)
void __init mpc52xx_setup_pci(void)
{
struct device_node *pci;
+ struct of_device_id pci_ids[] = {
+ { .type = "pci", .compatible = "fsl,mpc5200-pci", },
+ { .type = "pci", .compatible = "mpc5200-pci", },
+ {}
+ };
- pci = of_find_compatible_node(NULL, NULL, "fsl,mpc5200-pci");
- if (!pci)
- pci = of_find_compatible_node(NULL, NULL, "mpc5200-pci");
+ pci = of_find_matching_node(NULL, pci_ids);
if (!pci)
return;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 07e8987..3f9d3cb 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -365,15 +365,25 @@ void __init mpc52xx_init_irq(void)
u32 intr_ctrl;
struct device_node *picnode;
struct device_node *np;
+ struct of_device_id pic_ids[] = {
+ { .compatible = "fsl,mpc5200-pic", },
+ { .compatible = "mpc5200-pic", },
+ {}
+ };
+ struct of_device_id sdma_ids[] = {
+ { .compatible = "fsl,mpc5200-bestcomm", },
+ { .compatible = "mpc5200-bestcomm", },
+ {}
+ };
/* Remap the necessary zones */
- picnode = of_find_compatible_node(NULL, NULL, "mpc5200-pic");
+ picnode = of_find_matching_node(NULL, pic_ids);
intr = of_iomap(picnode, 0);
if (!intr)
panic(__FILE__ ": find_and_map failed on 'mpc5200-pic'. "
"Check node !");
- np = of_find_compatible_node(NULL, NULL, "mpc5200-bestcomm");
+ np = of_find_matching_node(NULL, sdma_ids);
sdma = of_iomap(np, 0);
of_node_put(np);
if (!sdma)
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index 52f0277..722c8d4 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -60,9 +60,15 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 level)
int mpc52xx_pm_prepare(void)
{
struct device_node *np;
+ struct of_device_id immr_ids[] = {
+ { .compatible = "fsl,mpc5200-immr", },
+ { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */
+ { .type = "builtin", .compatible = "mpc5200", }, /* efika */
+ {}
+ };
/* map the whole register space */
- np = of_find_compatible_node(NULL, NULL, "mpc5200");
+ np = of_find_matching_node(NULL, immr_ids);
mbar = of_iomap(np, 0);
of_node_put(np);
if (!mbar) {
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
index 740ad73..c6b04c6 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -363,6 +363,11 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
{
struct device_node *ofn_sram;
struct resource res_bcom;
+ struct of_device_id sram_ids[] = {
+ { .compatible = "fsl,mpc5200-sram", },
+ { .compatible = "mpc5200-sram", },
+ {}
+ };
int rv;
@@ -373,7 +378,7 @@ mpc52xx_bcom_probe(struct of_device *op, const struct of_device_id *match)
of_node_get(op->node);
/* Prepare SRAM */
- ofn_sram = of_find_compatible_node(NULL, "sram", "mpc5200-sram");
+ ofn_sram = of_find_matching_node(NULL, sram_ids);
if (!ofn_sram) {
printk(KERN_ERR DRIVER_NAME ": "
"No SRAM found in device tree\n");
@@ -478,10 +483,8 @@ mpc52xx_bcom_remove(struct of_device *op)
}
static struct of_device_id mpc52xx_bcom_of_match[] = {
- {
- .type = "dma-controller",
- .compatible = "mpc5200-bestcomm",
- },
+ { .type = "dma-controller", .compatible = "fsl,mpc5200-bestcomm", },
+ { .type = "dma-controller", .compatible = "mpc5200-bestcomm", },
{},
};
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 50c56e2..1a7ca37 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -494,10 +494,8 @@ mpc52xx_ata_resume(struct of_device *op)
static struct of_device_id mpc52xx_ata_of_match[] = {
- {
- .type = "ata",
- .compatible = "mpc5200-ata",
- },
+ { .compatible = "fsl,mpc5200-ata", },
+ { .compatible = "mpc5200-ata", },
{},
};
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 79f7ead..2700482 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -1056,10 +1056,8 @@ static int mpc52xx_fec_of_resume(struct of_device *op)
#endif
static struct of_device_id mpc52xx_fec_match[] = {
- {
- .type = "network",
- .compatible = "mpc5200-fec",
- },
+ { .type = "network", .compatible = "fsl,mpc5200-fec", },
+ { .type = "network", .compatible = "mpc5200-fec", },
{ }
};
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index ba6e8b2..1837584 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -177,11 +177,9 @@ static int mpc52xx_fec_mdio_remove(struct of_device *of)
static struct of_device_id mpc52xx_fec_mdio_match[] = {
- {
- .type = "mdio",
- .compatible = "mpc5200b-fec-phy",
- },
- {},
+ { .compatible = "fsl,mpc5200b-mdio", },
+ { .compatible = "mpc5200b-fec-phy", },
+ {}
};
struct of_platform_driver mpc52xx_fec_mdio_driver = {
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index a269ae1..06f4316 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -130,7 +130,9 @@ static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
#if defined(CONFIG_PPC_MERGE)
static const struct of_device_id mpc52xx_uart_of_match[] = {
- { .type = "serial", .compatible = "mpc5200-psc-uart", },
+ { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", },
+ { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */
+ { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */
{},
};
#endif
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index d398c93..a3ebc63 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -628,8 +628,9 @@ static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op)
}
static struct of_device_id mpc52xx_psc_spi_of_match[] = {
- { .type = "spi", .compatible = "mpc5200-psc-spi", },
- {},
+ { .compatible = "fsl,mpc5200-psc-spi", },
+ { .compatible = "mpc5200-psc-spi", }, /* old */
+ {}
};
MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 0c3e6b7..a672527 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -136,6 +136,8 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match)
ohci = hcd_to_ohci(hcd);
if (is_bigendian) {
ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
+ if (of_device_is_compatible(dn, "fsl,mpc5200-ohci"))
+ ohci->flags |= OHCI_QUIRK_FRAME_NO;
if (of_device_is_compatible(dn, "mpc5200-ohci"))
ohci->flags |= OHCI_QUIRK_FRAME_NO;
}
^ permalink raw reply related
* [RFC/PATCH 0/2] mpc5200: tidy up the device tree bindings
From: Grant Likely @ 2008-01-18 17:04 UTC (permalink / raw)
To: linuxppc-dev, jrigby, matt, tnt
These two patches make the device tree bindings for 5200 platforms more
robust and match closer with the generic names recommended practice.
Please review and comment.
Cheers,
g.
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH/RFCv2] [POWERPC] Add support for freescale watchdog to CPM serial driver.
From: Scott Wood @ 2008-01-18 17:04 UTC (permalink / raw)
To: Jochen Friedrich; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <478F4AE3.5090803@scram.de>
Jochen Friedrich wrote:
> +void watchdog_poke(void)
> +{
> + if (wdt) {
> + out_be16(&wdt->swsrr, 0x556c);
> + out_be16(&wdt->swsrr, 0xaa39);
> + }
> +}
This should be a function pointer, to allow for other watchdog types.
-Scott
^ permalink raw reply
* Re: [PATCH v4] [POWERPC] Update MPC8610 HPCD to support audio drivers
From: Kumar Gala @ 2008-01-18 16:45 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, alsa-devel
In-Reply-To: <12006698934064-git-send-email-timur@freescale.com>
On Fri, 18 Jan 2008, Timur Tabi wrote:
> Update the MPC8610 HPCD files to support the audio driver. Update
> booting-without-of.txt with information on the SSI device.
>
> Signed-off-by: Timur Tabi <timur@freescale.com>
> ---
>
> Rebased for Kumar's repo.
>
> Documentation/powerpc/booting-without-of.txt | 41 ++++++
> arch/powerpc/boot/dts/mpc8610_hpcd.dts | 113 +++++++++++++++++-
> arch/powerpc/configs/mpc8610_hpcd_defconfig | 171 +++++++++++++++++++++++++-
> arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 15 +++
> 4 files changed, 336 insertions(+), 4 deletions(-)
applied.
- k
^ permalink raw reply
* Re: [PATCH] add modalias info to mv643xx_eth.ko
From: Dale Farnsworth @ 2008-01-18 16:31 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, netdev
In-Reply-To: <20080118093805.GA28004@aepfle.de>
On Fri, Jan 18, 2008 at 10:38:05AM +0100, Olaf Hering wrote:
> mv643xx_eth has an platform modalias file in sysfs.
> But the module itself has no alias: line. Autoloading fails
> without the alias info in the module.
>
> Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Dale Farnsworth <dale@farnsworth.org>
^ permalink raw reply
* [PATCH v4] [POWERPC] Update MPC8610 HPCD to support audio drivers
From: Timur Tabi @ 2008-01-18 15:24 UTC (permalink / raw)
To: galak, linuxppc-dev, alsa-devel; +Cc: Timur Tabi
Update the MPC8610 HPCD files to support the audio driver. Update
booting-without-of.txt with information on the SSI device.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
Rebased for Kumar's repo.
Documentation/powerpc/booting-without-of.txt | 41 ++++++
arch/powerpc/boot/dts/mpc8610_hpcd.dts | 113 +++++++++++++++++-
arch/powerpc/configs/mpc8610_hpcd_defconfig | 171 +++++++++++++++++++++++++-
arch/powerpc/platforms/86xx/mpc8610_hpcd.c | 15 +++
4 files changed, 336 insertions(+), 4 deletions(-)
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index a13d457..6ac726d 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -56,6 +56,7 @@ Table of Contents
m) Chipselect/Local Bus
n) 4xx/Axon EMAC ethernet nodes
o) Xilinx IP cores
+ p) Freescale Synchronous Serial Interface
VII - Specifying interrupt information for devices
1) interrupts property
@@ -2575,6 +2576,46 @@ platforms are moved over to use the flattened-device-tree model.
Requred properties:
- current-speed : Baud rate of uartlite
+ p) Freescale Synchronous Serial Interface
+
+ The SSI is a serial device that communicates with audio codecs. It can
+ be programmed in AC97, I2S, left-justified, or right-justified modes.
+
+ Required properties:
+ - compatible : compatible list, containing "fsl,ssi"
+ - cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on
+ - reg : offset and length of the register set for the device
+ - interrupts : <a b> where a is the interrupt number and b is a
+ field that represents an encoding of the sense and
+ level information for the interrupt. This should be
+ encoded based on the information in section 2)
+ depending on the type of interrupt controller you
+ have.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+ - fsl,mode : the operating mode for the SSI interface
+ "i2s-slave" - I2S mode, SSI is clock slave
+ "i2s-master" - I2S mode, SSI is clock master
+ "lj-slave" - left-justified mode, SSI is clock slave
+ "lj-master" - l.j. mode, SSI is clock master
+ "rj-slave" - right-justified mode, SSI is clock slave
+ "rj-master" - r.j., SSI is clock master
+ "ac97-slave" - AC97 mode, SSI is clock slave
+ "ac97-master" - AC97 mode, SSI is clock master
+
+ Optional properties:
+ - codec-handle : phandle to a 'codec' node that defines an audio
+ codec connected to this SSI. This node is typically
+ a child of an I2C or other control node.
+
+ Child 'codec' node required properties:
+ - compatible : compatible list, contains the name of the codec
+
+ Child 'codec' node optional properties:
+ - clock-frequency : The frequency of the input clock, which typically
+ comes from an on-board dedicated oscillator.
+
+
More devices will be defined as this spec matures.
VII - Specifying interrupt information for devices
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index 01040a7..d98715c 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -1,7 +1,7 @@
/*
* MPC8610 HPCD Device Tree Source
*
- * Copyright 2007 Freescale Semiconductor Inc.
+ * Copyright 2007-2008 Freescale Semiconductor Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License Version 2 as published
@@ -49,6 +49,7 @@
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
+ compatible = "fsl,mpc8610-immr", "simple-bus";
ranges = <0 e0000000 00100000>;
reg = <e0000000 1000>;
bus-frequency = <0>;
@@ -62,6 +63,13 @@
interrupts = <2b 2>;
interrupt-parent = <&mpic>;
dfsrr;
+
+ cs4270:codec@4f {
+ compatible = "cirrus,cs4270";
+ reg = <4f>;
+ /* MCLK source is a stand-alone oscillator */
+ clock-frequency = <bb8000>;
+ };
};
i2c@3100 {
@@ -111,6 +119,109 @@
reg = <e0000 1000>;
fsl,has-rstcr;
};
+
+ i2s@16000 {
+ compatible = "fsl,mpc8610-ssi";
+ cell-index = <0>;
+ reg = <16000 100>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3e 2>;
+ fsl,mode = "i2s-slave";
+ codec-handle = <&cs4270>;
+ };
+
+ ssi@16100 {
+ compatible = "fsl,mpc8610-ssi";
+ cell-index = <1>;
+ reg = <16100 100>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3f 2>;
+ };
+
+ dma@21300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8610-dma", "fsl,eloplus-dma";
+ cell-index = <0>;
+ reg = <21300 4>; /* DMA general status register */
+ ranges = <0 21100 200>;
+
+ dma-channel@0 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,eloplus-dma-channel";
+ cell-index = <0>;
+ reg = <0 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <14 2>;
+ };
+ dma-channel@1 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,eloplus-dma-channel";
+ cell-index = <1>;
+ reg = <80 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <15 2>;
+ };
+ dma-channel@2 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,eloplus-dma-channel";
+ cell-index = <2>;
+ reg = <100 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <16 2>;
+ };
+ dma-channel@3 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,eloplus-dma-channel";
+ cell-index = <3>;
+ reg = <180 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <17 2>;
+ };
+ };
+
+ dma@c300 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,mpc8610-dma", "fsl,mpc8540-dma";
+ cell-index = <1>;
+ reg = <c300 4>; /* DMA general status register */
+ ranges = <0 c100 200>;
+
+ dma-channel@0 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,mpc8540-dma-channel";
+ cell-index = <0>;
+ reg = <0 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3c 2>;
+ };
+ dma-channel@1 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,mpc8540-dma-channel";
+ cell-index = <1>;
+ reg = <80 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3d 2>;
+ };
+ dma-channel@2 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,mpc8540-dma-channel";
+ cell-index = <2>;
+ reg = <100 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3e 2>;
+ };
+ dma-channel@3 {
+ compatible = "fsl,mpc8610-dma-channel",
+ "fsl,mpc8540-dma-channel";
+ cell-index = <3>;
+ reg = <180 80>;
+ interrupt-parent = <&mpic>;
+ interrupts = <3f 2>;
+ };
+ };
+
};
pci0: pci@e0008000 {
diff --git a/arch/powerpc/configs/mpc8610_hpcd_defconfig b/arch/powerpc/configs/mpc8610_hpcd_defconfig
index 9614d24..2500ef4 100644
--- a/arch/powerpc/configs/mpc8610_hpcd_defconfig
+++ b/arch/powerpc/configs/mpc8610_hpcd_defconfig
@@ -696,7 +696,7 @@ CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
-CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
@@ -708,7 +708,60 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
#
# SPI support
@@ -763,7 +816,119 @@ CONFIG_DUMMY_CONSOLE=y
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_PCM_OSS_PLUGINS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CA0106 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS5530 is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_EMU10K1X is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_HDA_INTEL is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_HDSPM is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VX222 is not set
+# CONFIG_SND_YMFPCI is not set
+
+#
+# ALSA PowerMac devices
+#
+
+#
+# ALSA PowerPC devices
+#
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+CONFIG_SND_SOC_MPC8610=y
+CONFIG_SND_SOC_MPC8610_HPCD=y
+CONFIG_SND_SOC_CS4270=y
+CONFIG_SND_SOC_CS4270_VD33_ERRATA=y
+
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index c6d2f48..0b07485 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -34,9 +34,24 @@
#include <asm/mpic.h>
+#include <linux/of_platform.h>
#include <sysdev/fsl_pci.h>
#include <sysdev/fsl_soc.h>
+static struct of_device_id __initdata mpc8610_ids[] = {
+ { .compatible = "fsl,mpc8610-immr", },
+ {}
+};
+
+static int __init mpc8610_declare_of_platform_devices(void)
+{
+ /* Without this call, the SSI device driver won't get probed. */
+ of_platform_bus_probe(NULL, mpc8610_ids, NULL);
+
+ return 0;
+}
+machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices);
+
void __init
mpc86xx_hpcd_init_irq(void)
{
--
1.5.2.4
^ permalink raw reply related
* Re: [PATCH 2/2] mpc82xx: Embedded Planet EP8248E support
From: Scott Wood @ 2008-01-18 16:03 UTC (permalink / raw)
To: Sergej Stepanov; +Cc: linuxppc-dev
In-Reply-To: <1200654427.3204.4.camel@p60365-ste>
On Fri, Jan 18, 2008 at 12:07:07PM +0100, Sergej Stepanov wrote:
>
> > + /* "Serial" port/SCC1 */
> > + scc1: serial@11a00 {
> > + device_type = "serial";
> > + compatible = "fsl,mpc8248-scc-uart",
> > + "fsl,cpm2-scc-uart";
> > + reg = <0x11a00 0x20 0x8000 0x100>;
> > + interrupts = <40 8>;
> are you sure with 40 as interrupt? has not it be "28"(hex) here?
This is a version 1 dts file -- the default base is decimal.
-Scott
^ permalink raw reply
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