From: Florian Fainelli Date: Mon, 9 Jul 2007 16:06:43 +0000 (+0000) Subject: au1000 now runs .22, mtx-1 watchdog is mainline and i2c patch is planned for rewriting X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c731d18905afe546b85d35e1322d71c1d79433ed;p=librecmc%2Flibrecmc.git au1000 now runs .22, mtx-1 watchdog is mainline and i2c patch is planned for rewriting SVN-Revision: 7900 --- diff --git a/target/linux/au1000-2.6/Makefile b/target/linux/au1000-2.6/Makefile index 0b04a4f5a5..1c1674c2a0 100644 --- a/target/linux/au1000-2.6/Makefile +++ b/target/linux/au1000-2.6/Makefile @@ -11,7 +11,7 @@ BOARD:=au1000 BOARDNAME:=AMD Alchemy AU1x00 FEATURES:=jffs2 usb pci -LINUX_VERSION:=2.6.21.5 +LINUX_VERSION:=2.6.22 define Target/Description Build firmware for AMD Alchemy 1500 boards diff --git a/target/linux/au1000-2.6/files/drivers/char/watchdog/mtx-1_watchdog.c b/target/linux/au1000-2.6/files/drivers/char/watchdog/mtx-1_watchdog.c deleted file mode 100644 index ccd631ed3a..0000000000 --- a/target/linux/au1000-2.6/files/drivers/char/watchdog/mtx-1_watchdog.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Driver for the MTX-1 Watchdog. - * - * (c) Copyright 2005 4G Systems , All Rights Reserved. - * http://www.4g-systems.biz - * - * (C) Copyright 2007 OpenWrt.org, Florian Fainelli - * - * 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. - * - * Neither Michael Stickel nor 4G Systems admit liability nor provide - * warranty for any of this software. This material is provided - * "AS-IS" and at no charge. - * - * (c) Copyright 2005 4G Systems - * - * Release 0.01. - * - * Author: Michael Stickel michael.stickel@4g-systems.biz - * - * Release 0.02. - * Author: Florian Fainelli florian@openwrt.org - * use the Linux watchdog API - * - * The Watchdog is configured to reset the MTX-1 - * if it is not triggered for 100 seconds. - * It should not be triggered more often than 1.6 seconds. - * - * A timer triggers the watchdog every 5 seconds, until - * it is opened for the first time. After the first open - * it MUST be triggered every 2..95 seconds. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MTX1_WDT_INTERVAL (5 * HZ) - -static int ticks = 100 * HZ; - -static struct { - struct completion stop; - volatile int running; - struct timer_list timer; - volatile int queue; - int default_ticks; - unsigned long inuse; -} mtx1_wdt_device; - -static void mtx1_wdt_trigger(unsigned long unused) -{ - u32 tmp; - - if (mtx1_wdt_device.running) - ticks--; - /* - * toggle GPIO2_15 - */ - tmp = au_readl(GPIO2_DIR); - tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15)); - au_writel (tmp, GPIO2_DIR); - - if (mtx1_wdt_device.queue && ticks) - mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); - else { - complete(&mtx1_wdt_device.stop); - } -} - -static void mtx1_wdt_reset(void) -{ - ticks = mtx1_wdt_device.default_ticks; -} - - -static void mtx1_wdt_start(void) -{ - if (!mtx1_wdt_device.queue) { - mtx1_wdt_device.queue = 1; - au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR); - mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); - } - mtx1_wdt_device.running++; -} - -static int mtx1_wdt_stop(void) -{ - if (mtx1_wdt_device.queue) { - mtx1_wdt_device.queue = 0; - au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR); - } - - ticks = mtx1_wdt_device.default_ticks; - - return 0; -} - -/* Filesystem functions */ - -static char restart_after_close; - -static int mtx1_wdt_open(struct inode *inode, struct file *file) -{ - if (test_and_set_bit(0, &mtx1_wdt_device.inuse)) - return -EBUSY; - - return nonseekable_open(inode, file); -} - - -static int mtx1_wdt_release(struct inode *inode, struct file *file) -{ - clear_bit(0, &mtx1_wdt_device.inuse); - return 0; -} - -static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - void __user *argp = (void __user *)arg; - unsigned int value; - static struct watchdog_info ident = - { - .options = WDIOF_CARDRESET, - .identity = "MTX-1 WDT", - }; - - switch(cmd) { - case WDIOC_KEEPALIVE: - mtx1_wdt_reset(); - break; - case WDIOC_GETSTATUS: - if ( copy_to_user(argp, &value, sizeof(int)) ) - return -EFAULT; - break; - case WDIOC_GETSUPPORT: - if ( copy_to_user(argp, &ident, sizeof(ident)) ) - return -EFAULT; - break; - case WDIOC_SETOPTIONS: - if ( copy_from_user(&value, argp, sizeof(int)) ) - return -EFAULT; - switch(value) { - case WDIOS_ENABLECARD: - mtx1_wdt_start(); - break; - case WDIOS_DISABLECARD: - return mtx1_wdt_stop(); - default: - return -EINVAL; - } - break; - default: - return -ENOTTY; - } - return 0; -} - - -static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -{ - if (!count) - return -EIO; - - mtx1_wdt_reset(); - - if (count > 0) { - char buffer[10]; - int n = (count>9)?9:count; - - if (copy_from_user (&buffer, buf, n)) - return -EFAULT; - buffer[n]=0; - - if (count >= 4 && strncmp("auto", buffer, 4)==0) - restart_after_close = 1; - - else if (count >= 6 && strncmp("manual", buffer, 6)==0) - restart_after_close = 0; - - return n; - } - return count; -} - -#if 0 -static ssize_t mtx1_wdt_read (struct file *file, char *buf, size_t count, loff_t *ppos) -{ - char * state = restart_after_close ? "auto\n" : "manual\n"; - int n = strlen(state)+1; - - if (file->f_pos >= n) - return 0; - - if (count < n) - return -EINVAL; - - if(copy_to_user(buf, state, n)) - return -EFAULT; - - file->f_pos += n; - - return n; -} -#endif - -static struct file_operations mtx1_wdt_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .ioctl = mtx1_wdt_ioctl, - .open = mtx1_wdt_open, - .write = mtx1_wdt_write, - //.read = mtx1_wdt_read, - .release = mtx1_wdt_release -}; - - -static struct miscdevice mtx1_wdt_misc = { - .minor = WATCHDOG_MINOR, - .name = "watchdog", - .fops = &mtx1_wdt_fops -}; - - -static int __init mtx1_wdt_init(void) -{ - int ret; - - if ((ret = misc_register(&mtx1_wdt_misc)) < 0) { - printk(KERN_ERR " mtx-1_wdt : failed to register\n"); - return ret; - } - - init_completion(&mtx1_wdt_device.stop); - mtx1_wdt_device.queue = 0; - - clear_bit(0, &mtx1_wdt_device.inuse); - - setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); - - mtx1_wdt_device.default_ticks = ticks; - - mtx1_wdt_start(); - - printk(KERN_INFO "MTX-1 Watchdog driver\n"); - - return 0; -} - -static void __exit mtx1_wdt_exit(void) -{ - if (mtx1_wdt_device.queue) { - mtx1_wdt_device.queue = 0; - wait_for_completion(&mtx1_wdt_device.stop); - } - misc_deregister(&mtx1_wdt_misc); -} - -module_init(mtx1_wdt_init); -module_exit(mtx1_wdt_exit); - -MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); -MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch b/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch deleted file mode 100644 index 276659aded..0000000000 --- a/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff -urN linux-2.6.21.1/drivers/char/watchdog/Kconfig linux-2.6.21.1.new/drivers/char/watchdog/Kconfig ---- linux-2.6.21.1/drivers/char/watchdog/Kconfig 2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.new/drivers/char/watchdog/Kconfig 2007-05-24 20:05:52.000000000 +0200 -@@ -586,6 +586,14 @@ - To compile this driver as a module, choose M here: the - module will be called rm9k_wdt. - -+config MTX1_WATCHDOG -+ tristate "MTX-1 Hardware Watchdog" -+ depends on WATCHDOG && MIPS_MTX1 -+ help -+ Hardware driver for the AccessCube MTX-1 watchdog. This is a -+ watchdog timer that will reboot the machine after a 100 seconds -+ timer expired. -+ - # S390 Architecture - - config ZVM_WATCHDOG -diff -urN linux-2.6.21.1/drivers/char/watchdog/Makefile linux-2.6.21.1.new/drivers/char/watchdog/Makefile ---- linux-2.6.21.1/drivers/char/watchdog/Makefile 2007-04-27 23:49:26.000000000 +0200 -+++ linux-2.6.21.1.new/drivers/char/watchdog/Makefile 2007-05-24 20:05:41.000000000 +0200 -@@ -74,6 +74,7 @@ - # MIPS Architecture - obj-$(CONFIG_INDYDOG) += indydog.o - obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o -+obj-$(CONFIG_MTX1_WATCHDOG) += mtx-1_watchdog.o - - # S390 Architecture - diff --git a/target/linux/au1000-2.6/patches/010-au100_gpio_i2c.patch b/target/linux/au1000-2.6/patches/010-au100_gpio_i2c.patch deleted file mode 100644 index 8cb869ee2a..0000000000 --- a/target/linux/au1000-2.6/patches/010-au100_gpio_i2c.patch +++ /dev/null @@ -1,455 +0,0 @@ -diff -urN linux-2.6.19/drivers/i2c/busses/Kconfig linux-2.6.19.new/drivers/i2c/busses/Kconfig ---- linux-2.6.19/drivers/i2c/busses/Kconfig 2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.new/drivers/i2c/busses/Kconfig 2006-12-28 17:04:34.000000000 +0100 -@@ -84,6 +84,17 @@ - This driver can also be built as a module. If so, the module - will be called i2c-au1550. - -+config I2C_AU1X00GPIO -+ tristate "Au1x00 i2c using GPIO pins" -+ depends on I2C -+ select I2C_ALGOBIT -+ help -+ If you say yest to this option, support will be included for the -+ Au1x00 GPIO interface. -+ -+ This driver can also be built as a module. If so, the module -+ will be called i2c-au1x00gpio. -+ - config I2C_ELEKTOR - tristate "Elektor ISA card" - depends on I2C && ISA && BROKEN_ON_SMP -diff -urN linux-2.6.19/drivers/i2c/busses/Makefile linux-2.6.19.new/drivers/i2c/busses/Makefile ---- linux-2.6.19/drivers/i2c/busses/Makefile 2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.new/drivers/i2c/busses/Makefile 2006-12-28 03:07:37.000000000 +0100 -@@ -9,6 +9,7 @@ - obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o - obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o - obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o -+obj-$(CONFIG_I2C_AU1X00GPIO) += i2c-au1x00gpio.o - obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o - obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o - obj-$(CONFIG_I2C_I801) += i2c-i801.o -diff -urN linux-2.6.19/drivers/i2c/busses/i2c-au1x00gpio.c linux-2.6.19.new/drivers/i2c/busses/i2c-au1x00gpio.c ---- linux-2.6.19/drivers/i2c/busses/i2c-au1x00gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.19.new/drivers/i2c/busses/i2c-au1x00gpio.c 2006-12-28 17:02:10.000000000 +0100 -@@ -0,0 +1,406 @@ -+/* ------------------------------------------------------------------------- */ -+/* i2c-au1x00gpio.c i2c-hw access for Au1x00 GPIO pins. */ -+/* ------------------------------------------------------------------------- */ -+/* Copyright (C) 1995-2000 Michael Stickel -+ -+ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ -+/* ------------------------------------------------------------------------- */ -+ -+/* With some changes from Ky�stialkki and even -+ Frodo Looijaard -+ Simon G. Vogl -+*/ -+ -+/* $Id: i2c-au1x00gpio.c,v 1.1.1.2 2004/01/22 15:35:47 br1 Exp $ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+struct i2c_au1x00gpio -+{ -+ struct i2c_au1x00gpio *next; -+ -+ short scl_gpio; -+ short sda_gpio; -+ -+ unsigned long scl_mask; -+ unsigned long sda_mask; -+ -+ struct i2c_adapter adapter; -+ struct i2c_algo_bit_data bit_au1x00gpio_data; -+}; -+ -+static struct i2c_au1x00gpio *adapter_list; -+ -+ -+ -+/* ----- global defines ----------------------------------------------- */ -+#define DEB(x) /* should be reasonable open, close &c. */ -+#define DEB2(x) /* low level debugging - very slow */ -+#define DEBE(x) x /* error messages */ -+ -+/* ----- printer port defines ------------------------------------------*/ -+ -+/* ----- local functions ---------------------------------------------- */ -+ -+ -+//-- Primary GPIO -+static void bit_au1x00gpio_setscl(void *data, int state) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ if (state) -+ au_writel(adapter->scl_mask, SYS_TRIOUTCLR); // Disable Driver: Switch off Transistor => 1 -+ else -+ au_writel(adapter->scl_mask, SYS_OUTPUTCLR); // Clear Output and switch on Transistor => 0 -+} -+ -+ -+static void bit_au1x00gpio_setsda(void *data, int state) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ if (state) -+ au_writel(adapter->sda_mask, SYS_TRIOUTCLR); -+ else -+ au_writel(adapter->sda_mask, SYS_OUTPUTCLR); -+} -+ -+ -+static int bit_au1x00gpio_getscl(void *data) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ return (au_readl(SYS_PINSTATERD) & adapter->scl_mask) ? 1 : 0; -+} -+ -+ -+static int bit_au1x00gpio_getsda(void *data) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ return (au_readl(SYS_PINSTATERD) & adapter->sda_mask) ? 1 : 0; -+} -+ -+ -+ -+ -+/*-- -+ *-- Functions for accessing GPIO-2 -+ *-- -+ */ -+static void bit_au1x00gpio2_setscl(void *data, int state) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ if (state) -+ { -+ au_writel(au_readl(GPIO2_DIR) & ~adapter->scl_mask, GPIO2_DIR); -+ } -+ else -+ { -+ au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->scl_mask, GPIO2_OUTPUT); -+ au_writel(au_readl(GPIO2_DIR) | adapter->scl_mask, GPIO2_DIR); -+ } -+} -+ -+static void bit_au1x00gpio2_setsda(void *data, int state) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ if (state) -+ { -+ au_writel(au_readl(GPIO2_DIR) & ~adapter->sda_mask, GPIO2_DIR); -+ } -+ else -+ { -+ au_writel(au_readl(GPIO2_OUTPUT) & ~adapter->sda_mask, GPIO2_OUTPUT); -+ au_writel(au_readl(GPIO2_DIR) | adapter->sda_mask, GPIO2_DIR); -+ } -+} -+ -+static int bit_au1x00gpio2_getscl(void *data) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ return (au_readl(GPIO2_PINSTATE) & adapter->scl_mask) ? 1 : 0; -+} -+ -+static int bit_au1x00gpio2_getsda(void *data) -+{ -+ struct i2c_au1x00gpio * adapter = (struct i2c_au1x00gpio *)data; -+ return (au_readl(GPIO2_PINSTATE) & adapter->sda_mask) ? 1 : 0; -+} -+ -+ -+ -+static int check_i2c_au1x00gpio_adapter(struct i2c_au1x00gpio *adapter) -+{ -+ int state = 0; -+ -+ adapter->bit_au1x00gpio_data.setsda (adapter, 1); -+ adapter->bit_au1x00gpio_data.setscl (adapter, 1); -+ -+ if (adapter->bit_au1x00gpio_data.getsda(adapter)==0) -+ { -+ printk ("i2c-au1x00gpio: sda line should read 1 but reads 0\n"); -+ state = -1; -+ } -+ if (adapter->bit_au1x00gpio_data.getscl(adapter)==0) -+ { -+ printk ("i2c-au1x00gpio: scl line should read 1 but reads 0\n"); -+ state = -1; -+ } -+ -+ -+ adapter->bit_au1x00gpio_data.setsda (adapter, 0); -+ adapter->bit_au1x00gpio_data.setscl (adapter, 0); -+ -+ if (adapter->bit_au1x00gpio_data.getsda(adapter)==1) -+ { -+ printk ("i2c-au1x00gpio: sda line should read 0 but reads 1\n"); -+ state = -1; -+ } -+ if (adapter->bit_au1x00gpio_data.getscl(adapter)==1) -+ { -+ printk ("i2c-au1x00gpio: scl line should read 0 but reads 1\n"); -+ state = -1; -+ } -+ -+ if (state==0) -+ printk ("i2c-au1x00gpio: adapter with scl=GPIO%d,sda=GPIO%d is working\n", -+ adapter->scl_gpio, adapter->sda_gpio -+ ); -+ return state; -+} -+ -+ -+ -+#if 0 -+static int bit_au1x00gpio_reg(struct i2c_client *client) -+{ -+ return 0; -+} -+ -+static int bit_au1x00gpio_unreg(struct i2c_client *client) -+{ -+ return 0; -+} -+ -+static void bit_au1x00gpio_inc_use(struct i2c_adapter *adap) -+{ -+ MOD_INC_USE_COUNT; -+} -+ -+static void bit_au1x00gpio_dec_use(struct i2c_adapter *adap) -+{ -+ MOD_DEC_USE_COUNT; -+} -+#endif -+ -+ -+ -+static struct i2c_algo_bit_data bit_au1x00gpio_data = { -+ .data = NULL, -+ .setsda = bit_au1x00gpio_setsda, -+ .setscl = bit_au1x00gpio_setscl, -+ .getsda = bit_au1x00gpio_getsda, -+ .getscl = bit_au1x00gpio_getscl, -+ .udelay = 80, -+ .timeout = HZ, -+}; -+ -+ -+static struct i2c_adapter bit_au1x00gpio_ops = { -+ .owner = THIS_MODULE, -+ .name = "Au1x00 GPIO I2C adapter", -+ .id = I2C_HW_B_AU1x00GPIO, -+}; -+ -+ -+ -+/* -+ * scl_gpio: -+ * 0..31 for primary GPIO's -+ * 200..215 for secondary GPIO's -+ * -+ * sda_gpio: -+ * 0..31 for primary GPIO's -+ * 200..215 for secondary GPIO's -+ * -+ * You can even mix primary and secondary GPIO's. -+ * E.g.: i2c_au1x00gpio_create(4,206); -+ */ -+ -+static int i2c_au1x00gpio_create (int scl_gpio, int sda_gpio) -+{ -+ if ((scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215)) && -+ (scl_gpio < 32 || (scl_gpio >= 200 && scl_gpio <= 215))) -+ { -+ struct i2c_au1x00gpio *adapter = kmalloc(sizeof(struct i2c_au1x00gpio), -+ GFP_KERNEL); -+ if (!adapter) { -+ printk(KERN_ERR "i2c-au1x00-gpio: Unable to malloc.\n"); -+ return -1; -+ } -+ -+ printk(KERN_DEBUG "i2c-au1x00-gpio.o: attaching to SCL=GPIO%d, SDA=GPIO%d\n", -+ scl_gpio, sda_gpio); -+ -+ memset (adapter, 0, sizeof(struct i2c_au1x00gpio)); -+ -+ adapter->adapter = bit_au1x00gpio_ops; -+ -+ adapter->adapter.algo_data = &adapter->bit_au1x00gpio_data; -+ adapter->bit_au1x00gpio_data = bit_au1x00gpio_data; -+ adapter->bit_au1x00gpio_data.data = adapter; -+ -+ adapter->bit_au1x00gpio_data.data = adapter; -+ -+ adapter->scl_gpio = scl_gpio; -+ adapter->sda_gpio = sda_gpio; -+ -+ if (sda_gpio < 32) -+ { -+ adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio_setsda; -+ adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio_getsda; -+ adapter->sda_mask = 1<= 200 && sda_gpio <= 215) -+ { -+ adapter->bit_au1x00gpio_data.setsda = bit_au1x00gpio2_setsda; -+ adapter->bit_au1x00gpio_data.getsda = bit_au1x00gpio2_getsda; -+ adapter->sda_mask = 1<<(sda_gpio-200); -+ } -+ -+ -+ if (scl_gpio < 32) -+ { -+ adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio_setscl; -+ adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio_getscl; -+ adapter->scl_mask = 1<= 200 && scl_gpio <= 215) -+ { -+ adapter->bit_au1x00gpio_data.setscl = bit_au1x00gpio2_setscl; -+ adapter->bit_au1x00gpio_data.getscl = bit_au1x00gpio2_getscl; -+ adapter->scl_mask = 1<<(scl_gpio-200); -+ } -+ -+ au_writel(0L, SYS_PININPUTEN); -+ if (check_i2c_au1x00gpio_adapter(adapter)==0) -+ { -+ adapter->bit_au1x00gpio_data.setsda (adapter, 1); -+ adapter->bit_au1x00gpio_data.setscl (adapter, 1); -+ -+ if (i2c_bit_add_bus(&adapter->adapter) < 0) -+ { -+ printk(KERN_ERR "i2c-au1x00-gpio: Unable to register with I2C.\n"); -+ kfree(adapter); -+ return -1; /* No good */ -+ } -+ -+ adapter->next = adapter_list; -+ adapter_list = adapter; -+ return 0; -+ } -+ } -+ else -+ printk(KERN_ERR "i2c-au1x00-gpio: Invalid argument scl_gpio=%d, sda_gpio=%d.\n", scl_gpio, sda_gpio); -+ return -1; -+} -+ -+ -+ -+static void i2c_au1x00gpio_delete (int scl_gpio, int sda_gpio) -+{ -+ struct i2c_au1x00gpio *adapter, *prev = NULL; -+ -+ for (adapter = adapter_list; adapter; adapter = adapter->next) -+ { -+ if (adapter->scl_gpio == scl_gpio && -+ adapter->sda_gpio == sda_gpio) -+ { -+ i2c_del_adapter(&adapter->adapter); -+ if (prev) -+ prev->next = adapter->next; -+ else -+ adapter_list = adapter->next; -+ kfree(adapter); -+ return; -+ } -+ prev = adapter; -+ } -+} -+ -+ -+ -+ -+ -+#ifndef CONFIG_I2C_AU1X00GPIO_SCL -+#define CONFIG_I2C_AU1X00GPIO_SCL (210) -+#endif -+ -+#ifndef CONFIG_I2C_AU1X00GPIO_SDA -+#define CONFIG_I2C_AU1X00GPIO_SDA (9) -+#endif -+ -+static int au1x00gpiopin_scl = CONFIG_I2C_AU1X00GPIO_SCL; -+static int au1x00gpiopin_sda = CONFIG_I2C_AU1X00GPIO_SDA; -+ -+ -+ -+static int __init i2c_bit_au1x00gpio_init(void) -+{ -+ printk(KERN_INFO "i2c-au1x00gpio.o: i2c Au1x00 GPIO adapter module version\n"); -+ -+ if (i2c_au1x00gpio_create (au1x00gpiopin_scl, au1x00gpiopin_sda) == 0) -+ { -+ printk(KERN_INFO "i2c-au1x00gpio.o: registered I2C-Bus for GPIO%d,GPIO%d\n", -+ au1x00gpiopin_scl, au1x00gpiopin_sda -+ ); -+ return 0; -+ } -+ printk(KERN_INFO "i2c-au1x00gpio.o: failed to register I2C-Bus for GPIO%d,GPIO%d\n", -+ au1x00gpiopin_scl, au1x00gpiopin_sda -+ ); -+ return -1; -+} -+ -+ -+static void __exit i2c_bit_au1x00gpio_exit(void) -+{ -+ i2c_au1x00gpio_delete (au1x00gpiopin_scl, au1x00gpiopin_sda); -+} -+ -+module_param(au1x00gpiopin_scl, int, 0644); -+MODULE_PARM_DESC(au1x00gpiopin_scl, "GPIO pin number used for SCL pin."); -+ -+module_param(au1x00gpiopin_sda, int, 0644); -+MODULE_PARM_DESC(au1x00gpiopin_sda, "GPIO pin number used for SDA pin."); -+ -+MODULE_AUTHOR("Michael Stickel "); -+MODULE_DESCRIPTION("I2C-Bus adapter routines for Au1x00 GPIO adapter."); -+MODULE_LICENSE("GPL"); -+ -+module_init(i2c_bit_au1x00gpio_init); -+module_exit(i2c_bit_au1x00gpio_exit); -diff -urN linux-2.6.19/include/linux/i2c-id.h linux-2.6.19.new/include/linux/i2c-id.h ---- linux-2.6.19/include/linux/i2c-id.h 2006-11-29 22:57:37.000000000 +0100 -+++ linux-2.6.19.new/include/linux/i2c-id.h 2006-12-28 03:12:15.000000000 +0100 -@@ -231,6 +231,9 @@ - /* --- Au1550 PSC adapters adapters */ - #define I2C_HW_AU1550_PSC 0x1b0000 - -+/* --- Au1x00 i2c GPIO adapter */ -+#define I2C_HW_B_AU1x00GPIO 0x1b -+ - /* --- SMBus only adapters */ - #define I2C_HW_SMBUS_PIIX4 0x040000 - #define I2C_HW_SMBUS_ALI15X3 0x040001