Adapt PowerMac i2c-keywest driver to new driver model

parent 45411f68
...@@ -81,9 +81,6 @@ MODULE_PARM(debug, "i"); ...@@ -81,9 +81,6 @@ MODULE_PARM(debug, "i");
int probe = 0; int probe = 0;
int debug = 0; int debug = 0;
static struct keywest_iface *ifaces = NULL;
static void static void
do_stop(struct keywest_iface* iface, int result) do_stop(struct keywest_iface* iface, int result)
{ {
...@@ -306,6 +303,7 @@ keywest_smbus_xfer( struct i2c_adapter* adap, ...@@ -306,6 +303,7 @@ keywest_smbus_xfer( struct i2c_adapter* adap,
write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
write_reg(reg_ier, KW_I2C_IRQ_MASK); write_reg(reg_ier, KW_I2C_IRQ_MASK);
/* Wait interrupt operations completion */
wait_for_completion(&iface->complete); wait_for_completion(&iface->complete);
rc = iface->result; rc = iface->result;
...@@ -385,6 +383,7 @@ keywest_xfer( struct i2c_adapter *adap, ...@@ -385,6 +383,7 @@ keywest_xfer( struct i2c_adapter *adap,
write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR); write_reg(reg_control, read_reg(reg_control) | KW_I2C_CTL_XADDR);
write_reg(reg_ier, KW_I2C_IRQ_MASK); write_reg(reg_ier, KW_I2C_IRQ_MASK);
/* Wait interrupt operations completion */
wait_for_completion(&iface->complete); wait_for_completion(&iface->complete);
rc = iface->result; rc = iface->result;
...@@ -418,7 +417,7 @@ static struct i2c_algorithm keywest_algorithm = { ...@@ -418,7 +417,7 @@ static struct i2c_algorithm keywest_algorithm = {
static int static int
create_iface(struct device_node* np) create_iface(struct device_node *np, struct device *dev)
{ {
unsigned long steps, *psteps, *prate; unsigned long steps, *psteps, *prate;
unsigned bsteps, tsize, i, nchan, addroffset; unsigned bsteps, tsize, i, nchan, addroffset;
...@@ -487,8 +486,8 @@ create_iface(struct device_node* np) ...@@ -487,8 +486,8 @@ create_iface(struct device_node* np)
*prate); *prate);
} }
/* Select standard mode by default */ /* Select standard sub mode */
iface->cur_mode |= KW_I2C_MODE_STANDARD; iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
/* Write mode */ /* Write mode */
write_reg(reg_mode, iface->cur_mode); write_reg(reg_mode, iface->cur_mode);
...@@ -506,11 +505,13 @@ create_iface(struct device_node* np) ...@@ -506,11 +505,13 @@ create_iface(struct device_node* np)
return -ENODEV; return -ENODEV;
} }
dev_set_drvdata(dev, iface);
for (i=0; i<nchan; i++) { for (i=0; i<nchan; i++) {
struct keywest_chan* chan = &iface->channels[i]; struct keywest_chan* chan = &iface->channels[i];
u8 addr; u8 addr;
sprintf(chan->adapter.dev.name, "%s %d", np->parent->name, i); sprintf(chan->adapter.name, "%s %d", np->parent->name, i);
chan->iface = iface; chan->iface = iface;
chan->chan_no = i; chan->chan_no = i;
chan->adapter.id = I2C_ALGO_SMBUS; chan->adapter.id = I2C_ALGO_SMBUS;
...@@ -519,11 +520,12 @@ create_iface(struct device_node* np) ...@@ -519,11 +520,12 @@ create_iface(struct device_node* np)
chan->adapter.client_register = NULL; chan->adapter.client_register = NULL;
chan->adapter.client_unregister = NULL; chan->adapter.client_unregister = NULL;
i2c_set_adapdata(&chan->adapter, chan); i2c_set_adapdata(&chan->adapter, chan);
chan->adapter.dev.parent = dev;
rc = i2c_add_adapter(&chan->adapter); rc = i2c_add_adapter(&chan->adapter);
if (rc) { if (rc) {
printk("i2c-keywest.c: Adapter %s registration failed\n", printk("i2c-keywest.c: Adapter %s registration failed\n",
chan->adapter.dev.name); chan->adapter.name);
i2c_set_adapdata(&chan->adapter, NULL); i2c_set_adapdata(&chan->adapter, NULL);
} }
if (probe) { if (probe) {
...@@ -540,20 +542,18 @@ create_iface(struct device_node* np) ...@@ -540,20 +542,18 @@ create_iface(struct device_node* np)
printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n",
np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps);
iface->next = ifaces;
ifaces = iface;
return 0; return 0;
} }
static void static int
dispose_iface(struct keywest_iface *iface) dispose_iface(struct device *dev)
{ {
struct keywest_iface *iface = dev_get_drvdata(dev);
int i, rc; int i, rc;
ifaces = iface->next;
/* Make sure we stop all activity */ /* Make sure we stop all activity */
down(&iface->sem); down(&iface->sem);
spin_lock_irq(&iface->lock); spin_lock_irq(&iface->lock);
while (iface->state != state_idle) { while (iface->state != state_idle) {
spin_unlock_irq(&iface->lock); spin_unlock_irq(&iface->lock);
...@@ -578,31 +578,78 @@ dispose_iface(struct keywest_iface *iface) ...@@ -578,31 +578,78 @@ dispose_iface(struct keywest_iface *iface)
printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n");
} }
iounmap((void *)iface->base); iounmap((void *)iface->base);
dev_set_drvdata(dev, NULL);
kfree(iface); kfree(iface);
return 0;
} }
static int
create_iface_macio(struct macio_dev* dev, const struct of_match *match)
{
return create_iface(dev->ofdev.node, &dev->ofdev.dev);
}
static int
dispose_iface_macio(struct macio_dev* dev)
{
return dispose_iface(&dev->ofdev.dev);
}
static int
create_iface_of_platform(struct of_device* dev, const struct of_match *match)
{
return create_iface(dev->node, &dev->dev);
}
static int
dispose_iface_of_platform(struct of_device* dev)
{
return dispose_iface(&dev->dev);
}
static struct of_match i2c_keywest_match[] =
{
{
.name = OF_ANY_MATCH,
.type = "i2c",
.compatible = "keywest"
},
{},
};
static struct macio_driver i2c_keywest_macio_driver =
{
.name = "i2c-keywest",
.match_table = i2c_keywest_match,
.probe = create_iface_macio,
.remove = dispose_iface_macio
};
static struct of_platform_driver i2c_keywest_of_platform_driver =
{
.name = "i2c-keywest",
.match_table = i2c_keywest_match,
.probe = create_iface_of_platform,
.remove = dispose_iface_of_platform
};
static int __init static int __init
i2c_keywest_init(void) i2c_keywest_init(void)
{ {
struct device_node *np; int rc;
int rc = -ENODEV;
rc = macio_register_driver(&i2c_keywest_macio_driver);
np = find_compatible_devices("i2c", "keywest"); rc |= of_register_driver(&i2c_keywest_of_platform_driver);
while (np != 0) {
if (np->n_addrs >= 1 && np->n_intrs >= 1) return (rc == 0) ? 0 : -ENODEV;
rc = create_iface(np);
np = np->next;
}
if (ifaces)
rc = 0;
return rc;
} }
static void __exit static void __exit
i2c_keywest_cleanup(void) i2c_keywest_cleanup(void)
{ {
while(ifaces) macio_unregister_driver(&i2c_keywest_macio_driver);
dispose_iface(ifaces); of_unregister_driver(&i2c_keywest_of_platform_driver);
} }
module_init(i2c_keywest_init); module_init(i2c_keywest_init);
......
...@@ -67,7 +67,6 @@ struct keywest_iface ...@@ -67,7 +67,6 @@ struct keywest_iface
int stopretry; int stopretry;
struct timer_list timeout_timer; struct timer_list timeout_timer;
struct completion complete; struct completion complete;
struct keywest_iface* next;
}; };
enum { enum {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment