From: Jean Delvare <khali@linux-fr.org>
To: lm-sensors@vger.kernel.org
Subject: Re: [lm-sensors] [PATCH] hwmon w83627hf: add mfd support.
Date: Fri, 18 Sep 2009 16:16:38 +0000 [thread overview]
Message-ID: <20090918181638.42331042@hyperion.delvare> (raw)
In-Reply-To: <1252585810-5336-2-git-send-email-giometti@linux.it>
Hi Samuel,
On Fri, 18 Sep 2009 16:42:49 +0200, Samuel Ortiz wrote:
> On Fri, Sep 18, 2009 at 02:09:23PM +0200, Rodolfo Giometti wrote:
> > +#define W627_DEVID 0x52
> > +#define W627THF_DEVID 0x82
> > +#define W697_DEVID 0x60
> > +#define W637_DEVID 0x70
> > +#define W687THF_DEVID 0x85
> > +#define WINB_ACT_REG 0x30
> > +#define WINB_BASE_REG 0x60
> Are those 2 last ones HWMON specific. If that's so, please be more specific
> about it.
No, these are standard registers common to all logical devices.
> > +/* Constants specified below */
> > +
> > +/* Offset & size of I/O region we are interested in */
> This seems to be the hwmon region, so please be more specific about it in the
> comments and in the naming below.
Correct.
> > +#define WINB_REGION_OFFSET 5
> > +#define WINB_REGION_SIZE 2
> > +
> > +static int __init w83627hf_find(int sioaddr, unsigned short *addr,
> > + struct w83627hf_sio_data *sio_data)
> > +{
> > + int err = -ENODEV;
> > + u16 val;
> > +
> > + sio_data->sioaddr = sioaddr;
> > +
> > + superio_enter(sio_data);
> > + val = force_id ? force_id : superio_inb(sio_data, 0x20);
> > + switch (val) {
> > + case W627_DEVID:
> > + sio_data->type = w83627hf;
> > + break;
> > + case W627THF_DEVID:
> > + sio_data->type = w83627thf;
> > + break;
> > + case W697_DEVID:
> > + sio_data->type = w83697hf;
> > + break;
> > + case W637_DEVID:
> > + sio_data->type = w83637hf;
> > + break;
> > + case W687THF_DEVID:
> > + sio_data->type = w83687thf;
> > + break;
> > + case 0xff: /* No device at all */
> > + goto exit;
> > + default:
> > + pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val);
> > + goto exit;
> > + }
> > +
> > + sio_data->name = names[sio_data->type];
> > +
> > + superio_select(sio_data, W83627HF_LD_HWM);
> > + force_hwmon_addr &= (~7);
> > + if (force_hwmon_addr) {
> > + printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n",
> > + force_hwmon_addr);
> > + superio_outb(sio_data, WINB_BASE_REG, force_hwmon_addr >> 8);
> > + superio_outb(sio_data, WINB_BASE_REG + 1,
> > + force_hwmon_addr & 0xff);
> > + }
> > + val = (superio_inb(sio_data, WINB_BASE_REG) << 8) |
> > + superio_inb(sio_data, WINB_BASE_REG + 1);
> > + *addr = val & (~7);
> > + if (*addr = 0) {
> > + printk(KERN_WARNING DRVNAME ": Base address not set, "
> > + "skipping\n");
> > + goto exit;
> > + }
> > +
> > + val = superio_inb(sio_data, WINB_ACT_REG);
> > + if (!(val & 0x01)) {
> > + printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");
> > + superio_outb(sio_data, WINB_ACT_REG, val | 0x01);
> > + }
> > +
> > + err = 0;
> > + pr_info(DRVNAME ": Found %s chip at %#x\n",
> > + names[sio_data->type], *addr);
>
> I'm not familiar with this chip, but although the function is called
> w83627hf_find(), it seems to me that what we're doing here is enabling the
> hwmon subdevice. Am I correct ? If that's so, could we split this function,
> and maybe even move the hwmon specific part into the hwmon driver.
The enablement of the hwmon logical device is only a side effect. The
main goal of the function is to figure out whether a supported chip is
present, and which one. The original reason to put everything is the
same function is so that we don't have to enter and exit the super-io
config mode twice.
But I wouldn't object to it being split into two separate functions,
each one doing just one thing. That would be cleaner, and speed isn't
critical.
> > + exit:
> > + superio_exit(sio_data);
> > + return err;
> > +}
> > (...)
> > +static inline void superio_enter(struct w83627hf_sio_data *sio)
> > +{
> > + mutex_lock(&sio->lock);
> > +
> > + outb(0x87, sio->sioaddr);
> > + outb(0x87, sio->sioaddr);
>
> I'm not really happy with this one. The unbalanced locking here makes me feel
> unconfortable.
Me, I don't have any objection. Callers will have to balance
superio_enter and superio_exit anyway. So hiding the mutex in there
seems reasonable.
> Something like that:
>
> void superio_outb(struct w83627hf_sio_data *sio, int ld, int reg, int val)
> {
> mutex_lock(&sio->lock);
>
> /* Enter */
> outb(0x87, sio->sioaddr)
> outb(0x87, sio->sioaddr)
>
> /* Select module */
> outb(0x07, sio->sioaddr);
> outb(ld, sio->sioaddr + 1);
>
> /* Write */
> outb(reg, sio->sioaddr);
> outb(val, sio->sioaddr + 1);
>
> /* Exit */
> outb(0xAA, sio->sioaddr);
>
> mutex_unlock(&sio->lock);
> }
>
> would look saner to me. I know we're wasting many IO ops here, but it seems to
> me that the subdevices get to call the superio API only at init time.
> I think it's worth it as your subdevices wouldnt have to care about following
> these error prone steps, and you wouldnt have any more unbalanced locking
> risks.
The above has limitations. Think of the hwmon logical device enablement
function which we discussed above. In this function we must read a
register, and depending on the value, maybe write to it, but altering
only one bit (so based on the original value.)
There is no way to achieve this in a race-free manner with your
proposed superio_outb() function and the equivalent superio_inb()
implementation. Even a superio_alterb() function wouldn't do, because
we want to print a message.
At least with Rodolfo's proposal, this can be done. With your approach,
we'd need dedicated functions for every non-trivial register access.
As far as speed is concerned, I agree it's not critical, at least for
the use cases I know of.
--
Jean Delvare
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
next prev parent reply other threads:[~2009-09-18 16:16 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-10 12:30 [lm-sensors] [PATCH] hwmon w83627hf: add mfd support Rodolfo Giometti
2009-09-10 12:56 ` Jean Delvare
2009-09-11 7:42 ` Rodolfo Giometti
2009-09-11 10:58 ` Samuel Ortiz
2009-09-11 15:07 ` Rodolfo Giometti
2009-09-15 11:38 ` Samuel Ortiz
2009-09-17 13:34 ` Jean Delvare
2009-09-17 13:51 ` Rodolfo Giometti
2009-09-17 13:57 ` Jean Delvare
2009-09-17 14:03 ` Rodolfo Giometti
2009-09-17 14:07 ` Jean Delvare
2009-09-17 14:34 ` Samuel Ortiz
2009-09-18 7:42 ` Jean Delvare
2009-09-18 8:01 ` Samuel Ortiz
2009-09-18 11:02 ` Rodolfo Giometti
2009-09-18 12:09 ` Rodolfo Giometti
2009-09-18 14:42 ` Samuel Ortiz
2009-09-18 14:49 ` Jean Delvare
2009-09-18 16:16 ` Jean Delvare [this message]
2009-09-20 23:48 ` Samuel Ortiz
2009-09-22 8:22 ` Rodolfo Giometti
2009-09-22 8:26 ` Rodolfo Giometti
2009-09-22 8:33 ` Rodolfo Giometti
2009-10-01 13:23 ` Jean Delvare
2009-10-01 13:53 ` Samuel Ortiz
2009-11-02 13:23 ` Jean Delvare
2009-11-03 8:17 ` Rodolfo Giometti
-- strict thread matches above, loose matches on Subject: below --
2010-02-10 12:18 Rodolfo Giometti
2010-02-27 10:58 ` Jean Delvare
2011-09-22 9:11 ` Rodolfo Giometti
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=20090918181638.42331042@hyperion.delvare \
--to=khali@linux-fr.org \
--cc=lm-sensors@vger.kernel.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.