[PATCH v2 02/09] mfd: support 88pm8606 in 860x driver

Samuel Ortiz sameo at linux.intel.com
Thu Dec 10 05:35:58 EST 2009


Hi Haojian,

On Wed, Dec 09, 2009 at 08:11:22AM -0500, Haojian Zhuang wrote:
> 
> Now share one driver to these two devices. Only one I2C client is identified
> in platform init data. If another chip is also used, user should mark it in
> companion_addr field of platform init data. Then driver could create another
> I2C client for the companion chip.
> 
> All I2C operations are accessed by 860x-i2c driver. In order to support both
> I2C client address, the read/write API is changed in below.
The code looks better now. I still have a few comments though:

> -static inline int pm8607_read_device(struct pm8607_chip *chip,
> +static struct mutex io_lock;
Why do we need a static lock here ?

> +int pm860x_reg_read(struct i2c_client *i2c, int reg)
>  {
>  	unsigned char data;
>  	int ret;
> 
> -	mutex_lock(&chip->io_lock);
> -	ret = chip->read(chip, reg, 1, &data);
> -	mutex_unlock(&chip->io_lock);
> +	mutex_lock(&io_lock);
Why not keep mutex_unlock(&chip->io_lock); where chip is
i2c_get_clientdata(i2c) ?

>  static int __devinit pm860x_probe(struct i2c_client *client,
>  				  const struct i2c_device_id *id)
>  {
> -	struct pm8607_platform_data *pdata = client->dev.platform_data;
> -	struct pm8607_chip *chip;
> +	struct pm860x_platform_data *pdata = client->dev.platform_data;
> +	struct pm860x_chip *chip;
> +	struct i2c_board_info i2c_info = {
> +		.type		= "88PM860x",
> +		.platform_data	= client->dev.platform_data,
I dont think you want to use the same platform_data. At least you want to
reset the companion_addr field.


> +	};
> +	int addr_c, found_companion = 0;
>  	int ret;
> 
> -	chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
> -	if (chip == NULL)
> -		return -ENOMEM;
> -
> -	chip->client = client;
> -	chip->dev = &client->dev;
> -	chip->read = pm8607_read_device;
> -	chip->write = pm8607_write_device;
> -	memcpy(&chip->id, id, sizeof(struct i2c_device_id));
> -	i2c_set_clientdata(client, chip);
> -
> -	mutex_init(&chip->io_lock);
> -	dev_set_drvdata(chip->dev, chip);
> -
> -	ret = pm860x_device_init(chip, pdata);
> -	if (ret < 0)
> -		goto out;
> -
> +	if (pdata == NULL) {
> +		pr_info("No platform data in %s!\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	addr_c = pdata->companion_addr;
> +	if (addr_c && (addr_c != client->addr)) {
> +		i2c_info.addr = addr_c;
> +		found_companion = 1;
> +	}
> +
> +	if (found_companion || (addr_c == 0)) {
You probably dont need that check here.


> +		chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
> +		if (chip == NULL)
> +			return -ENOMEM;
> +
> +		chip->id = verify_addr(client);
> +		chip->client = client;
> +		i2c_set_clientdata(client, chip);
> +		chip->dev = &client->dev;
> +		mutex_init(&io_lock);
> +		dev_set_drvdata(chip->dev, chip);
> +
> +		if (found_companion) {
> +			chip->companion = i2c_new_device(client->adapter,
> +							 &i2c_info);
> +			i2c_set_clientdata(chip->companion, chip);
> +		}
I guess you've tested that code. I have a question: After returning from
i2c_new_device(), I'd expect pm860x_probe() to be called as the companion chip
is bound. Isnt that that the case ?

Cheers,
Samuel.
-- 
Intel Open Source Technology Centre
http://oss.intel.com/



More information about the linux-arm-kernel mailing list