]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'char-misc/char-misc-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 13 Sep 2012 06:18:32 +0000 (16:18 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 13 Sep 2012 06:18:32 +0000 (16:18 +1000)
30 files changed:
Documentation/devicetree/bindings/misc/at25.txt
Documentation/devicetree/bindings/w1/w1-gpio.txt [new file with mode: 0644]
Documentation/misc-devices/lis3lv02d
drivers/char/ppdev.c
drivers/char/tlclk.c
drivers/misc/bmp085-i2c.c
drivers/misc/bmp085-spi.c
drivers/misc/carma/carma-fpga-program.c
drivers/misc/carma/carma-fpga.c
drivers/misc/eeprom/at25.c
drivers/misc/lis3lv02d/lis3lv02d.c
drivers/misc/lis3lv02d/lis3lv02d.h
drivers/misc/lis3lv02d/lis3lv02d_i2c.c
drivers/misc/mei/hw.h
drivers/misc/mei/init.c
drivers/misc/mei/interface.h
drivers/misc/mei/interrupt.c
drivers/misc/mei/iorw.c
drivers/misc/mei/main.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/wd.c
drivers/misc/pch_phub.c
drivers/misc/ti-st/st_core.c
drivers/misc/ti-st/st_kim.c
drivers/misc/tifm_7xx1.c
drivers/w1/masters/Kconfig
drivers/w1/masters/omap_hdq.c
drivers/w1/masters/w1-gpio.c
include/linux/ti_wilink_st.h
include/linux/w1-gpio.h

index ab3c327929dd26c09f19272219a4c8c26b7d3dd3..1d3447165c374f673aa9a717f94f2387cfd852f1 100644 (file)
@@ -1,21 +1,35 @@
-Atmel AT25 eeprom
+EEPROMs (SPI) compatible with Atmel at25.
 
 Required properties:
 - compatible : "atmel,at25".
 - reg : chip select number
 - spi-max-frequency : max spi frequency to use
+- pagesize : size of the eeprom page
+- size : total eeprom size in bytes
+- address-width : number of address bits (one of 8, 16, or 24)
 
+Optional properties:
+- spi-cpha : SPI shifted clock phase, as per spi-bus bindings.
+- spi-cpol : SPI inverse clock polarity, as per spi-bus bindings.
+- read-only : this parameter-less property disables writes to the eeprom
+
+Obsolete legacy properties are can be used in place of "size", "pagesize",
+"address-width", and "read-only":
 - at25,byte-len : total eeprom size in bytes
 - at25,addr-mode : addr-mode flags, as defined in include/linux/spi/eeprom.h
 - at25,page-size : size of the eeprom page
 
-Examples:
-at25@0 {
-       compatible = "atmel,at25";
-       reg = <0>
-       spi-max-frequency = <5000000>;
+Additional compatible properties are also allowed.
+
+Example:
+       at25@0 {
+               compatible = "atmel,at25", "st,m95256";
+               reg = <0>
+               spi-max-frequency = <5000000>;
+               spi-cpha;
+               spi-cpol;
 
-       at25,byte-len = <0x8000>;
-       at25,addr-mode = <2>;
-       at25,page-size = <64>;
-};
+               pagesize = <64>;
+               size = <32768>;
+               address-width = <16>;
+       };
diff --git a/Documentation/devicetree/bindings/w1/w1-gpio.txt b/Documentation/devicetree/bindings/w1/w1-gpio.txt
new file mode 100644 (file)
index 0000000..6e09c35
--- /dev/null
@@ -0,0 +1,22 @@
+w1-gpio devicetree bindings
+
+Required properties:
+
+ - compatible: "w1-gpio"
+ - gpios: one or two GPIO specs:
+               - the first one is used as data I/O pin
+               - the second one is optional. If specified, it is used as
+                 enable pin for an external pin pullup.
+
+Optional properties:
+
+ - linux,open-drain: if specified, the data pin is considered in
+                    open-drain mode.
+
+Examples:
+
+       onewire@0 {
+               compatible = "w1-gpio";
+               gpios = <&gpio 126 0>, <&gpio 105 0>;
+       };
+
index f1a4ec840f86f2623ea53723286ed036532dc050..af815b9ba413afc6ba3e21beac2d613e771e0bdb 100644 (file)
@@ -4,7 +4,8 @@ Kernel driver lis3lv02d
 Supported chips:
 
   * STMicroelectronics LIS3LV02DL, LIS3LV02DQ (12 bits precision)
-  * STMicroelectronics LIS302DL, LIS3L02DQ, LIS331DL (8 bits)
+  * STMicroelectronics LIS302DL, LIS3L02DQ, LIS331DL (8 bits) and
+    LIS331DLH (16 bits)
 
 Authors:
         Yan Burman <burman.yan@gmail.com>
index 3fcf80ff12f2226fce01f5749e96972d3857072b..d0d824ebf2c187d492f29daef8bbf1043f56d7f1 100644 (file)
@@ -783,7 +783,8 @@ static int __init ppdev_init (void)
                err = PTR_ERR(ppdev_class);
                goto out_chrdev;
        }
-       if (parport_register_driver(&pp_driver)) {
+       err = parport_register_driver(&pp_driver);
+       if (err < 0) {
                printk (KERN_WARNING CHRDEV ": unable to register with parport\n");
                goto out_class;
        }
index ce29e7cce528ec01268f41eb05be4ad7f6dcee3c..e95e0ab0bd870a4c8d679d7dbb092ea2521ee42e 100644 (file)
@@ -784,8 +784,10 @@ static int __init tlclk_init(void)
        }
        tlclk_major = ret;
        alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL);
-       if (!alarm_events)
+       if (!alarm_events) {
+               ret = -ENOMEM;
                goto out1;
+       }
 
        /* Read telecom clock IRQ number (Set by BIOS) */
        if (!request_region(TLCLK_BASE, 8, "telco_clock")) {
index 9943971c13e346a6d1d0f742df90c428024e1f71..a4f33c995ea17c6eabe257ae92c4fc950e49f0a5 100644 (file)
@@ -57,12 +57,6 @@ static int bmp085_i2c_remove(struct i2c_client *client)
        return bmp085_remove(&client->dev);
 }
 
-static const struct of_device_id bmp085_of_match[] = {
-       { .compatible = "bosch,bmp085", },
-       { },
-};
-MODULE_DEVICE_TABLE(of, bmp085_of_match);
-
 static const struct i2c_device_id bmp085_id[] = {
        { BMP085_NAME, 0 },
        { "bmp180", 0 },
@@ -74,7 +68,6 @@ static struct i2c_driver bmp085_i2c_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = BMP085_NAME,
-               .of_match_table = bmp085_of_match
        },
        .id_table       = bmp085_id,
        .probe          = bmp085_i2c_probe,
index 78aaff9b5231731c56c1795a3cf26c0b02fffca1..5e982af9973054e8b4fb94524c303552db18c555 100644 (file)
@@ -73,19 +73,8 @@ static struct spi_driver bmp085_spi_driver = {
        .remove         = __devexit_p(bmp085_spi_remove)
 };
 
-static int __init bmp085_spi_init(void)
-{
-       return spi_register_driver(&bmp085_spi_driver);
-}
-
-static void __exit bmp085_spi_exit(void)
-{
-       spi_unregister_driver(&bmp085_spi_driver);
-}
+module_spi_driver(bmp085_spi_driver);
 
 MODULE_AUTHOR("Eric Andersson <eric.andersson@unixphere.com>");
 MODULE_DESCRIPTION("BMP085 SPI bus driver");
 MODULE_LICENSE("GPL");
-
-module_init(bmp085_spi_init);
-module_exit(bmp085_spi_exit);
index a2d25e4857e31387fc0457b5a47efc4c1e438bd0..eaddfe9db149a8f070ec11e5ae78c4e8821f175d 100644 (file)
@@ -978,7 +978,6 @@ static int fpga_of_probe(struct platform_device *op)
        dev_set_drvdata(priv->dev, priv);
        dma_cap_zero(mask);
        dma_cap_set(DMA_MEMCPY, mask);
-       dma_cap_set(DMA_INTERRUPT, mask);
        dma_cap_set(DMA_SLAVE, mask);
        dma_cap_set(DMA_SG, mask);
 
index 8c279da0741026322b6ab71d712e438a7e077fe9..0c43297ed9ac6262ca2e901703f3e3bb3c10a2cb 100644 (file)
@@ -666,7 +666,7 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
        src = SYS_FPGA_BLOCK;
        tx = chan->device->device_prep_dma_memcpy(chan, dst, src,
                                                  REG_BLOCK_SIZE,
-                                                 DMA_PREP_INTERRUPT);
+                                                 0);
        if (!tx) {
                dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n");
                return -ENOMEM;
index 25003d6ceb56f2bca0364c81c881b79dee870711..4ed93dd541164d2a1763688caab1b351d3a799c9 100644 (file)
@@ -302,6 +302,61 @@ static ssize_t at25_mem_write(struct memory_accessor *mem, const char *buf,
 
 /*-------------------------------------------------------------------------*/
 
+static int at25_np_to_chip(struct device *dev,
+                          struct device_node *np,
+                          struct spi_eeprom *chip)
+{
+       u32 val;
+
+       memset(chip, 0, sizeof(*chip));
+       strncpy(chip->name, np->name, sizeof(chip->name));
+
+       if (of_property_read_u32(np, "size", &val) == 0 ||
+           of_property_read_u32(np, "at25,byte-len", &val) == 0) {
+               chip->byte_len = val;
+       } else {
+               dev_err(dev, "Error: missing \"size\" property\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(np, "pagesize", &val) == 0 ||
+           of_property_read_u32(np, "at25,page-size", &val) == 0) {
+               chip->page_size = (u16)val;
+       } else {
+               dev_err(dev, "Error: missing \"pagesize\" property\n");
+               return -ENODEV;
+       }
+
+       if (of_property_read_u32(np, "at25,addr-mode", &val) == 0) {
+               chip->flags = (u16)val;
+       } else {
+               if (of_property_read_u32(np, "address-width", &val)) {
+                       dev_err(dev,
+                               "Error: missing \"address-width\" property\n");
+                       return -ENODEV;
+               }
+               switch (val) {
+               case 8:
+                       chip->flags |= EE_ADDR1;
+                       break;
+               case 16:
+                       chip->flags |= EE_ADDR2;
+                       break;
+               case 24:
+                       chip->flags |= EE_ADDR3;
+                       break;
+               default:
+                       dev_err(dev,
+                               "Error: bad \"address-width\" property: %u\n",
+                               val);
+                       return -ENODEV;
+               }
+               if (of_find_property(np, "read-only", NULL))
+                       chip->flags |= EE_READONLY;
+       }
+       return 0;
+}
+
 static int at25_probe(struct spi_device *spi)
 {
        struct at25_data        *at25 = NULL;
@@ -314,33 +369,11 @@ static int at25_probe(struct spi_device *spi)
        /* Chip description */
        if (!spi->dev.platform_data) {
                if (np) {
-                       u32 val;
-
-                       memset(&chip, 0, sizeof(chip));
-                       strncpy(chip.name, np->name, 10);
-
-                       err = of_property_read_u32(np, "at25,byte-len", &val);
-                       if (err) {
-                               dev_dbg(&spi->dev, "invalid chip dt description\n");
-                               goto fail;
-                       }
-                       chip.byte_len = val;
-
-                       err = of_property_read_u32(np, "at25,addr-mode", &val);
-                       if (err) {
-                               dev_dbg(&spi->dev, "invalid chip dt description\n");
-                               goto fail;
-                       }
-                       chip.flags = (u16)val;
-
-                       err = of_property_read_u32(np, "at25,page-size", &val);
-                       if (err) {
-                               dev_dbg(&spi->dev, "invalid chip dt description\n");
+                       err = at25_np_to_chip(&spi->dev, np, &chip);
+                       if (err)
                                goto fail;
-                       }
-                       chip.page_size = (u16)val;
                } else {
-                       dev_dbg(&spi->dev, "no chip description\n");
+                       dev_err(&spi->dev, "Error: no chip description\n");
                        err = -ENODEV;
                        goto fail;
                }
index a981e2a42f92a9427058d528fd784ed2798c6883..9d37c576d526674dc12dc5dc478ffc45374c2c36 100644 (file)
 #define LIS3_SENSITIVITY_12B           ((LIS3_ACCURACY * 1000) / 1024)
 #define LIS3_SENSITIVITY_8B            (18 * LIS3_ACCURACY)
 
+/*
+ * LIS3331DLH spec says 1LSBs corresponds 4G/1024 -> 1LSB is 1000/1024 mG.
+ * Sensitivity values for +/-2G, outdata in 12 bits for +/-2G scale. so 4
+ * bits adjustment is required
+ */
+#define LIS3DLH_SENSITIVITY_2G         ((LIS3_ACCURACY * 1000) / 1024)
+#define SHIFT_ADJ_2G                   4
+
 #define LIS3_DEFAULT_FUZZ_12B          3
 #define LIS3_DEFAULT_FLAT_12B          3
 #define LIS3_DEFAULT_FUZZ_8B           1
@@ -135,6 +143,19 @@ static s16 lis3lv02d_read_12(struct lis3lv02d *lis3, int reg)
        return (s16)((hi << 8) | lo);
 }
 
+/* 12bits for 2G range, 13 bits for 4G range and 14 bits for 8G range */
+static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+{
+       u8 lo, hi;
+       int v;
+
+       lis3->read(lis3, reg - 1, &lo);
+       lis3->read(lis3, reg, &hi);
+       v = (int) ((hi << 8) | lo);
+
+       return (s16) v >> lis3->shift_adj;
+}
+
 /**
  * lis3lv02d_get_axis - For the given axis, give the value converted
  * @axis:      1,2,3 - can also be negative
@@ -195,6 +216,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 static int lis3_12_rates[4] = {40, 160, 640, 2560};
 static int lis3_8_rates[2] = {100, 400};
 static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
+static int lis3_3dlh_rates[4] = {50, 100, 400, 1000};
 
 /* ODR is Output Data Rate */
 static int lis3lv02d_get_odr(struct lis3lv02d *lis3)
@@ -267,7 +289,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
                                (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
        }
 
-       if (lis3->whoami == WAI_3DC) {
+       if ((lis3->whoami == WAI_3DC) || (lis3->whoami == WAI_3DLH)) {
                ctlreg = CTRL_REG4;
                selftest = CTRL4_ST0;
        } else {
@@ -398,9 +420,17 @@ int lis3lv02d_poweron(struct lis3lv02d *lis3)
                lis3->read(lis3, CTRL_REG2, &reg);
                if (lis3->whoami ==  WAI_12B)
                        reg |= CTRL2_BDU | CTRL2_BOOT;
+               else if (lis3->whoami ==  WAI_3DLH)
+                       reg |= CTRL2_BOOT_3DLH;
                else
                        reg |= CTRL2_BOOT_8B;
                lis3->write(lis3, CTRL_REG2, reg);
+
+               if (lis3->whoami ==  WAI_3DLH) {
+                       lis3->read(lis3, CTRL_REG4, &reg);
+                       reg |= CTRL4_BDU;
+                       lis3->write(lis3, CTRL_REG4, reg);
+               }
        }
 
        err = lis3lv02d_get_pwron_wait(lis3);
@@ -956,6 +986,16 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3)
                lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
                lis3->scale = LIS3_SENSITIVITY_8B;
                break;
+       case WAI_3DLH:
+               pr_info("16 bits 3DLH sensor found\n");
+               lis3->read_data = lis3lv02d_read_16;
+               lis3->mdps_max_val = 2048; /* 12 bits for 2G */
+               lis3->shift_adj = SHIFT_ADJ_2G;
+               lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
+               lis3->odrs = lis3_3dlh_rates;
+               lis3->odr_mask = CTRL1_DR0 | CTRL1_DR1;
+               lis3->scale = LIS3DLH_SENSITIVITY_2G;
+               break;
        default:
                pr_err("unknown sensor type 0x%X\n", lis3->whoami);
                return -EINVAL;
index 2b1482ad3f16aedc776ef4429e6c9da7741c7d5a..c1a545e136a05bada02a9df4b79276ed78527c8c 100644 (file)
 /*
  * This driver tries to support the "digital" accelerometer chips from
  * STMicroelectronics such as LIS3LV02DL, LIS302DL, LIS3L02DQ, LIS331DL,
- * LIS35DE, or LIS202DL. They are very similar in terms of programming, with
- * almost the same registers. In addition to differing on physical properties,
- * they differ on the number of axes (2/3), precision (8/12 bits), and special
- * features (freefall detection, click...). Unfortunately, not all the
- * differences can be probed via a register.
- * They can be connected either via I²C or SPI.
+ * LIS331DLH, LIS35DE, or LIS202DL. They are very similar in terms of
+ * programming, with almost the same registers. In addition to differing
+ * on physical properties, they differ on the number of axes (2/3),
+ * precision (8/12 bits), and special features (freefall detection,
+ * click...). Unfortunately, not all the differences can be probed via
+ * a register. They can be connected either via I²C or SPI.
  */
 
 #include <linux/lis3lv02d.h>
@@ -96,12 +96,22 @@ enum lis3lv02d_reg {
 };
 
 enum lis3_who_am_i {
+       WAI_3DLH        = 0x32, /* 16 bits: LIS331DLH */
        WAI_3DC         = 0x33, /* 8 bits: LIS3DC, HP3DC */
        WAI_12B         = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
        WAI_8B          = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
        WAI_6B          = 0x52, /* 6 bits: LIS331DLF - not supported */
 };
 
+enum lis3_type {
+       LIS3DC,
+       HP3DC,
+       LIS3LV02D,
+       LIS2302D,
+       LIS331DLF,
+       LIS331DLH,
+};
+
 enum lis3lv02d_ctrl1_12b {
        CTRL1_Xen       = 0x01,
        CTRL1_Yen       = 0x02,
@@ -129,6 +139,27 @@ enum lis3lv02d_ctrl1_3dc {
        CTRL1_ODR3      = 0x80,
 };
 
+enum lis331dlh_ctrl1 {
+       CTRL1_DR0       = 0x08,
+       CTRL1_DR1       = 0x10,
+       CTRL1_PM0       = 0x20,
+       CTRL1_PM1       = 0x40,
+       CTRL1_PM2       = 0x80,
+};
+
+enum lis331dlh_ctrl2 {
+       CTRL2_HPEN1     = 0x04,
+       CTRL2_HPEN2     = 0x08,
+       CTRL2_FDS_3DLH  = 0x10,
+       CTRL2_BOOT_3DLH = 0x80,
+};
+
+enum lis331dlh_ctrl4 {
+       CTRL4_STSIGN    = 0x08,
+       CTRL4_BLE       = 0x40,
+       CTRL4_BDU       = 0x80,
+};
+
 enum lis3lv02d_ctrl2 {
        CTRL2_DAS       = 0x01,
        CTRL2_SIM       = 0x02,
@@ -279,6 +310,7 @@ struct lis3lv02d {
        int                     data_ready_count[2];
        atomic_t                wake_thread;
        unsigned char           irq_cfg;
+       unsigned int            shift_adj;
 
        struct lis3lv02d_platform_data *pdata;  /* for passing board config */
        struct mutex            mutex;     /* Serialize poll and selftest */
index e8c0019da97a81bb8643a10c6e956409b5569b82..15255eb8ac8129314457a1f1d736da50440d97e7 100644 (file)
@@ -90,7 +90,11 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
        if (ret < 0)
                return ret;
 
-       reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
+       if (lis3->whoami == WAI_3DLH)
+               reg |= CTRL1_PM0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
+       else
+               reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
+
        return lis3->write(lis3, CTRL_REG1, reg);
 }
 
@@ -232,6 +236,7 @@ static int lis3_i2c_runtime_resume(struct device *dev)
 
 static const struct i2c_device_id lis3lv02d_id[] = {
        {"lis3lv02d", 0 },
+       {"lis331dlh", LIS331DLH},
        {}
 };
 
index 24c4c962819e766f34a0ad211c28d8dcf5642609..9700532f02f6802ecb5aedc0465421c4aae80b79 100644 (file)
 /*
  * MEI device IDs
  */
-#define    MEI_DEV_ID_82946GZ  0x2974  /* 82946GZ/GL */
-#define    MEI_DEV_ID_82G35    0x2984  /* 82G35 Express */
-#define    MEI_DEV_ID_82Q965   0x2994  /* 82Q963/Q965 */
-#define    MEI_DEV_ID_82G965   0x29A4  /* 82P965/G965 */
-
-#define    MEI_DEV_ID_82GM965  0x2A04  /* Mobile PM965/GM965 */
-#define    MEI_DEV_ID_82GME965 0x2A14  /* Mobile GME965/GLE960 */
-
-#define    MEI_DEV_ID_ICH9_82Q35 0x29B4  /* 82Q35 Express */
-#define    MEI_DEV_ID_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
-#define    MEI_DEV_ID_ICH9_82Q33 0x29D4  /* 82Q33 Express */
-#define    MEI_DEV_ID_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
-#define    MEI_DEV_ID_ICH9_3200  0x29F4  /* 3200/3210 Server */
-
-#define    MEI_DEV_ID_ICH9_6   0x28B4  /* Bearlake */
-#define    MEI_DEV_ID_ICH9_7   0x28C4  /* Bearlake */
-#define    MEI_DEV_ID_ICH9_8   0x28D4  /* Bearlake */
-#define    MEI_DEV_ID_ICH9_9    0x28E4  /* Bearlake */
-#define    MEI_DEV_ID_ICH9_10  0x28F4  /* Bearlake */
-
-#define    MEI_DEV_ID_ICH9M_1  0x2A44  /* Cantiga */
-#define    MEI_DEV_ID_ICH9M_2  0x2A54  /* Cantiga */
-#define    MEI_DEV_ID_ICH9M_3  0x2A64  /* Cantiga */
-#define    MEI_DEV_ID_ICH9M_4  0x2A74  /* Cantiga */
-
-#define    MEI_DEV_ID_ICH10_1  0x2E04  /* Eaglelake */
-#define    MEI_DEV_ID_ICH10_2  0x2E14  /* Eaglelake */
-#define    MEI_DEV_ID_ICH10_3  0x2E24  /* Eaglelake */
-#define    MEI_DEV_ID_ICH10_4  0x2E34  /* Eaglelake */
-
-#define    MEI_DEV_ID_IBXPK_1  0x3B64  /* Calpella */
-#define    MEI_DEV_ID_IBXPK_2  0x3B65  /* Calpella */
-
-#define    MEI_DEV_ID_CPT_1    0x1C3A    /* Cougerpoint */
-#define    MEI_DEV_ID_PBG_1    0x1D3A    /* PBG */
-
-#define    MEI_DEV_ID_PPT_1    0x1E3A    /* Pantherpoint PPT */
-#define    MEI_DEV_ID_PPT_2    0x1CBA    /* Pantherpoint PPT */
-#define    MEI_DEV_ID_PPT_3    0x1DBA    /* Pantherpoint PPT */
-
-
+#define MEI_DEV_ID_82946GZ    0x2974  /* 82946GZ/GL */
+#define MEI_DEV_ID_82G35      0x2984  /* 82G35 Express */
+#define MEI_DEV_ID_82Q965     0x2994  /* 82Q963/Q965 */
+#define MEI_DEV_ID_82G965     0x29A4  /* 82P965/G965 */
+
+#define MEI_DEV_ID_82GM965    0x2A04  /* Mobile PM965/GM965 */
+#define MEI_DEV_ID_82GME965   0x2A14  /* Mobile GME965/GLE960 */
+
+#define MEI_DEV_ID_ICH9_82Q35 0x29B4  /* 82Q35 Express */
+#define MEI_DEV_ID_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
+#define MEI_DEV_ID_ICH9_82Q33 0x29D4  /* 82Q33 Express */
+#define MEI_DEV_ID_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
+#define MEI_DEV_ID_ICH9_3200  0x29F4  /* 3200/3210 Server */
+
+#define MEI_DEV_ID_ICH9_6     0x28B4  /* Bearlake */
+#define MEI_DEV_ID_ICH9_7     0x28C4  /* Bearlake */
+#define MEI_DEV_ID_ICH9_8     0x28D4  /* Bearlake */
+#define MEI_DEV_ID_ICH9_9     0x28E4  /* Bearlake */
+#define MEI_DEV_ID_ICH9_10    0x28F4  /* Bearlake */
+
+#define MEI_DEV_ID_ICH9M_1    0x2A44  /* Cantiga */
+#define MEI_DEV_ID_ICH9M_2    0x2A54  /* Cantiga */
+#define MEI_DEV_ID_ICH9M_3    0x2A64  /* Cantiga */
+#define MEI_DEV_ID_ICH9M_4    0x2A74  /* Cantiga */
+
+#define MEI_DEV_ID_ICH10_1    0x2E04  /* Eaglelake */
+#define MEI_DEV_ID_ICH10_2    0x2E14  /* Eaglelake */
+#define MEI_DEV_ID_ICH10_3    0x2E24  /* Eaglelake */
+#define MEI_DEV_ID_ICH10_4    0x2E34  /* Eaglelake */
+
+#define MEI_DEV_ID_IBXPK_1    0x3B64  /* Calpella */
+#define MEI_DEV_ID_IBXPK_2    0x3B65  /* Calpella */
+
+#define MEI_DEV_ID_CPT_1      0x1C3A  /* Couger Point */
+#define MEI_DEV_ID_PBG_1      0x1D3A  /* C600/X79 Patsburg */
+
+#define MEI_DEV_ID_PPT_1      0x1E3A  /* Panther Point */
+#define MEI_DEV_ID_PPT_2      0x1CBA  /* Panther Point */
+#define MEI_DEV_ID_PPT_3      0x1DBA  /* Panther Point */
+
+#define MEI_DEV_ID_LPT        0x8C3A  /* Lynx Point */
+#define MEI_DEV_ID_LPT_LP     0x9C3A  /* Lynx Point LP */
 /*
  * MEI HW Section
  */
index e77f86e69fb5f55ba89bfac1e6b217a4318d0fe2..98f1430e3e1446b272725bffbf25da609c0aa3e7 100644 (file)
 #include "interface.h"
 #include <linux/mei.h>
 
+const char *mei_dev_state_str(int state)
+{
+#define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
+       switch (state) {
+       MEI_DEV_STATE(INITIALIZING);
+       MEI_DEV_STATE(INIT_CLIENTS);
+       MEI_DEV_STATE(ENABLED);
+       MEI_DEV_STATE(RESETING);
+       MEI_DEV_STATE(DISABLED);
+       MEI_DEV_STATE(RECOVERING_FROM_RESET);
+       MEI_DEV_STATE(POWER_DOWN);
+       MEI_DEV_STATE(POWER_UP);
+       default:
+               return "unkown";
+       }
+#undef MEI_DEV_STATE
+}
+
+
 const uuid_le mei_amthi_guid  = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
                                                0xa8, 0x46, 0xe0, 0xff, 0x65,
                                                0x81, 0x4c);
@@ -123,7 +142,7 @@ struct mei_device *mei_device_init(struct pci_dev *pdev)
        mutex_init(&dev->device_lock);
        init_waitqueue_head(&dev->wait_recvd_msg);
        init_waitqueue_head(&dev->wait_stop_wd);
-       dev->mei_state = MEI_INITIALIZING;
+       dev->dev_state = MEI_DEV_INITIALIZING;
        dev->iamthif_state = MEI_IAMTHIF_IDLE;
        dev->wd_interface_reg = false;
 
@@ -182,7 +201,7 @@ int mei_hw_init(struct mei_device *dev)
        }
 
        if (err <= 0 && !dev->recvd_msg) {
-               dev->mei_state = MEI_DISABLED;
+               dev->dev_state = MEI_DEV_DISABLED;
                dev_dbg(&dev->pdev->dev,
                        "wait_event_interruptible_timeout failed"
                        "on wait for ME to turn on ME_RDY.\n");
@@ -192,7 +211,7 @@ int mei_hw_init(struct mei_device *dev)
 
        if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
              ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
-               dev->mei_state = MEI_DISABLED;
+               dev->dev_state = MEI_DEV_DISABLED;
                dev_dbg(&dev->pdev->dev,
                        "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
                        dev->host_hw_state, dev->me_hw_state);
@@ -258,15 +277,15 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
        struct mei_cl_cb *cb_next = NULL;
        bool unexpected;
 
-       if (dev->mei_state == MEI_RECOVERING_FROM_RESET) {
+       if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
                dev->need_reset = true;
                return;
        }
 
-       unexpected = (dev->mei_state != MEI_INITIALIZING &&
-                       dev->mei_state != MEI_DISABLED &&
-                       dev->mei_state != MEI_POWER_DOWN &&
-                       dev->mei_state != MEI_POWER_UP);
+       unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
+                       dev->dev_state != MEI_DEV_DISABLED &&
+                       dev->dev_state != MEI_DEV_POWER_DOWN &&
+                       dev->dev_state != MEI_DEV_POWER_UP);
 
        dev->host_hw_state = mei_hcsr_read(dev);
 
@@ -285,10 +304,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
 
        dev->need_reset = false;
 
-       if (dev->mei_state != MEI_INITIALIZING) {
-               if (dev->mei_state != MEI_DISABLED &&
-                   dev->mei_state != MEI_POWER_DOWN)
-                       dev->mei_state = MEI_RESETING;
+       if (dev->dev_state != MEI_DEV_INITIALIZING) {
+               if (dev->dev_state != MEI_DEV_DISABLED &&
+                   dev->dev_state != MEI_DEV_POWER_DOWN)
+                       dev->dev_state = MEI_DEV_RESETING;
 
                list_for_each_entry_safe(cl_pos,
                                cl_next, &dev->file_list, link) {
@@ -311,7 +330,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
 
        dev->me_clients_num = 0;
        dev->rd_msg_hdr = 0;
-       dev->stop = false;
        dev->wd_pending = false;
 
        /* update the state of the registers after reset */
@@ -322,7 +340,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
            dev->host_hw_state, dev->me_hw_state);
 
        if (unexpected)
-               dev_warn(&dev->pdev->dev, "unexpected reset.\n");
+               dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
+                        mei_dev_state_str(dev->dev_state));
 
        /* Wake up all readings so they can be interrupted */
        list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
@@ -371,7 +390,7 @@ void mei_host_start_message(struct mei_device *dev)
        if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
                                       mei_hdr->length)) {
                dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
-               dev->mei_state = MEI_RESETING;
+               dev->dev_state = MEI_DEV_RESETING;
                mei_reset(dev, 1);
        }
        dev->init_clients_state = MEI_START_MESSAGE;
@@ -403,7 +422,7 @@ void mei_host_enum_clients_message(struct mei_device *dev)
        host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
        if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
                                mei_hdr->length)) {
-               dev->mei_state = MEI_RESETING;
+               dev->dev_state = MEI_DEV_RESETING;
                dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
                mei_reset(dev, 1);
        }
@@ -444,7 +463,7 @@ void mei_allocate_me_clients_storage(struct mei_device *dev)
                        sizeof(struct mei_me_client), GFP_KERNEL);
        if (!clients) {
                dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
-               dev->mei_state = MEI_RESETING;
+               dev->dev_state = MEI_DEV_RESETING;
                mei_reset(dev, 1);
                return ;
        }
@@ -490,7 +509,7 @@ int mei_host_client_properties(struct mei_device *dev)
                if (mei_write_message(dev, mei_header,
                                (unsigned char *)host_cli_req,
                                mei_header->length)) {
-                       dev->mei_state = MEI_RESETING;
+                       dev->dev_state = MEI_DEV_RESETING;
                        dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
                        mei_reset(dev, 1);
                        return -EIO;
@@ -522,12 +541,12 @@ void mei_cl_init(struct mei_cl *priv, struct mei_device *dev)
        priv->dev = dev;
 }
 
-int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
+int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
 {
-       int i, res = -1;
+       int i, res = -ENOENT;
 
        for (i = 0; i < dev->me_clients_num; ++i)
-               if (uuid_le_cmp(cuuid,
+               if (uuid_le_cmp(*cuuid,
                                dev->me_clients[i].props.protocol_name) == 0) {
                        res = i;
                        break;
@@ -538,35 +557,35 @@ int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
 
 
 /**
- * mei_find_me_client_update_filext - searches for ME client guid
+ * mei_me_cl_update_filext - searches for ME client guid
  *                       sets client_id in mei_file_private if found
  * @dev: the device structure
- * @priv: private file structure to set client_id in
- * @cguid: searched guid of ME client
+ * @cl: private file structure to set client_id in
+ * @cuuid: searched uuid of ME client
  * @client_id: id of host client to be set in file private structure
  *
  * returns ME client index
  */
-u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
-                               const uuid_le *cguid, u8 client_id)
+int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
+                               const uuid_le *cuuid, u8 host_cl_id)
 {
        int i;
 
-       if (!dev || !priv || !cguid)
-               return 0;
+       if (!dev || !cl || !cuuid)
+               return -EINVAL;
 
        /* check for valid client id */
-       i = mei_find_me_client_index(dev, *cguid);
+       i = mei_me_cl_by_uuid(dev, cuuid);
        if (i >= 0) {
-               priv->me_client_id = dev->me_clients[i].client_id;
-               priv->state = MEI_FILE_CONNECTING;
-               priv->host_client_id = client_id;
+               cl->me_client_id = dev->me_clients[i].client_id;
+               cl->state = MEI_FILE_CONNECTING;
+               cl->host_client_id = host_cl_id;
 
-               list_add_tail(&priv->link, &dev->file_list);
+               list_add_tail(&cl->link, &dev->file_list);
                return (u8)i;
        }
 
-       return 0;
+       return -ENOENT;
 }
 
 /**
@@ -577,16 +596,16 @@ u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
  */
 void mei_host_init_iamthif(struct mei_device *dev)
 {
-       u8 i;
+       int i;
        unsigned char *msg_buf;
 
        mei_cl_init(&dev->iamthif_cl, dev);
        dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
 
        /* find ME amthi client */
-       i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl,
+       i = mei_me_cl_update_filext(dev, &dev->iamthif_cl,
                            &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
-       if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) {
+       if (i < 0) {
                dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
                return;
        }
index fb5c7db4723bd4da189f03adee97a7affd06a345..ec6c785a3961db4cd82e347436b23817326a026b 100644 (file)
 #include "mei_dev.h"
 
 
-#define AMT_WD_DEFAULT_TIMEOUT 120     /* seconds */
-#define AMT_WD_MIN_TIMEOUT 120 /* seconds */
-#define AMT_WD_MAX_TIMEOUT 65535       /* seconds */
-
-#define MEI_WATCHDOG_DATA_SIZE         16
-#define MEI_START_WD_DATA_SIZE         20
-#define MEI_WD_PARAMS_SIZE             4
-
 
 void mei_read_slots(struct mei_device *dev,
                     unsigned char *buffer,
@@ -64,7 +56,7 @@ int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
 
 
 int mei_wd_send(struct mei_device *dev);
-int mei_wd_stop(struct mei_device *dev, bool preserve);
+int mei_wd_stop(struct mei_device *dev);
 int mei_wd_host_init(struct mei_device *dev);
 /*
  * mei_watchdog_register  - Registering watchdog interface
index d78c05e693f7d45c8cf8ca0971ef2184a73c0597..3533edde04a525518624111b86e3b4c76c1c699d 100644 (file)
@@ -221,17 +221,10 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
                                cl->status = 0;
                                list_del(&cb_pos->cb_list);
                                dev_dbg(&dev->pdev->dev,
-                                       "completed read host client = %d,"
-                                       "ME client = %d, "
-                                       "data length = %lu\n",
+                                       "completed read H cl = %d, ME cl = %d, length = %lu\n",
                                        cl->host_client_id,
                                        cl->me_client_id,
                                        cb_pos->information);
-
-                               *(cb_pos->response_buffer.data +
-                                       cb_pos->information) = '\0';
-                               dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n",
-                                       cb_pos->response_buffer.data);
                                list_add_tail(&cb_pos->cb_list,
                                        &complete_list->mei_cb.cb_list);
                        }
@@ -633,7 +626,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
                if (version_res->host_version_supported) {
                        dev->version.major_version = HBM_MAJOR_VERSION;
                        dev->version.minor_version = HBM_MINOR_VERSION;
-                       if (dev->mei_state == MEI_INIT_CLIENTS &&
+                       if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
                            dev->init_clients_state == MEI_START_MESSAGE) {
                                dev->init_clients_timer = 0;
                                mei_host_enum_clients_message(dev);
@@ -707,7 +700,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
                        dev->me_clients[dev->me_client_presentation_num].props
                                                = props_res->client_properties;
 
-                       if (dev->mei_state == MEI_INIT_CLIENTS &&
+                       if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
                            dev->init_clients_state ==
                                        MEI_CLIENT_PROPERTIES_MESSAGE) {
                                dev->me_client_index++;
@@ -734,7 +727,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
                                         * Client ID 2 - Reserved for AMTHI
                                         */
                                        bitmap_set(dev->host_clients_map, 0, 3);
-                                       dev->mei_state = MEI_ENABLED;
+                                       dev->dev_state = MEI_DEV_ENABLED;
 
                                        /* if wd initialization fails, initialization the AMTHI client,
                                         * otherwise the AMTHI client will be initialized after the WD client connect response
@@ -759,7 +752,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
        case HOST_ENUM_RES_CMD:
                enum_res = (struct hbm_host_enum_response *) mei_msg;
                memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
-               if (dev->mei_state == MEI_INIT_CLIENTS &&
+               if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
                    dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
                                dev->init_clients_timer = 0;
                                dev->me_client_presentation_num = 0;
@@ -776,7 +769,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev,
                break;
 
        case HOST_STOP_RES_CMD:
-               dev->mei_state = MEI_DISABLED;
+               dev->dev_state = MEI_DEV_DISABLED;
                dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
                mei_reset(dev, 1);
                break;
@@ -1224,10 +1217,9 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
                }
        }
 
-       if (dev->stop && !dev->wd_pending) {
-               dev->wd_stopped = true;
+       if (dev->wd_state == MEI_WD_STOPPING) {
+               dev->wd_state = MEI_WD_IDLE;
                wake_up_interruptible(&dev->wait_stop_wd);
-               return 0;
        }
 
        if (dev->extra_write_index) {
@@ -1240,7 +1232,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
                *slots -= dev->extra_write_index;
                dev->extra_write_index = 0;
        }
-       if (dev->mei_state == MEI_ENABLED) {
+       if (dev->dev_state == MEI_DEV_ENABLED) {
                if (dev->wd_pending &&
                    mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
                        if (mei_wd_send(dev))
@@ -1250,14 +1242,12 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
 
                        dev->wd_pending = false;
 
-                       if (dev->wd_timeout)
-                               *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
+                       if (dev->wd_state == MEI_WD_RUNNING)
+                               *slots -= mei_data2slots(MEI_WD_START_MSG_SIZE);
                        else
-                               *slots -= mei_data2slots(MEI_WD_PARAMS_SIZE);
+                               *slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE);
                }
        }
-       if (dev->stop)
-               return -ENODEV;
 
        /* complete control write list CB */
        dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
@@ -1361,8 +1351,8 @@ void mei_timer(struct work_struct *work)
 
 
        mutex_lock(&dev->device_lock);
-       if (dev->mei_state != MEI_ENABLED) {
-               if (dev->mei_state == MEI_INIT_CLIENTS) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
+               if (dev->dev_state == MEI_DEV_INIT_CLIENTS) {
                        if (dev->init_clients_timer) {
                                if (--dev->init_clients_timer == 0) {
                                        dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
@@ -1484,8 +1474,8 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
 
        /* check if ME wants a reset */
        if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
-           dev->mei_state != MEI_RESETING &&
-           dev->mei_state != MEI_INITIALIZING) {
+           dev->dev_state != MEI_DEV_RESETING &&
+           dev->dev_state != MEI_DEV_INITIALIZING) {
                dev_dbg(&dev->pdev->dev, "FW not ready.\n");
                mei_reset(dev, 1);
                mutex_unlock(&dev->device_lock);
@@ -1498,7 +1488,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
                        dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
                        dev->host_hw_state |= (H_IE | H_IG | H_RDY);
                        mei_hcsr_set(dev);
-                       dev->mei_state = MEI_INIT_CLIENTS;
+                       dev->dev_state = MEI_DEV_INIT_CLIENTS;
                        dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
                        /* link is established
                         * start sending messages.
index 50f52e21f587a229e374a9f72149186aace43777..fcba98eb892e1e410d62a4c198d978ab82b667f5 100644 (file)
 #include <linux/mei.h>
 #include "interface.h"
 
+/**
+ * mei_me_cl_by_id return index to me_clients for client_id
+ *
+ * @dev: the device structure
+ * @client_id: me client id
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns index on success, -ENOENT on failure.
+ */
 
+int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
+{
+       int i;
+       for (i = 0; i < dev->me_clients_num; i++)
+               if (dev->me_clients[i].client_id == client_id)
+                       break;
+       if (WARN_ON(dev->me_clients[i].client_id != client_id))
+               return -ENOENT;
+
+       if (i == dev->me_clients_num)
+               return -ENOENT;
+
+       return i;
+}
 
 /**
  * mei_ioctl_connect_client - the connect to fw client IOCTL function
@@ -84,7 +108,7 @@ int mei_ioctl_connect_client(struct file *file,
 
        cb->major_file_operations = MEI_IOCTL;
 
-       if (dev->mei_state != MEI_ENABLED) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
                rets = -ENODEV;
                goto end;
        }
@@ -95,7 +119,7 @@ int mei_ioctl_connect_client(struct file *file,
        }
 
        /* find ME client we're trying to connect to */
-       i = mei_find_me_client_index(dev, data->in_client_uuid);
+       i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
        if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
                cl->me_client_id = dev->me_clients[i].client_id;
                cl->state = MEI_FILE_CONNECTING;
@@ -273,19 +297,12 @@ int amthi_read(struct mei_device *dev, struct file *file,
                return -ETIMEDOUT;
        }
 
-       for (i = 0; i < dev->me_clients_num; i++) {
-               if (dev->me_clients[i].client_id ==
-                   dev->iamthif_cl.me_client_id)
-                       break;
-       }
+       i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
 
-       if (i == dev->me_clients_num) {
+       if (i < 0) {
                dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
                return -ENODEV;
        }
-       if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id))
-               return -ENODEV;
-
        dev_dbg(&dev->pdev->dev, "checking amthi data\n");
        cb = find_amthi_read_list_entry(dev, file);
 
@@ -316,8 +333,7 @@ int amthi_read(struct mei_device *dev, struct file *file,
        dev->iamthif_timer = 0;
 
        if (cb) {
-               timeout = cb->read_time +
-                                       msecs_to_jiffies(IAMTHIF_READ_TIMER);
+               timeout = cb->read_time + msecs_to_jiffies(IAMTHIF_READ_TIMER);
                dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
                                timeout);
 
@@ -386,7 +402,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
        if (cl->state != MEI_FILE_CONNECTED)
                return -ENODEV;
 
-       if (dev->mei_state != MEI_ENABLED)
+       if (dev->dev_state != MEI_DEV_ENABLED)
                return -ENODEV;
 
        dev_dbg(&dev->pdev->dev, "check if read is pending.\n");
@@ -401,19 +417,8 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
 
        dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n",
                cl->host_client_id, cl->me_client_id);
-
-       for (i = 0; i < dev->me_clients_num; i++) {
-               if (dev->me_clients[i].client_id == cl->me_client_id)
-                       break;
-
-       }
-
-       if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
-               rets = -ENODEV;
-               goto unlock;
-       }
-
-       if (i == dev->me_clients_num) {
+       i = mei_me_cl_by_id(dev, cl->me_client_id);
+       if (i < 0) {
                rets = -ENODEV;
                goto unlock;
        }
index 7422c76528458134f450eb496d52b1a297e18f8a..e8b0858132c1560c7103e3f0b8f8e3d31f1ac424 100644 (file)
 #include <linux/mei.h>
 #include "interface.h"
 
-static const char mei_driver_name[] = "mei";
-
-/* The device pointer */
-/* Currently this driver works as long as there is only a single AMT device. */
-struct pci_dev *mei_device;
+/* AMT device is a singleton on the platform */
+static struct pci_dev *mei_pdev;
 
 /* mei_pci_tbl - PCI Device ID Table */
 static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
@@ -80,6 +77,8 @@ static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
 
        /* required last entry */
        {0, }
@@ -220,10 +219,10 @@ static int mei_open(struct inode *inode, struct file *file)
        int err;
 
        err = -ENODEV;
-       if (!mei_device)
+       if (!mei_pdev)
                goto out;
 
-       dev = pci_get_drvdata(mei_device);
+       dev = pci_get_drvdata(mei_pdev);
        if (!dev)
                goto out;
 
@@ -234,18 +233,24 @@ static int mei_open(struct inode *inode, struct file *file)
                goto out_unlock;
 
        err = -ENODEV;
-       if (dev->mei_state != MEI_ENABLED) {
-               dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED  mei_state= %d\n",
-                   dev->mei_state);
+       if (dev->dev_state != MEI_DEV_ENABLED) {
+               dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED  dev_state = %s\n",
+                   mei_dev_state_str(dev->dev_state));
                goto out_unlock;
        }
        err = -EMFILE;
-       if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT)
+       if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) {
+               dev_err(&dev->pdev->dev, "open_handle_count exceded %d",
+                       MEI_MAX_OPEN_HANDLE_COUNT);
                goto out_unlock;
+       }
 
        cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX);
-       if (cl_id >= MEI_CLIENTS_MAX)
+       if (cl_id >= MEI_CLIENTS_MAX) {
+               dev_err(&dev->pdev->dev, "client_id exceded %d",
+                               MEI_CLIENTS_MAX) ;
                goto out_unlock;
+       }
 
        cl->host_client_id  = cl_id;
 
@@ -386,17 +391,16 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
        dev = cl->dev;
 
        mutex_lock(&dev->device_lock);
-       if (dev->mei_state != MEI_ENABLED) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
                rets = -ENODEV;
                goto out;
        }
 
        if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
                /* Do not allow to read watchdog client */
-               i = mei_find_me_client_index(dev, mei_wd_guid);
+               i = mei_me_cl_by_uuid(dev, &mei_wd_guid);
                if (i >= 0) {
                        struct mei_me_client *me_client = &dev->me_clients[i];
-
                        if (cl->me_client_id == me_client->client_id) {
                                rets = -EBADF;
                                goto out;
@@ -541,7 +545,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
 
        mutex_lock(&dev->device_lock);
 
-       if (dev->mei_state != MEI_ENABLED) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
                mutex_unlock(&dev->device_lock);
                return -ENODEV;
        }
@@ -616,26 +620,16 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
                        rets = -ENOMEM;
                        goto unlock_dev;
                }
-               if (dev->mei_state != MEI_ENABLED) {
+               if (dev->dev_state != MEI_DEV_ENABLED) {
                        rets = -ENODEV;
                        goto unlock_dev;
                }
-               for (i = 0; i < dev->me_clients_num; i++) {
-                       if (dev->me_clients[i].client_id ==
-                               dev->iamthif_cl.me_client_id)
-                               break;
-               }
-
-               if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
+               i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
+               if (i < 0) {
                        rets = -ENODEV;
                        goto unlock_dev;
                }
-               if (i == dev->me_clients_num ||
-                   (dev->me_clients[i].client_id !=
-                     dev->iamthif_cl.me_client_id)) {
-                       rets = -ENODEV;
-                       goto unlock_dev;
-               } else if (length > dev->me_clients[i].props.max_msg_length ||
+               if (length > dev->me_clients[i].props.max_msg_length ||
                           length <= 0) {
                        rets = -EMSGSIZE;
                        goto unlock_dev;
@@ -688,16 +682,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
                    cl->me_client_id);
                goto unlock_dev;
        }
-       for (i = 0; i < dev->me_clients_num; i++) {
-               if (dev->me_clients[i].client_id ==
-                   cl->me_client_id)
-                       break;
-       }
-       if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
-               rets = -ENODEV;
-               goto unlock_dev;
-       }
-       if (i == dev->me_clients_num) {
+       i = mei_me_cl_by_id(dev, cl->me_client_id);
+       if (i < 0) {
                rets = -ENODEV;
                goto unlock_dev;
        }
@@ -790,7 +776,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
        dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd);
 
        mutex_lock(&dev->device_lock);
-       if (dev->mei_state != MEI_ENABLED) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
                rets = -ENODEV;
                goto out;
        }
@@ -869,7 +855,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
 
        mutex_lock(&dev->device_lock);
 
-       if (dev->mei_state != MEI_ENABLED)
+       if (dev->dev_state != MEI_DEV_ENABLED)
                goto out;
 
 
@@ -966,7 +952,7 @@ static int __devinit mei_probe(struct pci_dev *pdev,
                goto end;
        }
 
-       if (mei_device) {
+       if (mei_pdev) {
                err = -EEXIST;
                goto end;
        }
@@ -979,7 +965,7 @@ static int __devinit mei_probe(struct pci_dev *pdev,
        /* set PCI host mastering  */
        pci_set_master(pdev);
        /* pci request regions for mei driver */
-       err = pci_request_regions(pdev, mei_driver_name);
+       err = pci_request_regions(pdev, KBUILD_MODNAME);
        if (err) {
                dev_err(&pdev->dev, "failed to get pci regions.\n");
                goto disable_device;
@@ -1004,12 +990,12 @@ static int __devinit mei_probe(struct pci_dev *pdev,
                err = request_threaded_irq(pdev->irq,
                        NULL,
                        mei_interrupt_thread_handler,
-                       IRQF_ONESHOT, mei_driver_name, dev);
+                       IRQF_ONESHOT, KBUILD_MODNAME, dev);
        else
                err = request_threaded_irq(pdev->irq,
                        mei_interrupt_quick_handler,
                        mei_interrupt_thread_handler,
-                       IRQF_SHARED, mei_driver_name, dev);
+                       IRQF_SHARED, KBUILD_MODNAME, dev);
 
        if (err) {
                dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
@@ -1027,7 +1013,7 @@ static int __devinit mei_probe(struct pci_dev *pdev,
        if (err)
                goto release_irq;
 
-       mei_device = pdev;
+       mei_pdev = pdev;
        pci_set_drvdata(pdev, dev);
 
 
@@ -1072,7 +1058,7 @@ static void __devexit mei_remove(struct pci_dev *pdev)
 {
        struct mei_device *dev;
 
-       if (mei_device != pdev)
+       if (mei_pdev != pdev)
                return;
 
        dev = pci_get_drvdata(pdev);
@@ -1081,9 +1067,11 @@ static void __devexit mei_remove(struct pci_dev *pdev)
 
        mutex_lock(&dev->device_lock);
 
-       mei_wd_stop(dev, false);
+       cancel_delayed_work(&dev->timer_work);
 
-       mei_device = NULL;
+       mei_wd_stop(dev);
+
+       mei_pdev = NULL;
 
        if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
                dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
@@ -1136,12 +1124,15 @@ static int mei_pci_suspend(struct device *device)
        if (!dev)
                return -ENODEV;
        mutex_lock(&dev->device_lock);
+
+       cancel_delayed_work(&dev->timer_work);
+
        /* Stop watchdog if exists */
-       err = mei_wd_stop(dev, true);
+       err = mei_wd_stop(dev);
        /* Set new mei state */
-       if (dev->mei_state == MEI_ENABLED ||
-           dev->mei_state == MEI_RECOVERING_FROM_RESET) {
-               dev->mei_state = MEI_POWER_DOWN;
+       if (dev->dev_state == MEI_DEV_ENABLED ||
+           dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
+               dev->dev_state = MEI_DEV_POWER_DOWN;
                mei_reset(dev, 0);
        }
        mutex_unlock(&dev->device_lock);
@@ -1169,12 +1160,12 @@ static int mei_pci_resume(struct device *device)
                err = request_threaded_irq(pdev->irq,
                        NULL,
                        mei_interrupt_thread_handler,
-                       IRQF_ONESHOT, mei_driver_name, dev);
+                       IRQF_ONESHOT, KBUILD_MODNAME, dev);
        else
                err = request_threaded_irq(pdev->irq,
                        mei_interrupt_quick_handler,
                        mei_interrupt_thread_handler,
-                       IRQF_SHARED, mei_driver_name, dev);
+                       IRQF_SHARED, KBUILD_MODNAME, dev);
 
        if (err) {
                dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
@@ -1183,7 +1174,7 @@ static int mei_pci_resume(struct device *device)
        }
 
        mutex_lock(&dev->device_lock);
-       dev->mei_state = MEI_POWER_UP;
+       dev->dev_state = MEI_DEV_POWER_UP;
        mei_reset(dev, 1);
        mutex_unlock(&dev->device_lock);
 
@@ -1201,7 +1192,7 @@ static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
  *  PCI driver structure
  */
 static struct pci_driver mei_driver = {
-       .name = mei_driver_name,
+       .name = KBUILD_MODNAME,
        .id_table = mei_pci_tbl,
        .probe = mei_probe,
        .remove = __devexit_p(mei_remove),
index d61c4ddfc80c3fa80f804f2c0a7528284b7b957a..adb35fb9281c4ae82ba2a617c062293faa2b2bca 100644 (file)
 /*
  * watch dog definition
  */
-#define MEI_WATCHDOG_DATA_SIZE         16
-#define MEI_START_WD_DATA_SIZE         20
-#define MEI_WD_PARAMS_SIZE             4
+#define MEI_WD_HDR_SIZE       4
+#define MEI_WD_STOP_MSG_SIZE  MEI_WD_HDR_SIZE
+#define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16)
+
+#define MEI_WD_DEFAULT_TIMEOUT   120  /* seconds */
+#define MEI_WD_MIN_TIMEOUT       120  /* seconds */
+#define MEI_WD_MAX_TIMEOUT     65535  /* seconds */
+
+#define MEI_WD_STOP_TIMEOUT      10 /* msecs */
+
 #define MEI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)
 
 #define MEI_RD_MSG_BUF_SIZE           (128 * sizeof(u32))
 
-/*
- * MEI PCI Device object
- */
-extern struct pci_dev *mei_device;
-
 
 /*
  * AMTHI Client UUID
@@ -53,20 +55,22 @@ extern const uuid_le mei_wd_guid;
  */
 extern const u8 mei_wd_state_independence_msg[3][4];
 
+/*
+ * Number of Maximum MEI Clients
+ */
+#define MEI_CLIENTS_MAX 256
+
 /*
  * Number of File descriptors/handles
  * that can be opened to the driver.
  *
- * Limit to 253: 255 Total Clients
+ * Limit to 253: 256 Total Clients
+ * minus internal client for MEI Bus Messags
  * minus internal client for AMTHI
  * minus internal client for Watchdog
  */
-#define  MEI_MAX_OPEN_HANDLE_COUNT     253
+#define  MEI_MAX_OPEN_HANDLE_COUNT (MEI_CLIENTS_MAX - 3)
 
-/*
- * Number of Maximum MEI Clients
- */
-#define MEI_CLIENTS_MAX 255
 
 /* File state */
 enum file_state {
@@ -78,17 +82,19 @@ enum file_state {
 };
 
 /* MEI device states */
-enum mei_states {
-       MEI_INITIALIZING = 0,
-       MEI_INIT_CLIENTS,
-       MEI_ENABLED,
-       MEI_RESETING,
-       MEI_DISABLED,
-       MEI_RECOVERING_FROM_RESET,
-       MEI_POWER_DOWN,
-       MEI_POWER_UP
+enum mei_dev_state {
+       MEI_DEV_INITIALIZING = 0,
+       MEI_DEV_INIT_CLIENTS,
+       MEI_DEV_ENABLED,
+       MEI_DEV_RESETING,
+       MEI_DEV_DISABLED,
+       MEI_DEV_RECOVERING_FROM_RESET,
+       MEI_DEV_POWER_DOWN,
+       MEI_DEV_POWER_UP
 };
 
+const char *mei_dev_state_str(int state);
+
 /* init clients states*/
 enum mei_init_clients_states {
        MEI_START_MESSAGE = 0,
@@ -113,6 +119,12 @@ enum mei_file_transaction_states {
        MEI_READ_COMPLETE
 };
 
+enum mei_wd_states {
+       MEI_WD_IDLE,
+       MEI_WD_RUNNING,
+       MEI_WD_STOPPING,
+};
+
 /* MEI CB */
 enum mei_cb_major_types {
        MEI_READ = 0,
@@ -128,7 +140,7 @@ enum mei_cb_major_types {
 struct mei_message_data {
        u32 size;
        unsigned char *data;
-} __packed;
+};
 
 
 struct mei_cl_cb {
@@ -218,10 +230,9 @@ struct mei_device {
        /*
         * mei device  states
         */
-       enum mei_states mei_state;
+       enum mei_dev_state dev_state;
        enum mei_init_clients_states init_clients_state;
        u16 init_clients_timer;
-       bool stop;
        bool need_reset;
 
        u32 extra_write_index;
@@ -241,12 +252,11 @@ struct mei_device {
        bool mei_host_buffer_is_empty;
 
        struct mei_cl wd_cl;
+       enum mei_wd_states wd_state;
        bool wd_interface_reg;
        bool wd_pending;
-       bool wd_stopped;
-       bool wd_bypass; /* if false, don't refresh watchdog ME client */
-       u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */
-       unsigned char wd_data[MEI_START_WD_DATA_SIZE];
+       u16 wd_timeout;
+       unsigned char wd_data[MEI_WD_START_MSG_SIZE];
 
 
        struct file *iamthif_file_object;
@@ -279,9 +289,10 @@ void mei_host_init_iamthif(struct mei_device *dev);
 void mei_allocate_me_clients_storage(struct mei_device *dev);
 
 
-u8 mei_find_me_client_update_filext(struct mei_device *dev,
-                               struct mei_cl *priv,
-                               const uuid_le *cguid, u8 client_id);
+int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
+                       const uuid_le *cguid, u8 host_client_id);
+int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid);
+int mei_me_cl_by_id(struct mei_device *dev, u8 client_id);
 
 /*
  * MEI IO List Functions
@@ -348,7 +359,6 @@ void mei_run_next_iamthif_cmd(struct mei_device *dev);
 
 void mei_free_cb_private(struct mei_cl_cb *priv_cb);
 
-int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid);
 
 /*
  * Register Access Function
index 5133fd77b91cc8e01be11736094cd9869b265a86..d96c537f046ffd4abf58b2a84db5e5dc48690747 100644 (file)
@@ -48,8 +48,8 @@ const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
 static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
 {
        dev_dbg(&dev->pdev->dev, "wd: set timeout=%d.\n", timeout);
-       memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE);
-       memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE, &timeout, sizeof(u16));
+       memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE);
+       memcpy(dev->wd_data + MEI_WD_HDR_SIZE, &timeout, sizeof(u16));
 }
 
 /**
@@ -66,10 +66,11 @@ int mei_wd_host_init(struct mei_device *dev)
 
        /* look for WD client and connect to it */
        dev->wd_cl.state = MEI_FILE_DISCONNECTED;
-       dev->wd_timeout = AMT_WD_DEFAULT_TIMEOUT;
+       dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
+       dev->wd_state = MEI_WD_IDLE;
 
        /* find ME WD client */
-       mei_find_me_client_update_filext(dev, &dev->wd_cl,
+       mei_me_cl_update_filext(dev, &dev->wd_cl,
                                &mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
 
        dev_dbg(&dev->pdev->dev, "wd: check client\n");
@@ -108,10 +109,10 @@ int mei_wd_send(struct mei_device *dev)
        mei_hdr->msg_complete = 1;
        mei_hdr->reserved = 0;
 
-       if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE))
-               mei_hdr->length = MEI_START_WD_DATA_SIZE;
-       else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE))
-               mei_hdr->length = MEI_WD_PARAMS_SIZE;
+       if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
+               mei_hdr->length = MEI_WD_START_MSG_SIZE;
+       else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE))
+               mei_hdr->length = MEI_WD_STOP_MSG_SIZE;
        else
                return -EINVAL;
 
@@ -128,18 +129,17 @@ int mei_wd_send(struct mei_device *dev)
  *     -EIO when message send fails
  *     -EINVAL when invalid message is to be sent
  */
-int mei_wd_stop(struct mei_device *dev, bool preserve)
+int mei_wd_stop(struct mei_device *dev)
 {
        int ret;
-       u16 wd_timeout = dev->wd_timeout;
 
-       cancel_delayed_work(&dev->timer_work);
-       if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout)
+       if (dev->wd_cl.state != MEI_FILE_CONNECTED ||
+           dev->wd_state != MEI_WD_RUNNING)
                return 0;
 
-       dev->wd_timeout = 0;
-       memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE);
-       dev->stop = true;
+       memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_STOP_MSG_SIZE);
+
+       dev->wd_state = MEI_WD_STOPPING;
 
        ret = mei_flow_ctrl_creds(dev, &dev->wd_cl);
        if (ret < 0)
@@ -161,13 +161,14 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
        } else {
                dev->wd_pending = true;
        }
-       dev->wd_stopped = false;
+
        mutex_unlock(&dev->device_lock);
 
        ret = wait_event_interruptible_timeout(dev->wait_stop_wd,
-                                       dev->wd_stopped, 10 * HZ);
+                                       dev->wd_state == MEI_WD_IDLE,
+                                       msecs_to_jiffies(MEI_WD_STOP_TIMEOUT));
        mutex_lock(&dev->device_lock);
-       if (dev->wd_stopped) {
+       if (dev->wd_state == MEI_WD_IDLE) {
                dev_dbg(&dev->pdev->dev, "wd: stop completed ret=%d.\n", ret);
                ret = 0;
        } else {
@@ -177,9 +178,6 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
                        "wd: stop failed to complete ret=%d.\n", ret);
        }
 
-       if (preserve)
-               dev->wd_timeout = wd_timeout;
-
 out:
        return ret;
 }
@@ -196,16 +194,16 @@ static int mei_wd_ops_start(struct watchdog_device *wd_dev)
        int err = -ENODEV;
        struct mei_device *dev;
 
-       dev = pci_get_drvdata(mei_device);
+       dev = watchdog_get_drvdata(wd_dev);
        if (!dev)
                return -ENODEV;
 
        mutex_lock(&dev->device_lock);
 
-       if (dev->mei_state != MEI_ENABLED) {
+       if (dev->dev_state != MEI_DEV_ENABLED) {
                dev_dbg(&dev->pdev->dev,
-                       "wd: mei_state != MEI_ENABLED  mei_state = %d\n",
-                       dev->mei_state);
+                       "wd: dev_state != MEI_DEV_ENABLED  dev_state = %s\n",
+                       mei_dev_state_str(dev->dev_state));
                goto end_unlock;
        }
 
@@ -233,13 +231,13 @@ end_unlock:
 static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
 {
        struct mei_device *dev;
-       dev = pci_get_drvdata(mei_device);
 
+       dev = watchdog_get_drvdata(wd_dev);
        if (!dev)
                return -ENODEV;
 
        mutex_lock(&dev->device_lock);
-       mei_wd_stop(dev, false);
+       mei_wd_stop(dev);
        mutex_unlock(&dev->device_lock);
 
        return 0;
@@ -256,8 +254,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
 {
        int ret = 0;
        struct mei_device *dev;
-       dev = pci_get_drvdata(mei_device);
 
+       dev = watchdog_get_drvdata(wd_dev);
        if (!dev)
                return -ENODEV;
 
@@ -269,6 +267,8 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
                goto end;
        }
 
+       dev->wd_state = MEI_WD_RUNNING;
+
        /* Check if we can send the ping to HW*/
        if (dev->mei_host_buffer_is_empty &&
                mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
@@ -309,13 +309,13 @@ end:
 static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev, unsigned int timeout)
 {
        struct mei_device *dev;
-       dev = pci_get_drvdata(mei_device);
 
+       dev = watchdog_get_drvdata(wd_dev);
        if (!dev)
                return -ENODEV;
 
        /* Check Timeout value */
-       if (timeout < AMT_WD_MIN_TIMEOUT || timeout > AMT_WD_MAX_TIMEOUT)
+       if (timeout < MEI_WD_MIN_TIMEOUT || timeout > MEI_WD_MAX_TIMEOUT)
                return -EINVAL;
 
        mutex_lock(&dev->device_lock);
@@ -341,37 +341,42 @@ static const struct watchdog_ops wd_ops = {
 };
 static const struct watchdog_info wd_info = {
                .identity = INTEL_AMT_WATCHDOG_ID,
-               .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY,
+               .options = WDIOF_KEEPALIVEPING |
+                          WDIOF_SETTIMEOUT |
+                          WDIOF_ALARMONLY,
 };
 
 static struct watchdog_device amt_wd_dev = {
                .info = &wd_info,
                .ops = &wd_ops,
-               .timeout = AMT_WD_DEFAULT_TIMEOUT,
-               .min_timeout = AMT_WD_MIN_TIMEOUT,
-               .max_timeout = AMT_WD_MAX_TIMEOUT,
+               .timeout = MEI_WD_DEFAULT_TIMEOUT,
+               .min_timeout = MEI_WD_MIN_TIMEOUT,
+               .max_timeout = MEI_WD_MAX_TIMEOUT,
 };
 
 
-void  mei_watchdog_register(struct mei_device *dev)
+void mei_watchdog_register(struct mei_device *dev)
 {
-       dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n", dev->wd_timeout);
-
        if (watchdog_register_device(&amt_wd_dev)) {
                dev_err(&dev->pdev->dev,
                        "wd: unable to register watchdog device.\n");
                dev->wd_interface_reg = false;
-       } else {
-               dev_dbg(&dev->pdev->dev,
-                       "wd: successfully register watchdog interface.\n");
-               dev->wd_interface_reg = true;
+               return;
        }
+
+       dev_dbg(&dev->pdev->dev,
+               "wd: successfully register watchdog interface.\n");
+       dev->wd_interface_reg = true;
+       watchdog_set_drvdata(&amt_wd_dev, dev);
 }
 
 void mei_watchdog_unregister(struct mei_device *dev)
 {
-       if (dev->wd_interface_reg)
-               watchdog_unregister_device(&amt_wd_dev);
+       if (!dev->wd_interface_reg)
+               return;
+
+       watchdog_set_drvdata(&amt_wd_dev, NULL);
+       watchdog_unregister_device(&amt_wd_dev);
        dev->wd_interface_reg = false;
 }
 
index 9fbcacd703d502b660f5491a706e06fdd9952f2f..c9f20dae18557deb40f9ed55e9aebae6e4992222 100644 (file)
@@ -699,7 +699,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
        chip->pch_phub_base_address = pci_iomap(pdev, 1, 0);
 
 
-       if (chip->pch_phub_base_address == 0) {
+       if (chip->pch_phub_base_address == NULL) {
                dev_err(&pdev->dev, "%s : pci_iomap FAILED", __func__);
                ret = -ENOMEM;
                goto err_pci_iomap;
@@ -893,18 +893,7 @@ static struct pci_driver pch_phub_driver = {
        .resume = pch_phub_resume
 };
 
-static int __init pch_phub_pci_init(void)
-{
-       return pci_register_driver(&pch_phub_driver);
-}
-
-static void __exit pch_phub_pci_exit(void)
-{
-       pci_unregister_driver(&pch_phub_driver);
-}
-
-module_init(pch_phub_pci_init);
-module_exit(pch_phub_pci_exit);
+module_pci_driver(pch_phub_driver);
 
 MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB");
 MODULE_LICENSE("GPL");
index acfaeeb9e01a98e7f296d5c2081f35ef4d53b325..46937b107261df5fddeb39c6dd16d491e898833e 100644 (file)
 
 #include <linux/ti_wilink_st.h>
 
+extern void st_kim_recv(void *, const unsigned char *, long);
+void st_int_recv(void *, const unsigned char *, long);
 /* function pointer pointing to either,
  * st_kim_recv during registration to receive fw download responses
  * st_int_recv after registration to receive proto stack responses
  */
-void (*st_recv) (void*, const unsigned char*, long);
+static void (*st_recv) (void *, const unsigned char *, long);
 
 /********************************************************************/
 static void add_channel_to_table(struct st_data_s *st_gdata,
@@ -100,7 +102,7 @@ int st_int_write(struct st_data_s *st_gdata,
  * push the skb received to relevant
  * protocol stacks
  */
-void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
+static void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
 {
        pr_debug(" %s(prot:%d) ", __func__, chnl_id);
 
@@ -140,7 +142,7 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata)
  * This function is being called with spin lock held, protocol drivers are
  * only expected to complete their waits and do nothing more than that.
  */
-void st_reg_complete(struct st_data_s *st_gdata, char err)
+static void st_reg_complete(struct st_data_s *st_gdata, char err)
 {
        unsigned char i = 0;
        pr_info(" %s ", __func__);
@@ -379,7 +381,7 @@ done:
  *     completely, return that skb which has the pending data.
  *     In normal cases, return top of txq.
  */
-struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
+static struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
 {
        struct sk_buff *returning_skb;
 
@@ -401,7 +403,7 @@ struct sk_buff *st_int_dequeue(struct st_data_s *st_gdata)
  *     txq and waitq needs protection since the other contexts
  *     may be sending data, waking up chip.
  */
-void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
+static void st_int_enqueue(struct st_data_s *st_gdata, struct sk_buff *skb)
 {
        unsigned long flags = 0;
 
index 7c14f8fd98db2eec7e50c1ad5dff75a0bc90a82f..04a819944f6b4707a50eed443ef17450e9b31b23 100644 (file)
@@ -63,10 +63,27 @@ static struct platform_device *st_get_plat_device(int id)
  *     in case of error don't complete so that waiting for proper
  *     response times out
  */
-void validate_firmware_response(struct kim_data_s *kim_gdata)
+static void validate_firmware_response(struct kim_data_s *kim_gdata)
 {
        struct sk_buff *skb = kim_gdata->rx_skb;
-       if (unlikely(skb->data[5] != 0)) {
+       if (!skb)
+               return;
+
+       /* these magic numbers are the position in the response buffer which
+        * allows us to distinguish whether the response is for the read
+        * version info. command
+        */
+       if (skb->data[2] == 0x01 && skb->data[3] == 0x01 &&
+                       skb->data[4] == 0x10 && skb->data[5] == 0x00) {
+               /* fw version response */
+               memcpy(kim_gdata->resp_buffer,
+                               kim_gdata->rx_skb->data,
+                               kim_gdata->rx_skb->len);
+               complete_all(&kim_gdata->kim_rcvd);
+               kim_gdata->rx_state = ST_W4_PACKET_TYPE;
+               kim_gdata->rx_skb = NULL;
+               kim_gdata->rx_count = 0;
+       } else if (unlikely(skb->data[5] != 0)) {
                pr_err("no proper response during fw download");
                pr_err("data6 %x", skb->data[5]);
                kfree_skb(skb);
@@ -119,7 +136,7 @@ static inline int kim_check_data_len(struct kim_data_s *kim_gdata, int len)
  *     have been observed to come in bursts of different
  *     tty_receive and hence the logic
  */
-void kim_int_recv(struct kim_data_s *kim_gdata,
+static void kim_int_recv(struct kim_data_s *kim_gdata,
        const unsigned char *data, long count)
 {
        const unsigned char *ptr;
@@ -207,16 +224,19 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
                return -EIO;
        }
 
-       if (!wait_for_completion_timeout
-           (&kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
+       if (!wait_for_completion_interruptible_timeout(
+               &kim_gdata->kim_rcvd, msecs_to_jiffies(CMD_RESP_TIME))) {
                pr_err(" waiting for ver info- timed out ");
                return -ETIMEDOUT;
        }
        INIT_COMPLETION(kim_gdata->kim_rcvd);
+       /* the positions 12 & 13 in the response buffer provide with the
+        * chip, major & minor numbers
+        */
 
        version =
-               MAKEWORD(kim_gdata->resp_buffer[13],
-                               kim_gdata->resp_buffer[14]);
+               MAKEWORD(kim_gdata->resp_buffer[12],
+                               kim_gdata->resp_buffer[13]);
        chip = (version & 0x7C00) >> 10;
        min_ver = (version & 0x007F);
        maj_ver = (version & 0x0380) >> 7;
@@ -236,7 +256,7 @@ static long read_local_version(struct kim_data_s *kim_gdata, char *bts_scr_name)
        return 0;
 }
 
-void skip_change_remote_baud(unsigned char **ptr, long *len)
+static void skip_change_remote_baud(unsigned char **ptr, long *len)
 {
        unsigned char *nxt_action, *cur_action;
        cur_action = *ptr;
@@ -370,9 +390,9 @@ static long download_firmware(struct kim_data_s *kim_gdata)
                        break;
                case ACTION_WAIT_EVENT:  /* wait */
                        pr_debug("W");
-                       if (!wait_for_completion_timeout
-                                       (&kim_gdata->kim_rcvd,
-                                        msecs_to_jiffies(CMD_RESP_TIME))) {
+                       if (!wait_for_completion_interruptible_timeout(
+                                       &kim_gdata->kim_rcvd,
+                                       msecs_to_jiffies(CMD_RESP_TIME))) {
                                pr_err("response timeout during fw download ");
                                /* timed out */
                                release_firmware(kim_gdata->fw_entry);
@@ -410,16 +430,10 @@ void st_kim_recv(void *disc_data, const unsigned char *data, long count)
        struct st_data_s        *st_gdata = (struct st_data_s *)disc_data;
        struct kim_data_s       *kim_gdata = st_gdata->kim_data;
 
-       /* copy to local buffer */
-       if (unlikely(data[4] == 0x01 && data[5] == 0x10 && data[0] == 0x04)) {
-               /* must be the read_ver_cmd */
-               memcpy(kim_gdata->resp_buffer, data, count);
-               complete_all(&kim_gdata->kim_rcvd);
-               return;
-       } else {
-               kim_int_recv(kim_gdata, data, count);
-               /* either completes or times out */
-       }
+       /* proceed to gather all data and distinguish read fw version response
+        * from other fw responses when data gathering is complete
+        */
+       kim_int_recv(kim_gdata, data, count);
        return;
 }
 
@@ -454,11 +468,6 @@ long st_kim_start(void *kim_data)
                if (pdata->chip_enable)
                        pdata->chip_enable(kim_gdata);
 
-               /* Configure BT nShutdown to HIGH state */
-               gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
-               mdelay(5);      /* FIXME: a proper toggle */
-               gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
-               mdelay(100);
                /* re-initialize the completion */
                INIT_COMPLETION(kim_gdata->ldisc_installed);
                /* send notification to UIM */
@@ -467,8 +476,8 @@ long st_kim_start(void *kim_data)
                sysfs_notify(&kim_gdata->kim_pdev->dev.kobj,
                                NULL, "install");
                /* wait for ldisc to be installed */
-               err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
-                               msecs_to_jiffies(LDISC_TIME));
+               err = wait_for_completion_interruptible_timeout(
+                       &kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME));
                if (!err) {
                        /* ldisc installation timeout,
                         * flush uart, power cycle BT_EN */
@@ -500,8 +509,7 @@ long st_kim_start(void *kim_data)
  *     (b) upon failure to either install ldisc or download firmware.
  *     The function is responsible to (a) notify UIM about un-installation,
  *     (b) flush UART if the ldisc was installed.
- *     (c) reset BT_EN - pull down nshutdown at the end.
- *     (d) invoke platform's chip disabling routine.
+ *     (c) invoke platform's chip disabling routine.
  */
 long st_kim_stop(void *kim_data)
 {
@@ -526,20 +534,13 @@ long st_kim_stop(void *kim_data)
        sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, NULL, "install");
 
        /* wait for ldisc to be un-installed */
-       err = wait_for_completion_timeout(&kim_gdata->ldisc_installed,
-                       msecs_to_jiffies(LDISC_TIME));
+       err = wait_for_completion_interruptible_timeout(
+               &kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME));
        if (!err) {             /* timeout */
                pr_err(" timed out waiting for ldisc to be un-installed");
-               return -ETIMEDOUT;
+               err = -ETIMEDOUT;
        }
 
-       /* By default configure BT nShutdown to LOW state */
-       gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
-       mdelay(1);
-       gpio_set_value(kim_gdata->nshutdown, GPIO_HIGH);
-       mdelay(1);
-       gpio_set_value(kim_gdata->nshutdown, GPIO_LOW);
-
        /* platform specific disable */
        if (pdata->chip_disable)
                pdata->chip_disable(kim_gdata);
@@ -701,7 +702,7 @@ static const struct file_operations list_debugfs_fops = {
  * board-*.c file
  */
 
-struct dentry *kim_debugfs_dir;
+static struct dentry *kim_debugfs_dir;
 static int kim_probe(struct platform_device *pdev)
 {
        long status;
@@ -731,20 +732,6 @@ static int kim_probe(struct platform_device *pdev)
        /* refer to itself */
        kim_gdata->core_data->kim_data = kim_gdata;
 
-       /* Claim the chip enable nShutdown gpio from the system */
-       kim_gdata->nshutdown = pdata->nshutdown_gpio;
-       status = gpio_request(kim_gdata->nshutdown, "kim");
-       if (unlikely(status)) {
-               pr_err(" gpio %ld request failed ", kim_gdata->nshutdown);
-               return status;
-       }
-
-       /* Configure nShutdown GPIO as output=0 */
-       status = gpio_direction_output(kim_gdata->nshutdown, 0);
-       if (unlikely(status)) {
-               pr_err(" unable to configure gpio %ld", kim_gdata->nshutdown);
-               return status;
-       }
        /* get reference of pdev for request_firmware
         */
        kim_gdata->kim_pdev = pdev;
@@ -780,18 +767,10 @@ static int kim_probe(struct platform_device *pdev)
 
 static int kim_remove(struct platform_device *pdev)
 {
-       /* free the GPIOs requested */
-       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
        struct kim_data_s       *kim_gdata;
 
        kim_gdata = dev_get_drvdata(&pdev->dev);
 
-       /* Free the Bluetooth/FM/GPIO
-        * nShutdown gpio from the system
-        */
-       gpio_free(pdata->nshutdown_gpio);
-       pr_info("nshutdown GPIO Freed");
-
        debugfs_remove_recursive(kim_debugfs_dir);
        sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
        pr_info("sysfs entries removed");
@@ -804,7 +783,7 @@ static int kim_remove(struct platform_device *pdev)
        return 0;
 }
 
-int kim_suspend(struct platform_device *pdev, pm_message_t state)
+static int kim_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
 
@@ -814,7 +793,7 @@ int kim_suspend(struct platform_device *pdev, pm_message_t state)
        return -EOPNOTSUPP;
 }
 
-int kim_resume(struct platform_device *pdev)
+static int kim_resume(struct platform_device *pdev)
 {
        struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
 
index ba2479022670b65d7a1326b2ba39a20550aabbaf..f8d6654391e5df35f13ec7b7e825baf3710baee6 100644 (file)
@@ -434,21 +434,9 @@ static struct pci_driver tifm_7xx1_driver = {
        .resume = tifm_7xx1_resume,
 };
 
-static int __init tifm_7xx1_init(void)
-{
-       return pci_register_driver(&tifm_7xx1_driver);
-}
-
-static void __exit tifm_7xx1_exit(void)
-{
-       pci_unregister_driver(&tifm_7xx1_driver);
-}
-
+module_pci_driver(tifm_7xx1_driver);
 MODULE_AUTHOR("Alex Dubov");
 MODULE_DESCRIPTION("TI FlashMedia host driver");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, tifm_7xx1_pci_tbl);
 MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tifm_7xx1_init);
-module_exit(tifm_7xx1_exit);
index 5ceb1cd501955003182fe62b365da7d1b5d282f2..7e984034a11b03a97ae3e9fbfbfd4313297f98b8 100644 (file)
@@ -60,7 +60,6 @@ config W1_MASTER_GPIO
 
 config HDQ_MASTER_OMAP
        tristate "OMAP HDQ driver"
-       depends on ARCH_OMAP2PLUS
        help
          Say Y here if you want support for the 1-wire or HDQ Interface
          on an OMAP processor.
index 4b0fcf3c2d035f8aba0d0e0ba938f34df6621ef2..ca8e60bb2f9cb386f454a33224d6cc7906a20fc7 100644 (file)
@@ -18,9 +18,6 @@
 #include <linux/sched.h>
 #include <linux/pm_runtime.h>
 
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
 #include "../w1.h"
 #include "../w1_int.h"
 
@@ -73,11 +70,11 @@ struct hdq_data {
 };
 
 static int __devinit omap_hdq_probe(struct platform_device *pdev);
-static int omap_hdq_remove(struct platform_device *pdev);
+static int __devexit omap_hdq_remove(struct platform_device *pdev);
 
 static struct platform_driver omap_hdq_driver = {
        .probe =        omap_hdq_probe,
-       .remove =       omap_hdq_remove,
+       .remove =       __devexit_p(omap_hdq_remove),
        .driver =       {
                .name = "omap_hdq",
        },
@@ -538,39 +535,35 @@ static void omap_w1_write_byte(void *_hdq, u8 byte)
                hdq_data->init_trans = 0;
                mutex_unlock(&hdq_data->hdq_mutex);
        }
-
-       return;
 }
 
 static int __devinit omap_hdq_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct hdq_data *hdq_data;
        struct resource *res;
        int ret, irq;
        u8 rev;
 
-       hdq_data = kmalloc(sizeof(*hdq_data), GFP_KERNEL);
+       hdq_data = devm_kzalloc(dev, sizeof(*hdq_data), GFP_KERNEL);
        if (!hdq_data) {
                dev_dbg(&pdev->dev, "unable to allocate memory\n");
-               ret = -ENOMEM;
-               goto err_kmalloc;
+               return -ENOMEM;
        }
 
-       hdq_data->dev = &pdev->dev;
+       hdq_data->dev = dev;
        platform_set_drvdata(pdev, hdq_data);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_dbg(&pdev->dev, "unable to get resource\n");
-               ret = -ENXIO;
-               goto err_resource;
+               return -ENXIO;
        }
 
-       hdq_data->hdq_base = ioremap(res->start, SZ_4K);
+       hdq_data->hdq_base = devm_request_and_ioremap(dev, res);
        if (!hdq_data->hdq_base) {
                dev_dbg(&pdev->dev, "ioremap failed\n");
-               ret = -EINVAL;
-               goto err_ioremap;
+               return -ENOMEM;
        }
 
        hdq_data->hdq_usecount = 0;
@@ -591,7 +584,8 @@ static int __devinit omap_hdq_probe(struct platform_device *pdev)
                goto err_irq;
        }
 
-       ret = request_irq(irq, hdq_isr, IRQF_DISABLED, "omap_hdq", hdq_data);
+       ret = devm_request_irq(dev, irq, hdq_isr, IRQF_DISABLED,
+                       "omap_hdq", hdq_data);
        if (ret < 0) {
                dev_dbg(&pdev->dev, "could not request irq\n");
                goto err_irq;
@@ -616,19 +610,10 @@ err_irq:
 err_w1:
        pm_runtime_disable(&pdev->dev);
 
-       iounmap(hdq_data->hdq_base);
-
-err_ioremap:
-err_resource:
-       platform_set_drvdata(pdev, NULL);
-       kfree(hdq_data);
-
-err_kmalloc:
        return ret;
-
 }
 
-static int omap_hdq_remove(struct platform_device *pdev)
+static int __devexit omap_hdq_remove(struct platform_device *pdev)
 {
        struct hdq_data *hdq_data = platform_get_drvdata(pdev);
 
@@ -644,27 +629,11 @@ static int omap_hdq_remove(struct platform_device *pdev)
 
        /* remove module dependency */
        pm_runtime_disable(&pdev->dev);
-       free_irq(INT_24XX_HDQ_IRQ, hdq_data);
-       platform_set_drvdata(pdev, NULL);
-       iounmap(hdq_data->hdq_base);
-       kfree(hdq_data);
 
        return 0;
 }
 
-static int __init
-omap_hdq_init(void)
-{
-       return platform_driver_register(&omap_hdq_driver);
-}
-module_init(omap_hdq_init);
-
-static void __exit
-omap_hdq_exit(void)
-{
-       platform_driver_unregister(&omap_hdq_driver);
-}
-module_exit(omap_hdq_exit);
+module_platform_driver(omap_hdq_driver);
 
 module_param(w1_id, int, S_IRUSR);
 MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection");
index df600d14974d6ddcbe2ec00bdbb6b199b779537c..6012c4ea3206ac58e5d8c0efc561859b10c4b4b1 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/slab.h>
 #include <linux/w1-gpio.h>
 #include <linux/gpio.h>
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
 
 #include "../w1.h"
 #include "../w1_int.h"
@@ -42,12 +44,55 @@ static u8 w1_gpio_read_bit(void *data)
        return gpio_get_value(pdata->pin) ? 1 : 0;
 }
 
+#ifdef CONFIG_OF
+static struct of_device_id w1_gpio_dt_ids[] = {
+       { .compatible = "w1-gpio" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
+
+static int w1_gpio_probe_dt(struct platform_device *pdev)
+{
+       struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
+       struct device_node *np = pdev->dev.of_node;
+       const struct of_device_id *of_id =
+                       of_match_device(w1_gpio_dt_ids, &pdev->dev);
+
+       if (!of_id)
+               return 0;
+
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       if (of_get_property(np, "linux,open-drain", NULL))
+               pdata->is_open_drain = 1;
+
+       pdata->pin = of_get_gpio(np, 0);
+       pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
+       pdev->dev.platform_data = pdata;
+
+       return 0;
+}
+#else
+static int w1_gpio_probe_dt(struct platform_device *pdev)
+{
+       return 0;
+}
+#endif
+
 static int __init w1_gpio_probe(struct platform_device *pdev)
 {
        struct w1_bus_master *master;
-       struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
+       struct w1_gpio_platform_data *pdata;
        int err;
 
+       err = w1_gpio_probe_dt(pdev);
+       if (err < 0)
+               return err;
+
+       pdata = pdev->dev.platform_data;
+
        if (!pdata)
                return -ENXIO;
 
@@ -59,6 +104,13 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
        if (err)
                goto free_master;
 
+       if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
+               err = gpio_request_one(pdata->ext_pullup_enable_pin,
+                                      GPIOF_INIT_LOW, "w1 pullup");
+               if (err < 0)
+                       goto free_gpio;
+       }
+
        master->data = pdata;
        master->read_bit = w1_gpio_read_bit;
 
@@ -72,15 +124,21 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
 
        err = w1_add_master_device(master);
        if (err)
-               goto free_gpio;
+               goto free_gpio_ext_pu;
 
        if (pdata->enable_external_pullup)
                pdata->enable_external_pullup(1);
 
+       if (gpio_is_valid(pdata->ext_pullup_enable_pin))
+               gpio_set_value(pdata->ext_pullup_enable_pin, 1);
+
        platform_set_drvdata(pdev, master);
 
        return 0;
 
+ free_gpio_ext_pu:
+       if (gpio_is_valid(pdata->ext_pullup_enable_pin))
+               gpio_free(pdata->ext_pullup_enable_pin);
  free_gpio:
        gpio_free(pdata->pin);
  free_master:
@@ -97,6 +155,9 @@ static int __exit w1_gpio_remove(struct platform_device *pdev)
        if (pdata->enable_external_pullup)
                pdata->enable_external_pullup(0);
 
+       if (gpio_is_valid(pdata->ext_pullup_enable_pin))
+               gpio_set_value(pdata->ext_pullup_enable_pin, 0);
+
        w1_remove_master_device(master);
        gpio_free(pdata->pin);
        kfree(master);
@@ -135,6 +196,7 @@ static struct platform_driver w1_gpio_driver = {
        .driver = {
                .name   = "w1-gpio",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(w1_gpio_dt_ids),
        },
        .remove = __exit_p(w1_gpio_remove),
        .suspend = w1_gpio_suspend,
index 3ca0269dd0b587d4dfa4a157bcde969de57d6030..932b7639224883535456c37c1d30801ec6f7b305 100644 (file)
@@ -281,9 +281,10 @@ struct kim_data_s {
 long st_kim_start(void *);
 long st_kim_stop(void *);
 
-void st_kim_recv(void *, const unsigned char *, long count);
 void st_kim_complete(void *);
 void kim_st_list_protocols(struct st_data_s *, void *);
+void st_kim_recv(void *, const unsigned char *, long);
+
 
 /*
  * BTS headers
index 3adeff82212f80aa95bca4456c56355706a18bfa..065e3ae79ab0e7f09138cceb19d8f35ce6d72d67 100644 (file)
@@ -19,6 +19,7 @@ struct w1_gpio_platform_data {
        unsigned int pin;
        unsigned int is_open_drain:1;
        void (*enable_external_pullup)(int enable);
+       unsigned int ext_pullup_enable_pin;
 };
 
 #endif /* _LINUX_W1_GPIO_H */