Index: git/drivers/mfd/tps6507x.c =================================================================== --- git.orig/drivers/mfd/tps6507x.c 2010-01-12 08:43:00.961383768 -0600 +++ git/drivers/mfd/tps6507x.c 2010-01-12 08:52:41.725819096 -0600 @@ -57,12 +57,40 @@ return 0; } +/* + * Register a client device. This is non-fatal since there is no need to + * fail the entire device init due to a single platform device failing. + */ +static void tps6507x_client_dev_register(struct tps6507x_dev *tps6507x, + const char *name, + struct platform_device **pdev) +{ + int ret; + + *pdev = platform_device_alloc(name, -1); + if (*pdev == NULL) { + dev_err(tps6507x->dev, "Failed to allocate %s\n", name); + return; + } + + (*pdev)->dev.parent = tps6507x->dev; + platform_set_drvdata(*pdev, tps6507x); + ret = platform_device_add(*pdev); + if (ret != 0) { + dev_err(tps6507x->dev, "Failed to register %s: %d\n", name, ret); + platform_device_put(*pdev); + *pdev = NULL; + } +} int tps6507x_device_init(struct tps6507x_dev *tps6507x, int irq, struct tps6507x_board *pdata) { int ret = 0; + struct platform_device *pdev; + tps6507x_client_dev_register(tps6507x, "tps6507x-pmic", + &pdev); return ret; } @@ -71,7 +99,6 @@ { struct tps6507x_dev *tps6507x; int ret = 0; - tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL); if (tps6507x == NULL) { kfree(i2c); Index: git/drivers/regulator/tps6507x-regulator.c =================================================================== --- git.orig/drivers/regulator/tps6507x-regulator.c 2010-01-12 08:43:01.125399079 -0600 +++ git/drivers/regulator/tps6507x-regulator.c 2010-01-12 08:53:16.586248235 -0600 @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -105,9 +104,47 @@ unsigned reg_high:1; }; +static const struct tps_info tps6507x_pmic_regs[] = { + { + .name = "VDCDC1", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC3", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO1_VSEL_table), + .table = LDO1_VSEL_table, + }, + { + .name = "LDO2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO2_VSEL_table), + .table = LDO2_VSEL_table, + }, +}; + struct tps_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; - struct i2c_client *client; + struct tps6507x_dev *mfd; struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; struct tps_info *info[TPS6507X_NUM_REGULATOR]; struct mutex io_lock; @@ -115,12 +152,21 @@ static inline int tps6507x_pmic_read(struct tps_pmic *tps, u8 reg) { - return i2c_smbus_read_byte_data(tps->client, reg); + u8 val; + int err; + + err = tps->mfd->read_dev(tps->mfd, reg, 1, &val); + + if (err) { + return err; + } + + return val; } static inline int tps6507x_pmic_write(struct tps_pmic *tps, u8 reg, u8 val) { - return i2c_smbus_write_byte_data(tps->client, reg, val); + return tps->mfd->write_dev(tps->mfd, reg, 1, &val); } static int tps6507x_pmic_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) @@ -131,7 +177,7 @@ data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -139,7 +185,7 @@ data |= mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -154,7 +200,7 @@ data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -162,7 +208,7 @@ data &= ~mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -177,7 +223,7 @@ data = tps6507x_pmic_read(tps, reg); if (data < 0) - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return data; @@ -191,7 +237,7 @@ err = tps6507x_pmic_write(tps, reg, val); if (err < 0) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return err; @@ -494,27 +540,24 @@ .list_voltage = tps6507x_pmic_ldo_list_voltage, }; -static -int tps6507x_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) +static __devinit +int tps6507x_pmic_probe(struct platform_device *pdev) { + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); static int desc_id; - struct tps_info *info = (void *)id->driver_data; + struct tps_info *info = &tps6507x_pmic_regs[0]; struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps_pmic *tps; - struct tps6507x_board *tps_board; + struct tps6507x_board *tps_board; int i; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) - return -EIO; - /** - * tps_board points to tps6507x related constants + * tps_board points to pmic related constants * coming from the board-evm file. */ - tps_board = (struct tps6507x_board *)client->dev.platform_data; + tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; if (!tps_board) return -EIO; @@ -536,7 +579,7 @@ mutex_init(&tps->io_lock); /* common for all regulators */ - tps->client = client; + tps->mfd = tps6507x_dev; for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { /* Register the regulators */ @@ -551,19 +594,16 @@ tps->desc[i].owner = THIS_MODULE; rdev = regulator_register(&tps->desc[i], - &client->dev, init_data, tps); + tps6507x_dev->dev, init_data, tps); if (IS_ERR(rdev)) { - dev_err(&client->dev, "failed to register %s\n", - id->name); + dev_err(tps6507x_dev->dev, "failed to register %s regulator\n", + pdev->name); /* Unregister */ while (i) regulator_unregister(tps->rdev[--i]); - tps->client = NULL; - - /* clear the client data in i2c */ - i2c_set_clientdata(client, NULL); + tps->mfd = NULL; kfree(tps); return PTR_ERR(rdev); @@ -573,87 +613,34 @@ tps->rdev[i] = rdev; } - i2c_set_clientdata(client, tps); +// tps6507x_dev->pmic.pdev = pdev; // XXXX - but tps6507x_dev is pdev !!! return 0; } -/** - * tps6507x_remove - TPS6507x driver i2c remove handler - * @client: i2c driver client device structure - * - * Unregister TPS driver as an i2c client device driver - */ -static int __devexit tps6507x_pmic_remove(struct i2c_client *client) +static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) { - struct tps_pmic *tps = i2c_get_clientdata(client); + + struct tps_pmic *tps = platform_get_drvdata(pdev); //REVISIT this is wrong int i; for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); - tps->client = NULL; + tps->mfd = NULL; - /* clear the client data in i2c */ - i2c_set_clientdata(client, NULL); kfree(tps); return 0; } -static const struct tps_info tps6507x_pmic_regs[] = { - { - .name = "VDCDC1", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC3", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO1_VSEL_table), - .table = LDO1_VSEL_table, - }, - { - .name = "LDO2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO2_VSEL_table), - .table = LDO2_VSEL_table, - }, -}; - -static const struct i2c_device_id tps6507x_pmic_id[] = { - {.name = "tps6507x", - .driver_data = (unsigned long) tps6507x_pmic_regs,}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); - -static struct i2c_driver tps6507x_i2c_driver = { +static struct platform_driver tps6507x_pmic_driver = { .driver = { - .name = "tps6507x", + .name = "tps6507x-pmic", .owner = THIS_MODULE, }, .probe = tps6507x_pmic_probe, .remove = __devexit_p(tps6507x_pmic_remove), - .id_table = tps6507x_pmic_id, }; /** @@ -663,7 +650,7 @@ */ static int __init tps6507x_pmic_init(void) { - return i2c_add_driver(&tps6507x_i2c_driver); + return platform_driver_register(&tps6507x_pmic_driver); } subsys_initcall(tps6507x_pmic_init); @@ -674,10 +661,11 @@ */ static void __exit tps6507x_pmic_cleanup(void) { - i2c_del_driver(&tps6507x_i2c_driver); + platform_driver_unregister(&tps6507x_pmic_driver); } module_exit(tps6507x_pmic_cleanup); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps6507x-pmic"); Index: git/include/linux/mfd/tps6507x.h =================================================================== --- git.orig/include/linux/mfd/tps6507x.h 2010-01-12 08:43:00.961383768 -0600 +++ git/include/linux/mfd/tps6507x.h 2010-01-12 08:52:41.753688570 -0600 @@ -156,10 +156,13 @@ struct device *dev; struct i2c_client *i2c_client; int (*read_dev)(struct tps6507x_dev *tps6507x, char reg, int size, - void *dest); + void *dest); int (*write_dev)(struct tps6507x_dev *tps6507x, char reg, int size, - void *src); + void *src); struct mutex adc_mutex; + + /* Client devices */ + struct tps6507x_pmic *pmic; }; #endif /* __LINUX_MFD_TPS6507X_H */