On Sat, Aug 06, 2005 at 09:08:15PM -0300, Aristeu Sergio Rozanski Filho wrote: > > Would be good to test before submitting? :) > I would like but I don't have the hardware and Alex (who reported this > on bugzilla) told me he doesn't have it anymore. feel free to discard it > until someone tests it
Does anyone volunteer to test this 8xx i2c driver? > > > > +static void > > > +cpm_iic_interrupt(void *dev_id, struct pt_regs *regs) > > > + { > > > + volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id; > > > > You got an extra space everywhere other than the initial TAB? > fixed this and others I found in the file, patch attached > > -- > Aristeu > > 8xx: port i2c-algo_8xx to 2.6 > > Based on Tom Rini's work > > Signed-off-by: Aristeu Sergio Rozanski Filho <aris at cathedrallabs.org> > > Index: 8xx/drivers/i2c/algos/i2c-algo-8xx.c > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ 8xx/drivers/i2c/algos/i2c-algo-8xx.c 2005-08-06 21:04:37.000000000 > -0300 > @@ -0,0 +1,625 @@ > +/* > + * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM > + * Copyright (c) 1999 Dan Malek (dmalek at jlc.net). > + * > + 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. > + * > + * moved into proper i2c interface; separated out platform specific > + * parts into i2c-rpx.c > + * Brad Parker (brad at heeltoe.com) > + */ > + > +// XXX todo > +// timeout sleep? > + > +/* $Id: i2c-algo-8xx.c,v 1.7 2002/08/03 22:48:18 ac9410 Exp $ */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/delay.h> > +#include <linux/slab.h> > +#include <linux/version.h> > +#include <linux/init.h> > +#include <asm/uaccess.h> > +#include <linux/ioport.h> > +#include <linux/errno.h> > +#include <linux/sched.h> > + > +#include <asm/mpc8xx.h> > +#include <asm/commproc.h> > + > +#include <linux/i2c.h> > +#include <linux/i2c-algo-8xx.h> > + > +#define CPM_MAX_READ 513 > +/* Try uncomment this if you have an older CPU(earlier than rev D4) */ > +/* #define I2C_CHIP_ERRATA */ > + > +static char *module_name = "i2c_algo_8xx"; > +#define DEBUGP(level, x, y...) do { \ > + if (cpm_debug >= level) \ > + printk(KERN_DEBUG "%s: " x, \ > + module_name, ## y); \ > + } while(0) > + > +static wait_queue_head_t iic_wait; > +static ushort r_tbase, r_rbase; > + > +int cpm_scan = 0; > +int cpm_debug = 0; > + > +static void > +cpm_iic_interrupt(void *dev_id, struct pt_regs *regs) > +{ > + volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id; > + > + DEBUGP(2, "cpm_iic_interrupt(dev_id=%p)\n", dev_id); > + > +#ifdef I2C_CHIP_ERRATA > + /* Chip errata, clear enable. > + * This seems to not be needed on rev D4 or newer CPUs. > + * Someone with an older CPU needs to verify this. > + */ > + i2c->i2c_i2mod &= ~1; > +#endif > + > + /* Clear interrupt. > + */ > + i2c->i2c_i2cer = 0xff; > + > + /* Get 'me going again. > + */ > + wake_up_interruptible(&iic_wait); > +} > + > +static void > +cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap) > +{ > + volatile iic_t *iip = cpm_adap->iip; > + volatile i2c8xx_t *i2c = cpm_adap->i2c; > + unsigned char brg; > + bd_t *bd = (bd_t *)__res; > + > + DEBUGP(1, "cpm_iic_init() - iip=%p\n", iip); > + > + /* Initialize the parameter ram. > + * We need to make sure many things are initialized to zero, > + * especially in the case of a microcode patch. > + */ > + iip->iic_rstate = 0; > + iip->iic_rdp = 0; > + iip->iic_rbptr = 0; > + iip->iic_rbc = 0; > + iip->iic_rxtmp = 0; > + iip->iic_tstate = 0; > + iip->iic_tdp = 0; > + iip->iic_tbptr = 0; > + iip->iic_tbc = 0; > + iip->iic_txtmp = 0; > + > + /* Set up the IIC parameters in the parameter ram. > + */ > + iip->iic_tbase = r_tbase = cpm_adap->dp_addr; > + iip->iic_rbase = r_rbase = cpm_adap->dp_addr + sizeof(cbd_t) * 2; > + > + iip->iic_tfcr = SMC_EB; > + iip->iic_rfcr = SMC_EB; > + > + /* Set maximum receive size. > + */ > + iip->iic_mrblr = CPM_MAX_READ; > + > + /* Initialize Tx/Rx parameters. > + */ > + if (cpm_adap->reloc == 0) { > + volatile cpm8xx_t *cp = cpm_adap->cp; > + > + cp->cp_cpcr = > + mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; > + while (cp->cp_cpcr & CPM_CR_FLG); > + } else { > + iip->iic_rbptr = iip->iic_rbase; > + iip->iic_tbptr = iip->iic_tbase; > + iip->iic_rstate = 0; > + iip->iic_tstate = 0; > + } > + > + /* Select an arbitrary address. Just make sure it is unique. > + */ > + i2c->i2c_i2add = 0xfe; > + > + /* Make clock run at 60 KHz. > + */ > + brg = (unsigned char) (bd->bi_intfreq/(32*2*60000) -3); > + i2c->i2c_i2brg = brg; > + > + i2c->i2c_i2mod = 0x00; > + i2c->i2c_i2com = 0x01; /* Master mode */ > + > + /* Disable interrupts. > + */ > + i2c->i2c_i2cmr = 0; > + i2c->i2c_i2cer = 0xff; > + > + init_waitqueue_head(&iic_wait); > + > + /* Install interrupt handler. > + */ > + DEBUGP(1, "Install ISR for IRQ %d\n", CPMVEC_I2C); > + cpm_install_handler(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c); > +} > + > + > +static int > +cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm_adap) > +{ > + volatile i2c8xx_t *i2c = cpm_adap->i2c; > + > + /* Shut down IIC. > + */ > + i2c->i2c_i2mod &= ~1; > + i2c->i2c_i2cmr = 0; > + i2c->i2c_i2cer = 0xff; > + > + return 0; > +} > + > +static void > +cpm_reset_iic_params(volatile iic_t *iip) > +{ > + iip->iic_tbase = r_tbase; > + iip->iic_rbase = r_rbase; > + > + iip->iic_tfcr = SMC_EB; > + iip->iic_rfcr = SMC_EB; > + > + iip->iic_mrblr = CPM_MAX_READ; > + > + iip->iic_rstate = 0; > + iip->iic_rdp = 0; > + iip->iic_rbptr = iip->iic_rbase; > + iip->iic_rbc = 0; > + iip->iic_rxtmp = 0; > + iip->iic_tstate = 0; > + iip->iic_tdp = 0; > + iip->iic_tbptr = iip->iic_tbase; > + iip->iic_tbc = 0; > + iip->iic_txtmp = 0; > +} > + > +#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */ > +#define BD_SC_OV ((ushort)0x0002) /* OV - receive overrun */ > +#define CPM_CR_CLOSE_RXBD ((ushort)0x0007) > + > +static void force_close(struct i2c_algo_8xx_data *cpm) > +{ > + volatile i2c8xx_t *i2c = cpm->i2c; > + if (cpm->reloc == 0) { /* micro code disabled */ > + volatile cpm8xx_t *cp = cpm->cp; > + > + DEBUGP(1, "force_close()\n"); > + cp->cp_cpcr = > + mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) | > + CPM_CR_FLG; > + > + while (cp->cp_cpcr & CPM_CR_FLG); > + } > + i2c->i2c_i2cmr = 0x00; /* Disable all interrupts */ > + i2c->i2c_i2cer = 0xff; > +} > + > + > +/* Read from IIC... > + * abyte = address byte, with r/w flag already set > + */ > +static int > +cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, int > count) > +{ > + volatile iic_t *iip = cpm->iip; > + volatile i2c8xx_t *i2c = cpm->i2c; > + volatile cpm8xx_t *cp = cpm->cp; > + volatile cbd_t *tbdf, *rbdf; > + u_char *tb; > + unsigned long flags, tmo; > + > + if (count >= CPM_MAX_READ) > + return -EINVAL; > + > + /* check for and use a microcode relocation patch */ > + if (cpm->reloc) > + cpm_reset_iic_params(iip); > + > + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; > + rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; > + > + /* To read, we need an empty buffer of the proper length. > + * All that is used is the first byte for address, the remainder > + * is just used for timing (and doesn't really have to exist). > + */ > + tb = cpm->temp; > + tb = (u_char *)(((uint)tb + 15) & ~15); > + tb[0] = abyte; /* Device address byte w/rw flag */ > + > + flush_dcache_range((unsigned long) tb, (unsigned long) (tb + 1)); > + > + DEBUGP(1, "cpm_iic_read(abyte=0x%x)\n", abyte); > + > + tbdf->cbd_bufaddr = __pa(tb); > + tbdf->cbd_datlen = count + 1; > + tbdf->cbd_sc = > + BD_SC_READY | BD_SC_LAST | > + BD_SC_WRAP | BD_IIC_START; > + > + iip->iic_mrblr = count + 1; /* prevent excessive read, +1 > + is needed otherwise will the > + RXB interrupt come too early */ > + > + /* flush will invalidate too. */ > + flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); > + > + rbdf->cbd_datlen = 0; > + rbdf->cbd_bufaddr = __pa(buf); > + > + rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP| BD_SC_INTRPT; > + if(count > 16){ > + /* Chip bug, set enable here */ > + local_irq_save(flags); > + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ > + i2c->i2c_i2cer = 0xff; > + i2c->i2c_i2mod |= 1; /* Enable */ > + i2c->i2c_i2com |= 0x80; /* Begin transmission */ > + > + /* Wait for IIC transfer */ > + tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); > + local_irq_restore(flags); > + } else { /* busy wait for small transfers, its faster */ > + i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */ > + i2c->i2c_i2cer = 0xff; > + i2c->i2c_i2mod |= 1; /* Enable */ > + i2c->i2c_i2com |= 0x80; /* Begin transmission */ > + tmo = jiffies + 1*HZ; > + /* Busy wait, with a timeout */ > + while(!(i2c->i2c_i2cer & 0x11 || time_after(jiffies, tmo))); > + } > + > + if (signal_pending(current) || !tmo){ > + force_close(cpm); > + DEBUGP(1, "IIC read: timeout!\n"); > + return -EIO; > + } > +#ifdef I2C_CHIP_ERRATA > + /* Chip errata, clear enable. This is not needed on rev D4 CPUs. > + Disabling I2C too early may cause too short stop condition */ > + udelay(4); > + i2c->i2c_i2mod &= ~1; > +#endif > + > + DEBUGP(1, "tx sc %04x, rx sc %04x\n", tbdf->cbd_sc, rbdf->cbd_sc); > + > + if (tbdf->cbd_sc & BD_SC_READY) { > + printk(KERN_INFO "IIC read; complete but tbuf ready\n"); > + force_close(cpm); > + printk(KERN_INFO "tx sc %04x, rx sc %04x\n", > + tbdf->cbd_sc, rbdf->cbd_sc); > + } > + > + if (tbdf->cbd_sc & BD_SC_NAK) { > + DEBUGP(1, "IIC read; no ack\n"); > + return -EREMOTEIO; > + } > + > + if (rbdf->cbd_sc & BD_SC_EMPTY) { > + /* force_close(cpm); */ > + DEBUGP(1, "IIC read; complete but rbuf empty\n"); > + DEBUGP(1, "tx sc %04x, rx sc %04x\n", tbdf->cbd_sc, > rbdf->cbd_sc); > + return -EREMOTEIO; > + } > + > + if (rbdf->cbd_sc & BD_SC_OV) { > + DEBUGP(1, "IIC read; Overrun\n"); > + return -EREMOTEIO;; > + } > + > + DEBUGP(1, "read %d bytes\n", rbdf->cbd_datlen); > + > + if (rbdf->cbd_datlen < count) { > + DEBUGP(1, "IIC read; short, wanted %d got %d\n", count, > + rbdf->cbd_datlen); > + return 0; > + } > + > + return count; > +} > + > +/* Write to IIC... > + * addr = address byte, with r/w flag already set > + */ > +static int > +cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,int > count) > +{ > + volatile iic_t *iip = cpm->iip; > + volatile i2c8xx_t *i2c = cpm->i2c; > + volatile cpm8xx_t *cp = cpm->cp; > + volatile cbd_t *tbdf; > + u_char *tb; > + unsigned long flags, tmo; > + > + /* check for and use a microcode relocation patch */ > + if (cpm->reloc) > + cpm_reset_iic_params(iip); > + tb = cpm->temp; > + tb = (u_char *)(((uint)tb + 15) & ~15); > + *tb = abyte; /* Device address byte w/rw flag */ > + > + flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1)); > + flush_dcache_range((unsigned long) buf, (unsigned long) (buf+count)); > + > + DEBUGP(1, "cpm_iic_write(abyte=0x%x)\n", abyte); > + > + /* set up 2 descriptors */ > + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; > + > + tbdf[0].cbd_bufaddr = __pa(tb); > + tbdf[0].cbd_datlen = 1; > + tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START; > + > + tbdf[1].cbd_bufaddr = __pa(buf); > + tbdf[1].cbd_datlen = count; > + tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP; > + > + if (count > 16) { > + /* Chip bug, set enable here */ > + local_irq_save(flags); > + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ > + i2c->i2c_i2cer = 0xff; > + i2c->i2c_i2mod |= 1; /* Enable */ > + i2c->i2c_i2com |= 0x80; /* Begin transmission */ > + > + /* Wait for IIC transfer */ > + tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); > + local_irq_restore(flags); > + } else { /* busy wait for small transfers, its faster */ > + i2c->i2c_i2cmr = 0x00; /* Disable I2C interupts */ > + i2c->i2c_i2cer = 0xff; > + i2c->i2c_i2mod |= 1; /* Enable */ > + i2c->i2c_i2com |= 0x80; /* Begin transmission */ > + tmo = jiffies + 1*HZ; > + /* Busy wait, with a timeout */ > + while(!(i2c->i2c_i2cer & 0x12 || time_after(jiffies, tmo))); > + } > + > + if (signal_pending(current) || !tmo){ > + force_close(cpm); > + if (!tmo) > + DEBUGP(1, "IIC write: timeout!\n"); > + return -EIO; > + } > + > +#if I2C_CHIP_ERRATA > + /* Chip errata, clear enable. This is not needed on rev D4 CPUs. > + Disabling I2C too early may cause too short stop condition */ > + udelay(4); > + i2c->i2c_i2mod &= ~1; > +#endif > + DEBUGP(1, "tx0 sc %04x, tx1 sc %04x\n", tbdf[0].cbd_sc, > + tbdf[1].cbd_sc); > + > + if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_NAK) { > + DEBUGP(1, "IIC write; no ack\n"); > + return 0; > + } > + > + if ((tbdf[0].cbd_sc | tbdf[1].cbd_sc) & BD_SC_READY) { > + DEBUGP(1, "IIC write; complete but tbuf ready\n"); > + return 0; > + } > + > + return count; > +} > + > +/* See if an IIC address exists.. > + * addr = 7 bit address, unshifted > + */ > +static int > +cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr) > +{ > + volatile iic_t *iip = cpm->iip; > + volatile i2c8xx_t *i2c = cpm->i2c; > + volatile cpm8xx_t *cp = cpm->cp; > + volatile cbd_t *tbdf, *rbdf; > + u_char *tb; > + unsigned long flags, len, tmo; > + > + DEBUGP(2, "cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr); > + > + /* check for and use a microcode relocation patch */ > + if (cpm->reloc) > + cpm_reset_iic_params(iip); > + > + if (addr == 0) { > + DEBUGP(1, "iip %p, dp_addr 0x%x\n", cpm->iip, cpm->dp_addr); > + DEBUGP(1, "iic_tbase %d, r_tbase %d\n", iip->iic_tbase, > + r_tbase); > + } > + > + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; > + rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; > + > + tb = cpm->temp; > + tb = (u_char *)(((uint)tb + 15) & ~15); > + > + /* do a simple read */ > + tb[0] = (addr << 1) | 1; /* device address (+ read) */ > + len = 2; > + > + flush_dcache_range((unsigned long) tb, (unsigned long) (tb+1)); > + > + tbdf->cbd_bufaddr = __pa(tb); > + tbdf->cbd_datlen = len; > + tbdf->cbd_sc = > + BD_SC_READY | BD_SC_LAST | > + BD_SC_WRAP | BD_IIC_START; > + > + rbdf->cbd_datlen = 0; > + rbdf->cbd_bufaddr = __pa(tb+2); > + rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP | BD_SC_INTRPT; > + > + local_irq_save(flags); > + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ > + i2c->i2c_i2cer = 0xff; > + i2c->i2c_i2mod |= 1; /* Enable */ > + i2c->i2c_i2com |= 0x80; /* Begin transmission */ > + > + DEBUGP(1, "about to sleep\n"); > + > + /* wait for IIC transfer */ > + tmo = interruptible_sleep_on_timeout(&iic_wait,1*HZ); > + local_irq_restore(flags); > + > +#ifdef I2C_CHIP_ERRATA > + /* Chip errata, clear enable. This is not needed on rev D4 CPUs. > + Disabling I2C too early may cause too short stop condition */ > + udelay(4); > + i2c->i2c_i2mod &= ~1; > +#endif > + > + if (signal_pending(current) || !tmo){ > + force_close(cpm); > + if (!tmo) > + DEBUGP(1, "IIC tryaddress: timeout!\n"); > + return -EIO; > + } > + > + DEBUGP(2, "back from sleep\n"); > + > + if (tbdf->cbd_sc & BD_SC_NAK) { > + DEBUGP(2, "IIC try; no ack\n"); > + return 0; > + } > + > + if (tbdf->cbd_sc & BD_SC_READY) > + printk(KERN_INFO "IIC try; complete but tbuf ready\n"); > + > + return 1; > +} > + > +static int cpm_xfer(struct i2c_adapter *i2c_adap, > + struct i2c_msg msgs[], > + int num) > +{ > + struct i2c_algo_8xx_data *adap = i2c_adap->algo_data; > + struct i2c_msg *pmsg; > + int i, ret; > + u_char addr; > + > + for (i = 0; i < num; i++) { > + pmsg = &msgs[i]; > + > + DEBUGP(1, "#%d addr=0x%x flags=0x%x len=%d\n buf=%p\n", > + i, pmsg->addr, pmsg->flags, pmsg->len, pmsg->buf); > + > + addr = pmsg->addr << 1; > + if (pmsg->flags & I2C_M_RD) > + addr |= 1; > + if (pmsg->flags & I2C_M_REV_DIR_ADDR) > + addr ^= 1; > + > + if (pmsg->flags & I2C_M_RD) { > + /* read bytes into buffer*/ > + ret = cpm_iic_read(adap, addr, pmsg->buf, pmsg->len); > + DEBUGP(1, "read %d bytes\n", ret); > + if (ret < pmsg->len) > + return (ret < 0)? ret:-EREMOTEIO; > + } else { > + /* write bytes from buffer */ > + ret = cpm_iic_write(adap, addr, pmsg->buf, pmsg->len); > + DEBUGP(1, "wrote %d\n", ret); > + if (ret < pmsg->len) > + return (ret < 0)? ret:-EREMOTEIO; > + } > + } > + return num; > +} > + > +static u32 cpm_func(struct i2c_adapter *adap) > +{ > + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | > + I2C_FUNC_PROTOCOL_MANGLING; > +} > + > +static struct i2c_algorithm i2c_algo_8xx = { > + .name = "MPC8xx CPM algorithm", > + .id = I2C_ALGO_MPC8XX, > + .master_xfer = cpm_xfer, > + .functionality = cpm_func, > +}; > + > +/* > + * registering functions to load algorithms at runtime > + */ > +int i2c_8xx_add_bus(struct i2c_adapter *adap) > +{ > + int i; > + struct i2c_algo_8xx_data *cpm_adap = adap->algo_data; > + > + DEBUGP(1, "hw routines for %s registered.\n", adap->name); > + > + /* register new adapter to i2c module... */ > + > + adap->id |= i2c_algo_8xx.id; > + adap->algo = &i2c_algo_8xx; > + > + i2c_add_adapter(adap); > + cpm_iic_init(cpm_adap); > + > + /* scan bus */ > + if (cpm_scan) { > + printk(KERN_INFO "%s: scanning bus %s...\n", module_name, > + adap->name); > + for (i = 0; i < 128; i++) > + if (cpm_iic_tryaddress(cpm_adap, i)) { > + printk("(%02x)", i << 1); > + } > + printk("\n"); > + } > + return 0; > +} > + > +int i2c_8xx_del_bus(struct i2c_adapter *adap) > +{ > + int res; > + struct i2c_algo_8xx_data *cpm_adap = adap->algo_data; > + > + cpm_iic_shutdown(cpm_adap); > + > + if ((res = i2c_del_adapter(adap)) < 0) > + return res; > + > + printk(KERN_INFO "%s: adapter unregistered: %s\n", module_name, > + adap->name); > + > + return 0; > +} > + > +module_param(cpm_debug, int, S_IRUGO | S_IWUSR); > +MODULE_PARM_DESC(cpm_debug, "Sets the debug level. (0 = none, 1 = normal, " > + ">1 = plenty"); > +MODULE_AUTHOR("Brad Parker <brad at heeltoe.com>"); > +MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm"); > +MODULE_LICENSE("GPL"); > + > +EXPORT_SYMBOL(i2c_8xx_add_bus); > +EXPORT_SYMBOL(i2c_8xx_del_bus); > + > Index: 8xx/drivers/i2c/algos/Makefile > =================================================================== > --- 8xx.orig/drivers/i2c/algos/Makefile 2005-08-06 14:40:49.000000000 > -0300 > +++ 8xx/drivers/i2c/algos/Makefile 2005-08-06 21:03:57.000000000 -0300 > @@ -8,6 +8,7 @@ > obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o > obj-$(CONFIG_I2C_ALGO_SIBYTE) += i2c-algo-sibyte.o > obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o > +obj-$(CONFIG_I2C_ALGO8XX) += i2c-algo-8xx.o > > ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) > EXTRA_CFLAGS += -DDEBUG > Index: 8xx/include/linux/i2c-algo-8xx.h > =================================================================== > --- /dev/null 1970-01-01 00:00:00.000000000 +0000 > +++ 8xx/include/linux/i2c-algo-8xx.h 2005-08-06 21:03:57.000000000 -0300 > @@ -0,0 +1,28 @@ > +/* ------------------------------------------------------------------------- > */ > +/* i2c-algo-8xx.h i2c driver algorithms for MPX8XX CPM > */ > +/* ------------------------------------------------------------------------- > */ > + > +/* $Id$ */ > + > +#ifndef I2C_ALGO_8XX_H > +#define I2C_ALGO_8XX_H > + > +#include <linux/i2c.h> > +#include <asm/8xx_immap.h> > +#include <asm/commproc.h> > + > +struct i2c_algo_8xx_data { > + uint dp_addr; > + int reloc; > + volatile i2c8xx_t *i2c; > + volatile iic_t *iip; > + volatile cpm8xx_t *cp; > + > + u_char temp[513]; > +}; > + > +int i2c_8xx_add_bus(struct i2c_adapter *); > +int i2c_8xx_del_bus(struct i2c_adapter *); > + > +#endif /* I2C_ALGO_8XX_H */ > +