public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Samuel Ortiz <sameo@linux.intel.com>
To: Mike Frysinger <vapier@gentoo.org>
Cc: linux-kernel@vger.kernel.org,
	uclinux-dist-devel@blackfin.uclinux.org,
	Michael Hennerich <michael.hennerich@analog.com>,
	Bryan Wu <cooloney@kernel.org>
Subject: Re: [PATCH v2] mfd: ADP5520 Multifunction LCD Backlight and Keypad Input Device Driver
Date: Thu, 1 Oct 2009 16:09:49 +0200	[thread overview]
Message-ID: <20091001140948.GD10199@sortiz.org> (raw)
In-Reply-To: <1253682664-27040-1-git-send-email-vapier@gentoo.org>

Hi Mike,

Some comments on this patch:

On Wed, Sep 23, 2009 at 01:11:04AM -0400, Mike Frysinger wrote:
> From: Michael Hennerich <michael.hennerich@analog.com>
> 
> Base driver for Analog Devices ADP5520/ADP5501 MFD PMICs
> 
> Subdevs:
> LCD Backlight   : drivers/video/backlight/adp5520_bl
> LEDs            : drivers/led/leds-adp5520
> GPIO            : drivers/gpio/adp5520-gpio (ADP5520 only)
> Keys            : drivers/input/keyboard/adp5520-keys (ADP5520 only)
> 
> Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
> Signed-off-by: Bryan Wu <cooloney@kernel.org>
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
> v2
> 	- fix return type of irq handler
> 	- fix unbalanced paren in BL_CTRL_VAL() macro
> 
>  drivers/mfd/Kconfig         |   10 ++
>  drivers/mfd/Makefile        |    1 +
>  drivers/mfd/adp5520.c       |  371 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/adp5520.h |  303 +++++++++++++++++++++++++++++++++++
>  4 files changed, 685 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mfd/adp5520.c
>  create mode 100644 include/linux/mfd/adp5520.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 570be13..34e8595 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -160,6 +160,16 @@ config PMIC_DA903X
>  	  individual components like LCD backlight, voltage regulators,
>  	  LEDs and battery-charger under the corresponding menus.
>  
> +config PMIC_ADP5520
> +	bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
> +	depends on I2C=y
> +	help
> +	  Say yes here to add support for Analog Devices AD5520 and ADP5501,
> +	  Multifunction Power Management IC. This includes
> +	  the I2C driver and the core APIs _only_, you have to select
> +	  individual components like LCD backlight, LEDs, GPIOs and Kepad
> +	  under the corresponding menus.
> +
>  config MFD_WM8400
>  	tristate "Support Wolfson Microelectronics WM8400"
>  	select MFD_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f3b277b..a42248e 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -50,3 +50,4 @@ obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-adc.o
>  obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-gpio.o
>  obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
>  obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
> +obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
> diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
> new file mode 100644
> index 0000000..1083626
> --- /dev/null
> +++ b/drivers/mfd/adp5520.c
> @@ -0,0 +1,371 @@
> +/*
> + * Base driver for Analog Devices ADP5520/ADP5501 MFD PMICs
> + * LCD Backlight: drivers/video/backlight/adp5520_bl
> + * LEDs		: drivers/led/leds-adp5520
> + * GPIO		: drivers/gpio/adp5520-gpio (ADP5520 only)
> + * Keys		: drivers/input/keyboard/adp5520-keys (ADP5520 only)
> + *
> + * Copyright 2009 Analog Devices Inc.
> + *
> + * Derived from da903x:
> + * Copyright (C) 2008 Compulab, Ltd.
> + * 	Mike Rapoport <mike@compulab.co.il>
> + *
> + * Copyright (C) 2006-2008 Marvell International Ltd.
> + * 	Eric Miao <eric.miao@marvell.com>
> + *
> + * Licensed under the GPL-2 or later.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/workqueue.h>
> +#include <linux/i2c.h>
> +
> +#include <linux/mfd/adp5520.h>
> +
> +struct adp5520_chip {
> +	struct i2c_client *client;
> +	struct device *dev;
> +	struct mutex lock;
> +	struct work_struct irq_work;
> +	struct blocking_notifier_head notifier_list;
> +	int irq;
> +};
> +
> +static int __adp5520_read(struct i2c_client *client,
> +				int reg, uint8_t *val)
> +{
> +	int ret;
> +
> +	ret = i2c_smbus_read_byte_data(client, reg);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
> +		return ret;
> +	}
> +
> +	*val = (uint8_t)ret;
> +	return 0;
> +}
> +
> +static int __adp5520_write(struct i2c_client *client,
> +				 int reg, uint8_t val)
> +{
> +	int ret;
> +
> +	ret = i2c_smbus_write_byte_data(client, reg, val);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
> +				val, reg);
> +		return ret;
> +	}
> +	return 0;
> +}
> +
> +int __adp5520_ack_bits(struct i2c_client *client, int reg, uint8_t bit_mask)
> +{
> +	struct adp5520_chip *chip = i2c_get_clientdata(client);
> +	uint8_t reg_val;
> +	int ret;
> +
> +	mutex_lock(&chip->lock);
> +
> +	ret = __adp5520_read(client, reg, &reg_val);
> +
> +	if (!ret) {
> +		reg_val |= bit_mask;
> +		ret = __adp5520_write(client, reg, reg_val);
> +	}
> +
> +	mutex_unlock(&chip->lock);
> +	return ret;
> +}
> +
> +int adp5520_write(struct device *dev, int reg, uint8_t val)
> +{
> +	return __adp5520_write(to_i2c_client(dev), reg, val);
> +}
> +EXPORT_SYMBOL_GPL(adp5520_write);
> +
> +int adp5520_read(struct device *dev, int reg, uint8_t *val)
> +{
> +	return __adp5520_read(to_i2c_client(dev), reg, val);
> +}
> +EXPORT_SYMBOL_GPL(adp5520_read);
> +
> +int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask)
> +{
> +	struct adp5520_chip *chip = dev_get_drvdata(dev);
> +	uint8_t reg_val;
> +	int ret;
> +
> +	mutex_lock(&chip->lock);
> +
> +	ret = __adp5520_read(chip->client, reg, &reg_val);
> +
> +	if (!ret && ((reg_val & bit_mask) == 0)) {
> +		reg_val |= bit_mask;
> +		ret = __adp5520_write(chip->client, reg, reg_val);
> +	}
> +
> +	mutex_unlock(&chip->lock);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(adp5520_set_bits);
> +
> +int adp5520_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
> +{
> +	struct adp5520_chip *chip = dev_get_drvdata(dev);
> +	uint8_t reg_val;
> +	int ret;
> +
> +	mutex_lock(&chip->lock);
> +
> +	ret = __adp5520_read(chip->client, reg, &reg_val);
> +
> +	if (!ret && (reg_val & bit_mask)) {
> +		reg_val &= ~bit_mask;
> +		ret = __adp5520_write(chip->client, reg, reg_val);
> +	}
> +
> +	mutex_unlock(&chip->lock);
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(adp5520_clr_bits);
> +
> +int adp5520_register_notifier(struct device *dev, struct notifier_block *nb,
> +				unsigned int events)
> +{
> +	struct adp5520_chip *chip = dev_get_drvdata(dev);
> +
> +	if (chip->irq) {
> +		adp5520_set_bits(chip->dev, INTERRUPT_ENABLE,
> +			events & (KP_IEN | KR_IEN | OVP_IEN | CMPR_IEN));
> +
> +		return blocking_notifier_chain_register(&chip->notifier_list,
> +			 nb);
> +	}
> +
> +	return -ENODEV;
> +}
> +EXPORT_SYMBOL_GPL(adp5520_register_notifier);
> +
> +int adp5520_unregister_notifier(struct device *dev, struct notifier_block *nb,
> +				unsigned int events)
> +{
> +	struct adp5520_chip *chip = dev_get_drvdata(dev);
> +
> +	adp5520_clr_bits(chip->dev, INTERRUPT_ENABLE,
> +		events & (KP_IEN | KR_IEN | OVP_IEN | CMPR_IEN));
> +
> +	return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
> +}
> +EXPORT_SYMBOL_GPL(adp5520_unregister_notifier);
> +
> +static void adp5520_irq_work(struct work_struct *work)
> +{
> +	struct adp5520_chip *chip =
> +		container_of(work, struct adp5520_chip, irq_work);
> +	unsigned int events;
> +	uint8_t reg_val;
> +	int ret;
> +
> +	ret = __adp5520_read(chip->client, MODE_STATUS, &reg_val);
> +	if (ret)
> +		goto out;
> +
> +	events =  reg_val & (OVP_INT | CMPR_INT | GPI_INT | KR_INT | KP_INT);
> +
> +	blocking_notifier_call_chain(&chip->notifier_list, events, NULL);
> +	/* ACK, Sticky bits are W1C */
> +	__adp5520_ack_bits(chip->client, MODE_STATUS, events);
> +
> +out:
> +	enable_irq(chip->client->irq);
> +}
> +
> +static irqreturn_t adp5520_irq_handler(int irq, void *data)
> +{
> +	struct adp5520_chip *chip = data;
> +
> +	disable_irq_nosync(irq);
> +	schedule_work(&chip->irq_work);
Have you considered using a threaded irq handler here ?


> +	return IRQ_HANDLED;
> +}
> +
> +static int __remove_subdev(struct device *dev, void *unused)
> +{
> +	platform_device_unregister(to_platform_device(dev));
> +	return 0;
> +}
> +
> +static int adp5520_remove_subdevs(struct adp5520_chip *chip)
> +{
> +	return device_for_each_child(chip->dev, NULL, __remove_subdev);
> +}
> +
> +static int __devinit adp5520_add_subdevs(struct adp5520_chip *chip,
> +					struct adp5520_platform_data *pdata)
> +{
> +	struct adp5520_subdev_info *subdev;
> +	struct platform_device *pdev;
> +	int i, ret = 0;
> +
> +	for (i = 0; i < pdata->num_subdevs; i++) {
> +		subdev = &pdata->subdevs[i];
> +
> +		pdev = platform_device_alloc(subdev->name, subdev->id);
> +
> +		pdev->dev.parent = chip->dev;
> +		pdev->dev.platform_data = subdev->platform_data;
> +
> +		ret = platform_device_add(pdev);
> +		if (ret)
> +			goto failed;
> +	}
> +	return 0;
Here I would expect the MFD core driver to know about all the potential
subdevices and add them in that routine, and not take the subdevices list from
the platform definition.
I realize da903x has the same issue btw.

Also, please note that you could use the mfd-core API for adding devices, but
that's just optional.

Cheers,
Samuel.

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

  parent reply	other threads:[~2009-10-01 14:08 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-17 18:27 [PATCH] mfd: ADP5520 Multifunction LCD Backlight and Keypad Input Device Driver Mike Frysinger
2009-09-23  5:11 ` [PATCH v2] " Mike Frysinger
2009-09-29 21:04   ` [Uclinux-dist-devel] " Mike Frysinger
2009-09-29 21:14     ` Andrew Morton
2009-09-29 21:19       ` Mike Frysinger
2009-09-29 21:31       ` Samuel Ortiz
2009-09-29 21:19   ` Andrew Morton
2009-09-29 21:57     ` Hennerich, Michael
2009-10-01 14:09   ` Samuel Ortiz [this message]
2009-10-02  9:38     ` Hennerich, Michael
2009-10-02 13:15       ` Samuel Ortiz
2009-10-02 14:39         ` Hennerich, Michael
2009-10-02 13:48       ` [Uclinux-dist-devel] [PATCH v2] mfd: ADP5520 Multifunction LCDBacklight " Hennerich, Michael
2009-10-02 14:05         ` Samuel Ortiz
2009-10-02 14:27         ` Mark Brown
2009-10-02 14:37           ` [Uclinux-dist-devel] [PATCH v2] mfd: ADP5520 MultifunctionLCDBacklight " Hennerich, Michael
2009-10-02 14:38             ` Mark Brown
2009-10-02 15:24               ` [Uclinux-dist-devel] [PATCH v2] mfd: ADP5520MultifunctionLCDBacklight " Hennerich, Michael
2009-10-06  7:44   ` [PATCH v3] mfd: ADP5520 Multifunction LCD Backlight " Mike Frysinger
2009-10-06 11:55     ` Mark Brown
2009-10-06 12:23       ` [PATCH v3] mfd: ADP5520 Multifunction LCD Backlight and KeypadInput " Hennerich, Michael
2009-10-06 12:36         ` Mark Brown
2009-10-06 12:55           ` Hennerich, Michael
2009-10-06 13:58             ` Mark Brown
2009-10-06 14:32               ` Hennerich, Michael
2009-10-06 14:48                 ` Mark Brown
2009-10-06 15:05                   ` Hennerich, Michael
2009-10-06 16:05                     ` Mark Brown
2009-10-07  8:50                       ` Hennerich, Michael
2009-10-07 10:06                         ` Mark Brown
2009-10-07 12:11                           ` Hennerich, Michael
2009-10-07 13:03                             ` Mark Brown
2009-10-07 13:01                           ` Hennerich, Michael
2009-10-07 13:19                             ` Mark Brown
2009-10-07 13:35                               ` Hennerich, Michael

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091001140948.GD10199@sortiz.org \
    --to=sameo@linux.intel.com \
    --cc=cooloney@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.hennerich@analog.com \
    --cc=uclinux-dist-devel@blackfin.uclinux.org \
    --cc=vapier@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox