From: Albert H. <he...@us...> - 2008-03-26 20:15:53
|
Update of /cvsroot/gc-linux/linux/drivers/exi In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv22420/drivers/exi Modified Files: exi-driver.c exi-hw.c exi-hw.h Log Message: Remove old ugecon driver (we use now usbgecko_udbg). Rewrite the following drivers as of_platform drivers using the device tree: - gcn-rsw - starlet-ipc - gcn-aram - rvl-mem2 - gcn-di - exi-driver, exi-hw - gcn-si - gcnfb (gcn-vifb) - gcn-ai Marked as broken gcn-mi and gcngx. Updated defconfigs. Index: exi-driver.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-driver.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- exi-driver.c 24 Feb 2008 18:05:31 -0000 1.14 +++ exi-driver.c 26 Mar 2008 20:15:11 -0000 1.15 @@ -1,7 +1,7 @@ /* * drivers/exi/exi-driver.c * - * Nintendo GameCube Expansion Interface support. Driver model routines. + * Nintendo GameCube EXternal Interface (EXI) driver model routines. * Copyright (C) 2004-2008 The GameCube Linux Team * Copyright (C) 2004 Arthur Othieno <a.o...@bl...> * Copyright (C) 2004,2005 Todd Jeffreys <to...@vo...> @@ -14,20 +14,23 @@ * */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/kthread.h> #include <linux/delay.h> #include <linux/exi.h> +#include <linux/init.h> +#include <linux/kthread.h> +#include <linux/module.h> +#include <linux/of_platform.h> #define DRV_MODULE_NAME "exi-driver" -#define DRV_DESCRIPTION "Nintendo GameCube EXpansion Interface driver" +#define DRV_DESCRIPTION "Nintendo GameCube EXternal Interface (EXI) driver" #define DRV_AUTHOR "Arthur Othieno <a.o...@bl...>, " \ "Todd Jeffreys <to...@vo...>, " \ "Albert Herranz" -static char exi_driver_version[] = "3.2-isobel"; +static char exi_driver_version[] = "4.0-isobel"; + +#define drv_printk(level, format, arg...) \ + printk(level DRV_MODULE_NAME ": " format , ## arg) struct exi_map_id_to_name { @@ -44,6 +47,7 @@ .name = "exi", .match = exi_bus_match, }; +EXPORT_SYMBOL(exi_bus_type); static struct device exi_bus_devices[EXI_MAX_CHANNELS] = { [0] = { @@ -67,7 +71,8 @@ static struct exi_map_id_to_name exi_map_id_to_name[] = { { .id = EXI_ID_NONE, .name = "(external card)" }, - { .id = 0xffff1698, .name = "Mask ROM/RTC/SRAM/UART" }, + { .id = 0xffff1698, .name = "GameCube Mask ROM/RTC/SRAM/UART" }, + { .id = 0xfffff308, .name = "Wii Mask ROM/RTC/SRAM/UART" }, { .id = 0x00000004, .name = "Memory Card 59" }, { .id = 0x00000008, .name = "Memory Card 123" }, { .id = 0x00000010, .name = "Memory Card 251" }, @@ -156,7 +161,7 @@ */ static void exi_bus_device_release(struct device *dev) { - exi_printk(KERN_WARNING, "exi_bus_device_release called!\n"); + drv_printk(KERN_WARNING, "exi_bus_device_release called!\n"); } static void exi_device_release(struct device *dev); @@ -211,7 +216,7 @@ get_device(&exi_device->dev); return exi_device; } - +EXPORT_SYMBOL(exi_device_get); /** * exi_device_put - Releases a use of the exi device @@ -224,6 +229,7 @@ if (exi_device) put_device(&exi_device->dev); } +EXPORT_SYMBOL(exi_device_put); /** * exi_get_exi_device - Returns a reference to an exi device @@ -236,6 +242,7 @@ // FIXME, maybe exi_device_get it too return &exi_devices[to_channel(exi_channel)][device]; } +EXPORT_SYMBOL(exi_get_exi_device); /* * Internal. Call device driver probe function on match. @@ -295,6 +302,7 @@ return driver_register(&driver->driver); } +EXPORT_SYMBOL(exi_driver_register); /** * exi_driver_unregister - unregister an EXI device driver. @@ -307,6 +315,7 @@ { driver_unregister(&driver->driver); } +EXPORT_SYMBOL(exi_driver_unregister); /* @@ -321,23 +330,23 @@ if (exi_device->eid.id != EXI_ID_INVALID) { /* device removed or changed */ - exi_printk(KERN_INFO, "about to remove [%s] id=0x%08x %s\n", + drv_printk(KERN_INFO, "about to remove [%s] id=0x%08x %s\n", exi_device->dev.bus_id, exi_device->eid.id, exi_name_id(exi_device->eid.id)); device_unregister(&exi_device->dev); - exi_printk(KERN_INFO, "remove completed\n"); + drv_printk(KERN_INFO, "remove completed\n"); exi_device->eid.id = EXI_ID_INVALID; } if (id != EXI_ID_INVALID) { /* a new device has been found */ - exi_printk(KERN_INFO, "about to add [%s] id=0x%08x %s\n", + drv_printk(KERN_INFO, "about to add [%s] id=0x%08x %s\n", exi_device->dev.bus_id, id, exi_name_id(id)); exi_device->eid.id = id; device_register(&exi_device->dev); - exi_printk(KERN_INFO, "add completed\n"); + drv_printk(KERN_INFO, "add completed\n"); } exi_update_ext_status(exi_get_exi_channel(exi_device)); @@ -412,19 +421,19 @@ extern void exi_channel_init(struct exi_channel *exi_channel, unsigned int channel); -static int __init exi_layer_init(void) +/* + * + */ +static int exi_init(struct resource *mem, unsigned int irq) { struct exi_channel *exi_channel; struct exi_device *exi_device; unsigned int channel, device; int retval; - exi_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION, - exi_driver_version); - extern unsigned long exi_running; if (!test_and_set_bit(1, &exi_running)) { - retval = exi_hw_init(DRV_MODULE_NAME); + retval = exi_hw_init(DRV_MODULE_NAME, mem, irq); if (retval) goto err_hw_init; } @@ -457,7 +466,7 @@ init_waitqueue_head(&exi_bus_waitq); exi_bus_task = kthread_run(exi_bus_thread, NULL, "kexid"); if (IS_ERR(exi_bus_task)) { - exi_printk(KERN_WARNING, "failed to start exi kernel thread\n"); + drv_printk(KERN_WARNING, "failed to start exi kernel thread\n"); } return 0; @@ -467,20 +476,38 @@ while(--channel > 0) { device_unregister(&exi_bus_devices[channel]); } - exi_hw_exit(); + exi_hw_exit(mem, irq); err_hw_init: return retval; } -EXPORT_SYMBOL(exi_driver_register); -EXPORT_SYMBOL(exi_driver_unregister); -EXPORT_SYMBOL(exi_bus_type); +/* + * + */ +static int __init exi_layer_init(void) +{ + struct device_node *np; + struct resource res; + int retval; -EXPORT_SYMBOL(exi_get_exi_device); -EXPORT_SYMBOL(exi_device_get); -EXPORT_SYMBOL(exi_device_put); + drv_printk(KERN_INFO, "%s - version %s\n", DRV_DESCRIPTION, + exi_driver_version); + + np = of_find_compatible_node(NULL, NULL, "nintendo,exi"); + if (!np) + return -ENODEV; + retval = of_address_to_resource(np, 0, &res); + if (retval) { + drv_printk(KERN_ERR, "no io memory range found\n"); + return -ENOMEM; + } + retval = exi_init(&res, irq_of_parse_and_map(np, 0)); + of_node_put(np); + + return retval; +} postcore_initcall(exi_layer_init); MODULE_AUTHOR(DRV_AUTHOR); Index: exi-hw.h =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-hw.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- exi-hw.h 4 Mar 2008 06:20:56 -0000 1.10 +++ exi-hw.h 26 Mar 2008 20:15:11 -0000 1.11 @@ -16,20 +16,11 @@ #ifndef __EXI_HW_H #define __EXI_HW_H +#include <linux/exi.h> #include <linux/interrupt.h> +#include <linux/resource.h> #include <asm/atomic.h> -#include <linux/exi.h> - -#ifdef CONFIG_PPC_MERGE -#include <platforms/embedded6xx/gamecube.h> -#else -#include <platforms/gamecube.h> -#endif - -#define exi_printk(level, format, arg...) \ - printk(level "exi: " format , ## arg) - #define EXI_MAX_CHANNELS 3 /* channels on the EXI bus */ #define EXI_DEVICES_PER_CHANNEL 3 /* number of devices per EXI channel */ @@ -51,17 +42,10 @@ #define EXI_IDI_MAX_SIZE 4 -#define EXI_IRQ 4 - #define EXI_DMA_ALIGN 0x1f /* 32 bytes */ -#define EXI_BASE (GCN_IO2_BASE+0x6800) -#define EXI_SIZE 0x40 - #define EXI_CHANNEL_SPACING 0x14 -#define EXI_IO_BASE(c) ((void __iomem *)(EXI_BASE + ((c)*EXI_CHANNEL_SPACING))) - #define EXI_CSR 0x00 #define EXI_CSR_EXIINTMASK (1<<0) #define EXI_CSR_EXIINT (1<<1) @@ -146,8 +130,8 @@ extern int exi_get_ext_line(struct exi_channel *exi_channel); extern void exi_update_ext_status(struct exi_channel *exi_channel); -extern int exi_hw_init(char *); -extern void exi_hw_exit(void); +extern int exi_hw_init(char *name, struct resource *mem, unsigned int irq); +extern void exi_hw_exit(struct resource *mem, unsigned int irq); #define exi_is_taken(x) ((x)->owner) Index: exi-hw.c =================================================================== RCS file: /cvsroot/gc-linux/linux/drivers/exi/exi-hw.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- exi-hw.c 4 Mar 2008 06:20:56 -0000 1.17 +++ exi-hw.c 26 Mar 2008 20:15:11 -0000 1.18 @@ -70,6 +70,9 @@ #include "exi-hw.h" +#define drv_printk(level, format, arg...) \ + printk(level "exi: " format , ## arg) + #ifdef EXI_DEBUG # define DBG(fmt, args...) \ printk(KERN_ERR "%s: " fmt, __FUNCTION__ , ## args) @@ -77,13 +80,19 @@ # define DBG(fmt, args...) #endif + extern wait_queue_head_t exi_bus_waitq; static void exi_tasklet(unsigned long param); + /* for compatibility with the old exi-lite framework */ unsigned long exi_running = 0; +/* io memory base for EXI */ +static void __iomem *exi_io_mem; + + /* * These are the available exi channels. */ @@ -92,7 +101,6 @@ .channel = 0, .lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, - .io_base = EXI_IO_BASE(0), .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[0].wait_queue), }, @@ -100,7 +108,6 @@ .channel = 1, .lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, - .io_base = EXI_IO_BASE(1), .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[1].wait_queue), }, @@ -108,7 +115,6 @@ .channel = 2, .lock = SPIN_LOCK_UNLOCKED, .io_lock = SPIN_LOCK_UNLOCKED, - .io_base = EXI_IO_BASE(2), .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER( exi_channels[2].wait_queue), }, @@ -402,7 +408,7 @@ } if (borked) { - exi_printk(KERN_ERR, "exi transfer took too long, " + drv_printk(KERN_ERR, "exi transfer took too long, " "is your hardware ok?"); } @@ -435,7 +441,7 @@ init_waitqueue_head(&exi_channel->wait_queue); exi_channel->channel = channel; - exi_channel->io_base = EXI_IO_BASE(channel); + exi_channel->io_base = exi_io_mem + channel * EXI_CHANNEL_SPACING; tasklet_init(&exi_channel->tasklet, exi_tasklet, (unsigned long)exi_channel); @@ -1357,12 +1363,18 @@ /* * Pseudo-Internal. Initialize basic channel structures and hardware. */ -int exi_hw_init(char *module_name) +int exi_hw_init(char *module_name, struct resource *mem, unsigned int irq) { struct exi_channel *exi_channel; int channel; int result; + exi_io_mem = ioremap(mem->start, mem->end - mem->start + 1); + if (!exi_io_mem) { + drv_printk(KERN_ERR, "ioremap failed\n"); + return -ENOMEM; + } + for(channel = 0; channel < EXI_MAX_CHANNELS; channel++) { exi_channel = __to_exi_channel(channel); @@ -1374,9 +1386,9 @@ exi_quiesce_all_channels(EXI_CSR_EXTINMASK); /* register the exi interrupt handler */ - result = request_irq(EXI_IRQ, exi_irq_handler, 0, module_name, NULL); + result = request_irq(irq, exi_irq_handler, 0, module_name, NULL); if (result) { - exi_printk(KERN_ERR, "unable to register irq%d\n", EXI_IRQ); + drv_printk(KERN_ERR, "failed to register IRQ %d\n", irq); } return result; @@ -1385,10 +1397,11 @@ /* * Pseudo-Internal. */ -void exi_hw_exit(void) +void exi_hw_exit(struct resource *mem, unsigned int irq) { exi_quiesce_all_channels(0); - free_irq(EXI_IRQ, NULL); + iounmap(exi_io_mem); + free_irq(irq, NULL); } |