* [patch 22/30] Powerpc: Output params value in early_init_devtree
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Add a printout of the params value to early_init_devtree.
This value is handy to have for comparison when debugging the
bootwrapper code.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/kernel/prom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1005,7 +1005,7 @@ static void __init early_reserve_mem(voi
void __init early_init_devtree(void *params)
{
- DBG(" -> early_init_devtree()\n");
+ DBG(" -> early_init_devtree(%p)\n", params);
/* Setup flat device-tree pointer */
initial_boot_params = params;
--
^ permalink raw reply
* [patch 20/30] PS3: Rename processor id symbols
From: Geoff Levand @ 2007-06-12 18:53 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Rename the PS3 static symbols node to ppe_id and cpu to thread_id
to clarify usage.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/interrupt.c | 55 +++++++++++++++++----------------
1 file changed, 29 insertions(+), 26 deletions(-)
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -79,14 +79,14 @@ struct ps3_bmp {
/**
* struct ps3_private - a per cpu data structure
* @bmp: ps3_bmp structure
- * @node: HV logical_ppe_id
- * @cpu: HV thread_id
+ * @ppe_id: HV logical_ppe_id
+ * @thread_id: HV thread_id
*/
struct ps3_private {
struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
- u64 node;
- unsigned int cpu;
+ u64 ppe_id;
+ u64 thread_id;
};
static DEFINE_PER_CPU(struct ps3_private, ps3_private);
@@ -106,7 +106,8 @@ static void ps3_chip_mask(unsigned int v
u64 old;
unsigned long flags;
- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+ pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
+ pd->thread_id, virq);
local_irq_save(flags);
asm volatile(
@@ -118,7 +119,7 @@ static void ps3_chip_mask(unsigned int v
: "r" (bit), "r" (p)
: "cc" );
- lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+ lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
@@ -137,7 +138,8 @@ static void ps3_chip_unmask(unsigned int
u64 old;
unsigned long flags;
- pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+ pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
+ pd->thread_id, virq);
local_irq_save(flags);
asm volatile(
@@ -149,7 +151,7 @@ static void ps3_chip_unmask(unsigned int
: "r" (bit), "r" (p)
: "cc" );
- lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+ lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
@@ -163,7 +165,7 @@ static void ps3_chip_unmask(unsigned int
static void ps3_chip_eoi(unsigned int virq)
{
const struct ps3_private *pd = get_irq_chip_data(virq);
- lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
+ lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, virq);
}
/**
@@ -242,8 +244,8 @@ int ps3_virq_destroy(unsigned int virq)
{
const struct ps3_private *pd = get_irq_chip_data(virq);
- pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
- pd->node, pd->cpu, virq);
+ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
+ __LINE__, pd->ppe_id, pd->thread_id, virq);
set_irq_chip_data(virq, NULL);
irq_dispose_mapping(virq);
@@ -279,7 +281,8 @@ int ps3_irq_plug_setup(enum ps3_cpu_bind
/* Binds outlet to cpu + virq. */
- result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
+ result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
+ outlet, 0);
if (result) {
pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
@@ -311,12 +314,12 @@ int ps3_irq_plug_destroy(unsigned int vi
int result;
const struct ps3_private *pd = get_irq_chip_data(virq);
- pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
- pd->node, pd->cpu, virq);
+ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, virq %u\n", __func__,
+ __LINE__, pd->ppe_id, pd->thread_id, virq);
ps3_chip_mask(virq);
- result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
+ result = lv1_disconnect_irq_plug_ext(pd->ppe_id, pd->thread_id, virq);
if (result)
pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
@@ -658,8 +661,8 @@ static void _dump_bmp(struct ps3_private
unsigned long flags;
spin_lock_irqsave(&pd->bmp.lock, flags);
- _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line);
- _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
+ _dump_64_bmp("stat", &pd->bmp.status, pd->thread_id, func, line);
+ _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
spin_unlock_irqrestore(&pd->bmp.lock, flags);
}
@@ -670,7 +673,7 @@ static void __maybe_unused _dump_mask(st
unsigned long flags;
spin_lock_irqsave(&pd->bmp.lock, flags);
- _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
+ _dump_64_bmp("mask", &pd->bmp.mask, pd->thread_id, func, line);
spin_unlock_irqrestore(&pd->bmp.lock, flags);
}
#else
@@ -723,8 +726,8 @@ static unsigned int ps3_get_irq(void)
plug &= 0x3f;
if (unlikely(plug) == NO_IRQ) {
- pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__,
- pd->cpu);
+ pr_debug("%s:%d: no plug found: thread_id %lu\n", __func__,
+ __LINE__, pd->thread_id);
dump_bmp(&per_cpu(ps3_private, 0));
dump_bmp(&per_cpu(ps3_private, 1));
return NO_IRQ;
@@ -754,16 +757,16 @@ void __init ps3_init_IRQ(void)
for_each_possible_cpu(cpu) {
struct ps3_private *pd = &per_cpu(ps3_private, cpu);
- lv1_get_logical_ppe_id(&pd->node);
- pd->cpu = get_hard_smp_processor_id(cpu);
+ lv1_get_logical_ppe_id(&pd->ppe_id);
+ pd->thread_id = get_hard_smp_processor_id(cpu);
spin_lock_init(&pd->bmp.lock);
- pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__,
- __LINE__, pd->node, pd->cpu,
+ pr_debug("%s:%d: ppe_id %lu, thread_id %lu, bmp %lxh\n",
+ __func__, __LINE__, pd->ppe_id, pd->thread_id,
ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
- result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu,
- ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
+ result = lv1_configure_irq_state_bitmap(pd->ppe_id,
+ pd->thread_id, ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
if (result)
pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
--
^ permalink raw reply
* [patch 18/30] PS3: Frame buffer system-bus rework
From: Geoff Levand @ 2007-06-12 18:53 UTC (permalink / raw)
To: paulus; +Cc: Geert Uytterhoeven, linuxppc-dev, linux-fbdev-devel
In-Reply-To: <20070612181825.730300780@am.sony.com>
From: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Convert the ps3fb device from a platform device to a PS3 system bus device.
Fix the remove and shutdown methods to support kexec and to make ps3fb a
loadable module.
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/setup.c | 9 -
drivers/video/Kconfig | 4
drivers/video/ps3fb.c | 288 ++++++++++++++++---------------------
include/asm-powerpc/ps3fb.h | 12 -
4 files changed, 132 insertions(+), 181 deletions(-)
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -108,7 +108,7 @@ static void ps3_panic(char *str)
while(1);
}
-#ifdef CONFIG_FB_PS3
+#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
static void prealloc(struct ps3_prealloc *p)
{
if (!p->size)
@@ -126,10 +126,11 @@ static void prealloc(struct ps3_prealloc
}
struct ps3_prealloc ps3fb_videomemory = {
- .name = "ps3fb videomemory",
- .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
- .align = 1024*1024 /* the GPU requires 1 MiB alignment */
+ .name = "ps3fb videomemory",
+ .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
+ .align = 1024*1024 /* the GPU requires 1 MiB alignment */
};
+EXPORT_SYMBOL_GPL(ps3fb_videomemory);
#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
static int __init early_parse_ps3fb(char *p)
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1790,8 +1790,8 @@ config FB_IBM_GXT4500
adaptor, found on some IBM System P (pSeries) machines.
config FB_PS3
- bool "PS3 GPU framebuffer driver"
- depends on (FB = y) && PS3_PS3AV
+ tristate "PS3 GPU framebuffer driver"
+ depends on FB && PS3_PS3AV
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -27,7 +27,6 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/platform_device.h>
#include <linux/console.h>
#include <linux/ioctl.h>
#include <linux/notifier.h>
@@ -46,6 +45,9 @@
#include <asm/ps3fb.h>
#include <asm/ps3.h>
+
+#define DEVICE_NAME "ps3fb"
+
#ifdef PS3FB_DEBUG
#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
#else
@@ -126,7 +128,6 @@ struct gpu_driver_info {
struct ps3fb_priv {
unsigned int irq_no;
- void *dev;
u64 context_handle, memory_handle;
void *xdr_ea;
@@ -171,7 +172,7 @@ static const struct ps3fb_res_table ps3f
{ 0, 0, 0, 0 , 0} };
/* default resolution */
-#define GPU_RES_INDEX 0 /* 720 x 480 */
+#define GPU_RES_INDEX 0 /* 720 x 480 */
static const struct fb_videomode ps3fb_modedb[] = {
/* 60 Hz broadcast modes (modes "1" to "5") */
@@ -298,10 +299,9 @@ static const struct fb_videomode ps3fb_m
#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
static int ps3fb_mode;
-module_param(ps3fb_mode, bool, 0);
-
-static char *mode_option __initdata;
+module_param(ps3fb_mode, int, 0);
+static char *mode_option __devinitdata;
static int ps3fb_get_res_table(u32 xres, u32 yres)
{
@@ -681,15 +681,15 @@ int ps3fb_wait_for_vsync(u32 crtc)
EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
-void ps3fb_flip_ctl(int on)
+void ps3fb_flip_ctl(int on, void *data)
{
+ struct ps3fb_priv *priv = data;
if (on)
- atomic_dec_if_positive(&ps3fb.ext_flip);
+ atomic_dec_if_positive(&priv->ext_flip);
else
- atomic_inc(&ps3fb.ext_flip);
+ atomic_inc(&priv->ext_flip);
}
-EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
/*
* ioctl
@@ -851,37 +851,9 @@ static irqreturn_t ps3fb_vsync_interrupt
return IRQ_HANDLED;
}
-#ifndef MODULE
-static int __init ps3fb_setup(char *options)
-{
- char *this_opt;
- int mode = 0;
- if (!options || !*options)
- return 0; /* no options */
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- if (!strncmp(this_opt, "mode:", 5))
- mode = simple_strtoul(this_opt + 5, NULL, 0);
- else
- mode_option = this_opt;
- }
- return mode;
-}
-#endif /* MODULE */
-
- /*
- * Initialisation
- */
-
-static void ps3fb_platform_release(struct device *device)
-{
- /* This is called when the reference count goes to zero. */
-}
-
-static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
+static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
+ struct ps3_system_bus_device *dev)
{
int error;
@@ -897,7 +869,6 @@ static int ps3fb_vsync_settings(struct g
return -EINVAL;
}
- ps3fb.dev = dev;
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
&ps3fb.irq_no);
if (error) {
@@ -907,7 +878,7 @@ static int ps3fb_vsync_settings(struct g
}
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
- "ps3fb vsync", ps3fb.dev);
+ DEVICE_NAME, dev);
if (error) {
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
error);
@@ -966,16 +937,47 @@ static struct fb_ops ps3fb_ops = {
};
static struct fb_fix_screeninfo ps3fb_fix __initdata = {
- .id = "PS3 FB",
+ .id = DEVICE_NAME,
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
.accel = FB_ACCEL_NONE,
};
-static int __init ps3fb_probe(struct platform_device *dev)
+static int ps3fb_set_sync(void)
+{
+ int status;
+
+#ifdef HEAD_A
+ status = lv1_gpu_context_attribute(0x0,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
+ if (status) {
+ printk(KERN_ERR
+ "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
+ __func__, status);
+ return -1;
+ }
+#endif
+#ifdef HEAD_B
+ status = lv1_gpu_context_attribute(0x0,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
+
+ if (status) {
+ printk(KERN_ERR
+ "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
+ __func__, status);
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
{
struct fb_info *info;
int retval = -ENOMEM;
+ u32 xres, yres;
u64 ddr_lpar = 0;
u64 lpar_dma_control = 0;
u64 lpar_driver_info = 0;
@@ -986,6 +988,30 @@ static int __init ps3fb_probe(struct pla
unsigned long offset;
struct task_struct *task;
+ status = ps3_open_hv_device(dev);
+ if (status) {
+ printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__);
+ goto err;
+ }
+
+ if (!ps3fb_mode)
+ ps3fb_mode = ps3av_get_mode();
+ DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
+
+ if (ps3fb_mode > 0 &&
+ !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
+ ps3fb.res_index = ps3fb_get_res_table(xres, yres);
+ DPRINTK("res_index:%d\n", ps3fb.res_index);
+ } else
+ ps3fb.res_index = GPU_RES_INDEX;
+
+ atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
+ atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
+ init_waitqueue_head(&ps3fb.wait_vsync);
+ ps3fb.num_frames = 1;
+
+ ps3fb_set_sync();
+
/* get gpu context handle */
status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
&ps3fb.memory_handle, &ddr_lpar);
@@ -1029,7 +1055,7 @@ static int __init ps3fb_probe(struct pla
* leakage into userspace
*/
memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
- info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
+ info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
if (!info)
goto err_free_irq;
@@ -1061,19 +1087,20 @@ static int __init ps3fb_probe(struct pla
if (retval < 0)
goto err_fb_dealloc;
- platform_set_drvdata(dev, info);
+ dev->core.driver_data = info;
printk(KERN_INFO
"fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
info->node, ps3fb_videomemory.size >> 10);
- task = kthread_run(ps3fbd, info, "ps3fbd");
+ task = kthread_run(ps3fbd, info, DEVICE_NAME);
if (IS_ERR(task)) {
retval = PTR_ERR(task);
goto err_unregister_framebuffer;
}
ps3fb.task = task;
+ ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
return 0;
@@ -1084,7 +1111,7 @@ err_fb_dealloc:
err_framebuffer_release:
framebuffer_release(info);
err_free_irq:
- free_irq(ps3fb.irq_no, ps3fb.dev);
+ free_irq(ps3fb.irq_no, dev);
ps3_irq_plug_destroy(ps3fb.irq_no);
err_iounmap_dinfo:
iounmap((u8 __iomem *)ps3fb.dinfo);
@@ -1096,26 +1123,30 @@ err:
return retval;
}
-static void ps3fb_shutdown(struct platform_device *dev)
+static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
{
- ps3fb_flip_ctl(0); /* flip off */
+ int status;
+ struct fb_info *info = dev->core.driver_data;
+
+ DPRINTK(" -> %s:%d\n", __func__, __LINE__);
+
+ ps3fb_flip_ctl(0, &ps3fb); /* flip off */
ps3fb.dinfo->irq.mask = 0;
- free_irq(ps3fb.irq_no, ps3fb.dev);
- ps3_irq_plug_destroy(ps3fb.irq_no);
- iounmap((u8 __iomem *)ps3fb.dinfo);
-}
-void ps3fb_cleanup(void)
-{
- int status;
+ if (info) {
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+ }
+ ps3av_register_flip_ctl(NULL, NULL);
if (ps3fb.task) {
struct task_struct *task = ps3fb.task;
ps3fb.task = NULL;
kthread_stop(task);
}
if (ps3fb.irq_no) {
- free_irq(ps3fb.irq_no, ps3fb.dev);
+ free_irq(ps3fb.irq_no, dev);
ps3_irq_plug_destroy(ps3fb.irq_no);
}
iounmap((u8 __iomem *)ps3fb.dinfo);
@@ -1128,134 +1159,65 @@ void ps3fb_cleanup(void)
if (status)
DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
- ps3av_dev_close();
-}
-
-EXPORT_SYMBOL_GPL(ps3fb_cleanup);
-
-static int ps3fb_remove(struct platform_device *dev)
-{
- struct fb_info *info = platform_get_drvdata(dev);
+ ps3_close_hv_device(dev);
+ DPRINTK(" <- %s:%d\n", __func__, __LINE__);
- if (info) {
- unregister_framebuffer(info);
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
- }
- ps3fb_cleanup();
return 0;
}
-static struct platform_driver ps3fb_driver = {
- .probe = ps3fb_probe,
- .remove = ps3fb_remove,
- .shutdown = ps3fb_shutdown,
- .driver = { .name = "ps3fb" }
+static struct ps3_system_bus_driver ps3fb_driver = {
+ .match_id = PS3_MATCH_ID_GRAPHICS,
+ .core.name = DEVICE_NAME,
+ .core.owner = THIS_MODULE,
+ .probe = ps3fb_probe,
+ .remove = ps3fb_shutdown,
+ .shutdown = ps3fb_shutdown,
};
-static struct platform_device ps3fb_device = {
- .name = "ps3fb",
- .id = 0,
- .dev = { .release = ps3fb_platform_release }
-};
-
-int ps3fb_set_sync(void)
+static int __init ps3fb_setup(void)
{
- int status;
+ char *options, *this_opt;
-#ifdef HEAD_A
- status = lv1_gpu_context_attribute(0x0,
- L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
- 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
- if (status) {
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
- __func__, status);
- return -1;
- }
+#ifdef MODULE
+ return 0;
#endif
-#ifdef HEAD_B
- status = lv1_gpu_context_attribute(0x0,
- L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
- 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
- if (status) {
- printk(KERN_ERR
- "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
- __func__, status);
- return -1;
+ if (fb_get_options(DEVICE_NAME, &options))
+ return -ENXIO;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+ if (!strncmp(this_opt, "mode:", 5))
+ ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
+ else
+ mode_option = this_opt;
}
-#endif
return 0;
}
-EXPORT_SYMBOL_GPL(ps3fb_set_sync);
-
static int __init ps3fb_init(void)
{
- int error;
-#ifndef MODULE
- int mode;
- char *option = NULL;
-
- if (fb_get_options("ps3fb", &option))
- goto err;
-#endif
-
- if (!ps3fb_videomemory.address)
- goto err;
-
- error = ps3av_dev_open();
- if (error) {
- printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
- goto err;
- }
-
- ps3fb_mode = ps3av_get_mode();
- DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
-#ifndef MODULE
- mode = ps3fb_setup(option); /* check boot option */
- if (mode)
- ps3fb_mode = mode;
-#endif
- if (ps3fb_mode > 0) {
- u32 xres, yres;
- ps3av_video_mode2res(ps3fb_mode, &xres, &yres);
- ps3fb.res_index = ps3fb_get_res_table(xres, yres);
- DPRINTK("res_index:%d\n", ps3fb.res_index);
- } else
- ps3fb.res_index = GPU_RES_INDEX;
-
- atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
- atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
- init_waitqueue_head(&ps3fb.wait_vsync);
- ps3fb.num_frames = 1;
-
- error = platform_driver_register(&ps3fb_driver);
- if (!error) {
- error = platform_device_register(&ps3fb_device);
- if (error)
- platform_driver_unregister(&ps3fb_driver);
- }
-
- ps3fb_set_sync();
-
- return error;
+ if (!ps3fb_videomemory.address || ps3fb_setup())
+ return -ENXIO;
-err:
- return -ENXIO;
+ return ps3_system_bus_driver_register(&ps3fb_driver);
}
-module_init(ps3fb_init);
-
-#ifdef MODULE
static void __exit ps3fb_exit(void)
{
- platform_device_unregister(&ps3fb_device);
- platform_driver_unregister(&ps3fb_driver);
+ DPRINTK(" -> %s:%d\n", __func__, __LINE__);
+ ps3_system_bus_driver_unregister(&ps3fb_driver);
+ DPRINTK(" <- %s:%d\n", __func__, __LINE__);
}
+module_init(ps3fb_init);
module_exit(ps3fb_exit);
MODULE_LICENSE("GPL");
-#endif /* MODULE */
+MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver");
+MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS);
--- a/include/asm-powerpc/ps3fb.h
+++ b/include/asm-powerpc/ps3fb.h
@@ -41,16 +41,4 @@ struct ps3fb_ioctl_res {
__u32 num_frames; /* num of frame buffers */
};
-#ifdef __KERNEL__
-
-#ifdef CONFIG_FB_PS3
-extern void ps3fb_flip_ctl(int on);
-extern void ps3fb_cleanup(void);
-#else
-static inline void ps3fb_flip_ctl(int on) {}
-static inline void ps3fb_cleanup(void) {}
-#endif
-
-#endif /* __KERNEL__ */
-
#endif /* _ASM_POWERPC_PS3FB_H_ */
--
^ permalink raw reply
* [patch 19/30] PS3: Device registration routines.
From: Geoff Levand @ 2007-06-12 18:53 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Add routines to probe devices present on the system
and to register those devices with the LDM.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/Makefile | 1
arch/powerpc/platforms/ps3/device-init.c | 499 +++++++++++++++++++++++++++++++
2 files changed, 500 insertions(+)
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -4,3 +4,4 @@ obj-y += system-bus.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SPU_BASE) += spu.o
+obj-y += device-init.o
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -0,0 +1,499 @@
+/*
+ * PS3 device registration routines.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/delay.h>
+#include <linux/freezer.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/init.h>
+
+#include <asm/firmware.h>
+#include <asm/lv1call.h>
+
+#include "platform.h"
+
+/**
+ * ps3_setup_gelic_device - Setup and register a gelic device instance.
+ *
+ * Allocates memory for a struct ps3_system_bus_device instance, initialises the
+ * structure members, and registers the device instance with the system bus.
+ */
+
+static int __devinit ps3_setup_gelic_device(
+ const struct ps3_repository_device *repo)
+{
+ int result;
+ struct layout {
+ struct ps3_system_bus_device dev;
+ struct ps3_dma_region d_region;
+ } *p;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
+ BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC);
+
+ p = kzalloc(sizeof(struct layout), GFP_KERNEL);
+
+ if (!p) {
+ result = -ENOMEM;
+ goto fail_malloc;
+ }
+
+ p->dev.match_id = PS3_MATCH_ID_GELIC;
+ p->dev.dev_type = PS3_DEVICE_TYPE_SB;
+ p->dev.bus_id = repo->bus_id;
+ p->dev.dev_id = repo->dev_id;
+ p->dev.d_region = &p->d_region;
+
+ result = ps3_repository_find_interrupt(repo,
+ PS3_INTERRUPT_TYPE_EVENT_PORT, &p->dev.interrupt_id);
+
+ if (result) {
+ pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+ __func__, __LINE__);
+ goto fail_find_interrupt;
+ }
+
+ BUG_ON(p->dev.interrupt_id != 0);
+
+ result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
+ PS3_DMA_OTHER, NULL, 0);
+
+ if (result) {
+ pr_debug("%s:%d ps3_dma_region_init failed\n",
+ __func__, __LINE__);
+ goto fail_dma_init;
+ }
+
+ result = ps3_system_bus_device_register(&p->dev);
+
+ if (result) {
+ pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+ __func__, __LINE__);
+ goto fail_device_register;
+ }
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+
+fail_device_register:
+fail_dma_init:
+fail_find_interrupt:
+ kfree(p);
+fail_malloc:
+ pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
+ return result;
+}
+
+static int __devinit ps3_setup_uhc_device(
+ const struct ps3_repository_device *repo, enum ps3_match_id match_id,
+ enum ps3_interrupt_type interrupt_type, enum ps3_reg_type reg_type)
+{
+ int result;
+ struct layout {
+ struct ps3_system_bus_device dev;
+ struct ps3_dma_region d_region;
+ struct ps3_mmio_region m_region;
+ } *p;
+ u64 bus_addr;
+ u64 len;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB);
+ BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB);
+
+ p = kzalloc(sizeof(struct layout), GFP_KERNEL);
+
+ if (!p) {
+ result = -ENOMEM;
+ goto fail_malloc;
+ }
+
+ p->dev.match_id = match_id;
+ p->dev.dev_type = PS3_DEVICE_TYPE_SB;
+ p->dev.bus_id = repo->bus_id;
+ p->dev.dev_id = repo->dev_id;
+ p->dev.d_region = &p->d_region;
+ p->dev.m_region = &p->m_region;
+
+ result = ps3_repository_find_interrupt(repo,
+ interrupt_type, &p->dev.interrupt_id);
+
+ if (result) {
+ pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+ __func__, __LINE__);
+ goto fail_find_interrupt;
+ }
+
+ result = ps3_repository_find_reg(repo, reg_type,
+ &bus_addr, &len);
+
+ if (result) {
+ pr_debug("%s:%d ps3_repository_find_reg failed\n",
+ __func__, __LINE__);
+ goto fail_find_reg;
+ }
+
+ result = ps3_dma_region_init(&p->dev, p->dev.d_region, PS3_DMA_64K,
+ PS3_DMA_INTERNAL, NULL, 0);
+
+ if (result) {
+ pr_debug("%s:%d ps3_dma_region_init failed\n",
+ __func__, __LINE__);
+ goto fail_dma_init;
+ }
+
+ result = ps3_mmio_region_init(&p->dev, p->dev.m_region, bus_addr, len,
+ PS3_MMIO_4K);
+
+ if (result) {
+ pr_debug("%s:%d ps3_mmio_region_init failed\n",
+ __func__, __LINE__);
+ goto fail_mmio_init;
+ }
+
+ result = ps3_system_bus_device_register(&p->dev);
+
+ if (result) {
+ pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+ __func__, __LINE__);
+ goto fail_device_register;
+ }
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+
+fail_device_register:
+fail_mmio_init:
+fail_dma_init:
+fail_find_reg:
+fail_find_interrupt:
+ kfree(p);
+fail_malloc:
+ pr_debug(" <- %s:%d: fail.\n", __func__, __LINE__);
+ return result;
+}
+
+static int __devinit ps3_setup_ehci_device(
+ const struct ps3_repository_device *repo)
+{
+ return ps3_setup_uhc_device(repo, PS3_MATCH_ID_EHCI,
+ PS3_INTERRUPT_TYPE_SB_EHCI, PS3_REG_TYPE_SB_EHCI);
+}
+
+static int __devinit ps3_setup_ohci_device(
+ const struct ps3_repository_device *repo)
+{
+ return ps3_setup_uhc_device(repo, PS3_MATCH_ID_OHCI,
+ PS3_INTERRUPT_TYPE_SB_OHCI, PS3_REG_TYPE_SB_OHCI);
+}
+
+static int __devinit ps3_setup_vuart_device(enum ps3_match_id match_id,
+ unsigned int port_number)
+{
+ int result;
+ struct layout {
+ struct ps3_system_bus_device dev;
+ } *p;
+
+ pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__,
+ match_id, port_number);
+
+ p = kzalloc(sizeof(struct layout), GFP_KERNEL);
+
+ if (!p)
+ return -ENOMEM;
+
+ p->dev.match_id = match_id;
+ p->dev.dev_type = PS3_DEVICE_TYPE_VUART;
+ p->dev.port_number = port_number;
+
+ result = ps3_system_bus_device_register(&p->dev);
+
+ if (result)
+ pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+ __func__, __LINE__);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+}
+
+static int __init ps3_register_vuart_devices(void)
+{
+ int result;
+ unsigned int port_number;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ result = ps3_repository_read_vuart_av_port(&port_number);
+ if (result)
+ port_number = 0; /* av default */
+
+ result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);
+ WARN_ON(result);
+
+ result = ps3_repository_read_vuart_sysmgr_port(&port_number);
+ if (result)
+ port_number = 2; /* sysmgr default */
+
+ result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,
+ port_number);
+ WARN_ON(result);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+}
+
+static int __init ps3_register_sound_devices(void)
+{
+ int result;
+ struct layout {
+ struct ps3_system_bus_device dev;
+ struct ps3_dma_region d_region;
+ struct ps3_mmio_region m_region;
+ } *p;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ p->dev.match_id = PS3_MATCH_ID_SOUND;
+ p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
+ p->dev.d_region = &p->d_region;
+ p->dev.m_region = &p->m_region;
+
+ result = ps3_system_bus_device_register(&p->dev);
+
+ if (result)
+ pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+ __func__, __LINE__);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+}
+
+static int __devinit ps3_register_graphics_devices(void)
+{
+ int result;
+ struct layout {
+ struct ps3_system_bus_device dev;
+ } *p;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ p = kzalloc(sizeof(struct layout), GFP_KERNEL);
+
+ if (!p)
+ return -ENOMEM;
+
+ p->dev.match_id = PS3_MATCH_ID_GRAPHICS;
+ p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;
+
+ result = ps3_system_bus_device_register(&p->dev);
+
+ if (result)
+ pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+ __func__, __LINE__);
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+}
+
+/**
+ * ps3_register_repository_device - Register a device from the repositiory info.
+ *
+ */
+
+static int __devinit ps3_register_repository_device(
+ const struct ps3_repository_device *repo)
+{
+ int result;
+
+ switch(repo->dev_type) {
+ case PS3_DEV_TYPE_SB_GELIC:
+ result = ps3_setup_gelic_device(repo);
+ if (result) {
+ pr_debug("%s:%d ps3_setup_gelic_device failed\n",
+ __func__, __LINE__);
+ }
+ break;
+ case PS3_DEV_TYPE_SB_USB:
+
+ /* Each USB device has both an EHCI and an OHCI HC */
+
+ result = ps3_setup_ehci_device(repo);
+
+ if (result) {
+ pr_debug("%s:%d ps3_setup_ehci_device failed\n",
+ __func__, __LINE__);
+ }
+
+ result = ps3_setup_ohci_device(repo);
+
+ if (result) {
+ pr_debug("%s:%d ps3_setup_ohci_device failed\n",
+ __func__, __LINE__);
+ }
+ break;
+ default:
+ result = 0;
+ pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
+ repo->dev_type);
+ }
+
+ return result;
+}
+
+/**
+ * ps3_probe_thread - Background repository probing at system startup.
+ *
+ * This implementation only supports background probing on a single bus.
+ */
+
+static int ps3_probe_thread(void *data)
+{
+ struct ps3_repository_device *repo = data;
+ int result;
+ unsigned int ms = 250;
+
+ pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
+
+ do {
+ try_to_freeze();
+
+ pr_debug("%s:%u: probing...\n", __func__, __LINE__);
+
+ do {
+ result = ps3_repository_find_device(repo);
+
+ 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\n", __func__,
+ __LINE__);
+ ps3_register_repository_device(repo);
+ ps3_repository_bump_device(repo);
+ ms = 250;
+ }
+ } while (!result);
+
+ pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);
+
+ if ( ms > 60000)
+ break;
+
+ msleep_interruptible(ms);
+
+ /* An exponential backoff. */
+ ms <<= 1;
+
+ } while (!kthread_should_stop());
+
+ pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);
+
+ return 0;
+}
+
+/**
+ * ps3_start_probe_thread - Starts the background probe thread.
+ *
+ */
+
+static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type)
+{
+ int result;
+ struct task_struct *task;
+ static struct ps3_repository_device repo; /* must be static */
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ memset(&repo, 0, sizeof(repo));
+
+ repo.bus_type = bus_type;
+
+ result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
+
+ if (result) {
+ printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);
+ return -ENODEV;
+ }
+
+ result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
+
+ if (result) {
+ printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,
+ result);
+ return -ENODEV;
+ }
+
+ task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);
+
+ if (IS_ERR(task)) {
+ result = PTR_ERR(task);
+ printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,
+ result);
+ return result;
+ }
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return 0;
+}
+
+/**
+ * ps3_register_devices - Probe the system and register devices found.
+ *
+ * A device_initcall() routine.
+ */
+
+static int __init ps3_register_devices(void)
+{
+ int result;
+
+ if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+ return -ENODEV;
+
+ pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+ /* ps3_repository_dump_bus_info(); */
+
+ result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);
+
+ ps3_register_vuart_devices();
+
+ ps3_register_graphics_devices();
+
+ ps3_repository_find_devices(PS3_BUS_TYPE_SB,
+ ps3_register_repository_device);
+
+ ps3_register_sound_devices();
+
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return 0;
+}
+
+device_initcall(ps3_register_devices);
--
^ permalink raw reply
* [patch 21/30] PS3: Use clear_bit
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Replace inline asm to bitops routines in the PS3 interrupt
chip mask routines.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/platforms/ps3/interrupt.c | 26 ++------------------------
1 file changed, 2 insertions(+), 24 deletions(-)
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -101,24 +101,13 @@ static DEFINE_PER_CPU(struct ps3_private
static void ps3_chip_mask(unsigned int virq)
{
struct ps3_private *pd = get_irq_chip_data(virq);
- u64 bit = 0x8000000000000000UL >> virq;
- u64 *p = &pd->bmp.mask;
- u64 old;
unsigned long flags;
pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
pd->thread_id, virq);
local_irq_save(flags);
- asm volatile(
- "1: ldarx %0,0,%3\n"
- "andc %0,%0,%2\n"
- "stdcx. %0,0,%3\n"
- "bne- 1b"
- : "=&r" (old), "+m" (*p)
- : "r" (bit), "r" (p)
- : "cc" );
-
+ clear_bit(63 - virq, &pd->bmp.mask);
lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
@@ -133,24 +122,13 @@ static void ps3_chip_mask(unsigned int v
static void ps3_chip_unmask(unsigned int virq)
{
struct ps3_private *pd = get_irq_chip_data(virq);
- u64 bit = 0x8000000000000000UL >> virq;
- u64 *p = &pd->bmp.mask;
- u64 old;
unsigned long flags;
pr_debug("%s:%d: thread_id %lu, virq %d\n", __func__, __LINE__,
pd->thread_id, virq);
local_irq_save(flags);
- asm volatile(
- "1: ldarx %0,0,%3\n"
- "or %0,%0,%2\n"
- "stdcx. %0,0,%3\n"
- "bne- 1b"
- : "=&r" (old), "+m" (*p)
- : "r" (bit), "r" (p)
- : "cc" );
-
+ set_bit(63 - virq, &pd->bmp.mask);
lv1_did_update_interrupt_mask(pd->ppe_id, pd->thread_id);
local_irq_restore(flags);
}
--
^ permalink raw reply
* [patch 26/30] Powerpc: Add u64 printf to bootwrapper
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Add support for the 'll' (long long) printf qualifier in the powerpc zImage
bootwrapper. This is useful for bootwrapper debugging on 64 bit platforms.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/stdio.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -190,7 +190,11 @@ int vsprintf(char *buf, const char *fmt,
/* get the conversion qualifier */
qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+ if (*fmt == 'l' && *(fmt + 1) =='l') {
+ qualifier = 'q';
+ fmt += 2;
+ } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L'
+ || *fmt =='Z') {
qualifier = *fmt;
++fmt;
}
@@ -281,6 +285,10 @@ int vsprintf(char *buf, const char *fmt,
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
+ } else if (qualifier == 'q') {
+ num = va_arg(args, unsigned long long);
+ if (flags & SIGN)
+ num = (signed long long) num;
} else if (qualifier == 'Z') {
num = va_arg(args, size_t);
} else if (qualifier == 'h') {
--
^ permalink raw reply
* [patch 30/30] PS3: Bootwrapper support.
From: Geoff Levand @ 2007-06-12 18:55 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Add suport to build the PS3 flash rom image.
zImage.ps3 is a wrapped image that contains a flat device tree, an lv1
compatible entry point, a standard _start entry point, a wrapper program,
and an optional initrd. otheros.bld is the gzip compresed rom image built
from zImage.ps3. otheros.bld is suitable for programming into the PS3 boot
flash memory.
Also remove the now unneeded lmb calls in the platform code.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/Makefile | 21 ++--
arch/powerpc/boot/ps3-head.S | 84 ++++++++++++++++
arch/powerpc/boot/ps3-hvcall.S | 184 +++++++++++++++++++++++++++++++++++++
arch/powerpc/boot/ps3.c | 158 +++++++++++++++++++++++++++++++
arch/powerpc/boot/wrapper | 42 ++++++++
arch/powerpc/boot/zImage.ps3.lds.S | 50 ++++++++++
arch/powerpc/platforms/ps3/mm.c | 2
7 files changed, 530 insertions(+), 11 deletions(-)
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -41,11 +41,13 @@ zliblinuxheader := zlib.h zconf.h zutil.
$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
$(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
+src-plat-$(CONFIG_PPC_PS3) += ps3-head.S ps3-hvcall.S ps3.c
+
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c $(zlib) devtree.c \
44x.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c
-src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
+src-plat := $(src-plat-y) of.c cuboot-83xx.c cuboot-85xx.c holly.c \
cuboot-ebony.c treeboot-ebony.c prpmc2800.c
src-boot := $(src-wlib) $(src-plat) empty.c
@@ -75,11 +77,11 @@ $(addprefix $(obj)/,$(zliblinuxheader)):
$(obj)/empty.c:
@touch $@
-$(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
+$(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds: $(obj)/%: $(srctree)/$(src)/%.S
@cp $< $@
clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
- empty.c zImage.coff.lds zImage.lds
+ empty.c zImage zImage.coff.lds zImage.ps3.lds zImage.lds
quiet_cmd_bootcc = BOOTCC $@
cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -102,7 +104,7 @@ hostprogs-y := addnote addRamDisk hack-c
targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
- $(obj)/zImage.lds $(obj)/zImage.coff.lds
+ $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
wrapper :=$(srctree)/$(src)/wrapper
wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \
@@ -187,11 +189,12 @@ $(obj)/zImage.%: vmlinux $(wrapperbits)
$(obj)/zImage.iseries: vmlinux
$(STRIP) -s -R .comment $< -o $@
-$(obj)/zImage.ps3: vmlinux
- $(STRIP) -s -R .comment $< -o $@
+$(obj)/zImage.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts
+ $(STRIP) -s -R .comment $< -o vmlinux.strip
+ $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,)
-$(obj)/zImage.initrd.ps3: vmlinux
- @echo " WARNING zImage.initrd.ps3 not supported (yet)"
+$(obj)/zImage.initrd.ps3: vmlinux $(wrapper) $(wrapperbits) $(srctree)/$(src)/dts/ps3.dts $(obj)/ramdisk.image.gz
+ $(call cmd,wrap,ps3,$(srctree)/$(src)/dts/ps3.dts,,$(obj)/ramdisk.image.gz)
$(obj)/zImage.holly-elf: vmlinux $(wrapperbits)
$(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,)
@@ -230,7 +233,7 @@ install: $(CONFIGURE) $(addprefix $(obj)
# anything not in $(targets)
clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \
- treeImage.* zImage.dts zImage.dts_initrd
+ treeImage.* zImage.dts zImage.dts_initrd otheros.bld
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
--- /dev/null
+++ b/arch/powerpc/boot/ps3-head.S
@@ -0,0 +1,84 @@
+/*
+ * PS3 bootwrapper entry.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ppc_asm.h"
+
+ .text
+
+/*
+ * __system_reset_overlay - The PS3 first stage entry.
+ *
+ * The bootwraper build script copies the 0x100 bytes at symbol
+ * __system_reset_overlay to offset 0x100 of the rom image.
+ */
+
+ .globl __system_reset_overlay
+__system_reset_overlay:
+
+ /* Switch to 32-bit mode. */
+
+ mfmsr r9
+ clrldi r9,r9,1
+ mtmsrd r9
+ nop
+
+ /* Get thread number in r3 and branch. */
+
+ mfspr r3, 0x88
+ cntlzw. r3, r3
+ li r4, 0
+ li r5, 0
+ beq 1f
+
+ /* Secondary goes to __secondary_hold in kernel. */
+
+ li r4, 0x60
+ mtctr r4
+ bctr
+
+ /* Primary waits for __secondary_hold_acknowledge. */
+1:
+ li r5, 0x10 /* __secondary_hold_acknowledge */
+ or 28, 28, 28 /* db8cyc */
+
+ ld r4, 0(r5)
+ cmpdi r4, 0
+ beq 1b
+
+ /* Primary goes to _zimage_start in wrapper. */
+
+ lis r4, _zimage_start@ha
+ addi r4, r4, _zimage_start@l
+ mtctr r4
+ bctr
+
+/*
+ * __system_reset_kernel - Place holder for the kernel reset vector.
+ *
+ * The bootwrapper build script copies 0x100 bytes from offset 0x100
+ * of the rom image to the symbol __system_reset_kernel. At runtime
+ * the bootwrapper program copies the 0x100 bytes at __system_reset_kernel
+ * to ram address 0x100. This symbol must occupy 0x100 bytes.
+ */
+
+ .globl __system_reset_kernel
+__system_reset_kernel:
+
+ . = __system_reset_kernel + 0x100
--- /dev/null
+++ b/arch/powerpc/boot/ps3-hvcall.S
@@ -0,0 +1,184 @@
+/*
+ * PS3 bootwrapper hvcalls.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ppc_asm.h"
+
+/*
+ * The PS3 hypervisor uses a 64 bit "C" language calling convention.
+ * The routines here marshal arguments between the 32 bit wrapper
+ * program and the 64 bit hvcalls.
+ *
+ * wrapper lv1
+ * 32-bit (h,l) 64-bit
+ *
+ * 1: r3,r4 <-> r3
+ * 2: r5,r6 <-> r4
+ * 3: r7,r8 <-> r5
+ * 4: r9,r10 <-> r6
+ * 5: 8(r1),12(r1) <-> r7
+ * 6: 16(r1),20(r1) <-> r8
+ * 7: 24(r1),28(r1) <-> r9
+ * 8: 32(r1),36(r1) <-> r10
+ *
+ */
+
+.macro GLOBAL name
+ .section ".text"
+ .balign 4
+ .globl \name
+\name:
+.endm
+
+.macro NO_SUPPORT name
+ GLOBAL \name
+ b ps3_no_support
+.endm
+
+.macro HVCALL num
+ li r11, \num
+ .long 0x44000022
+ extsw r3, r3
+.endm
+
+.macro SAVE_LR offset=4
+ mflr r0
+ stw r0, \offset(r1)
+.endm
+
+.macro LOAD_LR offset=4
+ lwz r0, \offset(r1)
+ mtlr r0
+.endm
+
+.macro LOAD_64_REG target,high,low
+ sldi r11, \high, 32
+ or \target, r11, \low
+.endm
+
+.macro LOAD_64_STACK target,offset
+ ld \target, \offset(r1)
+.endm
+
+.macro LOAD_R3
+ LOAD_64_REG r3,r3,r4
+.endm
+
+.macro LOAD_R4
+ LOAD_64_REG r4,r5,r6
+.endm
+
+.macro LOAD_R5
+ LOAD_64_REG r5,r7,r8
+.endm
+
+.macro LOAD_R6
+ LOAD_64_REG r6,r9,r10
+.endm
+
+.macro LOAD_R7
+ LOAD_64_STACK r7,8
+.endm
+
+.macro LOAD_R8
+ LOAD_64_STACK r8,16
+.endm
+
+.macro LOAD_R9
+ LOAD_64_STACK r9,24
+.endm
+
+.macro LOAD_R10
+ LOAD_64_STACK r10,32
+.endm
+
+.macro LOAD_REGS_0
+ stwu 1,-16(1)
+ stw 3, 8(1)
+.endm
+
+.macro LOAD_REGS_5
+ LOAD_R3
+ LOAD_R4
+ LOAD_R5
+ LOAD_R6
+ LOAD_R7
+.endm
+
+.macro LOAD_REGS_6
+ LOAD_REGS_5
+ LOAD_R8
+.endm
+
+.macro LOAD_REGS_8
+ LOAD_REGS_6
+ LOAD_R9
+ LOAD_R10
+.endm
+
+.macro STORE_REGS_0_1
+ lwz r11, 8(r1)
+ std r4, 0(r11)
+ mr r4, r3
+ li r3, 0
+ addi r1,r1,16
+.endm
+
+.macro STORE_REGS_5_2
+ lwz r11, 16(r1)
+ std r4, 0(r11)
+ lwz r11, 24(r1)
+ std r5, 0(r11)
+.endm
+
+.macro STORE_REGS_6_1
+ lwz r11, 24(r1)
+ std r4, 0(r11)
+.endm
+
+GLOBAL lv1_get_logical_ppe_id
+ SAVE_LR
+ LOAD_REGS_0
+ HVCALL 69
+ STORE_REGS_0_1
+ LOAD_LR
+ blr
+
+GLOBAL lv1_get_logical_partition_id
+ SAVE_LR
+ LOAD_REGS_0
+ HVCALL 74
+ STORE_REGS_0_1
+ LOAD_LR
+ blr
+
+GLOBAL lv1_get_repository_node_value
+ SAVE_LR
+ LOAD_REGS_5
+ HVCALL 91
+ STORE_REGS_5_2
+ LOAD_LR
+ blr
+
+GLOBAL lv1_panic
+ SAVE_LR
+ LOAD_REGS_8
+ HVCALL 255
+ LOAD_LR
+ blr
--- /dev/null
+++ b/arch/powerpc/boot/ps3.c
@@ -0,0 +1,158 @@
+/*
+ * PS3 bootwrapper support.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+
+extern s64 lv1_panic(u64 in_1);
+extern s64 lv1_get_logical_partition_id(u64 *out_1);
+extern s64 lv1_get_logical_ppe_id(u64 *out_1);
+extern s64 lv1_get_repository_node_value(u64 in_1, u64 in_2, u64 in_3,
+ u64 in_4, u64 in_5, u64 *out_1, u64 *out_2);
+
+#ifdef DEBUG
+#define DBG(fmt...) printf(fmt)
+#else
+static inline int __attribute__ ((format (printf, 1, 2))) DBG(
+ const char *fmt, ...) {return 0;}
+#endif
+
+BSS_STACK(4096);
+
+/* A buffer that may be edited by tools operating on a zImage binary so as to
+ * edit the command line passed to vmlinux (by setting /chosen/bootargs).
+ * The buffer is put in it's own section so that tools may locate it easier.
+ */
+static char cmdline[COMMAND_LINE_SIZE]
+ __attribute__((__section__("__builtin_cmdline")));
+
+static void prep_cmdline(void *chosen)
+{
+ if (cmdline[0] == '\0')
+ getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
+ else
+ setprop_str(chosen, "bootargs", cmdline);
+
+ printf("cmdline: '%s'\n", cmdline);
+}
+
+static void ps3_console_write(const char *buf, int len)
+{
+}
+
+static void ps3_exit(void)
+{
+ printf("ps3_exit\n");
+ lv1_panic(0); /* zero = no reboot */
+ while(1);
+}
+
+static int ps3_repository_read_rm_size(u64 *rm_size)
+{
+ s64 result;
+ u64 lpar_id;
+ u64 ppe_id;
+ u64 v2;
+
+ result = lv1_get_logical_partition_id(&lpar_id);
+
+ if (result)
+ return -1;
+
+ result = lv1_get_logical_ppe_id(&ppe_id);
+
+ if (result)
+ return -1;
+
+ /*
+ * n1: 0000000062690000 : ....bi..
+ * n2: 7075000000000000 : pu......
+ * n3: 0000000000000001 : ........
+ * n4: 726d5f73697a6500 : rm_size.
+ */
+
+ result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
+ 0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
+ &v2);
+
+ printf("%s:%d: ppe_id %lu \n", __func__, __LINE__,
+ (unsigned long)ppe_id);
+ printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
+ (unsigned long)lpar_id);
+ printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);
+
+ return result ? -1 : 0;
+}
+
+void ps3_copy_vectors(void)
+{
+ extern char __system_reset_kernel[];
+
+ memcpy((void*)0x100, __system_reset_kernel, 0x100);
+ flush_cache((void*)0x100, 0x100);
+}
+
+void platform_init(void)
+{
+ extern char _end[];
+ extern char _dtb_start[];
+ extern char _initrd_start[];
+ extern char _initrd_end[];
+ const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
+ void *chosen;
+ unsigned long ft_addr;
+ u64 rm_size;
+
+ console_ops.write = ps3_console_write;
+ platform_ops.exit = ps3_exit;
+
+ printf("\n-- PS3 bootwrapper --\n");
+
+ simple_alloc_init(_end, heapsize, 32, 64);
+ ft_init(_dtb_start, 0, 4);
+
+ chosen = finddevice("/chosen");
+
+ ps3_repository_read_rm_size(&rm_size);
+ dt_fixup_memory(0, rm_size);
+
+ if (_initrd_end > _initrd_start) {
+ setprop_val(chosen, "linux,initrd-start", (u32)(_initrd_start));
+ setprop_val(chosen, "linux,initrd-end", (u32)(_initrd_end));
+ }
+
+ prep_cmdline(chosen);
+
+ ft_addr = dt_ops.finalize();
+
+ ps3_copy_vectors();
+
+ printf(" flat tree at 0x%lx\n\r", ft_addr);
+
+ ((kernel_entry_t)0)(ft_addr, 0, NULL);
+
+ ps3_exit();
+}
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -144,6 +144,15 @@ miboot|uboot)
cuboot*)
gzip=
;;
+ps3)
+ platformo="$object/ps3-head.o $object/ps3-hvcall.o $object/ps3.o"
+ lds=$object/zImage.ps3.lds
+ gzip=
+ ext=bin
+ objflags="-O binary"
+ ksection=.kernel:vmlinux.bin
+ isection=.kernel:initrd
+ ;;
esac
vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -239,4 +248,37 @@ treeboot*)
fi
exit 0
;;
+ps3)
+ # The ps3's loader supports loading gzipped binary images from flash
+ # rom to addr zero. The loader enters the image at addr 0x100. A
+ # bootwrapper overlay is use to arrange for the kernel to be loaded
+ # to addr zero and to have a suitable bootwrapper entry at 0x100.
+ # To construct the rom image, 0x100 bytes from offset 0x100 in the
+ # kernel is copied to the bootwrapper symbol __system_reset_kernel.
+ # The 0x100 bytes at the bootwrapper symbol __system_reset_overlay is
+ # then copied to offset 0x100. At runtime the bootwrapper program
+ # copies the 0x100 bytes at __system_reset_kernel to addr 0x100.
+
+ system_reset_overlay=0x`${CROSS}nm "$ofile" \
+ | grep ' __system_reset_overlay$' \
+ | cut -d' ' -f1`
+ system_reset_overlay=`printf "%d" $system_reset_overlay`
+ system_reset_kernel=0x`${CROSS}nm "$ofile" \
+ | grep ' __system_reset_kernel$' \
+ | cut -d' ' -f1`
+ system_reset_kernel=`printf "%d" $system_reset_kernel`
+ overlay_dest="256"
+ overlay_size="256"
+
+ rm -f "$object/otheros.bld"
+
+ ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
+
+ dd if="$ofile.bin" of="$ofile.bin" conv=notrunc skip=$overlay_dest \
+ seek=$system_reset_kernel bs=1 count=$overlay_size
+ dd if="$ofile.bin" of="$ofile.bin" conv=notrunc skip=$system_reset_overlay \
+ seek=$overlay_dest bs=1 count=$overlay_size
+
+ gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
+ ;;
esac
--- /dev/null
+++ b/arch/powerpc/boot/zImage.ps3.lds.S
@@ -0,0 +1,50 @@
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_zimage_start)
+EXTERN(_zimage_start)
+SECTIONS
+{
+ _vmlinux_start = .;
+ .kernel:vmlinux.bin : { *(.kernel:vmlinux.bin) }
+ _vmlinux_end = .;
+
+ . = ALIGN(8);
+ _dtb_start = .;
+ .kernel:dtb : { *(.kernel:dtb) }
+ _dtb_end = .;
+
+ . = ALIGN(4096);
+ _initrd_start = .;
+ .kernel:initrd : { *(.kernel:initrd) }
+ _initrd_end = .;
+
+ _start = .;
+ .text :
+ {
+ *(.text)
+ *(.fixup)
+ }
+ _etext = .;
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.data*)
+ *(.sdata*)
+ __got2_start = .;
+ *(.got2)
+ __got2_end = .;
+ }
+
+ . = ALIGN(4096);
+ _edata = .;
+
+ . = ALIGN(4096);
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss)
+ *(.bss)
+ }
+ . = ALIGN(4096);
+ _end = . ;
+}
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -1212,8 +1212,6 @@ void __init ps3_mm_init(void)
BUG_ON(map.rm.base);
BUG_ON(!map.rm.size);
- lmb_add(map.rm.base, map.rm.size);
- lmb_analyze();
/* arrange to do this in ps3_mm_add_memory */
ps3_mm_region_create(&map.r1, map.total - map.rm.size);
--
^ permalink raw reply
* [patch 28/30] powerpc: Bootwrapper global scope kernel_entry_t.
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
For the convenience of custom platform code make the powerpc
bootwrapper typdef kernel_entry_t global in scope.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/main.c | 2 --
arch/powerpc/boot/ops.h | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -36,8 +36,6 @@ struct addr_range {
unsigned long size;
};
-typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
-
#undef DEBUG
static struct addr_range prep_kernel(void)
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -19,6 +19,8 @@
#define MAX_PATH_LEN 256
#define MAX_PROP_LEN 256 /* What should this be? */
+typedef void (*kernel_entry_t)(unsigned long r3, unsigned long r4, void *r5);
+
/* Platform specific operations */
struct platform_ops {
void (*fixups)(void);
--
^ permalink raw reply
* [patch 27/30] Powerpc: Fix constantness of bootwrapper arg
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Fixes the constantness of the powerpc bootwrapper's console_ops.write
routine. Allows writing of constant strings.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/of.c | 2 +-
arch/powerpc/boot/ops.h | 2 +-
arch/powerpc/boot/serial.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
--- a/arch/powerpc/boot/of.c
+++ b/arch/powerpc/boot/of.c
@@ -261,7 +261,7 @@ static int of_console_open(void)
return -1;
}
-static void of_console_write(char *buf, int len)
+static void of_console_write(const char *buf, int len)
{
call_prom("write", 3, 1, of_stdout_handle, buf, len);
}
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -51,7 +51,7 @@ extern struct dt_ops dt_ops;
/* Console operations */
struct console_ops {
int (*open)(void);
- void (*write)(char *buf, int len);
+ void (*write)(const char *buf, int len);
void (*edit_cmdline)(char *buf, int len);
void (*close)(void);
void *data;
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -27,7 +27,7 @@ static int serial_open(void)
return scdp->open();
}
-static void serial_write(char *buf, int len)
+static void serial_write(const char *buf, int len)
{
struct serial_console_data *scdp = console_ops.data;
--
^ permalink raw reply
* [patch 29/30] PS3: Device tree source.
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
The PS3 device tree source.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/dts/ps3.dts | 74 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
--- /dev/null
+++ b/arch/powerpc/boot/dts/ps3.dts
@@ -0,0 +1,74 @@
+/*
+ * PS3 Game Console device tree.
+ *
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ * Copyright 2006 Sony Corp.
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+/ {
+ model = "PS3 Game Console";
+ compatible = "PS3";
+ #size-cells = <2>;
+ #address-cells = <2>;
+
+ /*
+ * Need to keep linux,platform for a while, not used by kernel.
+ */
+
+ chosen {
+ linux,platform = <0>;
+ };
+
+ /*
+ * dtc expects a memory entry, so we'll put a null entry here.
+ * We'll get the size of the bootmem block from lv1 after startup.
+ */
+
+ memory {
+ device_type = "memory";
+ reg = <0 0 0 0>;
+ };
+
+ /*
+ * dtc expects a clock-frequency and timebase-frequency entries, so
+ * we'll put a null entries here. These will be initialized after
+ * startup with data from lv1.
+ *
+ * The boot cpu is always zero for PS3.
+ *
+ * Seems the only way currently to indicate a processor has multiple
+ * threads is with an ibm,ppc-interrupt-server#s entry. We'll put one
+ * here so we can bring up both of ours. See smp_setup_cpu_maps().
+ */
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+
+ CBE,PPE {
+ device_type = "cpu";
+ reg = <0>;
+ ibm,ppc-interrupt-server#s = <0 1>;
+ clock-frequency = <0>;
+ timebase-frequency = <0>;
+ i-cache-size = <8000>;
+ d-cache-size = <8000>;
+ i-cache-line-size = <80>;
+ d-cache-line-size = <80>;
+ };
+ };
+};
--
^ permalink raw reply
* [patch 00/30] PS3 patches for 2.6.23, take 2
From: Geoff Levand @ 2007-06-12 18:41 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Hi Paul.
This is the full set of PS3 related patches I have for 2.6.23.
Patches 1-19 were sent out before. The versions here have been
updated to address issues raised in the review. Patches 20 and
21 are new, and came from the review of Patches 1-19.
Patches 22-28 are new. These are changes to the core powerpc code.
They add some minor enhancements for debugging and add changes to the
bootwapper support needed for PS3.
Patches 29 and 30 are are new, and are the PS3 bootwrapper support.
These add the support needed to program the kernel into the PS3's
flash rom.
[01/30] Cell: Add spu shutdown method
[02/30] PS3: Rename IPI symbols
[03/30] PS3: Use __maybe_unused
[04/30] PS3: Compare firmware version
[05/30] PS3: Use ioremap_flags
[06/30] PS3: Fix sparse warnings
[07/30] PS3: Add support for HDMI RGB Full Range mode
[08/30] PS3: Move chip mask defs up
[09/30] PS3: Use inline DBG
[10/30] PS3: Kexec support
[11/30] PS3: System-bus rework
[12/30] PS3: System-bus uevent
[13/30] PS3: System-bus modinfo attribute
[14/30] PS3: Repository probe cleanups
[15/30] PS3: Vuart rework
[16/30] PS3: System manager re-work
[17/30] PS3: Rework AV settings driver
[18/30] PS3: Frame buffer system-bus rework
[19/30] PS3: Device registration routines.
[20/30] PS3: Rename processor id symbols
[21/30] PS3: Use clear_bit
[22/30] Powerpc: Output params value in early_init_devtree
[23/30] powerpc: Localize mmu_off
[24/30] powerpc: Correct __secondary_hold comment
[25/30] Powerpc: Add signed types to bootwrapper
[26/30] Powerpc: Add u64 printf to bootwrapper
[27/30] Powerpc: Fix constantness of bootwrapper arg
[28/30] powerpc: Bootwrapper global scope kernel_entry_t.
[29/30] PS3: Device tree source.
[30/30] PS3: Bootwrapper support.
-Geoff
--
^ permalink raw reply
* [patch 23/30] powerpc: Localize mmu_off
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
This just removes the dependency __mmu_off has on the symbol
__after_prom_start. I found the current code inconvenient when I
wanted to put some debugging code between the call to __mmu_off
and the branch to __after_prom_start.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/kernel/head_64.S | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1695,9 +1695,11 @@ _GLOBAL(__start_initialization_multiplat
2:
/* Switch off MMU if not already */
- LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
+ LOAD_REG_IMMEDIATE(r4, __mmu_off_return - KERNELBASE)
add r4,r4,r30
bl .__mmu_off
+__mmu_off_return:
+
b .__after_prom_start
_STATIC(__boot_from_prom)
--
^ permalink raw reply
* [patch 25/30] Powerpc: Add signed types to bootwrapper
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Add signed types to the powerpc zImage bootwrapper. These are needed by the
PS3 hcall interface.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/boot/types.h | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/powerpc/boot/types.h
+++ b/arch/powerpc/boot/types.h
@@ -7,6 +7,10 @@ typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
+typedef signed char s8;
+typedef short s16;
+typedef int s32;
+typedef long long s64;
#define min(x,y) ({ \
typeof(x) _x = (x); \
--
^ permalink raw reply
* [patch 24/30] powerpc: Correct __secondary_hold comment
From: Geoff Levand @ 2007-06-12 18:54 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
In-Reply-To: <20070612181825.730300780@am.sony.com>
Remove references to pSeries and OpenFirmware in the __secondary_hold
usage comment. __secondary_hold is a generic routine and can be used
by other platforms.
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
arch/powerpc/kernel/head_64.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
. = 0x60
/*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
+ * The following code is used to hold secondary processors
+ * in a spin loop after they have entered the kernel, but
* before the bulk of the kernel has been relocated. This code
* is relocated to physical address 0x60 before prom_init is run.
* All of it must fit below the first exception vector at 0x100.
--
^ permalink raw reply
* Re: [patch 00/18] PS3 patches for 2.6.23
From: Arnd Bergmann @ 2007-06-12 19:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Geert Uytterhoeven, Milton Miller
In-Reply-To: <466EE45A.4050104@am.sony.com>
On Tuesday 12 June 2007, Geoff Levand wrote:
>=20
> > The dependent series is currently split per file. =A0 While this makes =
it=20
> > easier to see what a given area looks like after all the patches, it=20
> > means that the kernel compile will break during the series. =A0Breaking=
=20
> > git bisect is frowned upon, so it will need to be re-split for merge. =
=A0
> > (Or disable the ps3 system bus during the merge of the series).
>=20
>=20
> Yes, I realize the state of the patches. =A0I will try to rework them for
> the next round. =A0As the existing PS3 support is incomplete, I don't
> think there will be many doing a git-bisect with PS3 support enabled.
I think it's ok to split the patches like this for review purposes.
=46or the upstream merge, it's probably best if Geoff commits all
patches with cross-dependencies as a single git checkin, and asks
Paul (or me) to pull from there. That will take care of the git-bisect
problem, and give a nicer changelog at the same time.
Of course, patches that only have directed dependencies should go
in as separate changesets whereever that makes sense.
Arnd <><
^ permalink raw reply
* Re: [patch 02/10] powerpc: Move CONFIG_PPC64 into CPU selection
From: Benjamin Herrenschmidt @ 2007-06-12 21:32 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann
In-Reply-To: <d8ba058b9bc8f9738d2c3d764c568c1e@kernel.crashing.org>
On Tue, 2007-06-12 at 13:35 +0200, Segher Boessenkool wrote:
> and/or allow a single kernel image to work on both 32-bit and
> 64-bit systems, The current situation is far removed from that,
> so this patch is a bit premature in that aspect.
Won't happen :-)
Ben.
^ permalink raw reply
* Re: [PATCH 2/5] Add RapidIO sector to MPC8641HPCN board dts file.
From: Phil Terry @ 2007-06-12 22:58 UTC (permalink / raw)
To: wei.zhang; +Cc: linuxppc-dev, paulus, linux-kernel
In-Reply-To: <11816389401714-git-send-email-wei.zhang@freescale.com>
On Tue, 2007-06-12 at 17:02 +0800, Zhang Wei wrote:
> Add RapidIO sector to the MPC8641HPCN board dts file.
>
> Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
> ---
> arch/powerpc/boot/dts/mpc8641_hpcn.dts | 13 +++++++++++++
> 1 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> index 04626b1..e2ce06e 100644
> --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> +++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
> @@ -329,6 +329,19 @@
> >;
> };
>
> + srio@c0000 {
> + device_type = "rapidio";
> + compatible = "fsl,rapidio-v1.0";
> + #address-cells = <2>;
> + reg = <c0000 20000>;
> + ranges = <0 0 c0000000 20000000>;
Don't understand the range setup... The code uses c0000000 as the start
and 20000000 as the size for the rapidio law. So whats the 0 0 for?
At first I thought address-cells 2 means that the range numbers are
pairs expressing 64-bit numbers, eg start 0 0, size c0000000 20000000
but thats not right...
Sorry if I'm asking stupid questions....
And thanks for the patch, just what I need.
BTW do you have any notes/documentation on the space allocation routines
intended use. I'm trying to work it out but I don't see any actual users
of it yet... I need something like it for my distributed DMA driver,
hence the interest.
Cheers
Phil
> + interrupt-parent = <&mpic>;
> + /* err_irq bell_outb_irq bell_inb_irq
> + msg1_tx_irq msg1_rx_irq
> + msg2_tx_irq msg2_rx_irq */
> + interrupts = <30 2 31 2 32 2 35 2 36 2 37 2 38 2>;
> + };
> +
> mpic: pic@40000 {
> clock-frequency = <0>;
> interrupt-controller;
^ permalink raw reply
* [PATCH 1/6] [C67x00] Add test of active flag when checking TDs
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <11816893411272-git-send-email-grant.likely@secretlab.ca>
The active flag in a TD needs to be checked to determine whether or not
the TD was processed in the frame. Without this check, the HCD assumes
the TD completed successfully, when in reality it was not processed at all.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-sched.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 84b40a4..952bdab 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -1020,8 +1020,8 @@ static void check_td_list(struct c67x00_hcd *c67x00, struct pt_regs *regs)
goto cont;
}
- if ((td->status & TD_STATUSMASK_NAK) || !td_sequence_ok(td) ||
- !td_acked(td))
+ if ((td->status & TD_STATUSMASK_NAK) ||
+ !td_sequence_ok(td) || !td_acked(td) || td_active(td))
goto cont;
/* Sequence ok and acked, don't need to fix toggle */
--
1.4.4.2
^ permalink raw reply related
* [PATCH 2/6] [C67x00] Fix calculation of frame bandwidth
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <11816893494143-git-send-email-grant.likely@secretlab.ca>
Use the correct formulas and values for calculating the bittime within
a frame.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-hcd.h | 10 ++++++--
drivers/usb/c67x00/c67x00-sched.c | 42 +++++++++++++++++++++++++++++++++---
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-hcd.h b/drivers/usb/c67x00/c67x00-hcd.h
index 8f8eff1..94ce7ec 100644
--- a/drivers/usb/c67x00/c67x00-hcd.h
+++ b/drivers/usb/c67x00/c67x00-hcd.h
@@ -46,12 +46,16 @@
* The current implementation switches between _STD (default) and _ISO (when
* isochronous transfers are scheduled), in order to optimize the throughput
* in normal cicrumstances, but also provide good isochronous behaviour.
+ *
+ * Bandwidth is described in bit time so with a 12MHz USB clock and 1ms
+ * frames; there are 12000 bit times per frame.
*/
-#define MAX_FRAME_BW_STD 4000
-#define MAX_FRAME_BW_ISO 2400
+#define TOTAL_FRAME_BW 12000
+#define DEFAULT_EOT 2250
-#define DEFAULT_EOT 6500
+#define MAX_FRAME_BW_STD (TOTAL_FRAME_BW - DEFAULT_EOT)
+#define MAX_FRAME_BW_ISO 2400
/*
* Periodic transfers may only use 90% of the full frame, but as
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 952bdab..0d08af7 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -520,11 +520,45 @@ static inline void giveback_urb(struct c67x00_hcd *c67x00, struct urb *urb,
/* -------------------------------------------------------------------------- */
-static int claim_frame_bw(struct c67x00_hcd *c67x00, int len, int periodic)
+static int claim_frame_bw(struct c67x00_hcd *c67x00, struct urb *urb,
+ int len, int periodic)
{
- int bit_time = len * 8;
+ struct urb_priv *urbp = urb->hcpriv;
+ int bit_time;
+
+ /* According to the C67x00 BIOS user manual, page 3-18,19, the
+ * following calculations provide the full speed bit times for
+ * a transaction.
+ *
+ * FS(in) = 112.5 + 9.36*BC + HOST_DELAY
+ * FS(in,iso) = 90.5 + 9.36*BC + HOST_DELAY
+ * FS(out) = 112.5 + 9.36*BC + HOST_DELAY
+ * FS(out,iso) = 78.4 + 9.36*BC + HOST_DELAY
+ * LS(in) = 802.4 + 75.78*BC + HOST_DELAY
+ * LS(out) = 802.6 + 74.67*BC + HOST_DELAY
+ *
+ * HOST_DELAY == 106 for the c67200 and c67300.
+ */
+
+ /* make calculations in 1/100 bit times to maintain resolution */
+ if (urbp->ep_data->dev->speed == USB_SPEED_LOW) {
+ /* Low speed pipe */
+ if (usb_pipein(urb->pipe))
+ bit_time = 80240 + 7578*len;
+ else
+ bit_time = 80260 + 7467*len;
+ } else {
+ /* FS pipes */
+ if (usb_pipeisoc(urb->pipe))
+ bit_time = usb_pipein(urb->pipe) ? 9050 : 7840;
+ else
+ bit_time = 11250;
+ bit_time += 936*len;
+ }
- /* TODO don't we need to take low speed into regards? */
+ /* Scale back down to integer bit times. Use a host delay of 106.
+ * (this is the only place it is used) */
+ bit_time = ((bit_time+50) / 100) + 106;
if (unlikely(bit_time + c67x00->bandwidth_allocated >=
c67x00->max_frame_bw))
@@ -565,7 +599,7 @@ static int create_td(struct c67x00_hcd *c67x00,
__u8 cmd = 0;
int tt = 0;
- if (claim_frame_bw(c67x00, len,
+ if (claim_frame_bw(c67x00, urb, len,
usb_pipeisoc(urb->pipe) || usb_pipeint(urb->pipe)))
return -EMSGSIZE; /* Not really an error, but expected */
--
1.4.4.2
^ permalink raw reply related
* [PATCH 4/6] [C67x00] Added error handling paths to lowlevel interface code
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <11816893493783-git-send-email-grant.likely@secretlab.ca>
Fix up some of the error paths in the low level code to not go into an
endless loop. Replace the endless loops with failout code.
This patch is just a first step. It eliminates the endless loops, but
some of the code paths don't yet have a failure path, so instead the
driver uses BUG_ON() to die with lots of noise. The driver needs to be
refactored to add in the failure paths so the driver can fail gracefully
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-drv.c | 8 ++++-
drivers/usb/c67x00/c67x00-ll-hpi.c | 57 ++++++++++++++++++++++-------------
drivers/usb/c67x00/c67x00-ll-hpi.h | 6 ++--
3 files changed, 46 insertions(+), 25 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index 6b38248..2737344 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -209,7 +209,11 @@ static int __devinit usb_c67x00_drv_probe(struct platform_device *pdev)
goto request_irq_failed;
}
- c67x00_ll_reset(drv);
+ ret = c67x00_ll_reset(drv);
+ if (ret) {
+ dev_err(&pdev->dev, "Device reset failed\n");
+ goto reset_failed;
+ }
for (i = 0; i < C67X00_SIES; i++)
probe_sie(&drv->sie[i]);
@@ -218,6 +222,8 @@ static int __devinit usb_c67x00_drv_probe(struct platform_device *pdev)
return 0;
+reset_failed:
+ free_irq(res2->start, drv);
request_irq_failed:
iounmap(drv->hpi.base);
map_failed:
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
index f47ce79..868736a 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -243,7 +243,7 @@ static inline u16 ll_recv_msg(struct c67x00_drv *drv)
INIT_COMPLETION(drv->lcp.msg_received);
WARN_ON(!res);
- return res;
+ return (res == 0) ? -EIO : 0;
}
static inline void ll_release(struct c67x00_drv *drv)
@@ -283,18 +283,22 @@ static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
{
struct c67x00_drv *drv = sie->drv;
struct lcp_int_data data;
+ int rc;
- c67x00_comm_exec_int(drv, HUSB_SIE_INIT_INT(sie->sie_num), &data);
+ rc = c67x00_comm_exec_int(drv, HUSB_SIE_INIT_INT(sie->sie_num), &data);
+ BUG_ON(rc); /* No return path for error code; crash spectacularly */
}
void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port)
{
struct c67x00_drv *drv = sie->drv;
struct lcp_int_data data;
+ int rc;
data.regs[0] = 50; /* Reset USB port for 50ms */
data.regs[1] = port | (sie->sie_num << 1);
- c67x00_comm_exec_int(drv, HUSB_RESET_INT, &data);
+ rc = c67x00_comm_exec_int(drv, HUSB_RESET_INT, &data);
+ BUG_ON(rc); /* No return path for error code; crash spectacularly */
}
void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr)
@@ -358,10 +362,12 @@ void c67x00_ll_susb_init(struct c67x00_sie *sie)
{
struct c67x00_drv *drv = sie->drv;
struct lcp_int_data data;
+ int rc;
data.regs[1] = 1; /* full speed */
data.regs[2] = sie->sie_num + 1;
- c67x00_comm_exec_int(drv, SUSB_INIT_INT, &data);
+ rc = c67x00_comm_exec_int(drv, SUSB_INIT_INT, &data);
+ BUG_ON(rc); /* No return path for error code; crash spectacularly */
hpi_clear_bits(drv, HPI_IRQ_ROUTING_REG,
SOFEOP_TO_HPI_EN(sie->sie_num));
@@ -384,45 +390,54 @@ void c67x00_ll_irq(struct c67x00_drv *drv)
u16 c67x00_comm_read_ctrl_reg(struct c67x00_drv * drv, u16 addr)
{
unsigned long msg, res;
+ int rc;
ll_start(drv);
- do {
- hpi_write_word(drv, COMM_CTRL_REG_ADDR, addr);
- hpi_send_mbox(drv, COMM_READ_CTRL_REG);
- } while (!ll_recv_msg(drv));
+ hpi_write_word(drv, COMM_CTRL_REG_ADDR, addr);
+ hpi_send_mbox(drv, COMM_READ_CTRL_REG);
+ rc = ll_recv_msg(drv);
+
+ BUG_ON(rc); /* No return path for error code; crash spectacularly */
+
msg = drv->lcp.last_msg;
if (msg != COMM_ACK) {
dev_warn(&drv->pdev->dev, "COMM_READ_CTRL_REG didn't ACK!\n");
res = 0;
- } else
+ } else {
res = hpi_read_word(drv, COMM_CTRL_REG_DATA);
+ }
ll_release(drv);
return res;
}
-void c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
+int c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
struct lcp_int_data *data)
{
+ int i, rc;
+
ll_start(drv);
- do {
- int i;
- hpi_write_word(drv, COMM_INT_NUM, nr);
- for (i = 0; i < COMM_REGS; i++)
- hpi_write_word(drv, COMM_R(i), data->regs[i]);
- hpi_send_mbox(drv, COMM_EXEC_INT);
- } while (!ll_recv_msg(drv));
+ hpi_write_word(drv, COMM_INT_NUM, nr);
+ for (i = 0; i < COMM_REGS; i++)
+ hpi_write_word(drv, COMM_R(i), data->regs[i]);
+ hpi_send_mbox(drv, COMM_EXEC_INT);
+ rc = ll_recv_msg(drv);
ll_release(drv);
+
+ return rc;
}
/* -------------------------------------------------------------------------- */
-void c67x00_ll_reset(struct c67x00_drv *drv)
+int c67x00_ll_reset(struct c67x00_drv *drv)
{
+ int rc;
+
ll_start(drv);
- do {
- hpi_send_mbox(drv, COMM_RESET);
- } while (!ll_recv_msg(drv));
+ hpi_send_mbox(drv, COMM_RESET);
+ rc = ll_recv_msg(drv);
ll_release(drv);
+
+ return rc;
}
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.h b/drivers/usb/c67x00/c67x00-ll-hpi.h
index 118cd7d..3f84348 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.h
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.h
@@ -85,14 +85,14 @@ void c67x00_read_mem_le16(struct c67x00_drv *drv, u16 addr,
u16 c67x00_comm_read_ctrl_reg(struct c67x00_drv *drv, u16 addr);
-void c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
- struct lcp_int_data *data);
+int c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
+ struct lcp_int_data *data);
/* Called by c67x00_irq to handle lcp interrupts */
void c67x00_ll_irq(struct c67x00_drv *drv);
void c67x00_ll_init(struct c67x00_drv *drv);
void c67x00_ll_release(struct c67x00_drv *drv);
-void c67x00_ll_reset(struct c67x00_drv *drv);
+int c67x00_ll_reset(struct c67x00_drv *drv);
#endif /* _USB_C67X00_LL_HPI_H */
--
1.4.4.2
^ permalink raw reply related
* [PATCH 6/6] [C67x00] Merge c67x00-hub.c into c67x00-hcd.c
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <11816893503814-git-send-email-grant.likely@secretlab.ca>
Rather than c67x00-hub.c being compiled seperately, the original code had
c67x00-hub.c *included* by c67x00-hcd.c. This is a very bad idea.
Simplest solution is to merge the two files into one and be done with it.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-hcd.c | 183 ++++++++++++++++++++++++++++++++++-
drivers/usb/c67x00/c67x00-hub.c | 206 ---------------------------------------
2 files changed, 182 insertions(+), 207 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
index d5458ea..4e6810d 100644
--- a/drivers/usb/c67x00/c67x00-hcd.c
+++ b/drivers/usb/c67x00/c67x00-hcd.c
@@ -89,8 +89,189 @@ static int c67x00_get_frame(struct usb_hcd *hcd)
}
/* -------------------------------------------------------------------------- */
+/* Root Hub Support */
-#include "c67x00-hub.c"
+static __u8 root_hub_hub_des[] = {
+ 0x09, /* __u8 bLength; */
+ 0x29, /* __u8 bDescriptorType; Hub-descriptor */
+ 0x02, /* __u8 bNbrPorts; */
+ 0x00, /* __u16 wHubCharacteristics; */
+ 0x00, /* (per-port OC, no power switching) */
+ 0x32, /* __u8 bPwrOn2pwrGood; 2ms */
+ 0x00, /* __u8 bHubContrCurrent; 0 mA */
+ 0x00, /* __u8 DeviceRemovable; ** 7 Ports max ** */
+ 0xff, /* __u8 PortPwrCtrlMask; ** 7 ports max ** */
+};
+
+#define OK(x) len = (x); break
+
+/* -------------------------------------------------------------------------- */
+
+static void c67x00_hub_reset_host_port(struct c67x00_sie *sie, int port)
+{
+ struct c67x00_hcd *c67x00 = sie->private_data;
+ unsigned long flags;
+
+ c67x00_ll_husb_reset(sie, port);
+
+ spin_lock_irqsave(&c67x00->lock, flags);
+ c67x00_ll_husb_reset_port(sie, port);
+ spin_unlock_irqrestore(&c67x00->lock, flags);
+
+ c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT);
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf)
+{
+ struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+ struct c67x00_sie *sie = c67x00->sie;
+ u16 status;
+ int i;
+
+ *buf = 0;
+ status = c67x00_ll_husb_get_status(sie);
+ for (i=0; i<C67X00_PORTS; i++)
+ if (status & PORT_CONNECT_CHANGE(i))
+ *buf |= (1 << i);
+
+ /* bit 0 denotes hub change, b1..n port change */
+ *buf <<= 1;
+
+ return !!*buf;
+}
+
+static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength)
+{
+ struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
+ struct c67x00_sie *sie = c67x00->sie;
+ u16 status, usb_status;
+ int retval = 0, len = 0;
+ unsigned int port = wIndex-1;
+ u16 wPortChange, wPortStatus;
+
+ switch (typeReq) {
+
+ case GetHubStatus:
+ *(__le32 *) buf = cpu_to_le32(0);
+ OK(4); /* hub power */
+ case GetPortStatus:
+ if (wIndex > C67X00_PORTS)
+ goto err;
+
+ status = c67x00_ll_husb_get_status(sie);
+ usb_status = c67x00_ll_get_usb_ctl(sie);
+
+ wPortChange = 0;
+ if (status & PORT_CONNECT_CHANGE(port))
+ wPortChange |= USB_PORT_STAT_C_CONNECTION;
+
+ wPortStatus = USB_PORT_STAT_POWER;
+ if (!(status & PORT_SE0_STATUS(port)))
+ wPortStatus |= USB_PORT_STAT_CONNECTION;
+ if (usb_status & LOW_SPEED_PORT(port)) {
+ wPortStatus |= USB_PORT_STAT_LOW_SPEED;
+ c67x00->low_speed_ports |= (1 << port);
+ } else
+ c67x00->low_speed_ports &= ~(1 << port);
+
+ if (usb_status & SOF_EOP_EN(port))
+ wPortStatus |= USB_PORT_STAT_ENABLE;
+
+ *(__le16 *) buf = cpu_to_le16(wPortStatus);
+ *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange);
+ OK(4);
+ case SetHubFeature: /* We don't implement these */
+ case ClearHubFeature:
+ switch (wValue) {
+ case C_HUB_OVER_CURRENT:
+ case C_HUB_LOCAL_POWER:
+ OK(0);
+ default:
+ goto err;
+ }
+ break;
+ case SetPortFeature:
+ if (wIndex > C67X00_PORTS)
+ goto err;
+
+ switch (wValue) {
+ case USB_PORT_FEAT_SUSPEND:
+ dev_dbg(c67x00_dev(c67x00),
+ "SetPortFeature %d (SUSPEND)\n", port);
+ OK(0);
+ case USB_PORT_FEAT_RESET:
+ c67x00_hub_reset_host_port(sie, port);
+ OK(0);
+ case USB_PORT_FEAT_POWER:
+ /* Power always enabled */
+ OK(0);
+ default:
+ dev_dbg(c67x00_dev(c67x00),
+ "%s: SetPortFeature %d (0x%04x) Error!\n",
+ __FUNCTION__, port, wValue);
+ goto err;
+ }
+ break;
+ case ClearPortFeature:
+ if (wIndex > C67X00_PORTS)
+ goto err;
+
+ switch (wValue) {
+ case USB_PORT_FEAT_ENABLE:
+ /* Reset the port so that the c67x00 also notices the
+ * disconnect */
+ c67x00_hub_reset_host_port(sie, port);
+ OK(0);
+ case USB_PORT_FEAT_C_ENABLE:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): C_ENABLE\n", port);
+ OK(0);
+ case USB_PORT_FEAT_SUSPEND:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): SUSPEND\n", port);
+ OK(0);
+ case USB_PORT_FEAT_C_SUSPEND:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): C_SUSPEND\n", port);
+ OK(0);
+ case USB_PORT_FEAT_POWER:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): POWER\n", port);
+ goto err;
+ case USB_PORT_FEAT_C_CONNECTION:
+ c67x00_ll_husb_clear_status(sie,
+ PORT_CONNECT_CHANGE(port));
+ OK(0);
+ case USB_PORT_FEAT_C_OVER_CURRENT:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): OVER_CURRENT\n", port);
+ OK(0);
+ case USB_PORT_FEAT_C_RESET:
+ dev_dbg(c67x00_dev(c67x00),
+ "ClearPortFeature (%d): C_RESET\n", port);
+ OK(0);
+ default:
+ dev_dbg(c67x00_dev(c67x00),
+ "%s: ClearPortFeature %d (0x%04x) Error!\n",
+ __FUNCTION__, port, wValue);
+ goto err;
+ }
+ break;
+ case GetHubDescriptor:
+ len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
+ memcpy(buf, root_hub_hub_des, len);
+ OK(len);
+ default:
+ dev_dbg(c67x00_dev(c67x00), "%s: unknown\n", __FUNCTION__);
+ err:
+ retval = -EPIPE;
+ }
+
+ return retval;
+}
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/c67x00/c67x00-hub.c b/drivers/usb/c67x00/c67x00-hub.c
deleted file mode 100644
index 2518106..0000000
--- a/drivers/usb/c67x00/c67x00-hub.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * c67x00-hub.c: Cypress C67X00 USB Host Controller Driver - HUB functionality
- *
- * Copyright (C) 2006-2007 Barco N.V.
- * Derived from the Cypress cy7c67200/300 ezusb linux driver and
- * based on multiple host controller drivers inside the linux kernel.
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301 USA.
- */
-
-/* Included in c67x00-hcd.c */
-
-static __u8 root_hub_hub_des[] = {
- 0x09, /* __u8 bLength; */
- 0x29, /* __u8 bDescriptorType; Hub-descriptor */
- 0x02, /* __u8 bNbrPorts; */
- 0x00, /* __u16 wHubCharacteristics; */
- 0x00, /* (per-port OC, no power switching) */
- 0x32, /* __u8 bPwrOn2pwrGood; 2ms */
- 0x00, /* __u8 bHubContrCurrent; 0 mA */
- 0x00, /* __u8 DeviceRemovable; ** 7 Ports max ** */
- 0xff, /* __u8 PortPwrCtrlMask; ** 7 ports max ** */
-};
-
-#define OK(x) len = (x); break
-
-/* -------------------------------------------------------------------------- */
-
-static void reset_host_port(struct c67x00_sie *sie, int port)
-{
- struct c67x00_hcd *c67x00 = sie->private_data;
- unsigned long flags;
-
- c67x00_ll_husb_reset(sie, port);
-
- spin_lock_irqsave(&c67x00->lock, flags);
- c67x00_ll_husb_reset_port(sie, port);
- spin_unlock_irqrestore(&c67x00->lock, flags);
-
- c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT);
-}
-
-/* -------------------------------------------------------------------------- */
-
-static int c67x00_hub_status_data(struct usb_hcd *hcd, char *buf)
-{
- struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
- struct c67x00_sie *sie = c67x00->sie;
- u16 status;
- int i;
-
- *buf = 0;
- status = c67x00_ll_husb_get_status(sie);
- for (i=0; i<C67X00_PORTS; i++)
- if (status & PORT_CONNECT_CHANGE(i))
- *buf |= (1 << i);
-
- /* bit 0 denotes hub change, b1..n port change */
- *buf <<= 1;
-
- return !!*buf;
-}
-
-static int c67x00_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
- u16 wIndex, char *buf, u16 wLength)
-{
- struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
- struct c67x00_sie *sie = c67x00->sie;
- u16 status, usb_status;
- int retval = 0, len = 0;
- unsigned int port = wIndex-1;
- u16 wPortChange, wPortStatus;
-
- switch (typeReq) {
-
- case GetHubStatus:
- *(__le32 *) buf = cpu_to_le32(0);
- OK(4); /* hub power */
- case GetPortStatus:
- if (wIndex > C67X00_PORTS)
- goto err;
-
- status = c67x00_ll_husb_get_status(sie);
- usb_status = c67x00_ll_get_usb_ctl(sie);
-
- wPortChange = 0;
- if (status & PORT_CONNECT_CHANGE(port))
- wPortChange |= USB_PORT_STAT_C_CONNECTION;
-
- wPortStatus = USB_PORT_STAT_POWER;
- if (!(status & PORT_SE0_STATUS(port)))
- wPortStatus |= USB_PORT_STAT_CONNECTION;
- if (usb_status & LOW_SPEED_PORT(port)) {
- wPortStatus |= USB_PORT_STAT_LOW_SPEED;
- c67x00->low_speed_ports |= (1 << port);
- } else
- c67x00->low_speed_ports &= ~(1 << port);
-
- if (usb_status & SOF_EOP_EN(port))
- wPortStatus |= USB_PORT_STAT_ENABLE;
-
- *(__le16 *) buf = cpu_to_le16(wPortStatus);
- *(__le16 *) (buf + 2) = cpu_to_le16(wPortChange);
- OK(4);
- case SetHubFeature: /* We don't implement these */
- case ClearHubFeature:
- switch (wValue) {
- case C_HUB_OVER_CURRENT:
- case C_HUB_LOCAL_POWER:
- OK(0);
- default:
- goto err;
- }
- break;
- case SetPortFeature:
- if (wIndex > C67X00_PORTS)
- goto err;
-
- switch (wValue) {
- case USB_PORT_FEAT_SUSPEND:
- dev_dbg(c67x00_dev(c67x00),
- "SetPortFeature %d (SUSPEND)\n", port);
- OK(0);
- case USB_PORT_FEAT_RESET:
- reset_host_port(sie, port);
- OK(0);
- case USB_PORT_FEAT_POWER:
- /* Power always enabled */
- OK(0);
- default:
- dev_dbg(c67x00_dev(c67x00),
- "%s: SetPortFeature %d (0x%04x) Error!\n",
- __FUNCTION__, port, wValue);
- goto err;
- }
- break;
- case ClearPortFeature:
- if (wIndex > C67X00_PORTS)
- goto err;
-
- switch (wValue) {
- case USB_PORT_FEAT_ENABLE:
- /* Reset the port so that the c67x00 also notices the
- * disconnect */
- reset_host_port(sie, port);
- OK(0);
- case USB_PORT_FEAT_C_ENABLE:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): C_ENABLE\n", port);
- OK(0);
- case USB_PORT_FEAT_SUSPEND:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): SUSPEND\n", port);
- OK(0);
- case USB_PORT_FEAT_C_SUSPEND:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): C_SUSPEND\n", port);
- OK(0);
- case USB_PORT_FEAT_POWER:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): POWER\n", port);
- goto err;
- case USB_PORT_FEAT_C_CONNECTION:
- c67x00_ll_husb_clear_status(sie,
- PORT_CONNECT_CHANGE(port));
- OK(0);
- case USB_PORT_FEAT_C_OVER_CURRENT:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): OVER_CURRENT\n", port);
- OK(0);
- case USB_PORT_FEAT_C_RESET:
- dev_dbg(c67x00_dev(c67x00),
- "ClearPortFeature (%d): C_RESET\n", port);
- OK(0);
- default:
- dev_dbg(c67x00_dev(c67x00),
- "%s: ClearPortFeature %d (0x%04x) Error!\n",
- __FUNCTION__, port, wValue);
- goto err;
- }
- break;
- case GetHubDescriptor:
- len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
- memcpy(buf, root_hub_hub_des, len);
- OK(len);
- default:
- dev_dbg(c67x00_dev(c67x00), "%s: unknown\n", __FUNCTION__);
- err:
- retval = -EPIPE;
- }
-
- return retval;
-}
--
1.4.4.2
^ permalink raw reply related
* [PATCH 5/6] [C67x00] Change 'struct c67x00_drv' to 'struct c67x00_device'
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <1181689350166-git-send-email-grant.likely@secretlab.ca>
The structure describes per-device data, not per driver data. Convention
seems to be to use the _device suffix for this kind of structure.
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-drv.c | 102 +++++++-------
drivers/usb/c67x00/c67x00-drv.h | 10 +-
drivers/usb/c67x00/c67x00-hcd.c | 4 +-
drivers/usb/c67x00/c67x00-hub.c | 2 +-
drivers/usb/c67x00/c67x00-ll-hpi.c | 266 ++++++++++++++++++------------------
drivers/usb/c67x00/c67x00-ll-hpi.h | 28 ++--
drivers/usb/c67x00/c67x00-sched.c | 10 +-
7 files changed, 211 insertions(+), 211 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c
index 2737344..fe29734 100644
--- a/drivers/usb/c67x00/c67x00-drv.c
+++ b/drivers/usb/c67x00/c67x00-drv.c
@@ -51,7 +51,7 @@ static struct platform_driver c67x00_driver;
/* -------------------------------------------------------------------------- */
static void setup_sie(struct c67x00_sie *sie,
- struct c67x00_drv *drv, int sie_num)
+ struct c67x00_device *dev, int sie_num)
{
static unsigned int id = 0;
@@ -61,9 +61,9 @@ static void setup_sie(struct c67x00_sie *sie,
/* driver used in hub.c: hub_port_init */
sie->pdev->dev.driver = &c67x00_driver.driver;
spin_lock_init(&sie->lock);
- sie->drv = drv;
+ sie->dev = dev;
sie->sie_num = sie_num;
- sie->mode = c67x00_sie_config(drv->pdata->sie_config, sie_num);
+ sie->mode = c67x00_sie_config(dev->pdata->sie_config, sie_num);
}
static void teardown_sie(struct c67x00_sie *sie)
@@ -76,7 +76,7 @@ static void teardown_sie(struct c67x00_sie *sie)
static void probe_sie(struct c67x00_sie *sie)
{
- switch (c67x00_sie_config(sie->drv->pdata->sie_config, sie->sie_num)) {
+ switch (c67x00_sie_config(sie->dev->pdata->sie_config, sie->sie_num)) {
case C67X00_SIE_HOST:
usb_hcd_c67x00_probe(sie);
break;
@@ -93,7 +93,7 @@ static void probe_sie(struct c67x00_sie *sie)
default:
dev_err(sie_dev(sie),
"Unsupported configuration: 0x%x for SIE %d\n",
- c67x00_sie_config(sie->drv->pdata->sie_config,
+ c67x00_sie_config(sie->dev->pdata->sie_config,
sie->sie_num), sie->sie_num);
break;
}
@@ -101,7 +101,7 @@ static void probe_sie(struct c67x00_sie *sie)
static void remove_sie(struct c67x00_sie *sie)
{
- switch (c67x00_sie_config(sie->drv->pdata->sie_config, sie->sie_num)) {
+ switch (c67x00_sie_config(sie->dev->pdata->sie_config, sie->sie_num)) {
case C67X00_SIE_HOST:
usb_hcd_c67x00_remove(sie);
break;
@@ -117,36 +117,36 @@ static void remove_sie(struct c67x00_sie *sie)
/* -------------------------------------------------------------------------- */
-static irqreturn_t c67x00_irq(int irq, void *__drv)
+static irqreturn_t c67x00_irq(int irq, void *__dev)
{
- struct c67x00_drv *drv = __drv;
+ struct c67x00_device *dev = __dev;
int i, count = 8;
- drv->int_status = c67x00_hpi_status(drv);
- if (!drv->int_status)
+ dev->int_status = c67x00_hpi_status(dev);
+ if (!dev->int_status)
return IRQ_NONE;
- while (drv->int_status != 0 && (count-- >= 0)) {
- c67x00_ll_irq(drv);
+ while (dev->int_status != 0 && (count-- >= 0)) {
+ c67x00_ll_irq(dev);
for (i = 0; i < C67X00_SIES; i++) {
- spin_lock(&drv->sie[i].lock);
- if (drv->int_status & SIEMSG_FLAG(i)) {
+ spin_lock(&dev->sie[i].lock);
+ if (dev->int_status & SIEMSG_FLAG(i)) {
u16 msg;
- msg = c67x00_ll_get_siemsg(drv, i);
- if (drv->sie[i].msg_received)
- drv->sie[i].msg_received(&drv->sie[i],
+ msg = c67x00_ll_get_siemsg(dev, i);
+ if (dev->sie[i].msg_received)
+ dev->sie[i].msg_received(&dev->sie[i],
msg);
}
- if (drv->sie[i].irq)
- drv->sie[i].irq(irq, &drv->sie[i]);
- spin_unlock(&drv->sie[i].lock);
+ if (dev->sie[i].irq)
+ dev->sie[i].irq(irq, &dev->sie[i]);
+ spin_unlock(&dev->sie[i].lock);
}
- drv->int_status = c67x00_hpi_status(drv);
+ dev->int_status = c67x00_hpi_status(dev);
}
- if (drv->int_status)
- dev_warn(&drv->pdev->dev, "Not all interrupts handled! "
- "status = 0x%04x\n", drv->int_status);
+ if (dev->int_status)
+ dev_warn(&dev->pdev->dev, "Not all interrupts handled! "
+ "status = 0x%04x\n", dev->int_status);
return IRQ_HANDLED;
}
@@ -155,7 +155,7 @@ static irqreturn_t c67x00_irq(int irq, void *__drv)
static int __devinit usb_c67x00_drv_probe(struct platform_device *pdev)
{
- struct c67x00_drv *drv;
+ struct c67x00_device *dev;
struct c67x00_platform_data *pdata;
struct resource *res, *res2;
int ret, i;
@@ -172,8 +172,8 @@ static int __devinit usb_c67x00_drv_probe(struct platform_device *pdev)
if (!pdata)
return -ENODEV;
- drv = kzalloc(sizeof(*drv), GFP_KERNEL);
- if (!drv)
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
return -ENOMEM;
if (!request_mem_region(res->start, res->end - res->start + 1,
@@ -182,82 +182,82 @@ static int __devinit usb_c67x00_drv_probe(struct platform_device *pdev)
ret = -EBUSY;
goto request_mem_failed;
}
- drv->hpi.base = ioremap(res->start, res->end - res->start + 1);
- if (!drv->hpi.base) {
+ dev->hpi.base = ioremap(res->start, res->end - res->start + 1);
+ if (!dev->hpi.base) {
dev_err(&pdev->dev, "Unable to map HPI registers\n");
ret = -EIO;
goto map_failed;
}
- spin_lock_init(&drv->hw_lock);
- drv->hpi.regstep = pdata->hpi_regstep;
- drv->pdata = pdev->dev.platform_data;
- drv->pdev = pdev;
+ spin_lock_init(&dev->hw_lock);
+ dev->hpi.regstep = pdata->hpi_regstep;
+ dev->pdata = pdev->dev.platform_data;
+ dev->pdev = pdev;
for (i = 0; i < C67X00_SIES; i++)
- setup_sie(&drv->sie[i], drv, i);
+ setup_sie(&dev->sie[i], dev, i);
- c67x00_ll_init(drv);
- c67x00_ll_hpi_reg_init(drv);
+ c67x00_ll_init(dev);
+ c67x00_ll_hpi_reg_init(dev);
dev_info(&pdev->dev, "USB OTG controller, p:0x%x, v:0x%p, irq:%i\n",
- res->start, drv->hpi.base, res2->start);
+ res->start, dev->hpi.base, res2->start);
- ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, drv);
+ ret = request_irq(res2->start, c67x00_irq, 0, pdev->name, dev);
if (ret) {
dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto request_irq_failed;
}
- ret = c67x00_ll_reset(drv);
+ ret = c67x00_ll_reset(dev);
if (ret) {
dev_err(&pdev->dev, "Device reset failed\n");
goto reset_failed;
}
for (i = 0; i < C67X00_SIES; i++)
- probe_sie(&drv->sie[i]);
+ probe_sie(&dev->sie[i]);
- platform_set_drvdata(pdev, drv);
+ platform_set_drvdata(pdev, dev);
return 0;
reset_failed:
- free_irq(res2->start, drv);
+ free_irq(res2->start, dev);
request_irq_failed:
- iounmap(drv->hpi.base);
+ iounmap(dev->hpi.base);
map_failed:
release_mem_region(res->start, res->end - res->start + 1);
request_mem_failed:
- kfree(drv);
+ kfree(dev);
return ret;
}
static int __devexit usb_c67x00_drv_remove(struct platform_device *pdev)
{
- struct c67x00_drv *drv = platform_get_drvdata(pdev);
+ struct c67x00_device *dev = platform_get_drvdata(pdev);
struct resource *res;
int i;
for (i = 0; i < C67X00_SIES; i++) {
- remove_sie(&drv->sie[i]);
- teardown_sie(&drv->sie[i]);
+ remove_sie(&dev->sie[i]);
+ teardown_sie(&dev->sie[i]);
}
- c67x00_ll_release(drv);
+ c67x00_ll_release(dev);
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (res)
- free_irq(res->start, drv);
+ free_irq(res->start, dev);
- iounmap(drv->hpi.base);
+ iounmap(dev->hpi.base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
release_mem_region(res->start, res->end - res->start + 1);
- kfree(drv);
+ kfree(dev);
return 0;
}
diff --git a/drivers/usb/c67x00/c67x00-drv.h b/drivers/usb/c67x00/c67x00-drv.h
index 8e7b99c..d29f4ad 100644
--- a/drivers/usb/c67x00/c67x00-drv.h
+++ b/drivers/usb/c67x00/c67x00-drv.h
@@ -31,7 +31,7 @@
#include <linux/workqueue.h>
#include "c67x00-ll-hpi.h"
-struct c67x00_drv;
+struct c67x00_device;
/**
* struct c67x00_sie - Common data associated with an SIE
@@ -40,7 +40,7 @@ struct c67x00_drv;
* @pdev: platform device associated with this SIE, created in c67x00-drv.c
* @irq: subdriver depenent irq handler, set NULL when not used
* @msg_received: called when an SIEmsg has been received
- * @drv: link to common driver structure
+ * @dev: link to common driver structure
* @sie_num: SIE number on chip, starting from 0
* @mode: SIE mode (host/peripheral/otg/not used)
*
@@ -57,7 +57,7 @@ struct c67x00_sie {
void (*msg_received) (struct c67x00_sie * sie, u16 msg);
/* Read only: */
- struct c67x00_drv *drv;
+ struct c67x00_device *dev;
int sie_num;
int mode;
};
@@ -73,7 +73,7 @@ struct c67x00_hpi {
#define C67X00_PORTS 2
/**
- * struct c67x00_drv - Common data structure associated with a c67x00 instance
+ * struct c67x00_device - Common data structure associated with a c67x00 instance
* @hpi: hpi addresses
* @sie: array of sie's on this chip
* @pdata: configuration provided by the platform
@@ -81,7 +81,7 @@ struct c67x00_hpi {
* @int_status: interrupt status register, only valid in_interrupt()
* @lcp: lcp dependent data
*/
-struct c67x00_drv {
+struct c67x00_device {
struct c67x00_hpi hpi;
struct c67x00_sie sie[C67X00_SIES];
struct platform_device *pdev;
diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c
index 357e34f..d5458ea 100644
--- a/drivers/usb/c67x00/c67x00-hcd.c
+++ b/drivers/usb/c67x00/c67x00-hcd.c
@@ -51,9 +51,9 @@ static irqreturn_t c67x00_hcd_irq(struct usb_hcd *hcd)
{
struct c67x00_hcd *c67x00 = hcd_to_c67x00_hcd(hcd);
struct c67x00_sie *sie = c67x00->sie;
- struct c67x00_drv *drv = sie->drv;
+ struct c67x00_device *dev = sie->dev;
int host = sie->sie_num;
- if (drv->int_status & SOFEOP_FLG(host)) {
+ if (dev->int_status & SOFEOP_FLG(host)) {
c67x00_ll_husb_clear_status(sie, SOF_EOP_IRQ_FLG);
c67x00_sched_sofeop(c67x00);
return IRQ_HANDLED;
diff --git a/drivers/usb/c67x00/c67x00-hub.c b/drivers/usb/c67x00/c67x00-hub.c
index 91ad898..2518106 100644
--- a/drivers/usb/c67x00/c67x00-hub.c
+++ b/drivers/usb/c67x00/c67x00-hub.c
@@ -50,7 +50,7 @@ static void reset_host_port(struct c67x00_sie *sie, int port)
c67x00_ll_husb_reset_port(sie, port);
spin_unlock_irqrestore(&c67x00->lock, flags);
- c67x00_ll_set_husb_eot(sie->drv, DEFAULT_EOT);
+ c67x00_ll_set_husb_eot(sie->dev, DEFAULT_EOT);
}
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.c b/drivers/usb/c67x00/c67x00-ll-hpi.c
index 868736a..052f35d 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.c
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.c
@@ -65,250 +65,250 @@
/* These functions could also be implemented with SPI of HSS.
* This is currently not supported */
-static inline u16 hpi_read_reg(struct c67x00_drv *drv, int reg)
+static inline u16 hpi_read_reg(struct c67x00_device *dev, int reg)
{
- return __raw_readw(drv->hpi.base + reg * drv->hpi.regstep);
+ return __raw_readw(dev->hpi.base + reg * dev->hpi.regstep);
}
-static inline void hpi_write_reg(struct c67x00_drv *drv, int reg, u16 value)
+static inline void hpi_write_reg(struct c67x00_device *dev, int reg, u16 value)
{
- __raw_writew(value, drv->hpi.base + reg * drv->hpi.regstep);
+ __raw_writew(value, dev->hpi.base + reg * dev->hpi.regstep);
}
-static inline u16 hpi_read_word_nolock(struct c67x00_drv *drv, u16 reg)
+static inline u16 hpi_read_word_nolock(struct c67x00_device *dev, u16 reg)
{
- hpi_write_reg(drv, HPI_ADDR, reg);
- return hpi_read_reg(drv, HPI_DATA);
+ hpi_write_reg(dev, HPI_ADDR, reg);
+ return hpi_read_reg(dev, HPI_DATA);
}
-static inline u16 hpi_read_word(struct c67x00_drv *drv, u16 reg)
+static inline u16 hpi_read_word(struct c67x00_device *dev, u16 reg)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- value = hpi_read_word_nolock(drv, reg);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ value = hpi_read_word_nolock(dev, reg);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
return value;
}
-static inline void hpi_write_word_nolock(struct c67x00_drv *drv, u16 reg,
+static inline void hpi_write_word_nolock(struct c67x00_device *dev, u16 reg,
u16 value)
{
- hpi_write_reg(drv, HPI_ADDR, reg);
- hpi_write_reg(drv, HPI_DATA, value);
+ hpi_write_reg(dev, HPI_ADDR, reg);
+ hpi_write_reg(dev, HPI_DATA, value);
}
-static inline void hpi_write_word(struct c67x00_drv *drv, u16 reg, u16 value)
+static inline void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value)
{
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- hpi_write_word_nolock(drv, reg, value);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ hpi_write_word_nolock(dev, reg, value);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
}
/*
* Only data is little endian, addr has cpu endianess
*/
-static inline void hpi_write_words_le16(struct c67x00_drv *drv, u16 addr,
+static inline void hpi_write_words_le16(struct c67x00_device *dev, u16 addr,
u16 * data, u16 count)
{
unsigned long flags;
int i;
- spin_lock_irqsave(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
- hpi_write_reg(drv, HPI_ADDR, addr);
+ hpi_write_reg(dev, HPI_ADDR, addr);
for (i = 0; i < count; i++)
- hpi_write_reg(drv, HPI_DATA, cpu_to_le16(*data++));
+ hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++));
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
}
/*
* Only data is little endian, addr has cpu endianess
*/
-static inline void hpi_read_words_le16(struct c67x00_drv *drv, u16 addr,
+static inline void hpi_read_words_le16(struct c67x00_device *dev, u16 addr,
u16 * data, u16 count)
{
unsigned long flags;
int i;
- spin_lock_irqsave(&drv->hw_lock, flags);
- hpi_write_reg(drv, HPI_ADDR, addr);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ hpi_write_reg(dev, HPI_ADDR, addr);
for (i = 0; i < count; i++)
- *data++ = le16_to_cpu(hpi_read_reg(drv, HPI_DATA));
+ *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA));
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
}
-static inline void hpi_set_bits(struct c67x00_drv *drv, u16 reg, u16 mask)
+static inline void hpi_set_bits(struct c67x00_device *dev, u16 reg, u16 mask)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- value = hpi_read_word_nolock(drv, reg);
- hpi_write_word_nolock(drv, reg, value | mask);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ value = hpi_read_word_nolock(dev, reg);
+ hpi_write_word_nolock(dev, reg, value | mask);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
}
-static inline void hpi_clear_bits(struct c67x00_drv *drv, u16 reg, u16 mask)
+static inline void hpi_clear_bits(struct c67x00_device *dev, u16 reg, u16 mask)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- value = hpi_read_word_nolock(drv, reg);
- hpi_write_word_nolock(drv, reg, value & ~mask);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ value = hpi_read_word_nolock(dev, reg);
+ hpi_write_word_nolock(dev, reg, value & ~mask);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
}
-static inline u16 hpi_recv_mbox(struct c67x00_drv *drv)
+static inline u16 hpi_recv_mbox(struct c67x00_device *dev)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- value = hpi_read_reg(drv, HPI_MAILBOX);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ value = hpi_read_reg(dev, HPI_MAILBOX);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
return value;
}
-static inline u16 hpi_send_mbox(struct c67x00_drv *drv, u16 value)
+static inline u16 hpi_send_mbox(struct c67x00_device *dev, u16 value)
{
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- hpi_write_reg(drv, HPI_MAILBOX, value);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ hpi_write_reg(dev, HPI_MAILBOX, value);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
return value;
}
-u16 c67x00_hpi_status(struct c67x00_drv * drv)
+u16 c67x00_hpi_status(struct c67x00_device * dev)
{
u16 value;
unsigned long flags;
- spin_lock_irqsave(&drv->hw_lock, flags);
- value = hpi_read_reg(drv, HPI_STATUS);
- spin_unlock_irqrestore(&drv->hw_lock, flags);
+ spin_lock_irqsave(&dev->hw_lock, flags);
+ value = hpi_read_reg(dev, HPI_STATUS);
+ spin_unlock_irqrestore(&dev->hw_lock, flags);
return value;
}
-void c67x00_ll_hpi_reg_init(struct c67x00_drv *drv)
+void c67x00_ll_hpi_reg_init(struct c67x00_device *dev)
{
int i;
- hpi_recv_mbox(drv);
- c67x00_hpi_status(drv);
- hpi_write_word(drv, HPI_IRQ_ROUTING_REG, 0);
+ hpi_recv_mbox(dev);
+ c67x00_hpi_status(dev);
+ hpi_write_word(dev, HPI_IRQ_ROUTING_REG, 0);
for (i=0; i<C67X00_SIES; i++) {
- hpi_write_word(drv, SIEMSG_REG(i), 0);
- hpi_read_word(drv, SIEMSG_REG(i));
+ hpi_write_word(dev, SIEMSG_REG(i), 0);
+ hpi_read_word(dev, SIEMSG_REG(i));
}
}
void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie)
{
- hpi_set_bits(sie->drv, HPI_IRQ_ROUTING_REG,
+ hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
SOFEOP_TO_HPI_EN(sie->sie_num));
}
void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie)
{
- hpi_clear_bits(sie->drv, HPI_IRQ_ROUTING_REG,
+ hpi_clear_bits(sie->dev, HPI_IRQ_ROUTING_REG,
SOFEOP_TO_HPI_EN(sie->sie_num));
}
/* -------------------------------------------------------------------------- */
/* Transactions */
-static inline void ll_start(struct c67x00_drv *drv)
+static inline void ll_start(struct c67x00_device *dev)
{
- INIT_COMPLETION(drv->lcp.msg_received);
- mutex_lock(&drv->lcp.mutex);
+ INIT_COMPLETION(dev->lcp.msg_received);
+ mutex_lock(&dev->lcp.mutex);
}
-static inline u16 ll_recv_msg(struct c67x00_drv *drv)
+static inline u16 ll_recv_msg(struct c67x00_device *dev)
{
u16 res;
- res = wait_for_completion_timeout(&drv->lcp.msg_received, 5 * HZ);
- INIT_COMPLETION(drv->lcp.msg_received);
+ res = wait_for_completion_timeout(&dev->lcp.msg_received, 5 * HZ);
+ INIT_COMPLETION(dev->lcp.msg_received);
WARN_ON(!res);
return (res == 0) ? -EIO : 0;
}
-static inline void ll_release(struct c67x00_drv *drv)
+static inline void ll_release(struct c67x00_device *dev)
{
- mutex_unlock(&drv->lcp.mutex);
+ mutex_unlock(&dev->lcp.mutex);
}
/* -------------------------------------------------------------------------- */
/* General functions */
-u16 c67x00_ll_get_siemsg(struct c67x00_drv *drv, int sie)
+u16 c67x00_ll_get_siemsg(struct c67x00_device *dev, int sie)
{
- return hpi_read_word(drv, SIEMSG_REG(sie));
+ return hpi_read_word(dev, SIEMSG_REG(sie));
}
-void c67x00_ll_set_siemsg(struct c67x00_drv *drv, int sie, u16 val)
+void c67x00_ll_set_siemsg(struct c67x00_device *dev, int sie, u16 val)
{
- hpi_write_word(drv, SIEMSG_REG(sie), val);
+ hpi_write_word(dev, SIEMSG_REG(sie), val);
}
u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie)
{
- return hpi_read_word(sie->drv, USB_CTL_REG(sie->sie_num));
+ return hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num));
}
/* -------------------------------------------------------------------------- */
/* Host specific functions */
-void c67x00_ll_set_husb_eot(struct c67x00_drv *drv, u16 value)
+void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value)
{
- ll_start(drv);
- hpi_write_word(drv, HUSB_pEOT, value);
- ll_release(drv);
+ ll_start(dev);
+ hpi_write_word(dev, HUSB_pEOT, value);
+ ll_release(dev);
}
static inline void c67x00_ll_husb_sie_init(struct c67x00_sie *sie)
{
- struct c67x00_drv *drv = sie->drv;
+ struct c67x00_device *dev = sie->dev;
struct lcp_int_data data;
int rc;
- rc = c67x00_comm_exec_int(drv, HUSB_SIE_INIT_INT(sie->sie_num), &data);
+ rc = c67x00_comm_exec_int(dev, HUSB_SIE_INIT_INT(sie->sie_num), &data);
BUG_ON(rc); /* No return path for error code; crash spectacularly */
}
void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port)
{
- struct c67x00_drv *drv = sie->drv;
+ struct c67x00_device *dev = sie->dev;
struct lcp_int_data data;
int rc;
data.regs[0] = 50; /* Reset USB port for 50ms */
data.regs[1] = port | (sie->sie_num << 1);
- rc = c67x00_comm_exec_int(drv, HUSB_RESET_INT, &data);
+ rc = c67x00_comm_exec_int(dev, HUSB_RESET_INT, &data);
BUG_ON(rc); /* No return path for error code; crash spectacularly */
}
void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr)
{
- hpi_write_word(sie->drv, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr);
+ hpi_write_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num), addr);
}
u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie)
{
- return hpi_read_word(sie->drv, HUSB_SIE_pCurrentTDPtr(sie->sie_num));
+ return hpi_read_word(sie->dev, HUSB_SIE_pCurrentTDPtr(sie->sie_num));
}
/**
@@ -316,28 +316,28 @@ u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie)
*/
void c67x00_ll_husb_clear_status(struct c67x00_sie *sie, u16 bits)
{
- hpi_write_word(sie->drv, HOST_STAT_REG(sie->sie_num), bits);
+ hpi_write_word(sie->dev, HOST_STAT_REG(sie->sie_num), bits);
}
u16 c67x00_ll_husb_get_status(struct c67x00_sie *sie)
{
- return hpi_read_word(sie->drv, HOST_STAT_REG(sie->sie_num));
+ return hpi_read_word(sie->dev, HOST_STAT_REG(sie->sie_num));
}
u16 c67x00_ll_husb_get_frame(struct c67x00_sie * sie)
{
- return hpi_read_word(sie->drv, HOST_FRAME_REG(sie->sie_num));
+ return hpi_read_word(sie->dev, HOST_FRAME_REG(sie->sie_num));
}
void c67x00_ll_husb_init_host_port(struct c67x00_sie *sie)
{
/* Set port into host mode */
- hpi_set_bits(sie->drv, USB_CTL_REG(sie->sie_num), HOST_MODE);
+ hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), HOST_MODE);
c67x00_ll_husb_sie_init(sie);
/* Clear interrupts */
c67x00_ll_husb_clear_status(sie, HOST_STAT_MASK);
/* Check */
- if (!(hpi_read_word(sie->drv, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
+ if (!(hpi_read_word(sie->dev, USB_CTL_REG(sie->sie_num)) & HOST_MODE))
dev_warn(sie_dev(sie),
"SIE %d not set to host mode\n", sie->sie_num);
}
@@ -348,94 +348,94 @@ void c67x00_ll_husb_reset_port(struct c67x00_sie *sie, int port)
c67x00_ll_husb_clear_status(sie, PORT_CONNECT_CHANGE(port));
/* Enable interrupts */
- hpi_set_bits(sie->drv, HPI_IRQ_ROUTING_REG,
+ hpi_set_bits(sie->dev, HPI_IRQ_ROUTING_REG,
SOFEOP_TO_CPU_EN(sie->sie_num));
- hpi_set_bits(sie->drv, HOST_IRQ_EN_REG(sie->sie_num),
+ hpi_set_bits(sie->dev, HOST_IRQ_EN_REG(sie->sie_num),
SOF_EOP_IRQ_EN | DONE_IRQ_EN);
/* Enable pull down transistors */
- hpi_set_bits(sie->drv, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port));
+ hpi_set_bits(sie->dev, USB_CTL_REG(sie->sie_num), PORT_RES_EN(port));
}
/* -------------------------------------------------------------------------- */
void c67x00_ll_susb_init(struct c67x00_sie *sie)
{
- struct c67x00_drv *drv = sie->drv;
+ struct c67x00_device *dev = sie->dev;
struct lcp_int_data data;
int rc;
data.regs[1] = 1; /* full speed */
data.regs[2] = sie->sie_num + 1;
- rc = c67x00_comm_exec_int(drv, SUSB_INIT_INT, &data);
+ rc = c67x00_comm_exec_int(dev, SUSB_INIT_INT, &data);
BUG_ON(rc); /* No return path for error code; crash spectacularly */
- hpi_clear_bits(drv, HPI_IRQ_ROUTING_REG,
+ hpi_clear_bits(dev, HPI_IRQ_ROUTING_REG,
SOFEOP_TO_HPI_EN(sie->sie_num));
- hpi_set_bits(drv, HPI_IRQ_ROUTING_REG, SOFEOP_TO_CPU_EN(sie->sie_num));
+ hpi_set_bits(dev, HPI_IRQ_ROUTING_REG, SOFEOP_TO_CPU_EN(sie->sie_num));
}
/* -------------------------------------------------------------------------- */
-void c67x00_ll_irq(struct c67x00_drv *drv)
+void c67x00_ll_irq(struct c67x00_device *dev)
{
- if ((drv->int_status & MBX_OUT_FLG) == 0)
+ if ((dev->int_status & MBX_OUT_FLG) == 0)
return;
- drv->lcp.last_msg = hpi_recv_mbox(drv);
- complete(&drv->lcp.msg_received);
+ dev->lcp.last_msg = hpi_recv_mbox(dev);
+ complete(&dev->lcp.msg_received);
}
/* -------------------------------------------------------------------------- */
-u16 c67x00_comm_read_ctrl_reg(struct c67x00_drv * drv, u16 addr)
+u16 c67x00_comm_read_ctrl_reg(struct c67x00_device * dev, u16 addr)
{
unsigned long msg, res;
int rc;
- ll_start(drv);
- hpi_write_word(drv, COMM_CTRL_REG_ADDR, addr);
- hpi_send_mbox(drv, COMM_READ_CTRL_REG);
- rc = ll_recv_msg(drv);
+ ll_start(dev);
+ hpi_write_word(dev, COMM_CTRL_REG_ADDR, addr);
+ hpi_send_mbox(dev, COMM_READ_CTRL_REG);
+ rc = ll_recv_msg(dev);
BUG_ON(rc); /* No return path for error code; crash spectacularly */
- msg = drv->lcp.last_msg;
+ msg = dev->lcp.last_msg;
if (msg != COMM_ACK) {
- dev_warn(&drv->pdev->dev, "COMM_READ_CTRL_REG didn't ACK!\n");
+ dev_warn(&dev->pdev->dev, "COMM_READ_CTRL_REG didn't ACK!\n");
res = 0;
} else {
- res = hpi_read_word(drv, COMM_CTRL_REG_DATA);
+ res = hpi_read_word(dev, COMM_CTRL_REG_DATA);
}
- ll_release(drv);
+ ll_release(dev);
return res;
}
-int c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
+int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
struct lcp_int_data *data)
{
int i, rc;
- ll_start(drv);
- hpi_write_word(drv, COMM_INT_NUM, nr);
+ ll_start(dev);
+ hpi_write_word(dev, COMM_INT_NUM, nr);
for (i = 0; i < COMM_REGS; i++)
- hpi_write_word(drv, COMM_R(i), data->regs[i]);
- hpi_send_mbox(drv, COMM_EXEC_INT);
- rc = ll_recv_msg(drv);
- ll_release(drv);
+ hpi_write_word(dev, COMM_R(i), data->regs[i]);
+ hpi_send_mbox(dev, COMM_EXEC_INT);
+ rc = ll_recv_msg(dev);
+ ll_release(dev);
return rc;
}
/* -------------------------------------------------------------------------- */
-int c67x00_ll_reset(struct c67x00_drv *drv)
+int c67x00_ll_reset(struct c67x00_device *dev)
{
int rc;
- ll_start(drv);
- hpi_send_mbox(drv, COMM_RESET);
- rc = ll_recv_msg(drv);
- ll_release(drv);
+ ll_start(dev);
+ hpi_send_mbox(dev, COMM_RESET);
+ rc = ll_recv_msg(dev);
+ ll_release(dev);
return rc;
}
@@ -446,12 +446,12 @@ int c67x00_ll_reset(struct c67x00_drv *drv)
* c67x00_write_mem_le16 - write into c67x00 memory
* Only data is little endian, addr has cpu endianess.
*/
-void c67x00_write_mem_le16(struct c67x00_drv *drv, u16 addr,
+void c67x00_write_mem_le16(struct c67x00_device *dev, u16 addr,
int len, char *data)
{
/* Sanity check */
if (addr + len > 0xffff) {
- dev_err(&drv->pdev->dev,
+ dev_err(&dev->pdev->dev,
"Trying to write beyond writable region!\n");
return;
}
@@ -459,23 +459,23 @@ void c67x00_write_mem_le16(struct c67x00_drv *drv, u16 addr,
if (addr & 0x01) {
/* unaligned access */
u16 tmp;
- tmp = hpi_read_word(drv, addr - 1);
+ tmp = hpi_read_word(dev, addr - 1);
tmp = (tmp & 0x00ff) | (*data++ << 8);
- hpi_write_word(drv, addr - 1, tmp);
+ hpi_write_word(dev, addr - 1, tmp);
addr++;
len--;
}
- hpi_write_words_le16(drv, addr, (u16 *) data, len / 2);
+ hpi_write_words_le16(dev, addr, (u16 *) data, len / 2);
data += len & ~0x01;
addr += len & ~0x01;
len &= 0x01;
if (len) {
u16 tmp;
- tmp = hpi_read_word(drv, addr);
+ tmp = hpi_read_word(dev, addr);
tmp = (tmp & 0xff00) | (*data++);
- hpi_write_word(drv, addr, tmp);
+ hpi_write_word(dev, addr, tmp);
addr++;
len--;
}
@@ -486,25 +486,25 @@ void c67x00_write_mem_le16(struct c67x00_drv *drv, u16 addr,
* c67x00_read_mem_le16 - read from c67x00 memory
* Only data is little endian, addr has cpu endianess.
*/
-void c67x00_read_mem_le16(struct c67x00_drv *drv, u16 addr, int len, char *data)
+void c67x00_read_mem_le16(struct c67x00_device *dev, u16 addr, int len, char *data)
{
if (addr & 0x01) {
/* unaligned access */
u16 tmp;
- tmp = hpi_read_word(drv, addr - 1);
+ tmp = hpi_read_word(dev, addr - 1);
*data++ = (tmp >> 8) & 0x00ff;
addr++;
len--;
}
- hpi_read_words_le16(drv, addr, (u16 *) data, len / 2);
+ hpi_read_words_le16(dev, addr, (u16 *) data, len / 2);
data += len & ~0x01;
addr += len & ~0x01;
len &= 0x01;
if (len) {
u16 tmp;
- tmp = hpi_read_word(drv, addr);
+ tmp = hpi_read_word(dev, addr);
*data++ = tmp & 0x00ff;
addr++;
len--;
@@ -513,12 +513,12 @@ void c67x00_read_mem_le16(struct c67x00_drv *drv, u16 addr, int len, char *data)
/* -------------------------------------------------------------------------- */
-void c67x00_ll_init(struct c67x00_drv *drv)
+void c67x00_ll_init(struct c67x00_device *dev)
{
- mutex_init(&drv->lcp.mutex);
- init_completion(&drv->lcp.msg_received);
+ mutex_init(&dev->lcp.mutex);
+ init_completion(&dev->lcp.msg_received);
}
-void c67x00_ll_release(struct c67x00_drv *drv)
+void c67x00_ll_release(struct c67x00_device *dev)
{
}
diff --git a/drivers/usb/c67x00/c67x00-ll-hpi.h b/drivers/usb/c67x00/c67x00-ll-hpi.h
index 3f84348..b3b8512 100644
--- a/drivers/usb/c67x00/c67x00-ll-hpi.h
+++ b/drivers/usb/c67x00/c67x00-ll-hpi.h
@@ -28,7 +28,7 @@
#include <linux/mutex.h>
struct c67x00_sie;
-struct c67x00_drv;
+struct c67x00_device;
struct lcp {
/* Internal use only */
@@ -46,22 +46,22 @@ struct lcp_int_data {
/* ------------------------------------------------------------------------- */
/* HPI */
-u16 c67x00_hpi_status(struct c67x00_drv *drv);
-void c67x00_ll_hpi_reg_init(struct c67x00_drv *drv);
+u16 c67x00_hpi_status(struct c67x00_device *dev);
+void c67x00_ll_hpi_reg_init(struct c67x00_device *dev);
void c67x00_ll_hpi_enable_sofeop(struct c67x00_sie *sie);
void c67x00_ll_hpi_disable_sofeop(struct c67x00_sie *sie);
/* -------------------------------------------------------------------------- */
/* General functions */
-u16 c67x00_ll_get_siemsg(struct c67x00_drv *drv, int sie);
-void c67x00_ll_set_siemsg(struct c67x00_drv *drv, int sie, u16 val);
+u16 c67x00_ll_get_siemsg(struct c67x00_device *dev, int sie);
+void c67x00_ll_set_siemsg(struct c67x00_device *dev, int sie, u16 val);
u16 c67x00_ll_get_usb_ctl(struct c67x00_sie *sie);
/* ------------------------------------------------------------------------- */
/* Host specific functions */
-void c67x00_ll_set_husb_eot(struct c67x00_drv *drv, u16 value);
+void c67x00_ll_set_husb_eot(struct c67x00_device *dev, u16 value);
void c67x00_ll_husb_reset(struct c67x00_sie *sie, int port);
void c67x00_ll_husb_set_current_td(struct c67x00_sie *sie, u16 addr);
u16 c67x00_ll_husb_get_current_td(struct c67x00_sie *sie);
@@ -78,21 +78,21 @@ void c67x00_ll_susb_init(struct c67x00_sie *sie);
/* ------------------------------------------------------------------------- */
-void c67x00_write_mem_le16(struct c67x00_drv *drv, u16 addr,
+void c67x00_write_mem_le16(struct c67x00_device *dev, u16 addr,
int len, char *data);
-void c67x00_read_mem_le16(struct c67x00_drv *drv, u16 addr,
+void c67x00_read_mem_le16(struct c67x00_device *dev, u16 addr,
int len, char *data);
-u16 c67x00_comm_read_ctrl_reg(struct c67x00_drv *drv, u16 addr);
+u16 c67x00_comm_read_ctrl_reg(struct c67x00_device *dev, u16 addr);
-int c67x00_comm_exec_int(struct c67x00_drv *drv, u16 nr,
+int c67x00_comm_exec_int(struct c67x00_device *dev, u16 nr,
struct lcp_int_data *data);
/* Called by c67x00_irq to handle lcp interrupts */
-void c67x00_ll_irq(struct c67x00_drv *drv);
+void c67x00_ll_irq(struct c67x00_device *dev);
-void c67x00_ll_init(struct c67x00_drv *drv);
-void c67x00_ll_release(struct c67x00_drv *drv);
-int c67x00_ll_reset(struct c67x00_drv *drv);
+void c67x00_ll_init(struct c67x00_device *dev);
+void c67x00_ll_release(struct c67x00_device *dev);
+int c67x00_ll_reset(struct c67x00_device *dev);
#endif /* _USB_C67X00_LL_HPI_H */
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 3a870cf..d408f2f 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -858,18 +858,18 @@ static void send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
int len = td_length(td);
if (len && ((td->pid_ep & TD_PIDEPMASK_PID) != TD_PID_IN))
- c67x00_write_mem_le16(c67x00->sie->drv,
+ c67x00_write_mem_le16(c67x00->sie->dev,
td_ly_base_addr(td), len, td->data);
#ifdef DEBUG_PATTERN
else { /* write known patterns into memories */
memset(td->data, NON_RECEIVED_PATTERN, len);
- c67x00_write_mem_le16(c67x00->sie->drv,
+ c67x00_write_mem_le16(c67x00->sie->dev,
td_ly_base_addr(td), len, td->data);
memset(td->data, UNREAD_PATTERN, len);
}
#endif /* DEBUG_PATTERN */
- c67x00_write_mem_le16(c67x00->sie->drv,
+ c67x00_write_mem_le16(c67x00->sie->dev,
td->td_addr, CY_TD_SIZE, (char *)td);
}
@@ -878,11 +878,11 @@ static void send_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
*/
static inline void parse_td(struct c67x00_hcd *c67x00, struct c67x00_td *td)
{
- c67x00_read_mem_le16(c67x00->sie->drv,
+ c67x00_read_mem_le16(c67x00->sie->dev,
td->td_addr, CY_TD_SIZE, (char *)td);
if (usb_pipein(td->pipe) && td_actual_bytes(td))
- c67x00_read_mem_le16(c67x00->sie->drv, td_ly_base_addr(td),
+ c67x00_read_mem_le16(c67x00->sie->dev, td_ly_base_addr(td),
td_actual_bytes(td), td->data);
}
--
1.4.4.2
^ permalink raw reply related
* [PATCH 0/6] Cleanups to c67x00 USB host controller driver
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
Peter,
Here's the series of changes that I've made to the c67x00 driver. Most of
them are pretty straight forward. Most invasive is the rename of
'struct c67x00_drv' to 'struct c67x00_device' which is big and scary, but
doesn't really do much.
One thing that I haven't tackled is the layout of the lowlevel drivers.
I think it should be reworked to add a generic ops structure which each
low level driver can populate with the correct ops functions. It should
simplify the code from the hard coded approach currently used.
I'll probably have more comments/fixes later as I work with it, but this
series is what I have now. Please add me to the CC list when you repost
an updated driver to the list. I'm not subscribed to linux-usb-devel.
Cheers,
g.
^ permalink raw reply
* [PATCH 3/6] [C67x00] Remove unnecessary references to pt_regs
From: Grant Likely @ 2007-06-12 23:02 UTC (permalink / raw)
To: Peter Korsgaard, linux-usb-devel, linuxppc-embedded
In-Reply-To: <11816893492706-git-send-email-grant.likely@secretlab.ca>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/usb/c67x00/c67x00-sched.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c
index 0d08af7..3a870cf 100644
--- a/drivers/usb/c67x00/c67x00-sched.c
+++ b/drivers/usb/c67x00/c67x00-sched.c
@@ -956,7 +956,7 @@ static inline void clear_pipe(struct c67x00_hcd *c67x00,
/* -------------------------------------------------------------------------- */
static void handle_successful_td(struct c67x00_hcd *c67x00,
- struct c67x00_td *td, struct pt_regs *regs)
+ struct c67x00_td *td)
{
struct urb *urb = td->urb;
@@ -1025,7 +1025,7 @@ static void handle_isoc(struct c67x00_hcd *c67x00, struct c67x00_td *td)
* check_td_list - handle tds which have been processed by the c67x00
* pre: current_td == 0
*/
-static void check_td_list(struct c67x00_hcd *c67x00, struct pt_regs *regs)
+static void check_td_list(struct c67x00_hcd *c67x00)
{
struct c67x00_td *td, *tmp;
struct urb *urb;
@@ -1070,7 +1070,7 @@ static void check_td_list(struct c67x00_hcd *c67x00, struct pt_regs *regs)
}
clear_endpoint = 0;
- handle_successful_td(c67x00, td, regs);
+ handle_successful_td(c67x00, td);
cont:
if (clear_endpoint)
@@ -1132,7 +1132,7 @@ static void c67x00_do_work(struct c67x00_hcd *c67x00)
if (!all_tds_processed(c67x00))
goto out;
- check_td_list(c67x00, NULL);
+ check_td_list(c67x00);
/* no td's are being processed (current == 0)
* and all have been "checked" */
--
1.4.4.2
^ permalink raw reply related
* Re: [patch 02/10] powerpc: Move CONFIG_PPC64 into CPU selection
From: Paul Mackerras @ 2007-06-13 0:42 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev, Arnd Bergmann
In-Reply-To: <d8ba058b9bc8f9738d2c3d764c568c1e@kernel.crashing.org>
Segher Boessenkool writes:
> It would be good to converge the 32- and 64-bit implementations,
> and/or allow a single kernel image to work on both 32-bit and
> 64-bit systems, The current situation is far removed from that,
> so this patch is a bit premature in that aspect.
There will always be differences in emphasis and focus between 32-bit
and 64-bit. For example, the vast majority of 32-bit systems are UP,
with a few 2-way SMP systems, an insignificant number of 4-way
systems, and nothing bigger than 4-way. In contrast, most 64-bit
machines are SMP, with enough large SMP machines (64-way and bigger)
to be worth worrying about. Hence the 64-bit code focuses on SMP
scalability whereas the 32-bit code focuses on performance for UP and
2-way systems - which is why the hash table invalidations get batched
up on 64-bit machines but not on 32-bit machines, for instance.
Similarly, 64-bit supports large memory (>4GB) and NUMA machines,
whereas 32-bit doesn't.
Paul.
^ 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