2004-10-20 00:42:09

by Greg KH

[permalink] [raw]
Subject: [BK PATCH] I2C update for 2.6.9

Hi,

Here are some i2c driver fixes and updates for 2.6.9. There is a new
chip and a new bus driver, as well as a bunch of minor fixes. The
majority of these patches have been in the past few -mm releases.

Please pull from: bk://kernel.bkbits.net/gregkh/linux/i2c-2.6

Individual patches will follow, sent to the sensors and linux-kernel
lists.

thanks,

greg k-h

Documentation/i2c/i2c-stub | 33 +
Documentation/i2c/sysfs-interface | 32 +
Documentation/i2c/writing-clients | 26 -
drivers/i2c/algos/i2c-algo-ite.c | 8
drivers/i2c/busses/Kconfig | 34 +
drivers/i2c/busses/Makefile | 2
drivers/i2c/busses/i2c-ali1535.c | 4
drivers/i2c/busses/i2c-ali1563.c | 4
drivers/i2c/busses/i2c-ali15x3.c | 4
drivers/i2c/busses/i2c-amd756.c | 50 +-
drivers/i2c/busses/i2c-amd8111.c | 4
drivers/i2c/busses/i2c-elektor.c | 8
drivers/i2c/busses/i2c-hydra.c | 4
drivers/i2c/busses/i2c-i801.c | 4
drivers/i2c/busses/i2c-i810.c | 6
drivers/i2c/busses/i2c-ibm_iic.c | 4
drivers/i2c/busses/i2c-mpc.c | 7
drivers/i2c/busses/i2c-nforce2.c | 5
drivers/i2c/busses/i2c-piix4.c | 4
drivers/i2c/busses/i2c-prosavage.c | 14
drivers/i2c/busses/i2c-s3c2410.c | 877 +++++++++++++++++++++++++++++++++++++
drivers/i2c/busses/i2c-savage4.c | 6
drivers/i2c/busses/i2c-sis5595.c | 4
drivers/i2c/busses/i2c-sis630.c | 4
drivers/i2c/busses/i2c-sis96x.c | 4
drivers/i2c/busses/i2c-stub.c | 125 +++++
drivers/i2c/busses/i2c-via.c | 4
drivers/i2c/busses/i2c-viapro.c | 4
drivers/i2c/busses/i2c-voodoo3.c | 6
drivers/i2c/busses/scx200_acb.c | 13
drivers/i2c/chips/Kconfig | 11
drivers/i2c/chips/Makefile | 1
drivers/i2c/chips/adm1021.c | 2
drivers/i2c/chips/adm1025.c | 16
drivers/i2c/chips/adm1031.c | 48 +-
drivers/i2c/chips/asb100.c | 18
drivers/i2c/chips/ds1621.c | 2
drivers/i2c/chips/eeprom.c | 2
drivers/i2c/chips/fscher.c | 2
drivers/i2c/chips/gl518sm.c | 8
drivers/i2c/chips/it87.c | 50 +-
drivers/i2c/chips/lm75.c | 2
drivers/i2c/chips/lm77.c | 2
drivers/i2c/chips/lm78.c | 40 -
drivers/i2c/chips/lm80.c | 7
drivers/i2c/chips/lm83.c | 22
drivers/i2c/chips/lm85.c | 53 +-
drivers/i2c/chips/lm87.c | 814 ++++++++++++++++++++++++++++++++++
drivers/i2c/chips/lm90.c | 49 +-
drivers/i2c/chips/max1619.c | 5
drivers/i2c/chips/pcf8574.c | 2
drivers/i2c/chips/pcf8591.c | 2
drivers/i2c/chips/smsc47m1.c | 58 +-
drivers/i2c/chips/via686a.c | 32 -
drivers/i2c/chips/w83627hf.c | 22
drivers/i2c/chips/w83781d.c | 76 +--
drivers/i2c/i2c-core.c | 20
drivers/w1/Makefile | 4
drivers/w1/dscore.c | 13
drivers/w1/w1.c | 29 -
drivers/w1/w1.h | 2
drivers/w1/w1_family.c | 11
drivers/w1/w1_int.c | 17
drivers/w1/w1_int.h | 2
drivers/w1/w1_netlink.c | 8
drivers/w1/w1_therm.c | 71 +-
include/linux/i2c-vid.h | 36 +
67 files changed, 2476 insertions(+), 387 deletions(-)
-----

<ben-linux:fluff.org>:
o I2C: S3C2410 I2C Bus driver

Evgeniy Polyakov:
o w1: schedule_timeout() issues
o w1_therm: more precise temperature calculation
o W1: let W1 select NET
o w1: Added slave->ttl - time to live for the registered slave

Gerd Knorr:
o I2C: i2c bus power management support

Greg Kroah-Hartman:
o I2C: convert from pci_module_init to pci_register_driver for all i2c drivers
o I2C: convert scx200_acb driver to not use pci_find_device
o I2C: change i2c-elektor.c driver from using pci_find_device()
o I2C: fix up __iomem marking for i2c bus drivers

Jean Delvare:
o I2C: lm87 driver ported to Linux 2.6
o I2C: Clean up i2c-amd756 and i2c-prosavage messages
o I2C: Fix amd756 name
o I2C: Update Kconfig for AMD bus drivers
o I2C: Fourth auto-fan control interface proposal
o I2C: Spare 1 byte in lm90 driver
o I2C: Store lm83 and lm90 temperatures in signed
o I2C: Cleanup lm78 init
o I2C: Update Documentation/i2c/writing-clients
o I2C: More verbose debug in w83781d detection
o I2C: Fix macro calls in chip drivers
o I2C: Do not init global variables to 0

Margit Schubert-While:
o I2C: minor lm85 fix

Mark M. Hoffman:
o i2c: kill some sensors driver macro abuse
o i2c: sensors chip driver updates
o i2c: Add Intel VRD 10.0 and AMD Opteron VID support
o I2C/SMBus stub for driver testing

Matthieu Castet:
o use of MODULE_DEVICE_TABLE in i2c busses driver

Nishanth Aravamudan:
o I2C: replace schedule_timeout() with msleep_interruptible() in i2c-ibm_iic.c
o i2c/i2c-mpc: replace schedule_timeout() with msleep_interruptible()
o i2c-algo-ite: remove iic_sleep()

Rudolf Marek:
o I2C: fix it8712 detection


2004-10-20 00:31:12

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2076, 2004/10/19 15:22:22-07:00, [email protected]

[PATCH] I2C: S3C2410 I2C Bus driver

Bus driver for the Samsung S3C2410 SoC onboard I2C controller

Signed-off-by: Ben Dooks <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/Kconfig | 7
drivers/i2c/busses/Makefile | 1
drivers/i2c/busses/i2c-s3c2410.c | 877 +++++++++++++++++++++++++++++++++++++++
3 files changed, 885 insertions(+)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig 2004-10-19 16:53:38 -07:00
+++ b/drivers/i2c/busses/Kconfig 2004-10-19 16:53:38 -07:00
@@ -291,6 +291,13 @@
depends on (RPXLITE || RPXCLASSIC) && I2C
select I2C_ALGO8XX

+config I2C_S3C2410
+ tristate "S3C2410 I2C Driver"
+ depends on I2C && ARCH_S3C2410
+ help
+ Say Y here to include support for I2C controller in the
+ Samsung S3C2410 based System-on-Chip devices.
+
config I2C_SAVAGE4
tristate "S3 Savage 4"
depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile 2004-10-19 16:53:38 -07:00
+++ b/drivers/i2c/busses/Makefile 2004-10-19 16:53:38 -07:00
@@ -26,6 +26,7 @@
obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
+obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
diff -Nru a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/busses/i2c-s3c2410.c 2004-10-19 16:53:38 -07:00
@@ -0,0 +1,877 @@
+/* linux/drivers/i2c/busses/i2c-s3c2410.c
+ *
+ * Copyright (C) 2004 Simtec Electronics
+ * Ben Dooks <[email protected]>
+ *
+ * S3C2410 I2C Controller
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/clock.h>
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-iic.h>
+#include <asm/arch/iic.h>
+
+/* i2c controller state */
+
+enum s3c24xx_i2c_state {
+ STATE_IDLE,
+ STATE_START,
+ STATE_READ,
+ STATE_WRITE,
+ STATE_STOP
+};
+
+struct s3c24xx_i2c {
+ spinlock_t lock;
+ wait_queue_head_t wait;
+
+ struct i2c_msg *msg;
+ unsigned int msg_num;
+ unsigned int msg_idx;
+ unsigned int msg_ptr;
+
+ enum s3c24xx_i2c_state state;
+
+ void __iomem *regs;
+ struct clk *clk;
+ struct device *dev;
+ struct resource *irq;
+ struct resource *ioarea;
+ struct i2c_adapter adap;
+};
+
+/* default platform data to use if not supplied in the platfrom_device
+*/
+
+static struct s3c2410_platform_i2c s3c24xx_i2c_default_platform = {
+ .flags = 0,
+ .slave_addr = 0x10,
+ .bus_freq = 100*1000,
+ .max_freq = 400*1000,
+};
+
+
+/* s3c24xx_i2c_get_platformdata
+ *
+ * get the platform data associated with the given device, or return
+ * the default if there is none
+*/
+
+static inline struct s3c2410_platform_i2c *s3c24xx_i2c_get_platformdata(struct device *dev)
+{
+ if (dev->platform_data != NULL)
+ return (struct s3c2410_platform_i2c *)dev->platform_data;
+
+ return &s3c24xx_i2c_default_platform;
+}
+
+/* s3c24xx_i2c_master_complete
+ *
+ * complete the message and wake up the caller, using the given return code,
+ * or zero to mean ok.
+*/
+
+static inline void s3c24xx_i2c_master_complete(struct s3c24xx_i2c *i2c, int ret)
+{
+ dev_dbg(i2c->dev, "master_complete %d\n", ret);
+
+ i2c->msg_ptr = 0;
+ i2c->msg = NULL;
+ i2c->msg_idx ++;
+ i2c->msg_num = 0;
+ if (ret)
+ i2c->msg_idx = ret;
+
+ wake_up(&i2c->wait);
+}
+
+static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ writel(tmp & ~S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
+
+}
+
+static inline void s3c24xx_i2c_enable_ack(struct s3c24xx_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ writel(tmp | S3C2410_IICCON_ACKEN, i2c->regs + S3C2410_IICCON);
+
+}
+
+/* irq enable/disable functions */
+
+static inline void s3c24xx_i2c_disable_irq(struct s3c24xx_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ writel(tmp & ~S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
+}
+
+static inline void s3c24xx_i2c_enable_irq(struct s3c24xx_i2c *i2c)
+{
+ unsigned long tmp;
+
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
+}
+
+
+/* s3c24xx_i2c_message_start
+ *
+ * put the start of a message onto the bus
+*/
+
+static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
+ struct i2c_msg *msg)
+{
+ unsigned int addr = (msg->addr & 0x7f) << 1;
+ unsigned long stat;
+
+ stat = readl(i2c->regs + S3C2410_IICSTAT);
+ stat &= ~S3C2410_IICSTAT_MODEMASK;
+ stat |= S3C2410_IICSTAT_START;
+ stat |= S3C2410_IICSTAT_TXRXEN;
+
+ if (msg->flags & I2C_M_RD) {
+ stat |= S3C2410_IICSTAT_MASTER_RX;
+ addr |= 1;
+ } else
+ stat |= S3C2410_IICSTAT_MASTER_TX;
+
+ // todo - check for wether ack wanted or not
+ s3c24xx_i2c_enable_ack(i2c);
+
+ dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr);
+ writeb(addr, i2c->regs + S3C2410_IICDS);
+ writel(stat, i2c->regs + S3C2410_IICSTAT);
+}
+
+static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
+{
+ unsigned long iicstat = readl(i2c->regs + S3C2410_IICSTAT);
+
+ dev_dbg(i2c->dev, "STOP\n");
+
+ /* stop the transfer */
+ iicstat &= ~ S3C2410_IICSTAT_START;
+ writel(iicstat, i2c->regs + S3C2410_IICSTAT);
+
+ i2c->state = STATE_STOP;
+
+ s3c24xx_i2c_master_complete(i2c, ret);
+ s3c24xx_i2c_disable_irq(i2c);
+}
+
+/* helper functions to determine the current state in the set of
+ * messages we are sending */
+
+/* is_lastmsg()
+ *
+ * returns TRUE if the current message is the last in the set
+*/
+
+static inline int is_lastmsg(struct s3c24xx_i2c *i2c)
+{
+ return i2c->msg_idx >= (i2c->msg_num - 1);
+}
+
+/* is_msglast
+ *
+ * returns TRUE if we this is the last byte in the current message
+*/
+
+static inline int is_msglast(struct s3c24xx_i2c *i2c)
+{
+ return i2c->msg_ptr == i2c->msg->len-1;
+}
+
+/* is_msgend
+ *
+ * returns TRUE if we reached the end of the current message
+*/
+
+static inline int is_msgend(struct s3c24xx_i2c *i2c)
+{
+ return i2c->msg_ptr >= i2c->msg->len;
+}
+
+/* i2s_s3c_irq_nextbyte
+ *
+ * process an interrupt and work out what to do
+ */
+
+static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
+{
+ unsigned long tmp;
+ unsigned char byte;
+ int ret = 0;
+
+ switch (i2c->state) {
+
+ case STATE_IDLE:
+ dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __FUNCTION__);
+ goto out;
+ break;
+
+ case STATE_STOP:
+ dev_err(i2c->dev, "%s: called in STATE_STOP\n", __FUNCTION__);
+ s3c24xx_i2c_disable_irq(i2c);
+ goto out_ack;
+
+ case STATE_START:
+ /* last thing we did was send a start condition on the
+ * bus, or started a new i2c message
+ */
+
+ if (iicstat & S3C2410_IICSTAT_LASTBIT &&
+ !(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
+ /* ack was not received... */
+
+ s3c24xx_i2c_stop(i2c, -EREMOTEIO);
+ goto out_ack;
+ }
+
+ if (i2c->msg->flags & I2C_M_RD)
+ i2c->state = STATE_READ;
+ else
+ i2c->state = STATE_WRITE;
+
+ /* terminate the transfer if there is nothing to do
+ * (used by the i2c probe to find devices */
+
+ if (is_lastmsg(i2c) && i2c->msg->len == 0) {
+ s3c24xx_i2c_stop(i2c, 0);
+ goto out_ack;
+ }
+
+ if (i2c->state == STATE_READ)
+ goto prepare_read;
+
+ /* fall through to the write state, as we will need to
+ * send a byte as well */
+
+ case STATE_WRITE:
+ /* we are writing data to the device... check for the
+ * end of the message, and if so, work out what to do
+ */
+
+ retry_write:
+ if (!is_msgend(i2c)) {
+ byte = i2c->msg->buf[i2c->msg_ptr++];
+ writeb(byte, i2c->regs + S3C2410_IICDS);
+
+ } else if (!is_lastmsg(i2c)) {
+ /* we need to go to the next i2c message */
+
+ dev_dbg(i2c->dev, "WRITE: Next Message\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx ++;
+ i2c->msg++;
+
+ /* check to see if we need to do another message */
+ if (i2c->msg->flags & I2C_M_NOSTART) {
+
+ if (i2c->msg->flags & I2C_M_RD) {
+ /* cannot do this, the controller
+ * forces us to send a new START
+ * when we change direction */
+
+ s3c24xx_i2c_stop(i2c, -EINVAL);
+ }
+
+ goto retry_write;
+ } else {
+
+ /* send the new start */
+ s3c24xx_i2c_message_start(i2c, i2c->msg);
+ i2c->state = STATE_START;
+ }
+
+ } else {
+ /* send stop */
+
+ s3c24xx_i2c_stop(i2c, 0);
+ }
+ break;
+
+ case STATE_READ:
+ /* we have a byte of data in the data register, do
+ * something with it, and then work out wether we are
+ * going to do any more read/write
+ */
+
+ if (!(i2c->msg->flags & I2C_M_IGNORE_NAK) &&
+ !(is_msglast(i2c) && is_lastmsg(i2c))) {
+
+ if (iicstat & S3C2410_IICSTAT_LASTBIT) {
+ dev_dbg(i2c->dev, "READ: No Ack\n");
+
+ s3c24xx_i2c_stop(i2c, -ECONNREFUSED);
+ goto out_ack;
+ }
+ }
+
+ byte = readb(i2c->regs + S3C2410_IICDS);
+ i2c->msg->buf[i2c->msg_ptr++] = byte;
+
+ prepare_read:
+ if (is_msglast(i2c)) {
+ /* last byte of buffer */
+
+ if (is_lastmsg(i2c))
+ s3c24xx_i2c_disable_ack(i2c);
+
+ } else if (is_msgend(i2c)) {
+ /* ok, we've read the entire buffer, see if there
+ * is anything else we need to do */
+
+ if (is_lastmsg(i2c)) {
+ /* last message, send stop and complete */
+ dev_dbg(i2c->dev, "READ: Send Stop\n");
+
+ s3c24xx_i2c_stop(i2c, 0);
+ } else {
+ /* go to the next transfer */
+ dev_dbg(i2c->dev, "READ: Next Transfer\n");
+
+ i2c->msg_ptr = 0;
+ i2c->msg_idx++;
+ i2c->msg++;
+ }
+ }
+
+ break;
+ }
+
+ /* acknowlegde the IRQ and get back on with the work */
+
+ out_ack:
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ tmp &= ~S3C2410_IICCON_IRQPEND;
+ writel(tmp, i2c->regs + S3C2410_IICCON);
+ out:
+ return ret;
+}
+
+/* s3c24xx_i2c_irq
+ *
+ * top level IRQ servicing routine
+*/
+
+static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id,
+ struct pt_regs *regs)
+{
+ struct s3c24xx_i2c *i2c = dev_id;
+ unsigned long status;
+ unsigned long tmp;
+
+ status = readl(i2c->regs + S3C2410_IICSTAT);
+
+ if (status & S3C2410_IICSTAT_ARBITR) {
+ // deal with arbitration loss
+ }
+
+ if (i2c->state == STATE_IDLE) {
+ dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
+
+ tmp = readl(i2c->regs + S3C2410_IICCON);
+ tmp &= ~S3C2410_IICCON_IRQPEND;
+ writel(tmp, i2c->regs + S3C2410_IICCON);
+ goto out;
+ }
+
+ /* pretty much this leaves us with the fact that we've
+ * transmitted or received whatever byte we last sent */
+
+ i2s_s3c_irq_nextbyte(i2c, status);
+
+ out:
+ return IRQ_HANDLED;
+}
+
+
+/* s3c24xx_i2c_set_master
+ *
+ * get the i2c bus for a master transaction
+*/
+
+static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
+{
+ unsigned long iicstat;
+ int timeout = 400;
+
+ while (timeout-- > 0) {
+ iicstat = readl(i2c->regs + S3C2410_IICSTAT);
+
+ if (!(iicstat & S3C2410_IICSTAT_BUSBUSY))
+ return 0;
+
+ msleep(1);
+ }
+
+ dev_dbg(i2c->dev, "timeout: GPEDAT is %08x\n",
+ __raw_readl(S3C2410_GPEDAT));
+
+ return -ETIMEDOUT;
+}
+
+/* s3c24xx_i2c_doxfer
+ *
+ * this starts an i2c transfer
+*/
+
+static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg msgs[], int num)
+{
+ unsigned long timeout;
+ int ret;
+
+ ret = s3c24xx_i2c_set_master(i2c);
+ if (ret != 0) {
+ dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ spin_lock_irq(&i2c->lock);
+
+ i2c->msg = msgs;
+ i2c->msg_num = num;
+ i2c->msg_ptr = 0;
+ i2c->msg_idx = 0;
+ i2c->state = STATE_START;
+
+ s3c24xx_i2c_enable_irq(i2c);
+ s3c24xx_i2c_message_start(i2c, msgs);
+ spin_unlock_irq(&i2c->lock);
+
+ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+
+ ret = i2c->msg_idx;
+
+ /* having these next two as dev_err() makes life very
+ * noisy when doing an i2cdetect */
+
+ if (timeout == 0)
+ dev_dbg(i2c->dev, "timeout\n");
+ else if (ret != num)
+ dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
+
+ /* ensure the stop has been through the bus */
+
+ msleep(1);
+
+ out:
+ return ret;
+}
+
+/* s3c24xx_i2c_xfer
+ *
+ * first port of call from the i2c bus code when an message needs
+ * transfering across the i2c bus.
+*/
+
+static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
+ struct i2c_msg msgs[], int num)
+{
+ struct s3c24xx_i2c *i2c = (struct s3c24xx_i2c *)adap->algo_data;
+ int retry;
+ int ret;
+
+ for (retry = 0; retry < adap->retries; retry++) {
+
+ ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
+
+ if (ret != -EAGAIN)
+ return ret;
+
+ dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
+
+ udelay(100);
+ }
+
+ return -EREMOTEIO;
+}
+
+/* i2c bus registration info */
+
+static struct i2c_algorithm s3c24xx_i2c_algorithm = {
+ .name = "S3C2410-I2C-Algorithm",
+ .id = I2C_ALGO_S3C2410,
+ .master_xfer = s3c24xx_i2c_xfer,
+};
+
+static struct s3c24xx_i2c s3c24xx_i2c = {
+ .lock = SPIN_LOCK_UNLOCKED,
+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait),
+ .adap = {
+ .name = "s3c2410-i2c",
+ .id = I2C_ALGO_S3C2410,
+ .algo = &s3c24xx_i2c_algorithm,
+ .retries = 2,
+ },
+};
+
+/* s3c24xx_i2c_calcdivisor
+ *
+ * return the divisor settings for a given frequency
+*/
+
+static int s3c24xx_i2c_calcdivisor(unsigned long clkin, unsigned int wanted,
+ unsigned int *div1, unsigned int *divs)
+{
+ unsigned int calc_divs = clkin / wanted;
+ unsigned int calc_div1;
+
+ if (calc_divs > (16*16))
+ calc_div1 = 512;
+ else
+ calc_div1 = 16;
+
+ calc_divs += calc_div1-1;
+ calc_divs /= calc_div1;
+
+ if (calc_divs == 0)
+ calc_divs = 1;
+ if (calc_divs > 17)
+ calc_divs = 17;
+
+ *divs = calc_divs;
+ *div1 = calc_div1;
+
+ return clkin / (calc_divs + calc_div1);
+}
+
+/* freq_acceptable
+ *
+ * test wether a frequency is within the acceptable range of error
+*/
+
+static inline int freq_acceptable(unsigned int freq, unsigned int wanted)
+{
+ int diff = freq - wanted;
+
+ return (diff >= -2 && diff <= 2);
+}
+
+/* s3c24xx_i2c_getdivisor
+ *
+ * work out a divisor for the user requested frequency setting,
+ * either by the requested frequency, or scanning the acceptable
+ * range of frequencies until something is found
+*/
+
+static int s3c24xx_i2c_getdivisor(struct s3c24xx_i2c *i2c,
+ struct s3c2410_platform_i2c *pdata,
+ unsigned long *iicon,
+ unsigned int *got)
+{
+ unsigned long clkin = clk_get_rate(i2c->clk);
+
+ unsigned int divs, div1;
+ int freq;
+ int start, end;
+
+ clkin /= 1000; /* clkin now in KHz */
+
+ dev_dbg(i2c->dev, "pdata %p, freq %lu %lu..%lu\n",
+ pdata, pdata->bus_freq, pdata->min_freq, pdata->max_freq);
+
+ if (pdata->bus_freq != 0) {
+ freq = s3c24xx_i2c_calcdivisor(clkin, pdata->bus_freq/1000,
+ &div1, &divs);
+ if (freq_acceptable(freq, pdata->bus_freq/1000))
+ goto found;
+ }
+
+ /* ok, we may have to search for something suitable... */
+
+ start = (pdata->max_freq == 0) ? pdata->bus_freq : pdata->max_freq;
+ end = pdata->min_freq;
+
+ start /= 1000;
+ end /= 1000;
+
+ /* search loop... */
+
+ for (; start > end; start--) {
+ freq = s3c24xx_i2c_calcdivisor(clkin, start, &div1, &divs);
+ if (freq_acceptable(freq, start))
+ goto found;
+ }
+
+ /* cannot find frequency spec */
+
+ return -EINVAL;
+
+ found:
+ *got = freq;
+ *iicon |= (divs-1);
+ *iicon |= (div1 == 512) ? S3C2410_IICCON_TXDIV_512 : 0;
+ return 0;
+}
+
+/* s3c24xx_i2c_init
+ *
+ * initialise the controller, set the IO lines and frequency
+*/
+
+static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
+{
+ unsigned long iicon = S3C2410_IICCON_IRQEN | S3C2410_IICCON_ACKEN;
+ struct s3c2410_platform_i2c *pdata;
+ unsigned int freq;
+
+ /* get the plafrom data */
+
+ pdata = s3c24xx_i2c_get_platformdata(i2c->adap.dev.parent);
+
+ /* inititalise the gpio */
+
+ s3c2410_gpio_cfgpin(S3C2410_GPE15, S3C2410_GPE15_IICSDA);
+ s3c2410_gpio_cfgpin(S3C2410_GPE14, S3C2410_GPE14_IICSCL);
+
+ /* write slave address */
+
+ writeb(pdata->slave_addr, i2c->regs + S3C2410_IICADD);
+
+ dev_info(i2c->dev, "slave address 0x%02x\n", pdata->slave_addr);
+
+ /* we need to work out the divisors for the clock... */
+
+ if (s3c24xx_i2c_getdivisor(i2c, pdata, &iicon, &freq) != 0) {
+ dev_err(i2c->dev, "cannot meet bus frequency required\n");
+ return -EINVAL;
+ }
+
+ /* todo - check that the i2c lines aren't being dragged anywhere */
+
+ dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
+
+ return 0;
+}
+
+static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c)
+{
+ if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
+ clk_disable(i2c->clk);
+ clk_unuse(i2c->clk);
+ clk_put(i2c->clk);
+ i2c->clk = NULL;
+ }
+
+ if (i2c->regs != NULL) {
+ iounmap(i2c->regs);
+ i2c->regs = NULL;
+ }
+
+ if (i2c->ioarea != NULL) {
+ release_resource(i2c->ioarea);
+ kfree(i2c->ioarea);
+ i2c->ioarea = NULL;
+ }
+}
+
+/* s3c24xx_i2c_probe
+ *
+ * called by the bus driver when a suitable device is found
+*/
+
+static int s3c24xx_i2c_probe(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct s3c24xx_i2c *i2c = &s3c24xx_i2c;
+ struct resource *res;
+ int ret;
+
+ /* find the clock and enable it */
+
+ i2c->dev = dev;
+ i2c->clk = clk_get(dev, "i2c");
+ if (IS_ERR(i2c->clk)) {
+ dev_err(dev, "cannot get clock\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ dev_dbg(dev, "clock source %p\n", i2c->clk);
+
+ clk_use(i2c->clk);
+ clk_enable(i2c->clk);
+
+ /* map the registers */
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(dev, "cannot find IO resource\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1,
+ pdev->name);
+
+ if (i2c->ioarea == NULL) {
+ dev_err(dev, "cannot request IO\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ i2c->regs = ioremap(res->start, (res->end-res->start)+1);
+
+ if (i2c->regs == NULL) {
+ dev_err(dev, "cannot map IO\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ dev_dbg(dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res);
+
+ /* setup info block for the i2c core */
+
+ i2c->adap.algo_data = i2c;
+ i2c->adap.dev.parent = dev;
+
+ /* initialise the i2c controller */
+
+ ret = s3c24xx_i2c_init(i2c);
+ if (ret != 0)
+ goto out;
+
+ /* find the IRQ for this unit (note, this relies on the init call to
+ * ensure no current IRQs pending
+ */
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(dev, "cannot find IRQ\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ ret = request_irq(res->start, s3c24xx_i2c_irq, SA_INTERRUPT,
+ pdev->name, i2c);
+
+ if (ret != 0) {
+ dev_err(dev, "cannot claim IRQ\n");
+ goto out;
+ }
+
+ i2c->irq = res;
+
+ dev_dbg(dev, "irq resource %p (%ld)\n", res, res->start);
+
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret < 0) {
+ dev_err(dev, "failed to add bus to i2c core\n");
+ goto out;
+ }
+
+ dev_set_drvdata(dev, i2c);
+
+ dev_info(dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id);
+
+ out:
+ if (ret < 0)
+ s3c24xx_i2c_free(i2c);
+
+ return ret;
+}
+
+/* s3c24xx_i2c_remove
+ *
+ * called when device is removed from the bus
+*/
+
+static int s3c24xx_i2c_remove(struct device *dev)
+{
+ struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
+
+ if (i2c != NULL) {
+ s3c24xx_i2c_free(i2c);
+ dev_set_drvdata(dev, NULL);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c24xx_i2c_resume(struct device *dev, u32 level)
+{
+ struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
+
+ if (i2c != NULL && level == RESUME_ENABLE) {
+ dev_dbg(dev, "resume: level %d\n", level);
+ s3c24xx_i2c_init(i2c);
+ }
+
+ return 0;
+}
+
+#else
+#define s3c24xx_i2c_resume NULL
+#endif
+
+/* device driver for platform bus bits */
+
+static struct device_driver s3c24xx_i2c_driver = {
+ .name = "s3c2410-i2c",
+ .bus = &platform_bus_type,
+ .probe = s3c24xx_i2c_probe,
+ .remove = s3c24xx_i2c_remove,
+ .resume = s3c24xx_i2c_resume,
+};
+
+static int __init i2c_adap_s3c_init(void)
+{
+ return driver_register(&s3c24xx_i2c_driver);
+}
+
+static void i2c_adap_s3c_exit(void)
+{
+ return driver_unregister(&s3c24xx_i2c_driver);
+}
+
+module_init(i2c_adap_s3c_init);
+module_exit(i2c_adap_s3c_exit);
+
+MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
+MODULE_AUTHOR("Ben Dooks, <[email protected]>");
+MODULE_LICENSE("GPL");

2004-10-20 00:31:48

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.8, 2004/09/29 16:14:12-07:00, [email protected]

[PATCH] w1: schedule_timeout() issues.

Need to set current state and check signals.

Signed-off-by: Evgeniy Polyakov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/w1/dscore.c | 13 ++++++++++---
drivers/w1/w1.c | 20 +++++++++++++++-----
drivers/w1/w1_family.c | 11 +++++++++--
drivers/w1/w1_int.c | 11 +++++++++--
4 files changed, 43 insertions(+), 12 deletions(-)


diff -Nru a/drivers/w1/dscore.c b/drivers/w1/dscore.c
--- a/drivers/w1/dscore.c 2004-10-19 16:54:19 -07:00
+++ b/drivers/w1/dscore.c 2004-10-19 16:54:19 -07:00
@@ -727,11 +727,18 @@
{
struct ds_device *dev;

- dev = usb_get_intfdata (intf);
- usb_set_intfdata (intf, NULL);
+ dev = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);

- while(atomic_read(&dev->refcnt))
+ while (atomic_read(&dev->refcnt)) {
+ printk(KERN_INFO "Waiting for DS to become free: refcnt=%d.\n",
+ atomic_read(&dev->refcnt));
+ set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ);
+
+ if (signal_pending(current))
+ flush_signals(current);
+ }

usb_put_dev(dev->udev);
kfree(dev);
diff -Nru a/drivers/w1/w1.c b/drivers/w1/w1.c
--- a/drivers/w1/w1.c 2004-10-19 16:54:19 -07:00
+++ b/drivers/w1/w1.c 2004-10-19 16:54:19 -07:00
@@ -449,8 +449,15 @@

dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name);

- while (atomic_read(&sl->refcnt))
- schedule_timeout(10);
+ while (atomic_read(&sl->refcnt)) {
+ printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
+ sl->name, atomic_read(&sl->refcnt));
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+
+ if (signal_pending(current))
+ flush_signals(current);
+ }

sysfs_remove_bin_file (&sl->dev.kobj, &sl->attr_bin);
device_remove_file(&sl->dev, &sl->attr_name);
@@ -507,8 +514,8 @@
* All who don't sleep must send ID bit and COMPLEMENT ID bit.
* They actually are ANDed between all senders.
*/
- id_bit = w1_read_bit(dev);
- comp_bit = w1_read_bit(dev);
+ id_bit = w1_touch_bit(dev, 1);
+ comp_bit = w1_touch_bit(dev, 1);

if (id_bit && comp_bit)
break;
@@ -539,7 +546,10 @@
* and make all who don't have "search_bit" in "i"'th position
* in it's registration number sleep.
*/
- w1_write_bit(dev, search_bit);
+ if (dev->bus_master->touch_bit)
+ w1_touch_bit(dev, search_bit);
+ else
+ w1_write_bit(dev, search_bit);

}
#endif
diff -Nru a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
--- a/drivers/w1/w1_family.c 2004-10-19 16:54:19 -07:00
+++ b/drivers/w1/w1_family.c 2004-10-19 16:54:19 -07:00
@@ -84,8 +84,15 @@

spin_unlock(&w1_flock);

- while (atomic_read(&fent->refcnt))
- schedule_timeout(10);
+ while (atomic_read(&fent->refcnt)) {
+ printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n",
+ fent->fid, atomic_read(&fent->refcnt));
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+
+ if (signal_pending(current))
+ flush_signals(current);
+ }
}

/*
diff -Nru a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
--- a/drivers/w1/w1_int.c 2004-10-19 16:54:19 -07:00
+++ b/drivers/w1/w1_int.c 2004-10-19 16:54:19 -07:00
@@ -181,8 +181,15 @@
"%s: Failed to send signal to w1 kernel thread %d.\n",
__func__, dev->kpid);

- while (atomic_read(&dev->refcnt))
- schedule_timeout(10);
+ while (atomic_read(&dev->refcnt)) {
+ printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
+ dev->name, atomic_read(&dev->refcnt));
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(HZ);
+
+ if (signal_pending(current))
+ flush_signals(current);
+ }

msg.id.mst.id = dev->id;
msg.id.mst.pid = dev->kpid;

2004-10-20 00:37:01

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.4, 2004/09/08 12:35:04-07:00, [email protected]

[PATCH] I2C: minor lm85 fix

Jean scribeth :
> Except lm85, but this should be fixed

Indeed, patch attached.


Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/lm85.c | 2 ++
1 files changed, 2 insertions(+)


diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c 2004-10-19 16:55:47 -07:00
+++ b/drivers/i2c/chips/lm85.c 2004-10-19 16:55:47 -07:00
@@ -707,6 +707,8 @@

int lm85_attach_adapter(struct i2c_adapter *adapter)
{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
return i2c_detect(adapter, &addr_data, lm85_detect);
}


2004-10-20 00:37:04

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.8, 2004/09/21 16:40:19-07:00, [email protected]

[PATCH] i2c/i2c-mpc: replace schedule_timeout() with msleep_interruptible()

Properly orders set_current_state() and add_wait_queue(). Uses
msleep_interruptible() in place of schedule_timeout() to guarantee the
task delays as expected. Uses set_current_state() instead of direct
assignment of current->state.

Signed-off-by: Nishanth Aravamudan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-mpc.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
--- a/drivers/i2c/busses/i2c-mpc.c 2004-10-19 16:54:50 -07:00
+++ b/drivers/i2c/busses/i2c-mpc.c 2004-10-19 16:54:50 -07:00
@@ -23,6 +23,7 @@
#include <asm/ocp.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
+#include <linux/delay.h>

#define MPC_I2C_ADDR 0x00
#define MPC_I2C_FDR 0x04
@@ -91,9 +92,9 @@
x = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
} else {
+ set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&i2c->queue, &wait);
while (!(i2c->interrupt & CSR_MIF)) {
- set_current_state(TASK_INTERRUPTIBLE);
if (signal_pending(current)) {
pr_debug("I2C: Interrupted\n");
result = -EINTR;
@@ -104,9 +105,9 @@
result = -EIO;
break;
}
- schedule_timeout(timeout);
+ msleep_interruptible(jiffies_to_msecs(timeout));
}
- current->state = TASK_RUNNING;
+ set_current_state(TASK_RUNNING);
remove_wait_queue(&i2c->queue, &wait);
x = i2c->interrupt;
i2c->interrupt = 0;

2004-10-20 00:42:10

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.3, 2004/09/08 12:34:34-07:00, [email protected]

[PATCH] I2C/SMBus stub for driver testing

* Greg KH <[email protected]> [2004-08-24 16:44:32 -0700]:
> > > Why not? It looks useful to me. Care to send me a patch adding
> > > this to the main kernel tree?

* Mark M. Hoffman <[email protected]> [2004-08-25 10:25:02 -0400]:
> Later today, sure.

Well here it is, one day later because I really didn't want to do this
with printk. I spent some time looking around and relayfs seems like
a good fit. Do you think relayfs will ever get merged? Meanwhile...

* * * * *

This patch, applied to 2.6.9-rc1, adds an I2C/SMBus test stub that is useful
for developing sensors drivers.

Signed-off-by: Mark M. Hoffman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


Documentation/i2c/i2c-stub | 33 +++++++++++
drivers/i2c/busses/Kconfig | 13 ++++
drivers/i2c/busses/Makefile | 1
drivers/i2c/busses/i2c-stub.c | 125 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 172 insertions(+)


diff -Nru a/Documentation/i2c/i2c-stub b/Documentation/i2c/i2c-stub
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/Documentation/i2c/i2c-stub 2004-10-19 16:55:52 -07:00
@@ -0,0 +1,33 @@
+MODULE: i2c-stub
+
+DESCRIPTION:
+
+This module is a very simple fake I2C/SMBus driver. It implements three
+types of SMBus commands: write quick, (r/w) byte data, and (r/w) word data.
+
+No hardware is needed nor associated with this module. It will accept write
+quick commands to all addresses; it will respond to the other commands (also
+to all addresses) by reading from or writing to an array in memory. It will
+also spam the kernel logs for every command it handles.
+
+The typical use-case is like this:
+ 1. load this module
+ 2. use i2cset (from lm_sensors project) to pre-load some data
+ 3. load the target sensors chip driver module
+ 4. observe its behavior in the kernel log
+
+CAVEATS:
+
+There are independent arrays for byte/data and word/data commands. Depending
+on if/how a target driver mixes them, you'll need to be careful.
+
+If your target driver polls some byte or word waiting for it to change, the
+stub could lock it up. Use i2cset to unlock it.
+
+If the hardware for your driver has banked registers (e.g. Winbond sensors
+chips) this module will not work well - although it could be extended to
+support that pretty easily.
+
+If you spam it hard enough, printk can be lossy. This module really wants
+something like relayfs.
+
diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig 2004-10-19 16:55:52 -07:00
+++ b/drivers/i2c/busses/Kconfig 2004-10-19 16:55:52 -07:00
@@ -376,6 +376,19 @@
This driver can also be built as a module. If so, the module
will be called i2c-sis96x.

+config I2C_STUB
+ tristate "I2C/SMBus Test Stub"
+ depends on I2C && EXPERIMENTAL && 'm'
+ default 'n'
+ help
+ This module may be useful to developers of SMBus client drivers,
+ especially for certain kinds of sensor chips.
+
+ If you do build this module, be sure to read the notes and warnings
+ in Documentation/i2c/i2c-stub.
+
+ If you don't know what to do here, definitely say N.
+
config I2C_VIA
tristate "VIA 82C586B"
depends on I2C && PCI && EXPERIMENTAL
diff -Nru a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
--- a/drivers/i2c/busses/Makefile 2004-10-19 16:55:52 -07:00
+++ b/drivers/i2c/busses/Makefile 2004-10-19 16:55:52 -07:00
@@ -30,6 +30,7 @@
obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o
obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o
+obj-$(CONFIG_I2C_STUB) += i2c-stub.o
obj-$(CONFIG_I2C_VIA) += i2c-via.o
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
diff -Nru a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/busses/i2c-stub.c 2004-10-19 16:55:52 -07:00
@@ -0,0 +1,125 @@
+/*
+ i2c-stub.c - Part of lm_sensors, Linux kernel modules for hardware
+ monitoring
+
+ Copyright (c) 2004 Mark M. Hoffman <[email protected]>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define DEBUG 1
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+
+static u8 stub_bytes[256];
+static u16 stub_words[256];
+
+/* Return -1 on error. */
+static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags,
+ char read_write, u8 command, int size, union i2c_smbus_data * data)
+{
+ s32 ret;
+
+ switch (size) {
+
+ case I2C_SMBUS_QUICK:
+ dev_dbg(&adap->dev, "smbus quick - addr 0x%02x\n", addr);
+ ret = 0;
+ break;
+
+ case I2C_SMBUS_BYTE_DATA:
+ if (read_write == I2C_SMBUS_WRITE) {
+ stub_bytes[command] = data->byte;
+ dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
+ "wrote 0x%02x at 0x%02x.\n",
+ addr, data->byte, command);
+ } else {
+ data->byte = stub_bytes[command];
+ dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, "
+ "read 0x%02x at 0x%02x.\n",
+ addr, data->byte, command);
+ }
+
+ ret = 0;
+ break;
+
+ case I2C_SMBUS_WORD_DATA:
+ if (read_write == I2C_SMBUS_WRITE) {
+ stub_words[command] = data->word;
+ dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
+ "wrote 0x%04x at 0x%02x.\n",
+ addr, data->word, command);
+ } else {
+ data->word = stub_words[command];
+ dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, "
+ "read 0x%04x at 0x%02x.\n",
+ addr, data->word, command);
+ }
+
+ ret = 0;
+ break;
+
+ default:
+ dev_dbg(&adap->dev, "Unsupported I2C/SMBus command\n");
+ ret = -1;
+ break;
+ } /* switch (size) */
+
+ return ret;
+}
+
+static u32 stub_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_WORD_DATA;
+}
+
+static struct i2c_algorithm smbus_algorithm = {
+ .name = "Non-I2C SMBus adapter",
+ .id = I2C_ALGO_SMBUS,
+ .functionality = stub_func,
+ .smbus_xfer = stub_xfer,
+};
+
+static struct i2c_adapter stub_adapter = {
+ .owner = THIS_MODULE,
+ .class = I2C_CLASS_HWMON,
+ .algo = &smbus_algorithm,
+ .name = "SMBus stub driver",
+};
+
+static int __init i2c_stub_init(void)
+{
+ printk(KERN_INFO "i2c-stub loaded\n");
+ return i2c_add_adapter(&stub_adapter);
+}
+
+static void __exit i2c_stub_exit(void)
+{
+ i2c_del_adapter(&stub_adapter);
+}
+
+MODULE_AUTHOR("Mark M. Hoffman <[email protected]>");
+MODULE_DESCRIPTION("I2C stub driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_stub_init);
+module_exit(i2c_stub_exit);
+

2004-10-20 00:47:44

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2077, 2004/10/19 15:24:45-07:00, [email protected]

[PATCH] I2C: lm87 driver ported to Linux 2.6

This is my port of the lm87 driver to Linux 2.6. It is based on the
preliminary work of Jeff Oliver. I then significantly improved the code,
added functionality, tested the whole thing on a real motherboard, fixed
a couple remaining bugs, and here we are.

I'll port a number of improvements and fixes back to the 2.4 version of
the driver after lm_sensors 2.8.8 is released (i.e. soon).

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/Kconfig | 11
drivers/i2c/chips/Makefile | 1
drivers/i2c/chips/lm87.c | 814 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 826 insertions(+)


diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig 2004-10-19 16:53:32 -07:00
+++ b/drivers/i2c/chips/Kconfig 2004-10-19 16:53:32 -07:00
@@ -169,6 +169,17 @@
This driver can also be built as a module. If so, the module
will be called lm85.

+config SENSORS_LM87
+ tristate "National Semiconductor LM87"
+ depends on I2C && EXPERIMENTAL
+ select I2C_SENSOR
+ help
+ If you say yes here you get support for National Semiconductor LM87
+ sensor chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm87.
+
config SENSORS_LM90
tristate "National Semiconductor LM90 and compatibles"
depends on I2C
diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile 2004-10-19 16:53:32 -07:00
+++ b/drivers/i2c/chips/Makefile 2004-10-19 16:53:32 -07:00
@@ -21,6 +21,7 @@
obj-$(CONFIG_SENSORS_LM80) += lm80.o
obj-$(CONFIG_SENSORS_LM83) += lm83.o
obj-$(CONFIG_SENSORS_LM85) += lm85.o
+obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
diff -Nru a/drivers/i2c/chips/lm87.c b/drivers/i2c/chips/lm87.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/drivers/i2c/chips/lm87.c 2004-10-19 16:53:32 -07:00
@@ -0,0 +1,814 @@
+/*
+ * lm87.c
+ *
+ * Copyright (C) 2000 Frodo Looijaard <[email protected]>
+ * Philip Edelbrock <[email protected]>
+ * Stephen Rousset <[email protected]>
+ * Dan Eaton <[email protected]>
+ * Copyright (C) 2004 Jean Delvare <[email protected]>
+ *
+ * Original port to Linux 2.6 by Jeff Oliver.
+ *
+ * The LM87 is a sensor chip made by National Semiconductor. It monitors up
+ * to 8 voltages (including its own power source), up to three temperatures
+ * (its own plus up to two external ones) and up to two fans. The default
+ * configuration is 6 voltages, two temperatures and two fans (see below).
+ * Voltages are scaled internally with ratios such that the nominal value of
+ * each voltage correspond to a register value of 192 (which means a
+ * resolution of about 0.5% of the nominal value). Temperature values are
+ * reported with a 1 deg resolution and a 3-4 deg accuracy. Complete
+ * datasheet can be obtained from National's website at:
+ * http://www.national.com/pf/LM/LM87.html
+ *
+ * Some functions share pins, so not all functions are available at the same
+ * time. Which are depends on the hardware setup. This driver assumes that
+ * the BIOS configured the chip correctly. In that respect, it differs from
+ * the original driver (from lm_sensors for Linux 2.4), which would force the
+ * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
+ * chipset wiring.
+ * For reference, here is the list of exclusive functions:
+ * - in0+in5 (default) or temp3
+ * - fan1 (default) or in6
+ * - fan2 (default) or in7
+ * - VID lines (default) or IRQ lines (not handled by this driver)
+ *
+ * The LM87 additionally features an analog output, supposedly usable to
+ * control the speed of a fan. All new chips use pulse width modulation
+ * instead. The LM87 is the only hardware monitoring chipset I know of
+ * which uses amplitude modulation. Be careful when using this feature.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <linux/i2c-vid.h>
+
+/*
+ * Addresses to scan
+ * LM87 has three possible addresses: 0x2c, 0x2d and 0x2e.
+ */
+
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { 0x2c, 0x2e, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
+static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
+
+/*
+ * Insmod parameters
+ */
+
+SENSORS_INSMOD_1(lm87);
+
+/*
+ * The LM87 registers
+ */
+
+/* nr in 0..5 */
+#define LM87_REG_IN(nr) (0x20 + (nr))
+#define LM87_REG_IN_MAX(nr) (0x2B + (nr) * 2)
+#define LM87_REG_IN_MIN(nr) (0x2C + (nr) * 2)
+/* nr in 0..1 */
+#define LM87_REG_AIN(nr) (0x28 + (nr))
+#define LM87_REG_AIN_MIN(nr) (0x1A + (nr))
+#define LM87_REG_AIN_MAX(nr) (0x3B + (nr))
+
+static u8 LM87_REG_TEMP[3] = { 0x27, 0x26, 0x20 };
+static u8 LM87_REG_TEMP_HIGH[3] = { 0x39, 0x37, 0x2B };
+static u8 LM87_REG_TEMP_LOW[3] = { 0x3A, 0x38, 0x2C };
+
+#define LM87_REG_TEMP_HW_INT_LOCK 0x13
+#define LM87_REG_TEMP_HW_EXT_LOCK 0x14
+#define LM87_REG_TEMP_HW_INT 0x17
+#define LM87_REG_TEMP_HW_EXT 0x18
+
+/* nr in 0..1 */
+#define LM87_REG_FAN(nr) (0x28 + (nr))
+#define LM87_REG_FAN_MIN(nr) (0x3B + (nr))
+#define LM87_REG_AOUT 0x19
+
+#define LM87_REG_CONFIG 0x40
+#define LM87_REG_CHANNEL_MODE 0x16
+#define LM87_REG_VID_FAN_DIV 0x47
+#define LM87_REG_VID4 0x49
+
+#define LM87_REG_ALARMS1 0x41
+#define LM87_REG_ALARMS2 0x42
+
+#define LM87_REG_COMPANY_ID 0x3E
+#define LM87_REG_REVISION 0x3F
+
+/*
+ * Conversions and various macros
+ * The LM87 uses signed 8-bit values for temperatures.
+ */
+
+#define IN_FROM_REG(reg,scale) (((reg) * (scale) + 96) / 192)
+#define IN_TO_REG(val,scale) ((val) <= 0 ? 0 : \
+ (val) * 192 >= (scale) * 255 ? 255 : \
+ ((val) * 192 + (scale)/2) / (scale))
+
+#define TEMP_FROM_REG(reg) ((reg) * 1000)
+#define TEMP_TO_REG(val) ((val) <= -127500 ? -128 : \
+ (val) >= 126500 ? 127 : \
+ (((val) < 0 ? (val)-500 : (val)+500) / 1000))
+
+#define FAN_FROM_REG(reg,div) ((reg) == 255 || (reg) == 0 ? 0 : \
+ 1350000 + (reg)*(div) / 2) / ((reg)*(div))
+#define FAN_TO_REG(val,div) ((val)*(div) * 255 <= 1350000 ? 255 : \
+ (1350000 + (val)*(div) / 2) / ((val)*(div)))
+
+#define FAN_DIV_FROM_REG(reg) (1 << (reg))
+
+/* analog out is 9.80mV/LSB */
+#define AOUT_FROM_REG(reg) (((reg) * 98 + 5) / 10)
+#define AOUT_TO_REG(val) ((val) <= 0 ? 0 : \
+ (val) >= 2500 ? 255 : \
+ ((val) * 10 + 49) / 98)
+
+/* nr in 0..1 */
+#define CHAN_NO_FAN(nr) (1 << (nr))
+#define CHAN_TEMP3 (1 << 2)
+#define CHAN_VCC_5V (1 << 3)
+#define CHAN_NO_VID (1 << 8)
+
+/*
+ * Functions declaration
+ */
+
+static int lm87_attach_adapter(struct i2c_adapter *adapter);
+static int lm87_detect(struct i2c_adapter *adapter, int address, int kind);
+static void lm87_init_client(struct i2c_client *client);
+static int lm87_detach_client(struct i2c_client *client);
+static struct lm87_data *lm87_update_device(struct device *dev);
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static struct i2c_driver lm87_driver = {
+ .owner = THIS_MODULE,
+ .name = "lm87",
+ .id = I2C_DRIVERID_LM87,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = lm87_attach_adapter,
+ .detach_client = lm87_detach_client,
+};
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct lm87_data {
+ struct i2c_client client;
+ struct semaphore update_lock;
+ char valid; /* zero until following fields are valid */
+ unsigned long last_updated; /* In jiffies */
+
+ u8 channel; /* register value */
+
+ u8 in[8]; /* register value */
+ u8 in_max[8]; /* register value */
+ u8 in_min[8]; /* register value */
+ u16 in_scale[8];
+
+ s8 temp[3]; /* register value */
+ s8 temp_high[3]; /* register value */
+ s8 temp_low[3]; /* register value */
+ s8 temp_crit_int; /* min of two register values */
+ s8 temp_crit_ext; /* min of two register values */
+
+ u8 fan[2]; /* register value */
+ u8 fan_min[2]; /* register value */
+ u8 fan_div[2]; /* register value, shifted right */
+ u8 aout; /* register value */
+
+ u16 alarms; /* register values, combined */
+ u8 vid; /* register values, combined */
+ u8 vrm;
+};
+
+/*
+ * Internal variables
+ */
+
+static int lm87_id;
+
+/*
+ * Sysfs stuff
+ */
+
+static inline int lm87_read_value(struct i2c_client *client, u8 reg)
+{
+ return i2c_smbus_read_byte_data(client, reg);
+}
+
+static inline int lm87_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+#define show_in(offset) \
+static ssize_t show_in##offset##_input(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%u\n", IN_FROM_REG(data->in[offset], \
+ data->in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_min(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%u\n", IN_FROM_REG(data->in_min[offset], \
+ data->in_scale[offset])); \
+} \
+static ssize_t show_in##offset##_max(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%u\n", IN_FROM_REG(data->in_max[offset], \
+ data->in_scale[offset])); \
+} \
+static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
+ show_in##offset##_input, NULL);
+show_in(0);
+show_in(1);
+show_in(2);
+show_in(3);
+show_in(4);
+show_in(5);
+show_in(6);
+show_in(7);
+
+static void set_in_min(struct device *dev, const char *buf, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
+ lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
+ LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
+}
+
+static void set_in_max(struct device *dev, const char *buf, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
+ lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
+ LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
+}
+
+#define set_in(offset) \
+static ssize_t set_in##offset##_min(struct device *dev, \
+ const char *buf, size_t count) \
+{ \
+ set_in_min(dev, buf, offset); \
+ return count; \
+} \
+static ssize_t set_in##offset##_max(struct device *dev, \
+ const char *buf, size_t count) \
+{ \
+ set_in_max(dev, buf, offset); \
+ return count; \
+} \
+static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
+ show_in##offset##_min, set_in##offset##_min); \
+static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
+ show_in##offset##_max, set_in##offset##_max);
+set_in(0);
+set_in(1);
+set_in(2);
+set_in(3);
+set_in(4);
+set_in(5);
+set_in(6);
+set_in(7);
+
+#define show_temp(offset) \
+static ssize_t show_temp##offset##_input(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[offset-1])); \
+} \
+static ssize_t show_temp##offset##_low(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_low[offset-1])); \
+} \
+static ssize_t show_temp##offset##_high(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_high[offset-1])); \
+}\
+static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
+ show_temp##offset##_input, NULL);
+show_temp(1);
+show_temp(2);
+show_temp(3);
+
+static void set_temp_low(struct device *dev, const char *buf, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->temp_low[nr] = TEMP_TO_REG(val);
+ lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
+}
+
+static void set_temp_high(struct device *dev, const char *buf, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->temp_high[nr] = TEMP_TO_REG(val);
+ lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
+}
+
+#define set_temp(offset) \
+static ssize_t set_temp##offset##_low(struct device *dev, \
+ const char *buf, size_t count) \
+{ \
+ set_temp_low(dev, buf, offset-1); \
+ return count; \
+} \
+static ssize_t set_temp##offset##_high(struct device *dev, \
+ const char *buf, size_t count) \
+{ \
+ set_temp_high(dev, buf, offset-1); \
+ return count; \
+} \
+static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
+ show_temp##offset##_high, set_temp##offset##_high); \
+static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
+ show_temp##offset##_low, set_temp##offset##_low);
+set_temp(1);
+set_temp(2);
+set_temp(3);
+
+static ssize_t show_temp_crit_int(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_int));
+}
+
+static ssize_t show_temp_crit_ext(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit_ext));
+}
+
+static DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit_int, NULL);
+static DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit_ext, NULL);
+static DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit_ext, NULL);
+
+#define show_fan(offset) \
+static ssize_t show_fan##offset##_input(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[offset-1], \
+ FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_min(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[offset-1], \
+ FAN_DIV_FROM_REG(data->fan_div[offset-1]))); \
+} \
+static ssize_t show_fan##offset##_div(struct device *dev, char *buf) \
+{ \
+ struct lm87_data *data = lm87_update_device(dev); \
+ return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[offset-1])); \
+} \
+static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
+ show_fan##offset##_input, NULL);
+show_fan(1);
+show_fan(2);
+
+static void set_fan_min(struct device *dev, const char *buf, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->fan_min[nr] = FAN_TO_REG(val,
+ FAN_DIV_FROM_REG(data->fan_div[nr]));
+ lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+ determined in part by the fan clock divider. This follows the principle
+ of least suprise; the user doesn't expect the fan minimum to change just
+ because the divider changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+ size_t count, int nr)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ unsigned long min = FAN_FROM_REG(data->fan_min[nr],
+ FAN_DIV_FROM_REG(data->fan_div[nr]));
+ u8 reg;
+
+ switch (val) {
+ case 1: data->fan_div[nr] = 0; break;
+ case 2: data->fan_div[nr] = 1; break;
+ case 4: data->fan_div[nr] = 2; break;
+ case 8: data->fan_div[nr] = 3; break;
+ default: return -EINVAL;
+ }
+
+ reg = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
+ switch (nr) {
+ case 0:
+ reg = (reg & 0xCF) | (data->fan_div[0] << 4);
+ break;
+ case 1:
+ reg = (reg & 0x3F) | (data->fan_div[1] << 6);
+ break;
+ }
+ lm87_write_value(client, LM87_REG_VID_FAN_DIV, reg);
+
+ data->fan_min[nr] = FAN_TO_REG(min, val);
+ lm87_write_value(client, LM87_REG_FAN_MIN(nr),
+ data->fan_min[nr]);
+ return count;
+}
+
+#define set_fan(offset) \
+static ssize_t set_fan##offset##_min(struct device *dev, const char *buf, \
+ size_t count) \
+{ \
+ set_fan_min(dev, buf, offset-1); \
+ return count; \
+} \
+static ssize_t set_fan##offset##_div(struct device *dev, const char *buf, \
+ size_t count) \
+{ \
+ return set_fan_div(dev, buf, count, offset-1); \
+} \
+static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
+ show_fan##offset##_min, set_fan##offset##_min); \
+static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
+ show_fan##offset##_div, set_fan##offset##_div);
+set_fan(1);
+set_fan(2);
+
+static ssize_t show_alarms(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", data->alarms);
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static ssize_t show_vid(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
+}
+static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
+
+static ssize_t show_vrm(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", data->vrm);
+}
+static ssize_t set_vrm(struct device *dev, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ data->vrm = simple_strtoul(buf, NULL, 10);
+ return count;
+}
+static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm);
+
+static ssize_t show_aout(struct device *dev, char *buf)
+{
+ struct lm87_data *data = lm87_update_device(dev);
+ return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
+}
+static ssize_t set_aout(struct device *dev, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+ data->aout = AOUT_TO_REG(val);
+ lm87_write_value(client, LM87_REG_AOUT, data->aout);
+ return count;
+}
+static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
+
+/*
+ * Real code
+ */
+
+static int lm87_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_detect(adapter, &addr_data, lm87_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *new_client;
+ struct lm87_data *data;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ goto exit;
+
+ if (!(data = kmalloc(sizeof(struct lm87_data), GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ memset(data, 0, sizeof(struct lm87_data));
+
+ /* The common I2C client data is placed right before the
+ LM87-specific data. */
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &lm87_driver;
+ new_client->flags = 0;
+
+ /* Default to an LM87 if forced */
+ if (kind == 0)
+ kind = lm87;
+
+ /* Now, we do the remaining detection. */
+ if (kind < 0) {
+ u8 rev = lm87_read_value(new_client, LM87_REG_REVISION);
+
+ if (rev < 0x01 || rev > 0x08
+ || (lm87_read_value(new_client, LM87_REG_CONFIG) & 0x80)
+ || lm87_read_value(new_client, LM87_REG_COMPANY_ID) != 0x02) {
+ dev_dbg(&adapter->dev,
+ "LM87 detection failed at 0x%02x.\n",
+ address);
+ goto exit_free;
+ }
+ }
+
+ /* We can fill in the remaining client fields */
+ strlcpy(new_client->name, "lm87", I2C_NAME_SIZE);
+ new_client->id = lm87_id++;
+ data->valid = 0;
+ init_MUTEX(&data->update_lock);
+
+ /* Tell the I2C layer a new client has arrived */
+ if ((err = i2c_attach_client(new_client)))
+ goto exit_free;
+
+ /* Initialize the LM87 chip */
+ lm87_init_client(new_client);
+
+ data->in_scale[0] = 2500;
+ data->in_scale[1] = 2700;
+ data->in_scale[2] = (data->channel & CHAN_VCC_5V) ? 5000 : 3300;
+ data->in_scale[3] = 5000;
+ data->in_scale[4] = 12000;
+ data->in_scale[5] = 2700;
+ data->in_scale[6] = 1875;
+ data->in_scale[7] = 1875;
+
+ /* Register sysfs hooks */
+ device_create_file(&new_client->dev, &dev_attr_in1_input);
+ device_create_file(&new_client->dev, &dev_attr_in1_min);
+ device_create_file(&new_client->dev, &dev_attr_in1_max);
+ device_create_file(&new_client->dev, &dev_attr_in2_input);
+ device_create_file(&new_client->dev, &dev_attr_in2_min);
+ device_create_file(&new_client->dev, &dev_attr_in2_max);
+ device_create_file(&new_client->dev, &dev_attr_in3_input);
+ device_create_file(&new_client->dev, &dev_attr_in3_min);
+ device_create_file(&new_client->dev, &dev_attr_in3_max);
+ device_create_file(&new_client->dev, &dev_attr_in4_input);
+ device_create_file(&new_client->dev, &dev_attr_in4_min);
+ device_create_file(&new_client->dev, &dev_attr_in4_max);
+
+ if (data->channel & CHAN_NO_FAN(0)) {
+ device_create_file(&new_client->dev, &dev_attr_in6_input);
+ device_create_file(&new_client->dev, &dev_attr_in6_min);
+ device_create_file(&new_client->dev, &dev_attr_in6_max);
+ } else {
+ device_create_file(&new_client->dev, &dev_attr_fan1_input);
+ device_create_file(&new_client->dev, &dev_attr_fan1_min);
+ device_create_file(&new_client->dev, &dev_attr_fan1_div);
+ }
+ if (data->channel & CHAN_NO_FAN(1)) {
+ device_create_file(&new_client->dev, &dev_attr_in7_input);
+ device_create_file(&new_client->dev, &dev_attr_in7_min);
+ device_create_file(&new_client->dev, &dev_attr_in7_max);
+ } else {
+ device_create_file(&new_client->dev, &dev_attr_fan2_input);
+ device_create_file(&new_client->dev, &dev_attr_fan2_min);
+ device_create_file(&new_client->dev, &dev_attr_fan2_div);
+ }
+
+ device_create_file(&new_client->dev, &dev_attr_temp1_input);
+ device_create_file(&new_client->dev, &dev_attr_temp1_max);
+ device_create_file(&new_client->dev, &dev_attr_temp1_min);
+ device_create_file(&new_client->dev, &dev_attr_temp1_crit);
+ device_create_file(&new_client->dev, &dev_attr_temp2_input);
+ device_create_file(&new_client->dev, &dev_attr_temp2_max);
+ device_create_file(&new_client->dev, &dev_attr_temp2_min);
+ device_create_file(&new_client->dev, &dev_attr_temp2_crit);
+
+ if (data->channel & CHAN_TEMP3) {
+ device_create_file(&new_client->dev, &dev_attr_temp3_input);
+ device_create_file(&new_client->dev, &dev_attr_temp3_max);
+ device_create_file(&new_client->dev, &dev_attr_temp3_min);
+ device_create_file(&new_client->dev, &dev_attr_temp3_crit);
+ } else {
+ device_create_file(&new_client->dev, &dev_attr_in0_input);
+ device_create_file(&new_client->dev, &dev_attr_in0_min);
+ device_create_file(&new_client->dev, &dev_attr_in0_max);
+ device_create_file(&new_client->dev, &dev_attr_in5_input);
+ device_create_file(&new_client->dev, &dev_attr_in5_min);
+ device_create_file(&new_client->dev, &dev_attr_in5_max);
+ }
+
+ if (!(data->channel & CHAN_NO_VID)) {
+ device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
+ device_create_file(&new_client->dev, &dev_attr_vrm);
+ }
+
+ device_create_file(&new_client->dev, &dev_attr_alarms);
+ device_create_file(&new_client->dev, &dev_attr_aout_output);
+
+ return 0;
+
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void lm87_init_client(struct i2c_client *client)
+{
+ struct lm87_data *data = i2c_get_clientdata(client);
+ u8 config;
+
+ data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
+ data->vrm = i2c_which_vrm();
+
+ config = lm87_read_value(client, LM87_REG_CONFIG);
+ if (!(config & 0x01)) {
+ int i;
+
+ /* Limits are left uninitialized after power-up */
+ for (i = 1; i < 6; i++) {
+ lm87_write_value(client, LM87_REG_IN_MIN(i), 0x00);
+ lm87_write_value(client, LM87_REG_IN_MAX(i), 0xFF);
+ }
+ for (i = 0; i < 2; i++) {
+ lm87_write_value(client, LM87_REG_TEMP_HIGH[i], 0x7F);
+ lm87_write_value(client, LM87_REG_TEMP_LOW[i], 0x00);
+ lm87_write_value(client, LM87_REG_AIN_MIN(i), 0x00);
+ lm87_write_value(client, LM87_REG_AIN_MAX(i), 0xFF);
+ }
+ if (data->channel & CHAN_TEMP3) {
+ lm87_write_value(client, LM87_REG_TEMP_HIGH[2], 0x7F);
+ lm87_write_value(client, LM87_REG_TEMP_LOW[2], 0x00);
+ } else {
+ lm87_write_value(client, LM87_REG_IN_MIN(0), 0x00);
+ lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
+ }
+ }
+ if ((config & 0x81) != 0x01) {
+ /* Start monitoring */
+ lm87_write_value(client, LM87_REG_CONFIG,
+ (config & 0xF7) | 0x01);
+ }
+}
+
+static int lm87_detach_client(struct i2c_client *client)
+{
+ int err;
+
+ if ((err = i2c_detach_client(client))) {
+ dev_err(&client->dev, "Client deregistration failed, "
+ "client not detached.\n");
+ return err;
+ }
+
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+static struct lm87_data *lm87_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+
+ down(&data->update_lock);
+
+ if (jiffies - data->last_updated > HZ
+ || jiffies < data->last_updated
+ || !data->valid) {
+ int i, j;
+
+ dev_dbg(&client->dev, "Updating data.\n");
+
+ i = (data->channel & CHAN_TEMP3) ? 1 : 0;
+ j = (data->channel & CHAN_TEMP3) ? 5 : 6;
+ for (; i < j; i++) {
+ data->in[i] = lm87_read_value(client,
+ LM87_REG_IN(i));
+ data->in_min[i] = lm87_read_value(client,
+ LM87_REG_IN_MIN(i));
+ data->in_max[i] = lm87_read_value(client,
+ LM87_REG_IN_MAX(i));
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (data->channel & CHAN_NO_FAN(i)) {
+ data->in[6+i] = lm87_read_value(client,
+ LM87_REG_AIN(i));
+ data->in_max[6+i] = lm87_read_value(client,
+ LM87_REG_AIN_MAX(i));
+ data->in_min[6+i] = lm87_read_value(client,
+ LM87_REG_AIN_MIN(i));
+
+ } else {
+ data->fan[i] = lm87_read_value(client,
+ LM87_REG_FAN(i));
+ data->fan_min[i] = lm87_read_value(client,
+ LM87_REG_FAN_MIN(i));
+ }
+ }
+
+ j = (data->channel & CHAN_TEMP3) ? 3 : 2;
+ for (i = 0 ; i < j; i++) {
+ data->temp[i] = lm87_read_value(client,
+ LM87_REG_TEMP[i]);
+ data->temp_high[i] = lm87_read_value(client,
+ LM87_REG_TEMP_HIGH[i]);
+ data->temp_low[i] = lm87_read_value(client,
+ LM87_REG_TEMP_LOW[i]);
+ }
+
+ i = lm87_read_value(client, LM87_REG_TEMP_HW_INT_LOCK);
+ j = lm87_read_value(client, LM87_REG_TEMP_HW_INT);
+ data->temp_crit_int = min(i, j);
+
+ i = lm87_read_value(client, LM87_REG_TEMP_HW_EXT_LOCK);
+ j = lm87_read_value(client, LM87_REG_TEMP_HW_EXT);
+ data->temp_crit_ext = min(i, j);
+
+ i = lm87_read_value(client, LM87_REG_VID_FAN_DIV);
+ data->fan_div[0] = (i >> 4) & 0x03;
+ data->fan_div[1] = (i >> 6) & 0x03;
+ data->vid = (i & 0x0F)
+ | (lm87_read_value(client, LM87_REG_VID4) & 0x01)
+ << 4;
+
+ data->alarms = lm87_read_value(client, LM87_REG_ALARMS1)
+ | (lm87_read_value(client, LM87_REG_ALARMS2)
+ << 8);
+ data->aout = lm87_read_value(client, LM87_REG_AOUT);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ up(&data->update_lock);
+
+ return data;
+}
+
+static int __init sensors_lm87_init(void)
+{
+ return i2c_add_driver(&lm87_driver);
+}
+
+static void __exit sensors_lm87_exit(void)
+{
+ i2c_del_driver(&lm87_driver);
+}
+
+MODULE_AUTHOR("Jean Delvare <[email protected]> and others");
+MODULE_DESCRIPTION("LM87 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm87_init);
+module_exit(sensors_lm87_exit);

2004-10-20 00:47:43

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2078, 2004/10/19 16:19:10-07:00, [email protected]

[PATCH] I2C: i2c bus power management support

The patch below adds power management support to the i2c bus.
It adds just two small functions which call down to the devices
power management functions if they are present, so the i2c device
drivers will receive the suspend and resume events.

From: Gerd Knorr <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/i2c-core.c | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+)


diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
--- a/drivers/i2c/i2c-core.c 2004-10-19 16:53:27 -07:00
+++ b/drivers/i2c/i2c-core.c 2004-10-19 16:53:27 -07:00
@@ -517,9 +517,29 @@
return 1;
}

+static int i2c_bus_suspend(struct device * dev, u32 state)
+{
+ int rc = 0;
+
+ if (dev->driver && dev->driver->suspend)
+ rc = dev->driver->suspend(dev,state,0);
+ return rc;
+}
+
+static int i2c_bus_resume(struct device * dev)
+{
+ int rc = 0;
+
+ if (dev->driver && dev->driver->resume)
+ rc = dev->driver->resume(dev,0);
+ return rc;
+}
+
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
+ .suspend = i2c_bus_suspend,
+ .resume = i2c_bus_resume,
};

static int __init i2c_init(void)

2004-10-20 00:53:32

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.4, 2004/09/14 10:52:06-07:00, [email protected]

[PATCH] I2C: Update Documentation/i2c/writing-clients

This is a very small an update to Documentation/i2c/writing-clients. The
changes are about i2c client driver ID. It used to say that chip driver
writers should ask for a unique ID. It now explains that such an ID is
not required and they can go without it. Until we get plain rid of it...

The patch additionally features CodingStyle updates. We can't ask people
to respect it and at the same time ignore it in our own docs.

I have made a similar change to the i2c (the project) documentation, and
will propose an update to Marcelo for Linux 2.4 (not sure he will accept
it though).

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


Documentation/i2c/writing-clients | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)


diff -Nru a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
--- a/Documentation/i2c/writing-clients 2004-10-19 16:55:11 -07:00
+++ b/Documentation/i2c/writing-clients 2004-10-19 16:55:11 -07:00
@@ -24,22 +24,24 @@
routines, a client structure specific information like the actual I2C
address.

- static struct i2c_driver foo_driver = {
- .owner = THIS_MODULE,
- .name = "Foo version 2.3 driver",
- .id = I2C_DRIVERID_FOO, /* usually from i2c-id.h */
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = &foo_attach_adapter,
- .detach_client = &foo_detach_client,
- .command = &foo_command /* may be NULL */
- }
+static struct i2c_driver foo_driver = {
+ .owner = THIS_MODULE,
+ .name = "Foo version 2.3 driver",
+ .id = I2C_DRIVERID_FOO, /* from i2c-id.h, optional */
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = &foo_attach_adapter,
+ .detach_client = &foo_detach_client,
+ .command = &foo_command /* may be NULL */
+}

The name can be chosen freely, and may be upto 40 characters long. Please
use something descriptive here.

-The id should be a unique ID. The range 0xf000 to 0xffff is reserved for
-local use, and you can use one of those until you start distributing the
-driver. Before you do that, contact the i2c authors to get your own ID(s).
+If used, the id should be a unique ID. The range 0xf000 to 0xffff is
+reserved for local use, and you can use one of those until you start
+distributing the driver, at which time you should contact the i2c authors
+to get your own ID(s). Note that most of the time you don't need an ID
+at all so you can just omit it.

Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
means that your driver will be notified when new adapters are found.

2004-10-20 00:53:30

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.2, 2004/09/08 12:34:06-07:00, [email protected]

[PATCH] use of MODULE_DEVICE_TABLE in i2c busses driver

hello,
since you say your are interested of using MODULE_DEVICE_TABLE in
http://bugzilla.kernel.org/show_bug.cgi?id=3091 I did a patch (attach).

Also I notice that some pci_device_id are marked __devinitdata that seem a bug
if I read Linux 2.6.0-test3 changelog.
To find them do a "grep pci_device_id /usr/src/linux/drivers/i2c/busses/* |
grep __devinitdata"


Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-ali1535.c | 2 ++
drivers/i2c/busses/i2c-ali1563.c | 2 ++
drivers/i2c/busses/i2c-ali15x3.c | 2 ++
drivers/i2c/busses/i2c-amd756.c | 2 ++
drivers/i2c/busses/i2c-amd8111.c | 2 ++
drivers/i2c/busses/i2c-hydra.c | 2 ++
drivers/i2c/busses/i2c-i801.c | 2 ++
drivers/i2c/busses/i2c-i810.c | 2 ++
drivers/i2c/busses/i2c-nforce2.c | 3 +++
drivers/i2c/busses/i2c-piix4.c | 2 ++
drivers/i2c/busses/i2c-prosavage.c | 2 ++
drivers/i2c/busses/i2c-savage4.c | 2 ++
drivers/i2c/busses/i2c-sis5595.c | 2 ++
drivers/i2c/busses/i2c-sis630.c | 2 ++
drivers/i2c/busses/i2c-sis96x.c | 2 ++
drivers/i2c/busses/i2c-via.c | 2 ++
drivers/i2c/busses/i2c-viapro.c | 2 ++
drivers/i2c/busses/i2c-voodoo3.c | 2 ++
18 files changed, 37 insertions(+)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-ali1535.c 2004-10-19 16:55:57 -07:00
@@ -496,6 +496,8 @@
{ },
};

+MODULE_DEVICE_TABLE (pci, ali1535_ids);
+
static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
if (ali1535_setup(dev)) {
diff -Nru a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
--- a/drivers/i2c/busses/i2c-ali1563.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-ali1563.c 2004-10-19 16:55:57 -07:00
@@ -394,6 +394,8 @@
{},
};

+MODULE_DEVICE_TABLE (pci, ali1563_id_table);
+
static struct pci_driver ali1563_pci_driver = {
.name = "ali1563_i2c",
.id_table = ali1563_id_table,
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-ali15x3.c 2004-10-19 16:55:57 -07:00
@@ -486,6 +486,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, ali15x3_ids);
+
static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
if (ali15x3_setup(dev)) {
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:55:57 -07:00
@@ -320,6 +320,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, amd756_ids);
+
static int __devinit amd756_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-amd8111.c 2004-10-19 16:55:57 -07:00
@@ -336,6 +336,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, amd8111_ids);
+
static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct amd_smbus *smbus;
diff -Nru a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
--- a/drivers/i2c/busses/i2c-hydra.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-hydra.c 2004-10-19 16:55:57 -07:00
@@ -120,6 +120,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, hydra_ids);
+
static int __devinit hydra_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-i801.c 2004-10-19 16:55:57 -07:00
@@ -599,6 +599,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, i801_ids);
+
static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{

diff -Nru a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- a/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:55:57 -07:00
@@ -201,6 +201,8 @@
{ 0, },
};

+MODULE_DEVICE_TABLE (pci, i810_ids);
+
static int __devinit i810_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-nforce2.c 2004-10-19 16:55:57 -07:00
@@ -298,6 +298,9 @@
};


+MODULE_DEVICE_TABLE (pci, nforce2_ids);
+
+
static int __devinit nforce2_probe_smb (struct pci_dev *dev, int reg,
struct nforce2_smbus *smbus, char *name)
{
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-piix4.c 2004-10-19 16:55:57 -07:00
@@ -459,6 +459,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, piix4_ids);
+
static int __devinit piix4_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:55:57 -07:00
@@ -313,6 +313,8 @@
{ 0, },
};

+MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
+
static struct pci_driver prosavage_driver = {
.name = "prosavage_smbus",
.id_table = prosavage_pci_tbl,
diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- a/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:55:57 -07:00
@@ -157,6 +157,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, savage4_ids);
+
static int __devinit savage4_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-sis5595.c 2004-10-19 16:55:57 -07:00
@@ -371,6 +371,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, sis5595_ids);
+
static int __devinit sis5595_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
if (sis5595_setup(dev)) {
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-sis630.c 2004-10-19 16:55:57 -07:00
@@ -468,6 +468,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, sis630_ids);
+
static int __devinit sis630_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
if (sis630_setup(dev)) {
diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-sis96x.c 2004-10-19 16:55:57 -07:00
@@ -278,6 +278,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, sis96x_ids);
+
static int __devinit sis96x_probe(struct pci_dev *dev,
const struct pci_device_id *id)
{
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- a/drivers/i2c/busses/i2c-via.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-via.c 2004-10-19 16:55:57 -07:00
@@ -99,6 +99,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, vt586b_ids);
+
static int __devinit vt586b_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
u16 base;
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-viapro.c 2004-10-19 16:55:57 -07:00
@@ -454,6 +454,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, vt596_ids);
+
static struct pci_driver vt596_driver = {
.name = "vt596_smbus",
.id_table = vt596_ids,
diff -Nru a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- a/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:55:57 -07:00
+++ b/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:55:57 -07:00
@@ -195,6 +195,8 @@
{ 0, }
};

+MODULE_DEVICE_TABLE (pci, voodoo3_ids);
+
static int __devinit voodoo3_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int retval;

2004-10-20 00:58:50

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.2, 2004/09/13 21:29:32-07:00, [email protected]

I2C: fix up __iomem marking for i2c bus drivers

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-i810.c | 2 +-
drivers/i2c/busses/i2c-prosavage.c | 6 +++---
drivers/i2c/busses/i2c-savage4.c | 2 +-
drivers/i2c/busses/i2c-voodoo3.c | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- a/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:55:21 -07:00
+++ b/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:55:21 -07:00
@@ -70,7 +70,7 @@
#define CYCLE_DELAY 10
#define TIMEOUT (HZ / 2)

-static void *ioaddr;
+static void __iomem *ioaddr;

/* The i810 GPIO registers have individual masks for each bit
so we never have to read before writing. Nice. */
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:55:21 -07:00
+++ b/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:55:21 -07:00
@@ -68,7 +68,7 @@
#define MAX_BUSSES 2

struct s_i2c_bus {
- void *mmvga;
+ void __iomem *mmvga;
int i2c_reg;
int adap_ok;
struct i2c_adapter adap;
@@ -76,7 +76,7 @@
};

struct s_i2c_chip {
- void *mmio;
+ void __iomem *mmio;
struct s_i2c_bus i2c_bus[MAX_BUSSES];
};

@@ -181,7 +181,7 @@
/*
* adapter initialisation
*/
-static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, u8 *mmvga, u32 i2c_reg)
+static int i2c_register_bus(struct pci_dev *dev, struct s_i2c_bus *p, void __iomem *mmvga, u32 i2c_reg)
{
int ret;
p->adap.owner = THIS_MODULE;
diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- a/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:55:21 -07:00
+++ b/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:55:21 -07:00
@@ -73,7 +73,7 @@
#define TIMEOUT (HZ / 2)


-static void *ioaddr;
+static void __iomem *ioaddr;

/* The sav GPIO registers don't have individual masks for each bit
so we always have to read before writing. */
diff -Nru a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- a/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:55:21 -07:00
+++ b/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:55:21 -07:00
@@ -61,7 +61,7 @@
#define TIMEOUT (HZ / 2)


-static void *ioaddr;
+static void __iomem *ioaddr;

/* The voo GPIO registers don't have individual masks for each bit
so we always have to read before writing. */

2004-10-20 01:46:23

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2075, 2004/10/19 15:22:05-07:00, [email protected]

[PATCH] I2C: Clean up i2c-amd756 and i2c-prosavage messages

A number of messages in the i2c-amd756 and i2c-prosavage drivers have a
leading ": " (especially the former). This is a legacy from lm_sensors'
printks of the 2.4 times. This patch cleans them up. While I was there,
I dropped a couple useless white spaces and dots as well.


Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-amd756.c | 38 ++++++++++++++++++-------------------
drivers/i2c/busses/i2c-prosavage.c | 4 +--
2 files changed, 21 insertions(+), 21 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:43 -07:00
+++ b/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:43 -07:00
@@ -116,14 +116,14 @@
int result = 0;
int timeout = 0;

- dev_dbg(&adap->dev, ": Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, "
+ dev_dbg(&adap->dev, "Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, "
"DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS),
inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS),
inb_p(SMB_HOST_DATA));

/* Make sure the SMBus host is ready to start transmitting */
if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) {
- dev_dbg(&adap->dev, ": SMBus busy (%04x). Waiting... \n", temp);
+ dev_dbg(&adap->dev, "SMBus busy (%04x). Waiting...\n", temp);
do {
msleep(1);
temp = inw_p(SMB_GLOBAL_STATUS);
@@ -131,7 +131,7 @@
(timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
- dev_dbg(&adap->dev, ": Busy wait timeout (%04x)\n", temp);
+ dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp);
goto abort;
}
timeout = 0;
@@ -148,46 +148,46 @@

/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
- dev_dbg(&adap->dev, ": Completion timeout!\n");
+ dev_dbg(&adap->dev, "Completion timeout!\n");
goto abort;
}

if (temp & GS_PRERR_STS) {
result = -1;
- dev_dbg(&adap->dev, ": SMBus Protocol error (no response)!\n");
+ dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
}

if (temp & GS_COL_STS) {
result = -1;
- dev_warn(&adap->dev, " SMBus collision!\n");
+ dev_warn(&adap->dev, "SMBus collision!\n");
}

if (temp & GS_TO_STS) {
result = -1;
- dev_dbg(&adap->dev, ": SMBus protocol timeout!\n");
+ dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
}

if (temp & GS_HCYC_STS)
- dev_dbg(&adap->dev, " SMBus protocol success!\n");
+ dev_dbg(&adap->dev, "SMBus protocol success!\n");

outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);

#ifdef DEBUG
if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) {
dev_dbg(&adap->dev,
- ": Failed reset at end of transaction (%04x)\n", temp);
+ "Failed reset at end of transaction (%04x)\n", temp);
}
#endif

dev_dbg(&adap->dev,
- ": Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
+ "Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n",
inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE),
inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA));

return result;

abort:
- dev_warn(&adap->dev, ": Sending abort.\n");
+ dev_warn(&adap->dev, "Sending abort\n");
outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
msleep(100);
outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
@@ -204,7 +204,7 @@
/** TODO: Should I supporte the 10-bit transfers? */
switch (size) {
case I2C_SMBUS_PROC_CALL:
- dev_dbg(&adap->dev, ": I2C_SMBUS_PROC_CALL not supported!\n");
+ dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
/* TODO: Well... It is supported, I'm just not sure what to do here... */
return -1;
case I2C_SMBUS_QUICK:
@@ -334,8 +334,8 @@
u8 temp;

if (amd756_ioport) {
- dev_err(&pdev->dev, ": Only one device supported. "
- "(you have a strange motherboard, btw..)\n");
+ dev_err(&pdev->dev, "Only one device supported "
+ "(you have a strange motherboard, btw)\n");
return -ENODEV;
}

@@ -352,7 +352,7 @@
pci_read_config_byte(pdev, SMBGCFG, &temp);
if ((temp & 128) == 0) {
dev_err(&pdev->dev,
- ": Error: SMBus controller I/O not enabled!\n");
+ "Error: SMBus controller I/O not enabled!\n");
return -ENODEV;
}

@@ -364,14 +364,14 @@
}

if (!request_region(amd756_ioport, SMB_IOSIZE, "amd756-smbus")) {
- dev_err(&pdev->dev, ": SMB region 0x%x already in use!\n",
+ dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
amd756_ioport);
return -ENODEV;
}

pci_read_config_byte(pdev, SMBREV, &temp);
- dev_dbg(&pdev->dev, ": SMBREV = 0x%X\n", temp);
- dev_dbg(&pdev->dev, ": AMD756_smba = 0x%X\n", amd756_ioport);
+ dev_dbg(&pdev->dev, "SMBREV = 0x%X\n", temp);
+ dev_dbg(&pdev->dev, "AMD756_smba = 0x%X\n", amd756_ioport);

/* set up the driverfs linkage to our parent device */
amd756_adapter.dev.parent = &pdev->dev;
@@ -382,7 +382,7 @@
error = i2c_add_adapter(&amd756_adapter);
if (error) {
dev_err(&pdev->dev,
- ": Adapter registration failed, module not inserted.\n");
+ "Adapter registration failed, module not inserted\n");
goto out_err;
}

diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:53:43 -07:00
+++ b/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:53:43 -07:00
@@ -228,7 +228,7 @@

ret = i2c_bit_del_bus(&chip->i2c_bus[i].adap);
if (ret) {
- dev_err(&dev->dev, ": %s not removed\n",
+ dev_err(&dev->dev, "%s not removed\n",
chip->i2c_bus[i].adap.name);
}
}
@@ -298,7 +298,7 @@
}
return 0;
err_adap:
- dev_err(&dev->dev, ": %s failed\n", bus->adap.name);
+ dev_err(&dev->dev, "%s failed\n", bus->adap.name);
prosavage_remove(dev);
return ret;
}

2004-10-20 01:46:25

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.6, 2004/09/21 16:39:31-07:00, [email protected]

[PATCH] i2c: Add Intel VRD 10.0 and AMD Opteron VID support

This patch adds support for Intel VRD 10.0 and AMD Opteron VID calculations.
It is based on the lm_sensors project CVS, r1.6.

Signed-off-by: Mark M. Hoffman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


include/linux/i2c-vid.h | 36 +++++++++++++++++++++++++++++++++++-
1 files changed, 35 insertions(+), 1 deletion(-)


diff -Nru a/include/linux/i2c-vid.h b/include/linux/i2c-vid.h
--- a/include/linux/i2c-vid.h 2004-10-19 16:55:01 -07:00
+++ b/include/linux/i2c-vid.h 2004-10-19 16:55:01 -07:00
@@ -29,7 +29,22 @@
*/

/*
- Legal val values 00 - 1F.
+ AMD Opteron processors don't follow the Intel VRM spec.
+ I'm going to "make up" 2.4 as the VRM spec for the Opterons.
+ No good reason just a mnemonic for the 24x Opteron processor
+ series
+
+ Opteron VID encoding is:
+
+ 00000 = 1.550 V
+ 00001 = 1.525 V
+ . . . .
+ 11110 = 0.800 V
+ 11111 = 0.000 V (off)
+ */
+
+/*
+ Legal val values 0x00 - 0x1f; except for VRD 10.0, 0x00 - 0x3f.
vrm is the Intel VRM document version.
Note: vrm version is scaled by 10 and the return value is scaled by 1000
to avoid floating point in the kernel.
@@ -41,9 +56,28 @@

static inline int vid_from_reg(int val, int vrm)
{
+ int vid;
+
switch(vrm) {
+
case 0:
return 0;
+
+ case 100: /* VRD 10.0 */
+ if((val & 0x1f) == 0x1f)
+ return 0;
+ if((val & 0x1f) <= 0x09 || val == 0x0a)
+ vid = 10875 - (val & 0x1f) * 250;
+ else
+ vid = 18625 - (val & 0x1f) * 250;
+ if(val & 0x20)
+ vid -= 125;
+ vid /= 10; /* only return 3 dec. places for now */
+ return vid;
+
+ case 24: /* Opteron processor */
+ return(val == 0x1f ? 0 : 1550 - val * 25);
+
case 91: /* VRM 9.1 */
case 90: /* VRM 9.0 */
return(val == 0x1f ? 0 :

2004-10-20 01:46:24

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2070, 2004/10/19 15:20:22-07:00, [email protected]

[PATCH] I2C: Fourth auto-fan control interface proposal

Here comes my fourth (and hopefully last) sysfs interface proposal for
implementing auto-fan control in 2.6. Previous proposals have been
discussed here:

[1] http://archives.andrew.net.au/lm-sensors/msg07517.html
[2] http://archives.andrew.net.au/lm-sensors/msg08049.html
[3] http://archives.andrew.net.au/lm-sensors/msg18008.html

The interface is still made up of two parts: per fan temp channels
selection, and trip points selection. Changes from the third proposal:

pwm[1-*]_enable value 2 is now used to explicitely state the auto pwm
mode. This was proposed by Mark D. Studebaker [4].

[4] http://archives.andrew.net.au/lm-sensors/msg18011.html

Temp channels selection
=======================

Renamed files from fan[1-*]_auto_channels to
pwm[1-*]_auto_channels_temp. The change from fan tp pwm is to match the
recent renaming suggested by Mark M. Hoffman [5]. The "_temp" suffix is
to leave some room for a "_fan" suffix at a later time if new chips
drive auto pwm according to fan speeds instead of temperature.

[5] http://archives.andrew.net.au/lm-sensors/msg18797.html

Trip points
===========

Trip points are now numbered (point1, point2, etc...) instead of named
(_off, _min, _max, _full...). This solves the problem of various chips
having a different number of trip points. The interface is still chip
independent in that it doesn't require chip-specific knowledge to be
used by user-space apps.

The reason for this change is that newer chips tend to have more trip
points. the LM63 has 8, the LM93 has no less than 12. Also, I read in
the LM63 datasheet that ideal pwm vs temperature curve were parabolic in
shape. Seems hard to achieve this if we arbitrarily lock the number of
trip points to 3 ;)

I also introduced an optional hysteresis temperature for trip points.
The LM63 has this. Since it makes full sense I'd expect other chips to
propose this as well.

As before, there are two sets of files, each chip driver picks the one
matching its internal model: trip points are either temperature
channel-dependent (ADM1031...) or pwm channel-dependent (IT87xx...). If
we ever come accross fan speed-driven pwm outputs where trip points are
fan channel-dependent we may have to offer a third set of files. We'll
see when/if this happens.

I hope I have taken everyone's comments and advice into account and we
can make this interface proposal part of the sysfs interface standard
now. I'm sorry it took so long. Comments welcome.


Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


Documentation/i2c/sysfs-interface | 25 ++++++++++++++++++++++++-
1 files changed, 24 insertions(+), 1 deletion(-)


diff -Nru a/Documentation/i2c/sysfs-interface b/Documentation/i2c/sysfs-interface
--- a/Documentation/i2c/sysfs-interface 2004-10-19 16:54:09 -07:00
+++ b/Documentation/i2c/sysfs-interface 2004-10-19 16:54:09 -07:00
@@ -138,6 +138,7 @@
*******
* PWM *
*******
+
pwm[1-3] Pulse width modulation fan control.
Integer value in the range 0 to 255
Read/Write
@@ -147,8 +148,30 @@
Switch PWM on and off.
Not always present even if fan*_pwm is.
0 to turn off
- 1 to turn on
+ 1 to turn on in manual mode
+ 2 to turn on in automatic mode
Read/Write
+
+pwm[1-*]_auto_channels_temp
+ Select which temperature channels affect this PWM output in
+ auto mode. Bitfield, 1 is temp1, 2 is temp2, 4 is temp3 etc...
+ Which values are possible depend on the chip used.
+
+pwm[1-*]_auto_point[1-*]_pwm
+pwm[1-*]_auto_point[1-*]_temp
+pwm[1-*]_auto_point[1-*]_temp_hyst
+ Define the PWM vs temperature curve. Number of trip points is
+ chip-dependent. Use this for chips which associate trip points
+ to PWM output channels.
+
+OR
+
+temp[1-*]_auto_point[1-*]_pwm
+temp[1-*]_auto_point[1-*]_temp
+temp[1-*]_auto_point[1-*]_temp_hyst
+ Define the PWM vs temperature curve. Number of trip points is
+ chip-dependent. Use this for chips which associate trip points
+ to temperature channels.


****************

2004-10-20 00:53:44

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.5, 2004/09/15 15:27:44-07:00, [email protected]

[PATCH] w1_therm: more precise temperature calculation

This patch will introduce new temperature calculation mechanism which
allows to use up to 9bit resolution(currently 3 digits after point).
Fixed timeout issues with multiple repeated reading.

Signed-off-by: Evgeniy Polyakov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/w1/w1_therm.c | 71 ++++++++++++++++++++++++++++++--------------------
1 files changed, 43 insertions(+), 28 deletions(-)


diff -Nru a/drivers/w1/w1_therm.c b/drivers/w1/w1_therm.c
--- a/drivers/w1/w1_therm.c 2004-10-19 16:55:06 -07:00
+++ b/drivers/w1/w1_therm.c 2004-10-19 16:55:06 -07:00
@@ -59,19 +59,28 @@
return sprintf(buf, "%s\n", sl->name);
}

+static inline int w1_convert_temp(u8 rom[9])
+{
+ int t, h;
+
+ if (rom[1] == 0)
+ t = ((s32)rom[0] >> 1)*1000;
+ else
+ t = 1000*(-1*(s32)(0x100-rom[0]) >> 1);
+
+ t -= 250;
+ h = 1000*((s32)rom[7] - (s32)rom[6]);
+ h /= (s32)rom[7];
+ t += h;
+
+ return t;
+}
+
static ssize_t w1_therm_read_temp(struct device *dev, char *buf)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
- s16 temp;
-
- /*
- * Must be more precise.
- */
- temp = 0;
- temp <<= sl->rom[1] / 2;
- temp |= sl->rom[0] / 2;

- return sprintf(buf, "%d\n", temp * 1000);
+ return sprintf(buf, "%d\n", w1_convert_temp(sl->rom));
}

static int w1_therm_check_rom(u8 rom[9])
@@ -92,7 +101,6 @@
struct w1_master *dev = sl->master;
u8 rom[9], crc, verdict;
int i, max_trying = 10;
- u16 temp;

atomic_inc(&sl->refcnt);
if (down_interruptible(&sl->master->mutex)) {
@@ -120,6 +128,7 @@
if (!w1_reset_bus (dev)) {
int count = 0;
u8 match[9] = {W1_MATCH_ROM, };
+ unsigned long tm;

memcpy(&match[1], (u64 *) & sl->reg_num, 8);

@@ -127,24 +136,29 @@

w1_write_8(dev, W1_CONVERT_TEMP);

- if (count < 10) {
- if (!w1_reset_bus(dev)) {
- w1_write_block(dev, match, 9);
-
- w1_write_8(dev, W1_READ_SCRATCHPAD);
- if ((count = w1_read_block(dev, rom, 9)) != 9) {
- dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
- }
+ tm = jiffies + msecs_to_jiffies(750);
+ while(time_before(jiffies, tm)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(tm-jiffies);

- crc = w1_calc_crc8(rom, 8);
+ if (signal_pending(current))
+ flush_signals(current);
+ }

- if (rom[8] == crc && rom[0])
- verdict = 1;
+ if (!w1_reset_bus (dev)) {
+ w1_write_block(dev, match, 9);
+
+ w1_write_8(dev, W1_READ_SCRATCHPAD);
+ if ((count = w1_read_block(dev, rom, 9)) != 9) {
+ dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
}
+
+ crc = w1_calc_crc8(rom, 8);
+
+ if (rom[8] == crc && rom[0])
+ verdict = 1;
+
}
- else
- dev_warn(&dev->dev,
- "18S20 doesn't respond to CONVERT_TEMP.\n");
}

if (!w1_therm_check_rom(rom))
@@ -157,12 +171,13 @@
crc, (verdict) ? "YES" : "NO");
if (verdict)
memcpy(sl->rom, rom, sizeof(sl->rom));
+ else
+ dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
+
for (i = 0; i < 9; ++i)
count += sprintf(buf + count, "%02x ", sl->rom[i]);
- temp = 0;
- temp <<= sl->rom[1] / 2;
- temp |= sl->rom[0] / 2;
- count += sprintf(buf + count, "t=%u\n", temp);
+
+ count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom));
out:
up(&dev->mutex);
out_dec:

2004-10-20 01:55:57

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.6, 2004/09/08 12:36:05-07:00, [email protected]

[PATCH] I2C: Fix macro calls in chip drivers

I noticed that some I2C chip drivers (all written or reviewed by me, I
feel ashamed to say) misuse macros. Passing function calls
(simple_strtol in this case) to macros evaluating their argument up to 4
times is certainly not wise and obviously performs poorly. It is not
critical in that it happens only when writing to the chips (setting
limits), which doesn't happen that often. However I'd say it's worth
fixing.

Thus, the patch below fixes that, by moving the function calls outside
of the macro calls.


Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/adm1025.c | 14 ++++++++------
drivers/i2c/chips/gl518sm.c | 6 ++++--
drivers/i2c/chips/lm80.c | 5 +++--
drivers/i2c/chips/lm83.c | 3 ++-
drivers/i2c/chips/lm90.c | 6 ++++--
drivers/i2c/chips/max1619.c | 3 ++-
6 files changed, 23 insertions(+), 14 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c
--- a/drivers/i2c/chips/adm1025.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/adm1025.c 2004-10-19 16:55:37 -07:00
@@ -212,8 +212,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
- data->in_min[offset] = IN_TO_REG(simple_strtol(buf, NULL, 10), \
- in_scale[offset]); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \
data->in_min[offset]); \
return count; \
@@ -223,8 +223,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
- data->in_max[offset] = IN_TO_REG(simple_strtol(buf, NULL, 10), \
- in_scale[offset]); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \
data->in_max[offset]); \
return count; \
@@ -246,7 +246,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
- data->temp_min[offset-1] = TEMP_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->temp_min[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \
data->temp_min[offset-1]); \
return count; \
@@ -256,7 +257,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct adm1025_data *data = i2c_get_clientdata(client); \
- data->temp_max[offset-1] = TEMP_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->temp_max[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \
data->temp_max[offset-1]); \
return count; \
diff -Nru a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c
--- a/drivers/i2c/chips/gl518sm.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/gl518sm.c 2004-10-19 16:55:37 -07:00
@@ -217,7 +217,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct gl518_data *data = i2c_get_clientdata(client); \
- data->value = type##_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = type##_TO_REG(val); \
gl518_write_value(client, reg, data->value); \
return count; \
}
@@ -229,7 +230,8 @@
struct i2c_client *client = to_i2c_client(dev); \
struct gl518_data *data = i2c_get_clientdata(client); \
int regvalue = gl518_read_value(client, reg); \
- data->value = type##_TO_REG(simple_strtoul(buf, NULL, 10)); \
+ unsigned long val = simple_strtoul(buf, NULL, 10); \
+ data->value = type##_TO_REG(val); \
regvalue = (regvalue & ~mask) | (data->value << shift); \
gl518_write_value(client, reg, regvalue); \
return count; \
diff -Nru a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c
--- a/drivers/i2c/chips/lm80.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/lm80.c 2004-10-19 16:55:37 -07:00
@@ -262,14 +262,15 @@
{
struct i2c_client *client = to_i2c_client(dev);
struct lm80_data *data = i2c_get_clientdata(client);
- unsigned long min;
+ unsigned long min, val;
u8 reg;

/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));

- data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10));
+ val = simple_strtoul(buf, NULL, 10);
+ data->fan_div[nr] = DIV_TO_REG(val);

reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1))))
| (data->fan_div[nr] << (2 * (nr + 1)));
diff -Nru a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
--- a/drivers/i2c/chips/lm83.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/lm83.c 2004-10-19 16:55:37 -07:00
@@ -180,7 +180,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm83_data *data = i2c_get_clientdata(client); \
- data->value = TEMP_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
return count; \
}
diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
--- a/drivers/i2c/chips/lm90.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/lm90.c 2004-10-19 16:55:37 -07:00
@@ -214,7 +214,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
- data->value = TEMP1_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = TEMP1_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
return count; \
}
@@ -224,7 +225,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct lm90_data *data = i2c_get_clientdata(client); \
- data->value = TEMP2_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = TEMP2_TO_REG(val); \
i2c_smbus_write_byte_data(client, regh, data->value >> 8); \
i2c_smbus_write_byte_data(client, regl, data->value & 0xff); \
return count; \
diff -Nru a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c
--- a/drivers/i2c/chips/max1619.c 2004-10-19 16:55:37 -07:00
+++ b/drivers/i2c/chips/max1619.c 2004-10-19 16:55:37 -07:00
@@ -145,7 +145,8 @@
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct max1619_data *data = i2c_get_clientdata(client); \
- data->value = TEMP_TO_REG(simple_strtol(buf, NULL, 10)); \
+ long val = simple_strtol(buf, NULL, 10); \
+ data->value = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
return count; \
}

2004-10-20 01:55:56

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.4, 2004/09/29 11:03:48-07:00, [email protected]

I2C: convert scx200_acb driver to not use pci_find_device

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/scx200_acb.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)


diff -Nru a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
--- a/drivers/i2c/busses/scx200_acb.c 2004-10-19 16:54:40 -07:00
+++ b/drivers/i2c/busses/scx200_acb.c 2004-10-19 16:54:40 -07:00
@@ -503,6 +503,12 @@
return rc;
}

+static struct pci_device_id scx200[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
+ { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
+ { },
+};
+
static int __init scx200_acb_init(void)
{
int i;
@@ -511,12 +517,7 @@
pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");

/* Verify that this really is a SCx200 processor */
- if (pci_find_device(PCI_VENDOR_ID_NS,
- PCI_DEVICE_ID_NS_SCx200_BRIDGE,
- NULL) == NULL
- && pci_find_device(PCI_VENDOR_ID_NS,
- PCI_DEVICE_ID_NS_SC1100_BRIDGE,
- NULL) == NULL)
+ if (pci_dev_present(scx200) == 0)
return -ENODEV;

rc = -ENXIO;

2004-10-20 01:55:55

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.5, 2004/09/08 12:35:33-07:00, [email protected]

[PATCH] I2C: Do not init global variables to 0

This trivial patch enforces the rule that global variables should not be
explicitely initialized to 0 for all i2c chip drivers.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/adm1021.c | 2 +-
drivers/i2c/chips/adm1025.c | 2 +-
drivers/i2c/chips/ds1621.c | 2 +-
drivers/i2c/chips/eeprom.c | 2 +-
drivers/i2c/chips/fscher.c | 2 +-
drivers/i2c/chips/gl518sm.c | 2 +-
drivers/i2c/chips/it87.c | 2 +-
drivers/i2c/chips/lm75.c | 2 +-
drivers/i2c/chips/lm77.c | 2 +-
drivers/i2c/chips/lm80.c | 2 +-
drivers/i2c/chips/lm83.c | 2 +-
drivers/i2c/chips/lm85.c | 2 +-
drivers/i2c/chips/lm90.c | 2 +-
drivers/i2c/chips/max1619.c | 2 +-
drivers/i2c/chips/pcf8574.c | 2 +-
drivers/i2c/chips/pcf8591.c | 2 +-
16 files changed, 16 insertions(+), 16 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/adm1021.c 2004-10-19 16:55:42 -07:00
@@ -148,7 +148,7 @@
.detach_client = adm1021_detach_client,
};

-static int adm1021_id = 0;
+static int adm1021_id;

#define show(value) \
static ssize_t show_##value(struct device *dev, char *buf) \
diff -Nru a/drivers/i2c/chips/adm1025.c b/drivers/i2c/chips/adm1025.c
--- a/drivers/i2c/chips/adm1025.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/adm1025.c 2004-10-19 16:55:42 -07:00
@@ -153,7 +153,7 @@
* Internal variables
*/

-static int adm1025_id = 0;
+static int adm1025_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/ds1621.c b/drivers/i2c/chips/ds1621.c
--- a/drivers/i2c/chips/ds1621.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/ds1621.c 2004-10-19 16:55:42 -07:00
@@ -96,7 +96,7 @@
.detach_client = ds1621_detach_client,
};

-static int ds1621_id = 0;
+static int ds1621_id;

/* All registers are word-sized, except for the configuration register.
DS1621 uses a high-byte first convention, which is exactly opposite to
diff -Nru a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
--- a/drivers/i2c/chips/eeprom.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/eeprom.c 2004-10-19 16:55:42 -07:00
@@ -86,7 +86,7 @@
.detach_client = eeprom_detach_client,
};

-static int eeprom_id = 0;
+static int eeprom_id;

static void eeprom_update_client(struct i2c_client *client, u8 slice)
{
diff -Nru a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c
--- a/drivers/i2c/chips/fscher.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/fscher.c 2004-10-19 16:55:42 -07:00
@@ -156,7 +156,7 @@
* Internal variables
*/

-static int fscher_id = 0;
+static int fscher_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c
--- a/drivers/i2c/chips/gl518sm.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/gl518sm.c 2004-10-19 16:55:42 -07:00
@@ -164,7 +164,7 @@
* Internal variables
*/

-static int gl518_id = 0;
+static int gl518_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/it87.c 2004-10-19 16:55:42 -07:00
@@ -226,7 +226,7 @@
.detach_client = it87_detach_client,
};

-static int it87_id = 0;
+static int it87_id;

static ssize_t show_in(struct device *dev, char *buf, int nr)
{
diff -Nru a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c
--- a/drivers/i2c/chips/lm75.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm75.c 2004-10-19 16:55:42 -07:00
@@ -74,7 +74,7 @@
.detach_client = lm75_detach_client,
};

-static int lm75_id = 0;
+static int lm75_id;

#define show(value) \
static ssize_t show_##value(struct device *dev, char *buf) \
diff -Nru a/drivers/i2c/chips/lm77.c b/drivers/i2c/chips/lm77.c
--- a/drivers/i2c/chips/lm77.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm77.c 2004-10-19 16:55:42 -07:00
@@ -83,7 +83,7 @@
.detach_client = lm77_detach_client,
};

-static int lm77_id = 0;
+static int lm77_id;

/* straight from the datasheet */
#define LM77_TEMP_MIN (-55000)
diff -Nru a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c
--- a/drivers/i2c/chips/lm80.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm80.c 2004-10-19 16:55:42 -07:00
@@ -145,7 +145,7 @@
* Internal variables
*/

-static int lm80_id = 0;
+static int lm80_id;

/*
* Driver data (common to all clients)
diff -Nru a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
--- a/drivers/i2c/chips/lm83.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm83.c 2004-10-19 16:55:42 -07:00
@@ -152,7 +152,7 @@
* Internal variables
*/

-static int lm83_id = 0;
+static int lm83_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm85.c 2004-10-19 16:55:42 -07:00
@@ -405,7 +405,7 @@
};

/* Unique ID assigned to each LM85 detected */
-static int lm85_id = 0;
+static int lm85_id;


/* 4 Fans */
diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
--- a/drivers/i2c/chips/lm90.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/lm90.c 2004-10-19 16:55:42 -07:00
@@ -187,7 +187,7 @@
* Internal variables
*/

-static int lm90_id = 0;
+static int lm90_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/max1619.c b/drivers/i2c/chips/max1619.c
--- a/drivers/i2c/chips/max1619.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/max1619.c 2004-10-19 16:55:42 -07:00
@@ -120,7 +120,7 @@
* Internal variables
*/

-static int max1619_id = 0;
+static int max1619_id;

/*
* Sysfs stuff
diff -Nru a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
--- a/drivers/i2c/chips/pcf8574.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/pcf8574.c 2004-10-19 16:55:42 -07:00
@@ -77,7 +77,7 @@
.detach_client = pcf8574_detach_client,
};

-static int pcf8574_id = 0;
+static int pcf8574_id;

/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, char *buf)
diff -Nru a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
--- a/drivers/i2c/chips/pcf8591.c 2004-10-19 16:55:42 -07:00
+++ b/drivers/i2c/chips/pcf8591.c 2004-10-19 16:55:42 -07:00
@@ -99,7 +99,7 @@
.detach_client = pcf8591_detach_client,
};

-static int pcf8591_id = 0;
+static int pcf8591_id;

/* following are the sysfs callback functions */
#define show_in_channel(channel) \

2004-10-20 01:55:52

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2074, 2004/10/19 15:21:48-07:00, [email protected]

[PATCH] I2C: Fix amd756 name

This sets the proper name for busses supported by the i2c-amd756 driver.
So far, all busses were named AMD756 regardless of the real hardware.
Setting the real name is certainly less confusing for the user, and the
sensors-detect script expects this too.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-amd756.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:48 -07:00
+++ b/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:48 -07:00
@@ -310,6 +310,10 @@
};

enum chiptype { AMD756, AMD766, AMD768, NFORCE, AMD8111 };
+static const char* chipname[] = {
+ "AMD756", "AMD766", "AMD768",
+ "nVidia nForce", "AMD8111",
+};

static struct pci_device_id amd756_ids[] = {
{PCI_VENDOR_ID_AMD, 0x740B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD756 },
@@ -372,8 +376,8 @@
/* set up the driverfs linkage to our parent device */
amd756_adapter.dev.parent = &pdev->dev;

- snprintf(amd756_adapter.name, I2C_NAME_SIZE,
- "SMBus AMD756 adapter at %04x", amd756_ioport);
+ sprintf(amd756_adapter.name, "SMBus %s adapter at %04x",
+ chipname[id->driver_data], amd756_ioport);

error = i2c_add_adapter(&amd756_adapter);
if (error) {

2004-10-20 01:55:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2072, 2004/10/19 15:21:15-07:00, [email protected]

[PATCH] I2C: replace schedule_timeout() with msleep_interruptible() in i2c-ibm_iic.c

Use msleep_interruptible() instead of schedule_timeout() to
guarantee the task delays as expected. Remove the unnecessary
set_current_state() following the if, as schedule_timeout() [and thus,
mlseep_interruptible()] is guaranteed to return in TASK_RUNNING.

Signed-off-by: Nishanth Aravamudan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-ibm_iic.c | 4 +---
1 files changed, 1 insertion(+), 3 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
--- a/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-19 16:53:58 -07:00
+++ b/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-19 16:53:58 -07:00
@@ -416,10 +416,8 @@
init_waitqueue_entry(&wait, current);

add_wait_queue(&dev->wq, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
if (in_8(&iic->sts) & STS_PT)
- schedule_timeout(dev->adap.timeout * HZ);
- set_current_state(TASK_RUNNING);
+ msleep_interruptible(dev->adap.timeout * 1000);
remove_wait_queue(&dev->wq, &wait);

if (unlikely(signal_pending(current))){

2004-10-20 00:37:03

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.8, 2004/09/09 10:02:27-07:00, [email protected]

[PATCH] W1: let W1 select NET.

On Wed, 2004-08-25 at 23:41, Greg KH wrote:
> On Wed, Aug 25, 2004 at 11:21:29PM +0400, Evgeniy Polyakov wrote:
> > On Wed, 25 Aug 2004 10:49:12 -0700
> > Greg KH <[email protected]> wrote:
> >
> > > On Fri, Aug 13, 2004 at 02:35:40PM +0400, Evgeniy Polyakov wrote:
> > > > The patch below fixes this issue by letting W1 select NET.
> > > >
> > > > Patch was created by Adrian Bunk <[email protected]>.
> > >
> > > Nah, I'm going to hold off on this, it's not really needed (who
> > > doesn't build with NET enabled...)
> >
> > Hmmm, but someone really may want to build it without NET support.
> > I have an idea(I thought it out exactly for the case when you do not
> > apply it) to disable networking(netlink) support in compilation time if
> > CONFIG_NET is not defined.
> > And add some warning like:
> >
> > #ifndef CONFIG_NET
> > #warning Netlink support is disabled.
> > #endif
>
> That sounds like a good fix.



Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/w1/Makefile | 4 ++++
drivers/w1/w1_netlink.c | 8 ++++++++
2 files changed, 12 insertions(+)


diff -Nru a/drivers/w1/Makefile b/drivers/w1/Makefile
--- a/drivers/w1/Makefile 2004-10-19 16:55:26 -07:00
+++ b/drivers/w1/Makefile 2004-10-19 16:55:26 -07:00
@@ -2,6 +2,10 @@
# Makefile for the Dallas's 1-wire bus.
#

+ifneq ($(CONFIG_NET), y)
+EXTRA_CFLAGS += -DNETLINK_DISABLED
+endif
+
obj-$(CONFIG_W1) += wire.o
wire-objs := w1.o w1_int.o w1_family.o w1_netlink.o w1_io.o

diff -Nru a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
--- a/drivers/w1/w1_netlink.c 2004-10-19 16:55:26 -07:00
+++ b/drivers/w1/w1_netlink.c 2004-10-19 16:55:26 -07:00
@@ -26,6 +26,7 @@
#include "w1_log.h"
#include "w1_netlink.h"

+#ifndef NETLINK_DISABLED
void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
{
unsigned int size;
@@ -53,3 +54,10 @@
nlmsg_failure:
return;
}
+#else
+#warning Netlink support is disabled. Please compile with NET support enabled.
+
+void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
+{
+}
+#endif

2004-10-20 02:40:33

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.5, 2004/09/29 13:29:06-07:00, [email protected]

[PATCH] I2C: Store lm83 and lm90 temperatures in signed

Back when I wrote the lm83 and lm90 drivers, I decided to use unsigned
variables to store temperature values as mirrored from the chipset
registers. I wonder why, since the registers use signed values
themselves. The patch below changes the variables back to signed types,
so as to simplify the conversions made by the driver, making them faster
and easier to understand.

Additionally, the lm90 driver was lacking boundary checkings and proper
rounding when writing temperature limits to the chipset, so I added
these. I also reworded the comments about internal temperature values
representation for all chipsets.

Tested to work fine on my (LM90-compatible) ADM1032 chip. lm83 patch
untested, but it is more simple and directly copied from the lm90, so I
am confident it works fine too.


Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/lm83.c | 17 +++++++++--------
drivers/i2c/chips/lm90.c | 39 ++++++++++++++++++++++-----------------
2 files changed, 31 insertions(+), 25 deletions(-)


diff -Nru a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c
--- a/drivers/i2c/chips/lm83.c 2004-10-19 16:54:35 -07:00
+++ b/drivers/i2c/chips/lm83.c 2004-10-19 16:54:35 -07:00
@@ -80,13 +80,14 @@

/*
* Conversions and various macros
- * The LM83 uses signed 8-bit values.
+ * The LM83 uses signed 8-bit values with LSB = 1 degree Celcius.
*/

-#define TEMP_FROM_REG(val) (((val) > 127 ? (val) - 0x100 : (val)) * 1000)
-#define TEMP_TO_REG(val) ((val) <= -50000 ? -50 + 0x100 : (val) >= 127000 ? 127 : \
- (val) > -500 ? ((val)+500) / 1000 : \
- ((val)-500) / 1000 + 0x100)
+#define TEMP_FROM_REG(val) ((val) * 1000)
+#define TEMP_TO_REG(val) ((val) <= -128000 ? -128 : \
+ (val) >= 127000 ? 127 : \
+ (val) < 0 ? ((val) - 500) / 1000 : \
+ ((val) + 500) / 1000)

static const u8 LM83_REG_R_TEMP[] = {
LM83_REG_R_LOCAL_TEMP,
@@ -142,9 +143,9 @@
unsigned long last_updated; /* in jiffies */

/* registers values */
- u8 temp_input[4];
- u8 temp_high[4];
- u8 temp_crit;
+ s8 temp_input[4];
+ s8 temp_high[4];
+ s8 temp_crit;
u16 alarms; /* bitvector, combined */
};

diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
--- a/drivers/i2c/chips/lm90.c 2004-10-19 16:54:35 -07:00
+++ b/drivers/i2c/chips/lm90.c 2004-10-19 16:54:35 -07:00
@@ -127,19 +127,24 @@

/*
* Conversions and various macros
- * The LM90 uses signed 8-bit values for the local temperatures,
- * and signed 11-bit values for the remote temperatures (except
- * T_CRIT). Note that TEMP2_TO_REG does not round values, but
- * stick to the nearest lower value instead. Fixing it is just
- * not worth it.
- */
-
-#define TEMP1_FROM_REG(val) ((val & 0x80 ? val-0x100 : val) * 1000)
-#define TEMP1_TO_REG(val) ((val < 0 ? val+0x100*1000 : val) / 1000)
-#define TEMP2_FROM_REG(val) (((val & 0x8000 ? val-0x10000 : val) >> 5) * 125)
-#define TEMP2_TO_REG(val) ((((val / 125) << 5) + (val < 0 ? 0x10000 : 0)) & 0xFFE0)
-#define HYST_FROM_REG(val) (val * 1000)
-#define HYST_TO_REG(val) (val <= 0 ? 0 : val >= 31000 ? 31 : val / 1000)
+ * For local temperatures and limits, critical limits and the hysteresis
+ * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celcius.
+ * For remote temperatures and limits, it uses signed 11-bit values with
+ * LSB = 0.125 degree Celcius, left-justified in 16-bit registers.
+ */
+
+#define TEMP1_FROM_REG(val) ((val) * 1000)
+#define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \
+ (val) >= 127000 ? 127 : \
+ (val) < 0 ? ((val) - 500) / 1000 : \
+ ((val) + 500) / 1000)
+#define TEMP2_FROM_REG(val) ((val) / 32 * 125)
+#define TEMP2_TO_REG(val) ((val) <= -128000 ? 0x8000 : \
+ (val) >= 127875 ? 0x7FE0 : \
+ (val) < 0 ? ((val) - 62) / 125 * 32 : \
+ ((val) + 62) / 125 * 32)
+#define HYST_TO_REG(val) ((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \
+ ((val) + 500) / 1000)

/*
* Functions declaration
@@ -176,9 +181,9 @@
unsigned long last_updated; /* in jiffies */

/* registers values */
- u8 temp_input1, temp_low1, temp_high1; /* local */
- u16 temp_input2, temp_low2, temp_high2; /* remote, combined */
- u8 temp_crit1, temp_crit2;
+ s8 temp_input1, temp_low1, temp_high1; /* local */
+ s16 temp_input2, temp_low2, temp_high2; /* remote, combined */
+ s8 temp_crit1, temp_crit2;
u8 temp_hyst;
u16 alarms; /* bitvector, combined */
};
@@ -243,7 +248,7 @@
{ \
struct lm90_data *data = lm90_update_device(dev); \
return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->basereg) \
- - HYST_FROM_REG(data->temp_hyst)); \
+ - TEMP1_FROM_REG(data->temp_hyst)); \
}
show_temp_hyst(temp_hyst1, temp_crit1);
show_temp_hyst(temp_hyst2, temp_crit2);

2004-10-20 02:40:32

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.7, 2004/09/29 13:41:52-07:00, [email protected]

[PATCH] i2c: kill some sensors driver macro abuse

This patch kills a specific kind of ugly and ultimately useless macro
abuse found in many sensors chip drivers. Compile tested only.

Signed-off-by: Mark M. Hoffman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/adm1031.c | 42 +++++++++++++++++++++---------------------
drivers/i2c/chips/asb100.c | 10 +++++-----
drivers/i2c/chips/it87.c | 34 +++++++++++++++++-----------------
drivers/i2c/chips/lm78.c | 18 +++++++++---------
drivers/i2c/chips/lm85.c | 32 ++++++++++++++++----------------
drivers/i2c/chips/smsc47m1.c | 18 +++++++++---------
drivers/i2c/chips/via686a.c | 30 +++++++++++++++---------------
drivers/i2c/chips/w83627hf.c | 18 +++++++++---------
drivers/i2c/chips/w83781d.c | 18 +++++++++---------
9 files changed, 110 insertions(+), 110 deletions(-)


diff -Nru a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c
--- a/drivers/i2c/chips/adm1031.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/adm1031.c 2004-10-19 16:54:25 -07:00
@@ -298,12 +298,12 @@
#define fan_auto_channel_offset(offset) \
static ssize_t show_fan_auto_channel_##offset (struct device *dev, char *buf) \
{ \
- return show_fan_auto_channel(dev, buf, 0x##offset - 1); \
+ return show_fan_auto_channel(dev, buf, offset - 1); \
} \
static ssize_t set_fan_auto_channel_##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_auto_channel(dev, buf, count, 0x##offset - 1); \
+ return set_fan_auto_channel(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(auto_fan##offset##_channel, S_IRUGO | S_IWUSR, \
show_fan_auto_channel_##offset, \
@@ -365,25 +365,25 @@
#define auto_temp_reg(offset) \
static ssize_t show_auto_temp_##offset##_off (struct device *dev, char *buf) \
{ \
- return show_auto_temp_off(dev, buf, 0x##offset - 1); \
+ return show_auto_temp_off(dev, buf, offset - 1); \
} \
static ssize_t show_auto_temp_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_auto_temp_min(dev, buf, 0x##offset - 1); \
+ return show_auto_temp_min(dev, buf, offset - 1); \
} \
static ssize_t show_auto_temp_##offset##_max (struct device *dev, char *buf) \
{ \
- return show_auto_temp_max(dev, buf, 0x##offset - 1); \
+ return show_auto_temp_max(dev, buf, offset - 1); \
} \
static ssize_t set_auto_temp_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_auto_temp_min(dev, buf, count, 0x##offset - 1); \
+ return set_auto_temp_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_auto_temp_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_auto_temp_max(dev, buf, count, 0x##offset - 1); \
+ return set_auto_temp_max(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO, \
show_auto_temp_##offset##_off, NULL); \
@@ -429,12 +429,12 @@
#define pwm_reg(offset) \
static ssize_t show_pwm_##offset (struct device *dev, char *buf) \
{ \
- return show_pwm(dev, buf, 0x##offset - 1); \
+ return show_pwm(dev, buf, offset - 1); \
} \
static ssize_t set_pwm_##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_pwm(dev, buf, count, 0x##offset - 1); \
+ return set_pwm(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm_##offset, set_pwm_##offset)
@@ -565,25 +565,25 @@
#define fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset - 1); \
+ return show_fan(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset - 1); \
+ return show_fan_min(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
{ \
- return show_fan_div(dev, buf, 0x##offset - 1); \
+ return show_fan_div(dev, buf, offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_fan_##offset##_div (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_div(dev, buf, count, 0x##offset - 1); \
+ return set_fan_div(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, \
NULL); \
@@ -675,34 +675,34 @@
#define temp_reg(offset) \
static ssize_t show_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset - 1); \
+ return show_temp(dev, buf, offset - 1); \
} \
static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_temp_min(dev, buf, 0x##offset - 1); \
+ return show_temp_min(dev, buf, offset - 1); \
} \
static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \
{ \
- return show_temp_max(dev, buf, 0x##offset - 1); \
+ return show_temp_max(dev, buf, offset - 1); \
} \
static ssize_t show_temp_##offset##_crit (struct device *dev, char *buf) \
{ \
- return show_temp_crit(dev, buf, 0x##offset - 1); \
+ return show_temp_crit(dev, buf, offset - 1); \
} \
static ssize_t set_temp_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_min(dev, buf, count, 0x##offset - 1); \
+ return set_temp_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_temp_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_max(dev, buf, count, 0x##offset - 1); \
+ return set_temp_max(dev, buf, count, offset - 1); \
} \
static ssize_t set_temp_##offset##_crit (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_crit(dev, buf, count, 0x##offset - 1); \
+ return set_temp_crit(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, \
NULL); \
diff -Nru a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
--- a/drivers/i2c/chips/asb100.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/asb100.c 2004-10-19 16:54:25 -07:00
@@ -266,29 +266,29 @@
static ssize_t \
show_in##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
- return show_in_min(dev, buf, 0x##offset); \
+ return show_in_min(dev, buf, offset); \
} \
static ssize_t \
show_in##offset##_max (struct device *dev, char *buf) \
{ \
- return show_in_max(dev, buf, 0x##offset); \
+ return show_in_max(dev, buf, offset); \
} \
static ssize_t set_in##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_min(dev, buf, count, 0x##offset); \
+ return set_in_min(dev, buf, count, offset); \
} \
static ssize_t set_in##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_max(dev, buf, count, 0x##offset); \
+ return set_in_max(dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
show_in##offset##_min, set_in##offset##_min); \
diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/it87.c 2004-10-19 16:54:25 -07:00
@@ -273,7 +273,7 @@
static ssize_t \
show_in##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);

@@ -281,22 +281,22 @@
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
- return show_in_min(dev, buf, 0x##offset); \
+ return show_in_min(dev, buf, offset); \
} \
static ssize_t \
show_in##offset##_max (struct device *dev, char *buf) \
{ \
- return show_in_max(dev, buf, 0x##offset); \
+ return show_in_max(dev, buf, offset); \
} \
static ssize_t set_in##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_min(dev, buf, count, 0x##offset); \
+ return set_in_min(dev, buf, count, offset); \
} \
static ssize_t set_in##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_max(dev, buf, count, 0x##offset); \
+ return set_in_max(dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
show_in##offset##_min, set_in##offset##_min); \
@@ -360,27 +360,27 @@
#define show_temp_offset(offset) \
static ssize_t show_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset - 1); \
+ return show_temp(dev, buf, offset - 1); \
} \
static ssize_t \
show_temp_##offset##_max (struct device *dev, char *buf) \
{ \
- return show_temp_max(dev, buf, 0x##offset - 1); \
+ return show_temp_max(dev, buf, offset - 1); \
} \
static ssize_t \
show_temp_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_temp_min(dev, buf, 0x##offset - 1); \
+ return show_temp_min(dev, buf, offset - 1); \
} \
static ssize_t set_temp_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_max(dev, buf, count, 0x##offset - 1); \
+ return set_temp_max(dev, buf, count, offset - 1); \
} \
static ssize_t set_temp_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_min(dev, buf, count, 0x##offset - 1); \
+ return set_temp_min(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
@@ -423,12 +423,12 @@
#define show_sensor_offset(offset) \
static ssize_t show_sensor_##offset (struct device *dev, char *buf) \
{ \
- return show_sensor(dev, buf, 0x##offset - 1); \
+ return show_sensor(dev, buf, offset - 1); \
} \
static ssize_t set_sensor_##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_sensor(dev, buf, count, 0x##offset - 1); \
+ return set_sensor(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \
show_sensor_##offset, set_sensor_##offset);
@@ -505,25 +505,25 @@
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset - 1); \
+ return show_fan(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset - 1); \
+ return show_fan_min(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
{ \
- return show_fan_div(dev, buf, 0x##offset - 1); \
+ return show_fan_div(dev, buf, offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_fan_##offset##_div (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_div(dev, buf, count, 0x##offset - 1); \
+ return set_fan_div(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/lm78.c 2004-10-19 16:54:25 -07:00
@@ -229,29 +229,29 @@
static ssize_t \
show_in##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in##offset, NULL); \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
- return show_in_min(dev, buf, 0x##offset); \
+ return show_in_min(dev, buf, offset); \
} \
static ssize_t \
show_in##offset##_max (struct device *dev, char *buf) \
{ \
- return show_in_max(dev, buf, 0x##offset); \
+ return show_in_max(dev, buf, offset); \
} \
static ssize_t set_in##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_min(dev, buf, count, 0x##offset); \
+ return set_in_min(dev, buf, count, offset); \
} \
static ssize_t set_in##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_max(dev, buf, count, 0x##offset); \
+ return set_in_max(dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
show_in##offset##_min, set_in##offset##_min); \
@@ -375,20 +375,20 @@
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset - 1); \
+ return show_fan(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset - 1); \
+ return show_fan_min(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
{ \
- return show_fan_div(dev, buf, 0x##offset - 1); \
+ return show_fan_div(dev, buf, offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/lm85.c 2004-10-19 16:54:25 -07:00
@@ -437,16 +437,16 @@
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset - 1); \
+ return show_fan(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset - 1); \
+ return show_fan_min(dev, buf, offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
@@ -527,16 +527,16 @@
#define show_pwm_reg(offset) \
static ssize_t show_pwm_##offset (struct device *dev, char *buf) \
{ \
- return show_pwm(dev, buf, 0x##offset - 1); \
+ return show_pwm(dev, buf, offset - 1); \
} \
static ssize_t set_pwm_##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_pwm(dev, buf, count, 0x##offset - 1); \
+ return set_pwm(dev, buf, count, offset - 1); \
} \
static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \
{ \
- return show_pwm_enable(dev, buf, 0x##offset - 1); \
+ return show_pwm_enable(dev, buf, offset - 1); \
} \
static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm_##offset, set_pwm_##offset); \
@@ -595,25 +595,25 @@
#define show_in_reg(offset) \
static ssize_t show_in_##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static ssize_t show_in_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_in_min(dev, buf, 0x##offset); \
+ return show_in_min(dev, buf, offset); \
} \
static ssize_t show_in_##offset##_max (struct device *dev, char *buf) \
{ \
- return show_in_max(dev, buf, 0x##offset); \
+ return show_in_max(dev, buf, offset); \
} \
static ssize_t set_in_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_min(dev, buf, count, 0x##offset); \
+ return set_in_min(dev, buf, count, offset); \
} \
static ssize_t set_in_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_max(dev, buf, count, 0x##offset); \
+ return set_in_max(dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL); \
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
@@ -675,25 +675,25 @@
#define show_temp_reg(offset) \
static ssize_t show_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset - 1); \
+ return show_temp(dev, buf, offset - 1); \
} \
static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_temp_min(dev, buf, 0x##offset - 1); \
+ return show_temp_min(dev, buf, offset - 1); \
} \
static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \
{ \
- return show_temp_max(dev, buf, 0x##offset - 1); \
+ return show_temp_max(dev, buf, offset - 1); \
} \
static ssize_t set_temp_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_min(dev, buf, count, 0x##offset - 1); \
+ return set_temp_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_temp_##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_max(dev, buf, count, 0x##offset - 1); \
+ return set_temp_max(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \
diff -Nru a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
--- a/drivers/i2c/chips/smsc47m1.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/smsc47m1.c 2004-10-19 16:54:25 -07:00
@@ -298,43 +298,43 @@
#define fan_present(offset) \
static ssize_t get_fan##offset (struct device *dev, char *buf) \
{ \
- return get_fan(dev, buf, 0x##offset - 1); \
+ return get_fan(dev, buf, offset - 1); \
} \
static ssize_t get_fan##offset##_min (struct device *dev, char *buf) \
{ \
- return get_fan_min(dev, buf, 0x##offset - 1); \
+ return get_fan_min(dev, buf, offset - 1); \
} \
static ssize_t set_fan##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static ssize_t get_fan##offset##_div (struct device *dev, char *buf) \
{ \
- return get_fan_div(dev, buf, 0x##offset - 1); \
+ return get_fan_div(dev, buf, offset - 1); \
} \
static ssize_t set_fan##offset##_div (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_div(dev, buf, count, 0x##offset - 1); \
+ return set_fan_div(dev, buf, count, offset - 1); \
} \
static ssize_t get_pwm##offset (struct device *dev, char *buf) \
{ \
- return get_pwm(dev, buf, 0x##offset - 1); \
+ return get_pwm(dev, buf, offset - 1); \
} \
static ssize_t set_pwm##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_pwm(dev, buf, count, 0x##offset - 1); \
+ return set_pwm(dev, buf, count, offset - 1); \
} \
static ssize_t get_pwm##offset##_en (struct device *dev, char *buf) \
{ \
- return get_pwm_en(dev, buf, 0x##offset - 1); \
+ return get_pwm_en(dev, buf, offset - 1); \
} \
static ssize_t set_pwm##offset##_en (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_pwm_en(dev, buf, count, 0x##offset - 1); \
+ return set_pwm_en(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
NULL); \
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/via686a.c 2004-10-19 16:54:25 -07:00
@@ -383,27 +383,27 @@
static ssize_t \
show_in##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static ssize_t \
show_in##offset##_min (struct device *dev, char *buf) \
{ \
- return show_in_min(dev, buf, 0x##offset); \
+ return show_in_min(dev, buf, offset); \
} \
static ssize_t \
show_in##offset##_max (struct device *dev, char *buf) \
{ \
- return show_in_max(dev, buf, 0x##offset); \
+ return show_in_max(dev, buf, offset); \
} \
static ssize_t set_in##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_min(dev, buf, count, 0x##offset); \
+ return set_in_min(dev, buf, count, offset); \
} \
static ssize_t set_in##offset##_max (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_in_max(dev, buf, count, 0x##offset); \
+ return set_in_max(dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL);\
static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
@@ -451,27 +451,27 @@
#define show_temp_offset(offset) \
static ssize_t show_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset - 1); \
+ return show_temp(dev, buf, offset - 1); \
} \
static ssize_t \
show_temp_##offset##_over (struct device *dev, char *buf) \
{ \
- return show_temp_over(dev, buf, 0x##offset - 1); \
+ return show_temp_over(dev, buf, offset - 1); \
} \
static ssize_t \
show_temp_##offset##_hyst (struct device *dev, char *buf) \
{ \
- return show_temp_hyst(dev, buf, 0x##offset - 1); \
+ return show_temp_hyst(dev, buf, offset - 1); \
} \
static ssize_t set_temp_##offset##_over (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_over(dev, buf, count, 0x##offset - 1); \
+ return set_temp_over(dev, buf, count, offset - 1); \
} \
static ssize_t set_temp_##offset##_hyst (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_temp_hyst(dev, buf, count, 0x##offset - 1); \
+ return set_temp_hyst(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL);\
static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
@@ -522,25 +522,25 @@
#define show_fan_offset(offset) \
static ssize_t show_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset - 1); \
+ return show_fan(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset - 1); \
+ return show_fan_min(dev, buf, offset - 1); \
} \
static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \
{ \
- return show_fan_div(dev, buf, 0x##offset - 1); \
+ return show_fan_div(dev, buf, offset - 1); \
} \
static ssize_t set_fan_##offset##_min (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_min(dev, buf, count, 0x##offset - 1); \
+ return set_fan_min(dev, buf, count, offset - 1); \
} \
static ssize_t set_fan_##offset##_div (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_div(dev, buf, count, 0x##offset - 1); \
+ return set_fan_div(dev, buf, count, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
diff -Nru a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
--- a/drivers/i2c/chips/w83627hf.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/w83627hf.c 2004-10-19 16:54:25 -07:00
@@ -369,20 +369,20 @@
static ssize_t \
show_regs_in_##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);

#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
{ \
- return show_in_##reg (dev, buf, 0x##offset); \
+ return show_in_##reg (dev, buf, offset); \
} \
static ssize_t \
store_regs_in_##reg##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return store_in_##reg (dev, buf, count, 0x##offset); \
+ return store_in_##reg (dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, \
show_regs_in_##reg##offset, store_regs_in_##reg##offset);
@@ -521,19 +521,19 @@
#define sysfs_fan_offset(offset) \
static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset); \
+ return show_fan(dev, buf, offset); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);

#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset); \
+ return show_fan_min(dev, buf, offset); \
} \
static ssize_t \
store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
{ \
- return store_fan_min(dev, buf, count, 0x##offset); \
+ return store_fan_min(dev, buf, count, offset); \
} \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_regs_fan_min##offset, store_regs_fan_min##offset);
@@ -595,20 +595,20 @@
static ssize_t \
show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset); \
+ return show_temp(dev, buf, offset); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);

#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
{ \
- return show_temp_##reg (dev, buf, 0x##offset); \
+ return show_temp_##reg (dev, buf, offset); \
} \
static ssize_t \
store_regs_temp_##reg##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return store_temp_##reg (dev, buf, count, 0x##offset); \
+ return store_temp_##reg (dev, buf, count, offset); \
} \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c 2004-10-19 16:54:25 -07:00
+++ b/drivers/i2c/chips/w83781d.c 2004-10-19 16:54:25 -07:00
@@ -318,18 +318,18 @@
static ssize_t \
show_regs_in_##offset (struct device *dev, char *buf) \
{ \
- return show_in(dev, buf, 0x##offset); \
+ return show_in(dev, buf, offset); \
} \
static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL);

#define sysfs_in_reg_offset(reg, offset) \
static ssize_t show_regs_in_##reg##offset (struct device *dev, char *buf) \
{ \
- return show_in_##reg (dev, buf, 0x##offset); \
+ return show_in_##reg (dev, buf, offset); \
} \
static ssize_t store_regs_in_##reg##offset (struct device *dev, const char *buf, size_t count) \
{ \
- return store_in_##reg (dev, buf, count, 0x##offset); \
+ return store_in_##reg (dev, buf, count, offset); \
} \
static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset);

@@ -384,18 +384,18 @@
#define sysfs_fan_offset(offset) \
static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \
{ \
- return show_fan(dev, buf, 0x##offset); \
+ return show_fan(dev, buf, offset); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);

#define sysfs_fan_min_offset(offset) \
static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \
{ \
- return show_fan_min(dev, buf, 0x##offset); \
+ return show_fan_min(dev, buf, offset); \
} \
static ssize_t store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \
{ \
- return store_fan_min(dev, buf, count, 0x##offset); \
+ return store_fan_min(dev, buf, count, offset); \
} \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset);

@@ -464,18 +464,18 @@
static ssize_t \
show_regs_temp_##offset (struct device *dev, char *buf) \
{ \
- return show_temp(dev, buf, 0x##offset); \
+ return show_temp(dev, buf, offset); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);

#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \
{ \
- return show_temp_##reg (dev, buf, 0x##offset); \
+ return show_temp_##reg (dev, buf, offset); \
} \
static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *buf, size_t count) \
{ \
- return store_temp_##reg (dev, buf, count, 0x##offset); \
+ return store_temp_##reg (dev, buf, count, offset); \
} \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);


2004-10-20 00:37:01

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.7, 2004/09/21 16:39:57-07:00, [email protected]

[PATCH] I2C: Cleanup lm78 init

This patch cleans the init part of the lm78 driver.

* Do not reset the chip.

* Get rid of useless code, which was accidentally left in when we
removed the limit initialization from the driver.

* Do not enable monitoring if it is already enabled (it wouldn't hurt,
but since we can avoid it at no cost...)

Similar changes were applied to the Linux 2.4 driver, which I
successfully tested on my own LM78 chip.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/lm78.c | 22 ++++------------------
1 files changed, 4 insertions(+), 18 deletions(-)


diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- a/drivers/i2c/chips/lm78.c 2004-10-19 16:54:56 -07:00
+++ b/drivers/i2c/chips/lm78.c 2004-10-19 16:54:56 -07:00
@@ -692,26 +692,12 @@
/* Called when we have found a new LM78. It should set limits, etc. */
static void lm78_init_client(struct i2c_client *client)
{
- struct lm78_data *data = i2c_get_clientdata(client);
- int vid;
-
- /* Reset all except Watchdog values and last conversion values
- This sets fan-divs to 2, among others */
- lm78_write_value(client, LM78_REG_CONFIG, 0x80);
-
- vid = lm78_read_value(client, LM78_REG_VID_FANDIV) & 0x0f;
- if (data->type == lm79)
- vid |=
- (lm78_read_value(client, LM78_REG_CHIPID) & 0x01) << 4;
- else
- vid |= 0x10;
- vid = VID_FROM_REG(vid);
+ u8 config = lm78_read_value(client, LM78_REG_CONFIG);

/* Start monitoring */
- lm78_write_value(client, LM78_REG_CONFIG,
- (lm78_read_value(client, LM78_REG_CONFIG) & 0xf7)
- | 0x01);
-
+ if (!(config & 0x01))
+ lm78_write_value(client, LM78_REG_CONFIG,
+ (config & 0xf7) | 0x01);
}

static struct lm78_data *lm78_update_device(struct device *dev)

2004-10-20 00:37:02

by Greg KH

[permalink] [raw]
Subject: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.1, 2004/09/08 12:33:40-07:00, [email protected]

[PATCH] i2c-algo-ite: remove iic_sleep()

Removes unused function iic_sleep().

Signed-off-by: Nishanth Aravamudan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/algos/i2c-algo-ite.c | 8 --------
1 files changed, 8 deletions(-)


diff -Nru a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c
--- a/drivers/i2c/algos/i2c-algo-ite.c 2004-10-19 16:56:02 -07:00
+++ b/drivers/i2c/algos/i2c-algo-ite.c 2004-10-19 16:56:02 -07:00
@@ -107,14 +107,6 @@
return(timeout<=0);
}

-/*
- * Puts this process to sleep for a period equal to timeout
- */
-static inline void iic_sleep(unsigned long timeout)
-{
- schedule_timeout( timeout * HZ);
-}
-
/* After we issue a transaction on the IIC bus, this function
* is called. It puts this process to sleep until we get an interrupt from
* from the controller telling us that the transaction we requested in complete.

2004-10-20 00:26:14

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2073, 2004/10/19 15:21:33-07:00, [email protected]

[PATCH] I2C: Update Kconfig for AMD bus drivers

This updates the AMD entries i2c/busses/Kconfig in two ways:
* Add missing PCI dependancy.
* Reword the help so that users know exactly what is supported by each
driver.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/Kconfig | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)


diff -Nru a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
--- a/drivers/i2c/busses/Kconfig 2004-10-19 16:53:53 -07:00
+++ b/drivers/i2c/busses/Kconfig 2004-10-19 16:53:53 -07:00
@@ -40,21 +40,23 @@
will be called i2c-ali15x3.

config I2C_AMD756
- tristate "AMD 756/766"
- depends on I2C && EXPERIMENTAL
+ tristate "AMD 756/766/768/8111 and nVidia nForce"
+ depends on I2C && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the AMD
- 756/766/768 mainboard I2C interfaces.
+ 756/766/768 mainboard I2C interfaces. The driver also includes
+ support for the first (SMBus 1.0) I2C interface of the AMD 8111 and
+ the nVidia nForce I2C interface.

This driver can also be built as a module. If so, the module
will be called i2c-amd756.

config I2C_AMD8111
tristate "AMD 8111"
- depends on I2C && EXPERIMENTAL
+ depends on I2C && PCI && EXPERIMENTAL
help
- If you say yes to this option, support will be included for the AMD
- 8111 mainboard I2C interfaces.
+ If you say yes to this option, support will be included for the
+ second (SMBus 2.0) AMD 8111 mainboard I2C interface.

This driver can also be built as a module. If so, the module
will be called i2c-amd8111.

2004-10-20 00:26:13

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1832.73.7, 2004/09/08 13:17:56-07:00, [email protected]

[PATCH] w1: Added slave->ttl - time to live for the registered slave.

Added slave->ttl - time to live for the registered slave.
When slave was not found we will not remove it immediately but wait until ->ttl attempts were done.
It prevents various debouncing effects(problems with pull-up, power).

Signed-off-by: Evgeniy Polyakov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/w1/w1.c | 9 +++++++--
drivers/w1/w1.h | 2 ++
drivers/w1/w1_int.c | 6 ++++--
drivers/w1/w1_int.h | 2 +-
4 files changed, 14 insertions(+), 5 deletions(-)


diff -Nru a/drivers/w1/w1.c b/drivers/w1/w1.c
--- a/drivers/w1/w1.c 2004-10-19 16:55:31 -07:00
+++ b/drivers/w1/w1.c 2004-10-19 16:55:31 -07:00
@@ -47,9 +47,11 @@

static int w1_timeout = 10;
int w1_max_slave_count = 10;
+int w1_max_slave_ttl = 10;

module_param_named(timeout, w1_timeout, int, 0);
module_param_named(max_slave_count, w1_max_slave_count, int, 0);
+module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);

spinlock_t w1_mlock = SPIN_LOCK_UNLOCKED;
LIST_HEAD(w1_masters);
@@ -431,6 +433,7 @@
return err;
}

+ sl->ttl = dev->slave_ttl;
dev->slave_count++;

memcpy(&msg.id.id, rn, sizeof(msg.id.id));
@@ -569,7 +572,7 @@
}

if (slave_count == dev->slave_count &&
- ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
+ rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn, 7)) {
w1_attach_slave_device(dev, (struct w1_reg_num *) &rn);
}
}
@@ -718,7 +721,7 @@
list_for_each_safe(ent, n, &dev->slist) {
sl = list_entry(ent, struct w1_slave, w1_slave_entry);

- if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) {
+ if (sl && !test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
list_del (&sl->w1_slave_entry);

w1_slave_detach (sl);
@@ -726,6 +729,8 @@

dev->slave_count--;
}
+ else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))
+ sl->ttl = dev->slave_ttl;
}
up(&dev->mutex);
}
diff -Nru a/drivers/w1/w1.h b/drivers/w1/w1.h
--- a/drivers/w1/w1.h 2004-10-19 16:55:31 -07:00
+++ b/drivers/w1/w1.h 2004-10-19 16:55:31 -07:00
@@ -63,6 +63,7 @@
atomic_t refcnt;
u8 rom[9];
u32 flags;
+ int ttl;

struct w1_master *master;
struct w1_family *family;
@@ -99,6 +100,7 @@
struct list_head slist;
int max_slave_count, slave_count;
unsigned long attempts;
+ int slave_ttl;
int initialized;
u32 id;

diff -Nru a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
--- a/drivers/w1/w1_int.c 2004-10-19 16:55:31 -07:00
+++ b/drivers/w1/w1_int.c 2004-10-19 16:55:31 -07:00
@@ -32,12 +32,13 @@
extern struct bus_type w1_bus_type;
extern struct device w1_device;
extern int w1_max_slave_count;
+extern int w1_max_slave_ttl;
extern struct list_head w1_masters;
extern spinlock_t w1_mlock;

extern int w1_process(void *);

-struct w1_master * w1_alloc_dev(u32 id, int slave_count,
+struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
struct device_driver *driver, struct device *device)
{
struct w1_master *dev;
@@ -65,6 +66,7 @@
dev->kpid = -1;
dev->initialized = 0;
dev->id = id;
+ dev->slave_ttl = slave_ttl;

atomic_set(&dev->refcnt, 2);

@@ -121,7 +123,7 @@
int retval = 0;
struct w1_netlink_msg msg;

- dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, &w1_driver, &w1_device);
+ dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_driver, &w1_device);
if (!dev)
return -ENOMEM;

diff -Nru a/drivers/w1/w1_int.h b/drivers/w1/w1_int.h
--- a/drivers/w1/w1_int.h 2004-10-19 16:55:31 -07:00
+++ b/drivers/w1/w1_int.h 2004-10-19 16:55:31 -07:00
@@ -27,7 +27,7 @@

#include "w1.h"

-struct w1_master * w1_alloc_dev(int, struct device_driver *, struct device *);
+struct w1_master * w1_alloc_dev(u32, int, int, struct device_driver *, struct device *);
void w1_free_dev(struct w1_master *dev);
int w1_add_master_device(struct w1_bus_master *);
void w1_remove_master_device(struct w1_bus_master *);

2004-10-20 03:36:19

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2069, 2004/10/19 15:14:51-07:00, [email protected]

[PATCH] I2C: Spare 1 byte in lm90 driver

I just noticed the other day that the lm90 driver uses an u16 to store
the value of the 8-bit alarms register. This is most probably due to the
fact that I originally copied the lm90 driver from the lm83 driver,
which actually has two 8-bit registers for alarms, and obviously forgot
to change the variable type.


Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/lm90.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)


diff -Nru a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c
--- a/drivers/i2c/chips/lm90.c 2004-10-19 16:54:14 -07:00
+++ b/drivers/i2c/chips/lm90.c 2004-10-19 16:54:14 -07:00
@@ -185,7 +185,7 @@
s16 temp_input2, temp_low2, temp_high2; /* remote, combined */
s8 temp_crit1, temp_crit2;
u8 temp_hyst;
- u16 alarms; /* bitvector, combined */
+ u8 alarms; /* bitvector */
};

/*

2004-10-20 00:26:13

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2079, 2004/10/19 16:46:21-07:00, [email protected]

I2C: convert from pci_module_init to pci_register_driver for all i2c drivers.

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-ali1535.c | 2 +-
drivers/i2c/busses/i2c-ali1563.c | 2 +-
drivers/i2c/busses/i2c-ali15x3.c | 2 +-
drivers/i2c/busses/i2c-amd756.c | 2 +-
drivers/i2c/busses/i2c-amd8111.c | 2 +-
drivers/i2c/busses/i2c-hydra.c | 2 +-
drivers/i2c/busses/i2c-i801.c | 2 +-
drivers/i2c/busses/i2c-i810.c | 2 +-
drivers/i2c/busses/i2c-nforce2.c | 2 +-
drivers/i2c/busses/i2c-piix4.c | 2 +-
drivers/i2c/busses/i2c-prosavage.c | 2 +-
drivers/i2c/busses/i2c-savage4.c | 2 +-
drivers/i2c/busses/i2c-sis5595.c | 2 +-
drivers/i2c/busses/i2c-sis630.c | 2 +-
drivers/i2c/busses/i2c-sis96x.c | 2 +-
drivers/i2c/busses/i2c-via.c | 2 +-
drivers/i2c/busses/i2c-viapro.c | 2 +-
drivers/i2c/busses/i2c-voodoo3.c | 2 +-
drivers/i2c/chips/via686a.c | 2 +-
19 files changed, 19 insertions(+), 19 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
--- a/drivers/i2c/busses/i2c-ali1535.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-ali1535.c 2004-10-19 16:53:22 -07:00
@@ -529,7 +529,7 @@

static int __init i2c_ali1535_init(void)
{
- return pci_module_init(&ali1535_driver);
+ return pci_register_driver(&ali1535_driver);
}

static void __exit i2c_ali1535_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
--- a/drivers/i2c/busses/i2c-ali1563.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-ali1563.c 2004-10-19 16:53:22 -07:00
@@ -405,7 +405,7 @@

static int __init ali1563_init(void)
{
- return pci_module_init(&ali1563_pci_driver);
+ return pci_register_driver(&ali1563_pci_driver);
}

module_init(ali1563_init);
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-ali15x3.c 2004-10-19 16:53:22 -07:00
@@ -519,7 +519,7 @@

static int __init i2c_ali15x3_init(void)
{
- return pci_module_init(&ali15x3_driver);
+ return pci_register_driver(&ali15x3_driver);
}

static void __exit i2c_ali15x3_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
--- a/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-amd756.c 2004-10-19 16:53:22 -07:00
@@ -408,7 +408,7 @@

static int __init amd756_init(void)
{
- return pci_module_init(&amd756_driver);
+ return pci_register_driver(&amd756_driver);
}

static void __exit amd756_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
--- a/drivers/i2c/busses/i2c-amd8111.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-amd8111.c 2004-10-19 16:53:22 -07:00
@@ -402,7 +402,7 @@

static int __init i2c_amd8111_init(void)
{
- return pci_module_init(&amd8111_driver);
+ return pci_register_driver(&amd8111_driver);
}


diff -Nru a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
--- a/drivers/i2c/busses/i2c-hydra.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-hydra.c 2004-10-19 16:53:22 -07:00
@@ -168,7 +168,7 @@

static int __init i2c_hydra_init(void)
{
- return pci_module_init(&hydra_driver);
+ return pci_register_driver(&hydra_driver);
}


diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-i801.c 2004-10-19 16:53:22 -07:00
@@ -633,7 +633,7 @@

static int __init i2c_i801_init(void)
{
- return pci_module_init(&i801_driver);
+ return pci_register_driver(&i801_driver);
}

static void __exit i2c_i801_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
--- a/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-i810.c 2004-10-19 16:53:22 -07:00
@@ -241,7 +241,7 @@

static int __init i2c_i810_init(void)
{
- return pci_module_init(&i810_driver);
+ return pci_register_driver(&i810_driver);
}

static void __exit i2c_i810_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
--- a/drivers/i2c/busses/i2c-nforce2.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-nforce2.c 2004-10-19 16:53:22 -07:00
@@ -394,7 +394,7 @@

static int __init nforce2_init(void)
{
- return pci_module_init(&nforce2_driver);
+ return pci_register_driver(&nforce2_driver);
}

static void __exit nforce2_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
--- a/drivers/i2c/busses/i2c-piix4.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-piix4.c 2004-10-19 16:53:22 -07:00
@@ -503,7 +503,7 @@

static int __init i2c_piix4_init(void)
{
- return pci_module_init(&piix4_driver);
+ return pci_register_driver(&piix4_driver);
}

static void __exit i2c_piix4_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
--- a/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-prosavage.c 2004-10-19 16:53:22 -07:00
@@ -324,7 +324,7 @@

static int __init i2c_prosavage_init(void)
{
- return pci_module_init(&prosavage_driver);
+ return pci_register_driver(&prosavage_driver);
}

static void __exit i2c_prosavage_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
--- a/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-savage4.c 2004-10-19 16:53:22 -07:00
@@ -188,7 +188,7 @@

static int __init i2c_savage4_init(void)
{
- return pci_module_init(&savage4_driver);
+ return pci_register_driver(&savage4_driver);
}

static void __exit i2c_savage4_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
--- a/drivers/i2c/busses/i2c-sis5595.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-sis5595.c 2004-10-19 16:53:22 -07:00
@@ -403,7 +403,7 @@

static int __init i2c_sis5595_init(void)
{
- return pci_module_init(&sis5595_driver);
+ return pci_register_driver(&sis5595_driver);
}

static void __exit i2c_sis5595_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
--- a/drivers/i2c/busses/i2c-sis630.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-sis630.c 2004-10-19 16:53:22 -07:00
@@ -505,7 +505,7 @@

static int __init i2c_sis630_init(void)
{
- return pci_module_init(&sis630_driver);
+ return pci_register_driver(&sis630_driver);
}


diff -Nru a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
--- a/drivers/i2c/busses/i2c-sis96x.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-sis96x.c 2004-10-19 16:53:22 -07:00
@@ -350,7 +350,7 @@
static int __init i2c_sis96x_init(void)
{
printk(KERN_INFO "i2c-sis96x version %s\n", SIS96x_VERSION);
- return pci_module_init(&sis96x_driver);
+ return pci_register_driver(&sis96x_driver);
}

static void __exit i2c_sis96x_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
--- a/drivers/i2c/busses/i2c-via.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-via.c 2004-10-19 16:53:22 -07:00
@@ -168,7 +168,7 @@

static int __init i2c_vt586b_init(void)
{
- return pci_module_init(&vt586b_driver);
+ return pci_register_driver(&vt586b_driver);
}

static void __exit i2c_vt586b_exit(void)
diff -Nru a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
--- a/drivers/i2c/busses/i2c-viapro.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-viapro.c 2004-10-19 16:53:22 -07:00
@@ -465,7 +465,7 @@

static int __init i2c_vt596_init(void)
{
- return pci_module_init(&vt596_driver);
+ return pci_register_driver(&vt596_driver);
}


diff -Nru a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
--- a/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/busses/i2c-voodoo3.c 2004-10-19 16:53:22 -07:00
@@ -234,7 +234,7 @@

static int __init i2c_voodoo3_init(void)
{
- return pci_module_init(&voodoo3_driver);
+ return pci_register_driver(&voodoo3_driver);
}

static void __exit i2c_voodoo3_exit(void)
diff -Nru a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c
--- a/drivers/i2c/chips/via686a.c 2004-10-19 16:53:22 -07:00
+++ b/drivers/i2c/chips/via686a.c 2004-10-19 16:53:22 -07:00
@@ -838,7 +838,7 @@

static int __init sm_via686a_init(void)
{
- return pci_module_init(&via686a_pci_driver);
+ return pci_register_driver(&via686a_pci_driver);
}

static void __exit sm_via686a_exit(void)

2004-10-20 03:36:19

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.3, 2004/09/29 11:01:14-07:00, [email protected]

I2C: change i2c-elektor.c driver from using pci_find_device()

Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/busses/i2c-elektor.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)


diff -Nru a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
--- a/drivers/i2c/busses/i2c-elektor.c 2004-10-19 16:54:45 -07:00
+++ b/drivers/i2c/busses/i2c-elektor.c 2004-10-19 16:54:45 -07:00
@@ -180,11 +180,10 @@
/* check to see we have memory mapped PCF8584 connected to the
Cypress cy82c693 PCI-ISA bridge as on UP2000 board */
if (base == 0) {
+ struct pci_dev *cy693_dev;

- struct pci_dev *cy693_dev =
- pci_find_device(PCI_VENDOR_ID_CONTAQ,
- PCI_DEVICE_ID_CONTAQ_82C693, NULL);
-
+ cy693_dev = pci_get_device(PCI_VENDOR_ID_CONTAQ,
+ PCI_DEVICE_ID_CONTAQ_82C693, NULL);
if (cy693_dev) {
char config;
/* yeap, we've found cypress, let's check config */
@@ -215,6 +214,7 @@
printk(KERN_INFO "i2c-elektor: found API UP2000 like board, will probe PCF8584 later.\n");
}
}
+ pci_dev_put(cy693_dev);
}
}
#endif

2004-10-20 00:26:12

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1867.7.3, 2004/09/14 10:50:58-07:00, [email protected]

[PATCH] I2C: More verbose debug in w83781d detection

Quoting myself:
> As for me, I will propose my extra-debug patch (slightly cleaned up)
> for inclusion into the 2.6 kernel. It helped us once, so it could
> prove to be valuable in the future as well.

Here is the patch. It makes the w83781d (mis)detection more verbose so
as to help debugging problems. The extra messages of course only show
when I2C chip debugging is enabled. It additionally features some code
refactoring, some CodingStyle cleanups and adds a missing white space in
one debug message.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/w83781d.c | 42 +++++++++++++++++++++++++++---------------
1 files changed, 27 insertions(+), 15 deletions(-)


diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c 2004-10-19 16:55:16 -07:00
+++ b/drivers/i2c/chips/w83781d.c 2004-10-19 16:55:16 -07:00
@@ -1062,6 +1062,9 @@

if (is_isa)
if (!request_region(address, W83781D_EXTENT, "w83781d")) {
+ dev_dbg(&adapter->dev, "Request of region "
+ "0x%x-0x%x for w83781d failed\n", address,
+ address + W83781D_EXTENT - 1);
err = -EBUSY;
goto ERROR0;
}
@@ -1075,15 +1078,11 @@
/* We need the timeouts for at least some LM78-like
chips. But only if we read 'undefined' registers. */
i = inb_p(address + 1);
- if (inb_p(address + 2) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
- if (inb_p(address + 3) != i) {
- err = -ENODEV;
- goto ERROR1;
- }
- if (inb_p(address + 7) != i) {
+ if (inb_p(address + 2) != i
+ || inb_p(address + 3) != i
+ || inb_p(address + 7) != i) {
+ dev_dbg(&adapter->dev, "Detection of w83781d "
+ "chip failed at step 1\n");
err = -ENODEV;
goto ERROR1;
}
@@ -1092,8 +1091,13 @@
/* Let's just hope nothing breaks here */
i = inb_p(address + 5) & 0x7f;
outb_p(~i & 0x7f, address + 5);
- if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
+ val2 = inb_p(address + 5) & 0x7f;
+ if (val2 != (~i & 0x7f)) {
outb_p(i, address + 5);
+ dev_dbg(&adapter->dev, "Detection of w83781d "
+ "chip failed at step 2 (0x%x != "
+ "0x%x at 0x%x)\n", val2, ~i & 0x7f,
+ address + 5);
err = -ENODEV;
goto ERROR1;
}
@@ -1125,7 +1129,9 @@
force_*=... parameter, and the Winbond will be reset to the right
bank. */
if (kind < 0) {
- if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80){
+ if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80) {
+ dev_dbg(&new_client->dev, "Detection failed at step "
+ "3\n");
err = -ENODEV;
goto ERROR2;
}
@@ -1135,6 +1141,8 @@
if ((!(val1 & 0x07)) &&
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
|| ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
+ dev_dbg(&new_client->dev, "Detection failed at step "
+ "4\n");
err = -ENODEV;
goto ERROR2;
}
@@ -1144,6 +1152,8 @@
((val1 & 0x80) && (val2 == 0x5c)))) {
if (w83781d_read_value
(new_client, W83781D_REG_I2C_ADDR) != address) {
+ dev_dbg(&new_client->dev, "Detection failed "
+ "at step 5\n");
err = -ENODEV;
goto ERROR2;
}
@@ -1166,6 +1176,8 @@
else if (val2 == 0x12)
vendid = asus;
else {
+ dev_dbg(&new_client->dev, "Chip was made by neither "
+ "Winbond nor Asus?\n");
err = -ENODEV;
goto ERROR2;
}
@@ -1186,10 +1198,10 @@
kind = w83697hf;
else {
if (kind == 0)
- dev_warn(&new_client->dev,
- "Ignoring 'force' parameter for unknown chip at"
- "adapter %d, address 0x%02x\n",
- i2c_adapter_id(adapter), address);
+ dev_warn(&new_client->dev, "Ignoring 'force' "
+ "parameter for unknown chip at "
+ "adapter %d, address 0x%02x\n",
+ i2c_adapter_id(adapter), address);
err = -EINVAL;
goto ERROR2;
}

2004-10-20 00:26:07

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.1939.9.6, 2004/09/29 13:37:26-07:00, [email protected]

[PATCH] i2c: sensors chip driver updates

This patch modifies some sysfs file names for sensors chip drivers in
accordance with the standard interface proposed here [1] and refined
here [2]. The lm_sensors userspace tools have been modified to accept
both the new and old names. This patch was tested for some drivers,
and at least compile tested for the rest.

[1] http://archives.andrew.net.au/lm-sensors/msg08477.html

[2] http://archives.andrew.net.au/lm-sensors/msg18391.html

Signed-off-by: Mark M. Hoffman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


Documentation/i2c/sysfs-interface | 7 ++++--
drivers/i2c/chips/adm1031.c | 6 ++---
drivers/i2c/chips/asb100.c | 8 +++----
drivers/i2c/chips/lm85.c | 17 ++++++++--------
drivers/i2c/chips/smsc47m1.c | 40 +++++++++++++++++++-------------------
drivers/i2c/chips/w83627hf.c | 4 +--
drivers/i2c/chips/w83781d.c | 16 +++++++++------
7 files changed, 53 insertions(+), 45 deletions(-)


diff -Nru a/Documentation/i2c/sysfs-interface b/Documentation/i2c/sysfs-interface
--- a/Documentation/i2c/sysfs-interface 2004-10-19 16:54:30 -07:00
+++ b/Documentation/i2c/sysfs-interface 2004-10-19 16:54:30 -07:00
@@ -135,12 +135,15 @@
Note that this is actually an internal clock divisor, which
affects the measurable speed range, not the read value.

-fan[1-3]_pwm Pulse width modulation fan control.
+*******
+* PWM *
+*******
+pwm[1-3] Pulse width modulation fan control.
Integer value in the range 0 to 255
Read/Write
255 is max or 100%.

-fan[1-3]_pwm_enable
+pwm[1-3]_enable
Switch PWM on and off.
Not always present even if fan*_pwm is.
0 to turn off
diff -Nru a/drivers/i2c/chips/adm1031.c b/drivers/i2c/chips/adm1031.c
--- a/drivers/i2c/chips/adm1031.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/adm1031.c 2004-10-19 16:54:30 -07:00
@@ -436,7 +436,7 @@
{ \
return set_pwm(dev, buf, count, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm_##offset, set_pwm_##offset)

pwm_reg(1);
@@ -799,7 +799,7 @@
device_create_file(&new_client->dev, &dev_attr_fan1_input);
device_create_file(&new_client->dev, &dev_attr_fan1_div);
device_create_file(&new_client->dev, &dev_attr_fan1_min);
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm);
+ device_create_file(&new_client->dev, &dev_attr_pwm1);
device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel);
device_create_file(&new_client->dev, &dev_attr_temp1_input);
device_create_file(&new_client->dev, &dev_attr_temp1_min);
@@ -826,7 +826,7 @@
device_create_file(&new_client->dev, &dev_attr_fan2_input);
device_create_file(&new_client->dev, &dev_attr_fan2_div);
device_create_file(&new_client->dev, &dev_attr_fan2_min);
- device_create_file(&new_client->dev, &dev_attr_fan2_pwm);
+ device_create_file(&new_client->dev, &dev_attr_pwm2);
device_create_file(&new_client->dev,
&dev_attr_auto_fan2_channel);
device_create_file(&new_client->dev, &dev_attr_temp3_input);
diff -Nru a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c
--- a/drivers/i2c/chips/asb100.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/asb100.c 2004-10-19 16:54:30 -07:00
@@ -591,12 +591,12 @@
return count;
}

-static DEVICE_ATTR(fan1_pwm, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
-static DEVICE_ATTR(fan1_pwm_enable, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm1, set_pwm1);
+static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
show_pwm_enable1, set_pwm_enable1);
#define device_create_file_pwm1(client) do { \
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm); \
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable); \
+ device_create_file(&new_client->dev, &dev_attr_pwm1); \
+ device_create_file(&new_client->dev, &dev_attr_pwm1_enable); \
} while (0)

/* This function is called when:
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/lm85.c 2004-10-19 16:54:30 -07:00
@@ -538,9 +538,10 @@
{ \
return show_pwm_enable(dev, buf, 0x##offset - 1); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm_##offset, set_pwm_##offset); \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL);
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \
+ show_pwm_enable##offset, NULL);

show_pwm_reg(1);
show_pwm_reg(2);
@@ -845,12 +846,12 @@
device_create_file(&new_client->dev, &dev_attr_fan2_min);
device_create_file(&new_client->dev, &dev_attr_fan3_min);
device_create_file(&new_client->dev, &dev_attr_fan4_min);
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm);
- device_create_file(&new_client->dev, &dev_attr_fan2_pwm);
- device_create_file(&new_client->dev, &dev_attr_fan3_pwm);
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable);
- device_create_file(&new_client->dev, &dev_attr_fan2_pwm_enable);
- device_create_file(&new_client->dev, &dev_attr_fan3_pwm_enable);
+ device_create_file(&new_client->dev, &dev_attr_pwm1);
+ device_create_file(&new_client->dev, &dev_attr_pwm2);
+ device_create_file(&new_client->dev, &dev_attr_pwm3);
+ device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
+ device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
+ device_create_file(&new_client->dev, &dev_attr_pwm3_enable);
device_create_file(&new_client->dev, &dev_attr_in0_input);
device_create_file(&new_client->dev, &dev_attr_in1_input);
device_create_file(&new_client->dev, &dev_attr_in2_input);
diff -Nru a/drivers/i2c/chips/smsc47m1.c b/drivers/i2c/chips/smsc47m1.c
--- a/drivers/i2c/chips/smsc47m1.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/smsc47m1.c 2004-10-19 16:54:30 -07:00
@@ -182,13 +182,13 @@
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
}

-static ssize_t get_fan_pwm(struct device *dev, char *buf, int nr)
+static ssize_t get_pwm(struct device *dev, char *buf, int nr)
{
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
}

-static ssize_t get_fan_pwm_en(struct device *dev, char *buf, int nr)
+static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
{
struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
@@ -256,7 +256,7 @@
return count;
}

-static ssize_t set_fan_pwm(struct device *dev, const char *buf,
+static ssize_t set_pwm(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -275,7 +275,7 @@
return count;
}

-static ssize_t set_fan_pwm_en(struct device *dev, const char *buf,
+static ssize_t set_pwm_en(struct device *dev, const char *buf,
size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -318,23 +318,23 @@
{ \
return set_fan_div(dev, buf, count, 0x##offset - 1); \
} \
-static ssize_t get_fan##offset##_pwm (struct device *dev, char *buf) \
+static ssize_t get_pwm##offset (struct device *dev, char *buf) \
{ \
- return get_fan_pwm(dev, buf, 0x##offset - 1); \
+ return get_pwm(dev, buf, 0x##offset - 1); \
} \
-static ssize_t set_fan##offset##_pwm (struct device *dev, \
+static ssize_t set_pwm##offset (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_pwm(dev, buf, count, 0x##offset - 1); \
+ return set_pwm(dev, buf, count, 0x##offset - 1); \
} \
-static ssize_t get_fan##offset##_pwm_en (struct device *dev, char *buf) \
+static ssize_t get_pwm##offset##_en (struct device *dev, char *buf) \
{ \
- return get_fan_pwm_en(dev, buf, 0x##offset - 1); \
+ return get_pwm_en(dev, buf, 0x##offset - 1); \
} \
-static ssize_t set_fan##offset##_pwm_en (struct device *dev, \
+static ssize_t set_pwm##offset##_en (struct device *dev, \
const char *buf, size_t count) \
{ \
- return set_fan_pwm_en(dev, buf, count, 0x##offset - 1); \
+ return set_pwm_en(dev, buf, count, 0x##offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
NULL); \
@@ -342,10 +342,10 @@
get_fan##offset##_min, set_fan##offset##_min); \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
get_fan##offset##_div, set_fan##offset##_div); \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
- get_fan##offset##_pwm, set_fan##offset##_pwm); \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, \
- get_fan##offset##_pwm_en, set_fan##offset##_pwm_en);
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
+ get_pwm##offset, set_pwm##offset); \
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
+ get_pwm##offset##_en, set_pwm##offset##_en);

fan_present(1);
fan_present(2);
@@ -462,15 +462,15 @@

if ((smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
== 0x04) {
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm);
- device_create_file(&new_client->dev, &dev_attr_fan1_pwm_enable);
+ device_create_file(&new_client->dev, &dev_attr_pwm1);
+ device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
} else
dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
"skipping\n");
if ((smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
== 0x04) {
- device_create_file(&new_client->dev, &dev_attr_fan2_pwm);
- device_create_file(&new_client->dev, &dev_attr_fan2_pwm_enable);
+ device_create_file(&new_client->dev, &dev_attr_pwm2);
+ device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
} else
dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
"skipping\n");
diff -Nru a/drivers/i2c/chips/w83627hf.c b/drivers/i2c/chips/w83627hf.c
--- a/drivers/i2c/chips/w83627hf.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/w83627hf.c 2004-10-19 16:54:30 -07:00
@@ -845,7 +845,7 @@
{ \
return store_pwm_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_regs_pwm_##offset, store_regs_pwm_##offset);

sysfs_pwm(1);
@@ -854,7 +854,7 @@

#define device_create_file_pwm(client, offset) \
do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \
+device_create_file(&client->dev, &dev_attr_pwm##offset); \
} while (0)

static ssize_t
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c 2004-10-19 16:54:30 -07:00
+++ b/drivers/i2c/chips/w83781d.c 2004-10-19 16:54:30 -07:00
@@ -740,22 +740,26 @@
{ \
return show_pwm_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_pwm_##offset (struct device *dev, \
+ const char *buf, size_t count) \
{ \
return store_pwm_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset);
+static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
+ show_regs_pwm_##offset, store_regs_pwm_##offset);

#define sysfs_pwmenable(offset) \
static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \
{ \
return show_pwmenable_reg(dev, buf, offset); \
} \
-static ssize_t store_regs_pwmenable_##offset (struct device *dev, const char *buf, size_t count) \
+static ssize_t store_regs_pwmenable_##offset (struct device *dev, \
+ const char *buf, size_t count) \
{ \
return store_pwmenable_reg(dev, buf, count, offset); \
} \
-static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);
+static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
+ show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);

sysfs_pwm(1);
sysfs_pwm(2);
@@ -765,12 +769,12 @@

#define device_create_file_pwm(client, offset) \
do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \
+device_create_file(&client->dev, &dev_attr_pwm##offset); \
} while (0)

#define device_create_file_pwmenable(client, offset) \
do { \
-device_create_file(&client->dev, &dev_attr_fan##offset##_pwm_enable); \
+device_create_file(&client->dev, &dev_attr_pwm##offset##_enable); \
} while (0)

static ssize_t

2004-10-20 04:02:54

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

ChangeSet 1.2071, 2004/10/19 15:20:59-07:00, [email protected]

[PATCH] I2C: fix it8712 detection

Following patch fixes the bug introduced by me in VID VRM patch.
Spotted (and later reviewed) by Jean Delvare. This bug is non-fatal,
it8712 will be just treated as it was before my VID VRM patch.

Tested on it8705 and it8712 hardware.

Signed-off-by: Rudolf Marek <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


drivers/i2c/chips/it87.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)


diff -Nru a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c
--- a/drivers/i2c/chips/it87.c 2004-10-19 16:54:04 -07:00
+++ b/drivers/i2c/chips/it87.c 2004-10-19 16:54:04 -07:00
@@ -105,6 +105,10 @@
/* Reset the registers on init if true */
static int reset;

+/* Chip Type */
+
+static u16 chip_type;
+
/* Many IT87 constants specified below */

/* Length of ISA address segment */
@@ -592,9 +596,9 @@
u16 val;

superio_enter();
- val = (superio_inb(DEVID) << 8) |
+ chip_type = (superio_inb(DEVID) << 8) |
superio_inb(DEVID + 1);
- if (val != IT8712F_DEVID) {
+ if (chip_type != IT8712F_DEVID) {
superio_exit();
return -ENODEV;
}
@@ -691,11 +695,9 @@
if (kind <= 0) {
i = it87_read_value(new_client, IT87_REG_CHIPID);
if (i == 0x90) {
- u16 val;
kind = it87;
- val = (superio_inb(DEVID) << 8) |
- superio_inb(DEVID + 1);
- if (val == IT8712F_DEVID) kind = it8712;
+ if ((is_isa) && (chip_type == IT8712F_DEVID))
+ kind = it8712;
}
else {
if (kind == 0)

2004-10-20 05:26:39

by Eugene Surovegin

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

On Tue, Oct 19, 2004 at 05:18:26PM -0700, Greg Kroah-Hartman wrote:
> ChangeSet 1.2072, 2004/10/19 15:21:15-07:00, [email protected]
>
> [PATCH] I2C: replace schedule_timeout() with msleep_interruptible() in i2c-ibm_iic.c
>
> Use msleep_interruptible() instead of schedule_timeout() to
> guarantee the task delays as expected. Remove the unnecessary
> set_current_state() following the if, as schedule_timeout() [and thus,
> mlseep_interruptible()] is guaranteed to return in TASK_RUNNING.
>
> Signed-off-by: Nishanth Aravamudan <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
>
> drivers/i2c/busses/i2c-ibm_iic.c | 4 +---
> 1 files changed, 1 insertion(+), 3 deletions(-)
>
>
> diff -Nru a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
> --- a/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-19 16:53:58 -07:00
> +++ b/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-19 16:53:58 -07:00
> @@ -416,10 +416,8 @@
> init_waitqueue_entry(&wait, current);
>
> add_wait_queue(&dev->wq, &wait);
> - set_current_state(TASK_INTERRUPTIBLE);
> if (in_8(&iic->sts) & STS_PT)
> - schedule_timeout(dev->adap.timeout * HZ);
> - set_current_state(TASK_RUNNING);
> + msleep_interruptible(dev->adap.timeout * 1000);
> remove_wait_queue(&dev->wq, &wait);
>
> if (unlikely(signal_pending(current))){

It looks like this change added race I tried to avoid here.

This code is modeled after __wait_event_interruptible_timeout, where
"prepare_to_wait" is done _before_ checking completion status. This
change breaks this, e.g. if IRQ happens right after we check iic->sts,
but before calling msleep_interruptible(). In this case we'll sleep
much more than required (seconds instead of microseconds)

Greg, if my analysis is correct, please rollback this change.

Nishanth, I'd be nice if you CC'ed me with this patch, my e-mail is at
the top of that source file.

--
Eugene


2004-10-20 06:36:31

by Eugene Surovegin

[permalink] [raw]
Subject: [PATCH] fix recently introduced race in IBM PPC4xx I2C driver

On Tue, Oct 19, 2004 at 10:21:08PM -0700, Eugene Surovegin wrote:

[snip]

> It looks like this change added race I tried to avoid here.
>
> This code is modeled after __wait_event_interruptible_timeout, where
> "prepare_to_wait" is done _before_ checking completion status. This
> change breaks this, e.g. if IRQ happens right after we check iic->sts,
> but before calling msleep_interruptible(). In this case we'll sleep
> much more than required (seconds instead of microseconds)
>
> Greg, if my analysis is correct, please rollback this change.
>
> Nishanth, I'd be nice if you CC'ed me with this patch, my e-mail is at
> the top of that source file.

Oh, well. I should have used wait_event_interruptible_timeout when I
ported this driver to 2.6.

This patch fixes recently introduced race and also cleans ups some
2.4-ism.

Please, apply.

Signed-off-by: Eugene Surovegin <[email protected]>

===== drivers/i2c/busses/i2c-ibm_iic.c 1.12 vs edited =====
--- 1.12/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-14 11:30:08 -07:00
+++ edited/drivers/i2c/busses/i2c-ibm_iic.c 2004-10-19 23:18:16 -07:00
@@ -412,18 +412,12 @@

if (dev->irq >= 0){
/* Interrupt mode */
- wait_queue_t wait;
- init_waitqueue_entry(&wait, current);
-
- add_wait_queue(&dev->wq, &wait);
- if (in_8(&iic->sts) & STS_PT)
- msleep_interruptible(dev->adap.timeout * 1000);
- remove_wait_queue(&dev->wq, &wait);
-
- if (unlikely(signal_pending(current))){
+ ret = wait_event_interruptible_timeout(dev->wq,
+ !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);
+
+ if (unlikely(ret < 0))
DBG("%d: wait interrupted\n", dev->idx);
- ret = -ERESTARTSYS;
- } else if (unlikely(in_8(&iic->sts) & STS_PT)){
+ else if (unlikely(in_8(&iic->sts) & STS_PT)){
DBG("%d: wait timeout\n", dev->idx);
ret = -ETIMEDOUT;
}

2004-10-20 16:04:54

by Jean Delvare

[permalink] [raw]
Subject: Re: [BK PATCH] I2C update for 2.6.9


Hi Greg,

>Here are some i2c driver fixes and updates for 2.6.9. There is a new
>chip and a new bus driver, as well as a bunch of minor fixes. The
>majority of these patches have been in the past few -mm releases.

It looks like only three of these patches actually hit the lm_sensors
mailing-list, and I don't see any (not even this annoucement) on the
LKML. Could it be that your patch generator went bad somehow?

Thanks,
Jean

2004-10-20 16:46:19

by Lee Revell

[permalink] [raw]
Subject: Re: [BK PATCH] I2C update for 2.6.9

On Wed, 2004-10-20 at 11:57, Jean Delvare wrote:
> Hi Greg,
>
> >Here are some i2c driver fixes and updates for 2.6.9. There is a new
> >chip and a new bus driver, as well as a bunch of minor fixes. The
> >majority of these patches have been in the past few -mm releases.
>
> It looks like only three of these patches actually hit the lm_sensors
> mailing-list, and I don't see any (not even this annoucement) on the
> LKML. Could it be that your patch generator went bad somehow?
>

Probably a list issue, vger seems to be bogged down, I am seeing 12-24
hour delays since yesterday.

Lee

2004-10-22 19:58:12

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH] fix recently introduced race in IBM PPC4xx I2C driver

On Tue, Oct 19, 2004 at 11:26:33PM -0700, Eugene Surovegin wrote:
> On Tue, Oct 19, 2004 at 10:21:08PM -0700, Eugene Surovegin wrote:
>
> [snip]
>
> > It looks like this change added race I tried to avoid here.
> >
> > This code is modeled after __wait_event_interruptible_timeout, where
> > "prepare_to_wait" is done _before_ checking completion status. This
> > change breaks this, e.g. if IRQ happens right after we check iic->sts,
> > but before calling msleep_interruptible(). In this case we'll sleep
> > much more than required (seconds instead of microseconds)
> >
> > Greg, if my analysis is correct, please rollback this change.
> >
> > Nishanth, I'd be nice if you CC'ed me with this patch, my e-mail is at
> > the top of that source file.
>
> Oh, well. I should have used wait_event_interruptible_timeout when I
> ported this driver to 2.6.
>
> This patch fixes recently introduced race and also cleans ups some
> 2.4-ism.
>
> Please, apply.

Applied, thanks.

greg k-h

2004-10-22 21:34:39

by Jean Delvare

[permalink] [raw]
Subject: Re: [BK PATCH] I2C update for 2.6.9

Hi Greg,

> Here are some i2c driver fixes and updates for 2.6.9. There is a new
> chip and a new bus driver, as well as a bunch of minor fixes. The
> majority of these patches have been in the past few -mm releases.

Checked against my personal list, no patch were lost. Thanks :)

--
Jean Delvare
http://khali.linux-fr.org/

2004-10-25 18:29:54

by Bill Davidsen

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

Greg KH wrote:

> Trip points
> ===========
>
> Trip points are now numbered (point1, point2, etc...) instead of named
> (_off, _min, _max, _full...). This solves the problem of various chips
> having a different number of trip points. The interface is still chip
> independent in that it doesn't require chip-specific knowledge to be
> used by user-space apps.

It would seem that all chips would have off, max, full, etc, but mapping
nondescript names into functionality may require some chip info anyway.
As you note, with some chips these are not nice linear points on a line,
so it would seem to tell if the top points were "max norm" and "max
safe" vs. "critical" and "shutdown NOW" is still going to need some
information on the chip, both points and operating range.

That's an observation, not a complaint, not even a question unless you
feel the urge to enlighten me.
>
> The reason for this change is that newer chips tend to have more trip
> points. the LM63 has 8, the LM93 has no less than 12. Also, I read in
> the LM63 datasheet that ideal pwm vs temperature curve were parabolic in
> shape. Seems hard to achieve this if we arbitrarily lock the number of
> trip points to 3 ;)
>
> I also introduced an optional hysteresis temperature for trip points.
> The LM63 has this. Since it makes full sense I'd expect other chips to
> propose this as well.
>
> As before, there are two sets of files, each chip driver picks the one
> matching its internal model: trip points are either temperature
> channel-dependent (ADM1031...) or pwm channel-dependent (IT87xx...). If
> we ever come accross fan speed-driven pwm outputs where trip points are
> fan channel-dependent we may have to offer a third set of files. We'll
> see when/if this happens.
>
> I hope I have taken everyone's comments and advice into account and we
> can make this interface proposal part of the sysfs interface standard
> now. I'm sorry it took so long. Comments welcome.

--
-bill davidsen ([email protected])
"The secret to procrastination is to put things off until the
last possible moment - but no longer" -me

2004-10-25 21:08:45

by Jean Delvare

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

Hi Bill,

> Greg KH wrote:

I actually wrote this.

> > Trip points
> > ===========
> >
> > Trip points are now numbered (point1, point2, etc...) instead of
> > named(_off, _min, _max, _full...). This solves the problem of
> > various chips having a different number of trip points. The
> > interface is still chip independent in that it doesn't require
> > chip-specific knowledge to be used by user-space apps.
>
> It would seem that all chips would have off, max, full, etc, but
> mapping nondescript names into functionality may require some chip
> info anyway. As you note, with some chips these are not nice linear
> points on a line,
> so it would seem to tell if the top points were "max norm" and "max
> safe" vs. "critical" and "shutdown NOW" is still going to need some
> information on the chip, both points and operating range.

The interface is actually (almost) self-sufficient. A point is the union
of a temperature and a fan speed. Most often, point1 will have a speed
of 0, which means it really is _off. point1 will be fan_min. point(P-1)
will be _max, point(P) will have a speed of 100% and will be _full. The
advantage of the numbered approach is that you can have has many points
as the chip provides. It will also help user-space applications, since
all points can be handled the exact same way, without having to
interpret the names, know that some names have predefined fan speeds,
etc.

The only thing the interface doesn't tell is the shape of the curve
resulting from the various trip points. This is admittedly chip
dependent. I think it would be next to impossible to export this through
sysfs, and I'm not sure it would be worth the pain anyway. The exact
shape of the curve isn't that important IMHO.

Your objection about "critical", "shutdown NOW" etc if out of the scope
of this interface. The critical limits are defined by tempN_crit files.
Actions taken by the chip when the limit is crossed is admittedly
chip-dependent. Not a big deal either, since in most cases this is
either not configurable or motherboard-dependent and set by the BIOS for
us anyway.

I hope I answered your question-which-was-not-really-one. :)

--
Jean Delvare
http://khali.linux-fr.org/

2004-10-26 21:03:25

by Bill Davidsen

[permalink] [raw]
Subject: Re: [PATCH] I2C update for 2.6.9

Jean Delvare wrote:
> Hi Bill,
>
>
>>Greg KH wrote:
>
>
> I actually wrote this.
>
>
>>>Trip points
>>>===========
>>>
>>>Trip points are now numbered (point1, point2, etc...) instead of
>>>named(_off, _min, _max, _full...). This solves the problem of
>>>various chips having a different number of trip points. The
>>>interface is still chip independent in that it doesn't require
>>>chip-specific knowledge to be used by user-space apps.
>>
>>It would seem that all chips would have off, max, full, etc, but
>>mapping nondescript names into functionality may require some chip
>>info anyway. As you note, with some chips these are not nice linear
>>points on a line,
>> so it would seem to tell if the top points were "max norm" and "max
>>safe" vs. "critical" and "shutdown NOW" is still going to need some
>>information on the chip, both points and operating range.
>
>
> The interface is actually (almost) self-sufficient. A point is the union
> of a temperature and a fan speed. Most often, point1 will have a speed
> of 0, which means it really is _off. point1 will be fan_min. point(P-1)
> will be _max, point(P) will have a speed of 100% and will be _full. The
> advantage of the numbered approach is that you can have has many points
> as the chip provides. It will also help user-space applications, since
> all points can be handled the exact same way, without having to
> interpret the names, know that some names have predefined fan speeds,
> etc.
>
> The only thing the interface doesn't tell is the shape of the curve
> resulting from the various trip points. This is admittedly chip
> dependent. I think it would be next to impossible to export this through
> sysfs, and I'm not sure it would be worth the pain anyway. The exact
> shape of the curve isn't that important IMHO.
>
> Your objection about "critical", "shutdown NOW" etc if out of the scope
> of this interface. The critical limits are defined by tempN_crit files.
> Actions taken by the chip when the limit is crossed is admittedly
> chip-dependent. Not a big deal either, since in most cases this is
> either not configurable or motherboard-dependent and set by the BIOS for
> us anyway.
>
> I hope I answered your question-which-was-not-really-one. :)
>
You have definitely given me a lot more information, and I do understand
why you do it this way. The shape of the curve may be of interest I
would think, if point3 to point4 is 30C to 40C I'm in a normal chip
range. If they represent 40c to 85C I really worry about flames coming
out next. That clearly can be known in the application as well, but it
isn't as easy to to as having names like max_norm, etc.

Anyway, thinks for the expanded info, more than I expected from a
non-question.

BTW: I see that the new G5 dual-CPU Mac does run the CPUs at 85C, liquid
cooled. At least ComputerWorld says they do. Yikes!

--
-bill davidsen ([email protected])
"The secret to procrastination is to put things off until the
last possible moment - but no longer" -me