All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
To: Qiao Zhou <zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
Cc: "broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org"
	<broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>,
	"rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org"
	<rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org>,
	"sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org"
	<sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	"haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org"
	<haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Chao Xie <cxie4-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>,
	Yu Tang <ytang5-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>,
	Wilbur Wang <wwang27-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>,
	"linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org"
	<linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org>,
	"linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: Re: [PATCH 1/4] mfd: support 88pm80x in 80x driver
Date: Wed, 4 Jul 2012 15:27:13 +0000	[thread overview]
Message-ID: <201207041527.13954.arnd@arndb.de> (raw)
In-Reply-To: <B2A7C617B3AB7F44B7B44C7D374B431E13A09E8DEE-PBXNphkCnnUA/4UcAFAujRL4W9x8LtSr@public.gmane.org>

On Wednesday 04 July 2012, Qiao Zhou wrote:
> >> +	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
> >> +			      ARRAY_SIZE(onkey_devs), &onkey_resources[0],
> >> +			      chip->irq_base);
> >
> >According to what I discussed with Mark in the previous version, I think you
> >need to pass 0 instead of chip->irq_base here, and transform the interrupt
> >numbers using the domain in the client drivers.
> >
> >> +
> >> +const struct i2c_device_id pm80x_id_table[] = {
> >> +	{"88PM800", CHIP_PM800},
> >> +	{"88PM805", CHIP_PM805},
> >> +};
> >> +MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
> >
> >Since these are separate modules now, you have to move the device table
> >into the split files as well.
> Is it ok to export it in 88pm80x.h?

You mean putting the MODULE_DEVICE_TABLE() into 88pm80x.h? No, that would
not work.

The correct way is to have two MODULE_DEVICE_TABLE statements, one per file.
Actually the table only makes sense for loadable modules, so if you decide
to keep the driver only built-in, it's best to just drop this table.

> >> +
> >> +/**
> >> + * pm80x_reg_read: Read a single 88PM80x register.
> >> + *
> >> + * @map: regmap to read from.
> >> + * @reg: Register to read.
> >> + */
> >> +int pm80x_reg_read(struct regmap *map, u32 reg)
> >> +{
> >> +	unsigned int val;
> >> +	int ret;
> >> +
> >> +	ret = regmap_read(map, reg, &val);
> >> +
> >> +	if (ret < 0)
> >> +		return ret;
> >> +	else
> >> +		return val;
> >> +}
> >> +EXPORT_SYMBOL_GPL(pm80x_reg_read);
> >
> >In your introductory email you write
> >
> >"Exported r/w API which requires regmap handle. as currently the pm800
> >chip has 3 i2c device, only passing a pm80x_chip info can't ensure r/w the
> >register in correct i2c device."
> >
> >Your first driver version had this, then you removed the functions
> >after I asked you to, and now they are back, so I assume there is something
> >I don't see yet. It looks like the function is just an unnecessary wrapper
> >that is better open-coded in the caller. Can you explain again what the
> >difference is?
>
> After you suggest to change the r/w API so that caller doesn't care about it's
> via i2c or spi, it makes sense. However due to pm800 has 3 i2c devices, and
> it's hard to export such interface for pm800. Currently to add such interface
> via regmap handle, caller still doesn't care about the actual hw implement,
> also it's clear that all pm80x sub-driver or plat call the unified r/w API.

But there is nothing unified about the function above, it just calls
regmap_read(), so the caller already has access to the regmap pointer.

> >> +/**
> >> + * pm80x_bulk_read: Read multiple 88PM80x registers
> >> + *
> >> + * @map: regmap to read from
> >> + * @reg: First register
> >> + * @buf: Buffer to fill.  The data will be returned big endian.
> >> + * @count: Number of registers
> >> + */
> >> +int pm80x_bulk_read(struct regmap *map, u32 reg, u8 *buf, int count)
> >> +{
> >> +	return regmap_raw_read(map, reg, buf, count);
> >> +}
> >
> >Unused function? Either export this if you want to provide it as
> >the general API, or drop the function.
> It's used by rtc driver.

Then it needs to be exported, so the rtc driver can be a module.


> >
> >I would still argue that the majority of the constants in this file
> >should get moved into the driver .c file that uses them. Putting them
> >into the header is better done only for interfaces between the
> >driver parts, and for constants that are used by multiple drivers.
>
> These registers still in this header file are either used by mfd core
> driver, regulator/rtc/onkey/codec, or used in platform initial setting.

Exactly. All the values that are only used by the core driver should be
part of the core driver (or a local header in the mfd directory if they
need to be shared between multiple files). The platform code should not
really touch the registers, but only things like the platform_data
structure, which indeed belongs into the global header.

> >> +struct pm80x_subchip {
> >> +	struct i2c_client *power_page;	/* chip client for power page */
> >> +	struct i2c_client *gpadc_page;	/* chip client for gpadc page */
> >> +	struct regmap *regmap_power;
> >> +	struct regmap *regmap_gpadc;
> >> +	unsigned short power_page_addr;	/* power page I2C address */
> >> +	unsigned short gpadc_page_addr;	/* gpadc page I2C address */
> >> +};
> >> +
> >> +struct pm80x_chip {
> >> +	struct pm80x_subchip *subchip;
> >> +	struct device *dev;
> >> +	struct i2c_client *client;
> >> +	struct regmap *regmap;
> >> +	struct regmap_irq_chip *regmap_irq_chip;
> >> +	struct regmap_irq_chip_data *irq_data;
> >> +	unsigned char version;
> >> +	int id;
> >> +	int irq;
> >> +	int irq_mode;
> >> +	int irq_base;
> >> +	unsigned int wu_flag;
> >> +};
> >
> >One thing I forgot to ask in the previous review although I had already
> >noticed it then: What is the separation of pm80x_chip and pm80x_subchip
> >used for?
> Pm80x_chip is common for both pm800 and pm805, while pm80x_subchip
> handles the other i2c devices as discussed before, only that these two
> i2c devices are not as much as pm800 and pm805 i2c device, and they are
> only for gpadc & power settings purpose. The subchip can be treated as
> some special feature/function for pm800.

ok

> >> +struct pm80x_rtc_pdata {
> >> +	int		vrtc;
> >> +	int		rtc_wakeup;
> >> +};
> >> +
> >> +struct pm80x_platform_data {
> >> +	struct pm80x_rtc_pdata *rtc;
> >> +	unsigned short pm800_addr;
> >> +	unsigned short pm805_addr;
> >> +	unsigned short power_page_addr;	/* power page I2C address */
> >> +	unsigned short gpadc_page_addr;	/* gpadc page I2C address */
> >> +	int irq_mode;		/* Clear interrupt by read/write(0/1) */
> >> +	int irq_base;		/* IRQ base of chip */
> >> +	int batt_det;		/* enable/disable */
> >> +};
> >
> >You removed the callback here as I asked you to, which I think is a useful
> >cleanup, but you can actually managed to convinced me that it would be ok
> >to have it, so I don't mind if you want to put it back and use auxdata.
> Actually it's convenient for us to put it back currently, and would use
> auxdata instead.

ok

> >On the other hand, I think it probably makes sense to drop the irq_base
> >member in this struct and rely on irq domains to allocate them dynamically
> >as mentioned before.
> Do you mean that both regmap_add_irq_chip and mfd_add_devices api pass -1 as
> the irq_base, so that system can dynamically allocate the irq_base for it?

regmap_add_irq_chip should pass -1, mfd_add_devices should pass 0.
Mark can probably correct me if that's wrong.

> Given the proper regmap_irq_chip & device resource, is there anything else
> needed? As I don't want to miss the exact meaning of " transform the
> interrupt numbers using the domain in the client drivers" you mentioned above.

The drivers using the numbers need to call regmap_irq_get_virq() to get the
real interrupt number. See include/linux/mfd/wm8994/core.h for an example.

	Arnd

WARNING: multiple messages have this Message-ID (diff)
From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4] mfd: support 88pm80x in 80x driver
Date: Wed, 4 Jul 2012 15:27:13 +0000	[thread overview]
Message-ID: <201207041527.13954.arnd@arndb.de> (raw)
In-Reply-To: <B2A7C617B3AB7F44B7B44C7D374B431E13A09E8DEE@sc-vexch3.marvell.com>

On Wednesday 04 July 2012, Qiao Zhou wrote:
> >> +	ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
> >> +			      ARRAY_SIZE(onkey_devs), &onkey_resources[0],
> >> +			      chip->irq_base);
> >
> >According to what I discussed with Mark in the previous version, I think you
> >need to pass 0 instead of chip->irq_base here, and transform the interrupt
> >numbers using the domain in the client drivers.
> >
> >> +
> >> +const struct i2c_device_id pm80x_id_table[] = {
> >> +	{"88PM800", CHIP_PM800},
> >> +	{"88PM805", CHIP_PM805},
> >> +};
> >> +MODULE_DEVICE_TABLE(i2c, pm80x_id_table);
> >
> >Since these are separate modules now, you have to move the device table
> >into the split files as well.
> Is it ok to export it in 88pm80x.h?

You mean putting the MODULE_DEVICE_TABLE() into 88pm80x.h? No, that would
not work.

The correct way is to have two MODULE_DEVICE_TABLE statements, one per file.
Actually the table only makes sense for loadable modules, so if you decide
to keep the driver only built-in, it's best to just drop this table.

> >> +
> >> +/**
> >> + * pm80x_reg_read: Read a single 88PM80x register.
> >> + *
> >> + * @map: regmap to read from.
> >> + * @reg: Register to read.
> >> + */
> >> +int pm80x_reg_read(struct regmap *map, u32 reg)
> >> +{
> >> +	unsigned int val;
> >> +	int ret;
> >> +
> >> +	ret = regmap_read(map, reg, &val);
> >> +
> >> +	if (ret < 0)
> >> +		return ret;
> >> +	else
> >> +		return val;
> >> +}
> >> +EXPORT_SYMBOL_GPL(pm80x_reg_read);
> >
> >In your introductory email you write
> >
> >"Exported r/w API which requires regmap handle. as currently the pm800
> >chip has 3 i2c device, only passing a pm80x_chip info can't ensure r/w the
> >register in correct i2c device."
> >
> >Your first driver version had this, then you removed the functions
> >after I asked you to, and now they are back, so I assume there is something
> >I don't see yet. It looks like the function is just an unnecessary wrapper
> >that is better open-coded in the caller. Can you explain again what the
> >difference is?
>
> After you suggest to change the r/w API so that caller doesn't care about it's
> via i2c or spi, it makes sense. However due to pm800 has 3 i2c devices, and
> it's hard to export such interface for pm800. Currently to add such interface
> via regmap handle, caller still doesn't care about the actual hw implement,
> also it's clear that all pm80x sub-driver or plat call the unified r/w API.

But there is nothing unified about the function above, it just calls
regmap_read(), so the caller already has access to the regmap pointer.

> >> +/**
> >> + * pm80x_bulk_read: Read multiple 88PM80x registers
> >> + *
> >> + * @map: regmap to read from
> >> + * @reg: First register
> >> + * @buf: Buffer to fill.  The data will be returned big endian.
> >> + * @count: Number of registers
> >> + */
> >> +int pm80x_bulk_read(struct regmap *map, u32 reg, u8 *buf, int count)
> >> +{
> >> +	return regmap_raw_read(map, reg, buf, count);
> >> +}
> >
> >Unused function? Either export this if you want to provide it as
> >the general API, or drop the function.
> It's used by rtc driver.

Then it needs to be exported, so the rtc driver can be a module.


> >
> >I would still argue that the majority of the constants in this file
> >should get moved into the driver .c file that uses them. Putting them
> >into the header is better done only for interfaces between the
> >driver parts, and for constants that are used by multiple drivers.
>
> These registers still in this header file are either used by mfd core
> driver, regulator/rtc/onkey/codec, or used in platform initial setting.

Exactly. All the values that are only used by the core driver should be
part of the core driver (or a local header in the mfd directory if they
need to be shared between multiple files). The platform code should not
really touch the registers, but only things like the platform_data
structure, which indeed belongs into the global header.

> >> +struct pm80x_subchip {
> >> +	struct i2c_client *power_page;	/* chip client for power page */
> >> +	struct i2c_client *gpadc_page;	/* chip client for gpadc page */
> >> +	struct regmap *regmap_power;
> >> +	struct regmap *regmap_gpadc;
> >> +	unsigned short power_page_addr;	/* power page I2C address */
> >> +	unsigned short gpadc_page_addr;	/* gpadc page I2C address */
> >> +};
> >> +
> >> +struct pm80x_chip {
> >> +	struct pm80x_subchip *subchip;
> >> +	struct device *dev;
> >> +	struct i2c_client *client;
> >> +	struct regmap *regmap;
> >> +	struct regmap_irq_chip *regmap_irq_chip;
> >> +	struct regmap_irq_chip_data *irq_data;
> >> +	unsigned char version;
> >> +	int id;
> >> +	int irq;
> >> +	int irq_mode;
> >> +	int irq_base;
> >> +	unsigned int wu_flag;
> >> +};
> >
> >One thing I forgot to ask in the previous review although I had already
> >noticed it then: What is the separation of pm80x_chip and pm80x_subchip
> >used for?
> Pm80x_chip is common for both pm800 and pm805, while pm80x_subchip
> handles the other i2c devices as discussed before, only that these two
> i2c devices are not as much as pm800 and pm805 i2c device, and they are
> only for gpadc & power settings purpose. The subchip can be treated as
> some special feature/function for pm800.

ok

> >> +struct pm80x_rtc_pdata {
> >> +	int		vrtc;
> >> +	int		rtc_wakeup;
> >> +};
> >> +
> >> +struct pm80x_platform_data {
> >> +	struct pm80x_rtc_pdata *rtc;
> >> +	unsigned short pm800_addr;
> >> +	unsigned short pm805_addr;
> >> +	unsigned short power_page_addr;	/* power page I2C address */
> >> +	unsigned short gpadc_page_addr;	/* gpadc page I2C address */
> >> +	int irq_mode;		/* Clear interrupt by read/write(0/1) */
> >> +	int irq_base;		/* IRQ base of chip */
> >> +	int batt_det;		/* enable/disable */
> >> +};
> >
> >You removed the callback here as I asked you to, which I think is a useful
> >cleanup, but you can actually managed to convinced me that it would be ok
> >to have it, so I don't mind if you want to put it back and use auxdata.
> Actually it's convenient for us to put it back currently, and would use
> auxdata instead.

ok

> >On the other hand, I think it probably makes sense to drop the irq_base
> >member in this struct and rely on irq domains to allocate them dynamically
> >as mentioned before.
> Do you mean that both regmap_add_irq_chip and mfd_add_devices api pass -1 as
> the irq_base, so that system can dynamically allocate the irq_base for it?

regmap_add_irq_chip should pass -1, mfd_add_devices should pass 0.
Mark can probably correct me if that's wrong.

> Given the proper regmap_irq_chip & device resource, is there anything else
> needed? As I don't want to miss the exact meaning of " transform the
> interrupt numbers using the domain in the client drivers" you mentioned above.

The drivers using the numbers need to call regmap_irq_get_virq() to get the
real interrupt number. See include/linux/mfd/wm8994/core.h for an example.

	Arnd

  parent reply	other threads:[~2012-07-04 15:27 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-04  8:55 [PATCH 0/4 V2] add 88pm80x mfd driver Qiao Zhou
2012-07-04  8:55 ` Qiao Zhou
     [not found] ` <1341392115-9425-1-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-04  8:55   ` [PATCH 1/4] mfd: support 88pm80x in 80x driver Qiao Zhou
2012-07-04  8:55     ` Qiao Zhou
     [not found]     ` <1341392115-9425-2-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-04 11:37       ` Arnd Bergmann
2012-07-04 11:37         ` Arnd Bergmann
     [not found]         ` <201207041137.49020.arnd-r2nGTMty4D4@public.gmane.org>
2012-07-04 15:14           ` Qiao Zhou
2012-07-04 15:14             ` Qiao Zhou
     [not found]             ` <B2A7C617B3AB7F44B7B44C7D374B431E13A09E8DEE-PBXNphkCnnUA/4UcAFAujRL4W9x8LtSr@public.gmane.org>
2012-07-04 15:27               ` Arnd Bergmann [this message]
2012-07-04 15:27                 ` Arnd Bergmann
     [not found]                 ` <201207041527.13954.arnd-r2nGTMty4D4@public.gmane.org>
2012-07-04 15:33                   ` Mark Brown
2012-07-04 15:33                     ` Mark Brown
     [not found]                     ` <20120704153307.GE4111-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org>
2012-07-04 15:47                       ` Qiao Zhou
2012-07-04 15:47                         ` Qiao Zhou
2012-07-04 15:44                   ` Qiao Zhou
2012-07-04 15:44                     ` Qiao Zhou
2012-07-04  8:55   ` [PATCH 2/4] mfd: workaround: add companion chip in 88pm80x Qiao Zhou
2012-07-04  8:55     ` Qiao Zhou
2012-07-04  8:55   ` [PATCH 3/4] rtc: add rtc support to 88PM80X PMIC Qiao Zhou
2012-07-04  8:55     ` Qiao Zhou
2012-07-04  8:55   ` [PATCH 4/4] input: add onkey " Qiao Zhou
2012-07-04  8:55     ` Qiao Zhou
  -- strict thread matches above, loose matches on Subject: below --
2012-07-05 11:07 [PATCH 0/4 V3] add 88pm80x mfd driver Qiao Zhou
     [not found] ` <1341486425-697-1-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-05 11:07   ` [PATCH 1/4] mfd: support 88pm80x in 80x driver Qiao Zhou
2012-07-05 11:07     ` Qiao Zhou
     [not found]     ` <1341486425-697-2-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-05 12:06       ` Arnd Bergmann
2012-07-05 12:06         ` Arnd Bergmann
     [not found]         ` <201207051206.10376.arnd-r2nGTMty4D4@public.gmane.org>
2012-07-05 13:52           ` Qiao Zhou
2012-07-05 13:52             ` Qiao Zhou
2012-07-05 11:56 [PATCH 0/4 V3.1] add 88pm80x mfd driver Qiao Zhou
2012-07-05 11:56 ` [PATCH 1/4] mfd: support 88pm80x in 80x driver Qiao Zhou
2012-07-06  6:48 [PATCH 0/4 V4] add 88pm80x mfd driver Qiao Zhou
     [not found] ` <1341557330-24413-1-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-06  6:48   ` [PATCH 1/4] mfd: support 88pm80x in 80x driver Qiao Zhou
2012-07-06  6:48     ` Qiao Zhou
2012-07-09  6:13 [PATCH 0/4 V4] add 88pm80x mfd driver Qiao Zhou
     [not found] ` <1341814418-13300-1-git-send-email-zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2012-07-09  6:13   ` [PATCH 1/4] mfd: support 88pm80x in 80x driver Qiao Zhou
2012-07-09  6:13     ` Qiao Zhou

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=201207041527.13954.arnd@arndb.de \
    --to=arnd-r2ngtmty4d4@public.gmane.org \
    --cc=broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org \
    --cc=cxie4-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org \
    --cc=haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=rpurdie-Fm38FmjxZ/leoWH0uzbU5w@public.gmane.org \
    --cc=sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=wwang27-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org \
    --cc=ytang5-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org \
    --cc=zhouqiao-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.