Merge tag 'char-misc-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 1 Oct 2012 19:09:59 +0000 (12:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 1 Oct 2012 19:09:59 +0000 (12:09 -0700)
Pull char/misc driver merge from Greg Kroah-Hartman:
 "Here is the "big" char/misc driver tree update for the 3.7-rc1 merge
  window.

  Nothing major, just a number of driver updates and fixes, all of which
  have been in the linux-next releases for a while now either in my
  tree, or in Andrew's (the lis3l driver changes came from his tree last
  week).

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"
* tag 'char-misc-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (52 commits)
  drivers/misc/lis3lv02d/lis3lv02d_i2c.c: add lis3lv02d device tree init
  drivers/misc/lis3lv02d/lis3lv02d_spi.c: add lis3lv02d device tree init
  drivers/misc/lis3lv02d: remove lis3lv02d driver DT init
  drivers/misc/lis3lv02d/lis3lv02d_spi.c: add DT matching table passthru code
  drivers/misc/lis3lv02d: add generic DT matching code
  lis3lv02d: fix some comments specific to lis331dlh driver
  MISC: hpilo, remove pci_disable_device
  pcmcia: synclink_cs: fix potential tty NULL dereference
  drivers/char/mmtimer.c: Remove useless kfree
  drivers/char: removes unnecessary semicolon
  char/misc: remove CONFIG_EXPERIMENTAL dependencies
  mei: don't print buffer as a string
  mei: struct mei_message_data doesn't have to be packed
  mei: add error messages for open count errors
  misc: use module_spi_driver
  tifm: use module_pci_driver
  misc/at25, dt: Improve at25 SPI eeprom device tree bindings.
  mei: add lynx point pci device ids
  mei: fix max number of open handles
  mei: rename struct pci_dev *mei_device to mei_pdev
  ...

43 files changed:
Documentation/devicetree/bindings/misc/at25.txt
Documentation/devicetree/bindings/misc/lis302.txt [new file with mode: 0644]
Documentation/devicetree/bindings/w1/w1-gpio.txt [new file with mode: 0644]
Documentation/misc-devices/lis3lv02d
drivers/char/Kconfig
drivers/char/mmtimer.c
drivers/char/nwbutton.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/ppdev.c
drivers/char/rtc.c
drivers/char/tlclk.c
drivers/char/virtio_console.c
drivers/misc/Kconfig
drivers/misc/bmp085-i2c.c
drivers/misc/bmp085-spi.c
drivers/misc/c2port/Kconfig
drivers/misc/carma/carma-fpga-program.c
drivers/misc/carma/carma-fpga.c
drivers/misc/eeprom/Kconfig
drivers/misc/eeprom/at25.c
drivers/misc/hpilo.c
drivers/misc/lis3lv02d/lis3lv02d.c
drivers/misc/lis3lv02d/lis3lv02d.h
drivers/misc/lis3lv02d/lis3lv02d_i2c.c
drivers/misc/lis3lv02d/lis3lv02d_spi.c
drivers/misc/mei/Kconfig
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/misc/lis302.txt b/Documentation/devicetree/bindings/misc/lis302.txt
new file mode 100644 (file)
index 0000000..6def86f
--- /dev/null
@@ -0,0 +1,112 @@
+LIS302 accelerometer devicetree bindings
+
+This device is matched via its bus drivers, and has a number of properties
+that apply in on the generic device (independent from the bus).
+
+
+Required properties for the SPI bindings:
+ - compatible:                 should be set to "st,lis3lv02d_spi"
+ - reg:                        the chipselect index
+ - spi-max-frequency:  maximal bus speed, should be set to 1000000 unless
+                       constrained by external circuitry
+ - interrupts:         the interrupt generated by the device
+
+Required properties for the I2C bindings:
+ - compatible:         should be set to "st,lis3lv02d"
+ - reg:                        i2c slave address
+ - Vdd-supply:         The input supply for Vdd
+ - Vdd_IO-supply:      The input supply for Vdd_IO
+
+
+Optional properties for all bus drivers:
+
+ - st,click-single-{x,y,z}:    if present, tells the device to issue an
+                               interrupt on single click events on the
+                               x/y/z axis.
+ - st,click-double-{x,y,z}:    if present, tells the device to issue an
+                               interrupt on double click events on the
+                               x/y/z axis.
+ - st,click-thresh-{x,y,z}:    set the x/y/z axis threshold
+ - st,click-click-time-limit:  click time limit, from 0 to 127.5msec
+                               with step of 0.5 msec
+ - st,click-latency:           click latency, from 0 to 255 msec with
+                               step of 1 msec.
+ - st,click-window:            click window, from 0 to 255 msec with
+                               step of 1 msec.
+ - st,irq{1,2}-disable:                disable IRQ 1/2
+ - st,irq{1,2}-ff-wu-1:                raise IRQ 1/2 on FF_WU_1 condition
+ - st,irq{1,2}-ff-wu-2:                raise IRQ 1/2 on FF_WU_2 condition
+ - st,irq{1,2}-data-ready:     raise IRQ 1/2 on data ready contition
+ - st,irq{1,2}-click:          raise IRQ 1/2 on click condition
+ - st,irq-open-drain:          consider IRQ lines open-drain
+ - st,irq-active-low:          make IRQ lines active low
+ - st,wu-duration-1:           duration register for Free-Fall/Wake-Up
+                               interrupt 1
+ - st,wu-duration-2:           duration register for Free-Fall/Wake-Up
+                               interrupt 2
+ - st,wakeup-{x,y,z}-{lo,hi}:  set wakeup condition on x/y/z axis for
+                               upper/lower limit
+ - st,highpass-cutoff-hz=:     1, 2, 4 or 8 for 1Hz, 2Hz, 4Hz or 8Hz of
+                               highpass cut-off frequency
+ - st,hipass{1,2}-disable:     disable highpass 1/2.
+ - st,default-rate=:           set the default rate
+ - st,axis-{x,y,z}=:           set the axis to map to the three coordinates
+ - st,{min,max}-limit-{x,y,z}  set the min/max limits for x/y/z axis
+                               (used by self-test)
+
+
+Example for a SPI device node:
+
+       lis302@0 {
+               compatible = "st,lis302dl-spi";
+               reg = <0>;
+               spi-max-frequency = <1000000>;
+               interrupt-parent = <&gpio>;
+               interrupts = <104 0>;
+
+               st,click-single-x;
+               st,click-single-y;
+               st,click-single-z;
+               st,click-thresh-x = <10>;
+               st,click-thresh-y = <10>;
+               st,click-thresh-z = <10>;
+               st,irq1-click;
+               st,irq2-click;
+               st,wakeup-x-lo;
+               st,wakeup-x-hi;
+               st,wakeup-y-lo;
+               st,wakeup-y-hi;
+               st,wakeup-z-lo;
+               st,wakeup-z-hi;
+       };
+
+Example for a I2C device node:
+
+       lis331dlh: lis331dlh@18 {
+               compatible = "st,lis331dlh", "st,lis3lv02d";
+               reg = <0x18>;
+               Vdd-supply = <&lis3_reg>;
+               Vdd_IO-supply = <&lis3_reg>;
+
+               st,click-single-x;
+               st,click-single-y;
+               st,click-single-z;
+               st,click-thresh-x = <10>;
+               st,click-thresh-y = <10>;
+               st,click-thresh-z = <10>;
+               st,irq1-click;
+               st,irq2-click;
+               st,wakeup-x-lo;
+               st,wakeup-x-hi;
+               st,wakeup-y-lo;
+               st,wakeup-y-hi;
+               st,wakeup-z-lo;
+               st,wakeup-z-hi;
+               st,min-limit-x = <120>;
+               st,min-limit-y = <120>;
+               st,min-limit-z = <140>;
+               st,max-limit-x = <550>;
+               st,max-limit-y = <550>;
+               st,max-limit-z = <750>;
+       };
+
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 ea6f6325f9ba0cf1ff8dd91ae85e5a112646542c..72bedad6bf8cca35cc93593f5112d71216ed677a 100644 (file)
@@ -418,8 +418,8 @@ config APPLICOM
          If unsure, say N.
 
 config SONYPI
-       tristate "Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && X86 && PCI && INPUT && !64BIT
+       tristate "Sony Vaio Programmable I/O Control Device support"
+       depends on X86 && PCI && INPUT && !64BIT
        ---help---
          This driver enables access to the Sony Programmable I/O Control
          Device which can be found in many (all ?) Sony Vaio laptops.
@@ -566,7 +566,7 @@ source "drivers/char/tpm/Kconfig"
 
 config TELCLOCK
        tristate "Telecom clock driver for ATCA SBC"
-       depends on EXPERIMENTAL && X86
+       depends on X86
        default n
        help
          The telecom clock device is specific to the MPCBL0010 and MPCBL0050
index 33dc2298af73a9118649208df8e75a79bef1bd15..3d6c0671e9965bcd020f81cece6680c3e5dfd726 100644 (file)
@@ -826,7 +826,7 @@ static int __init mmtimer_init(void)
 
        /* Allocate list of node ptrs to mmtimer_t's */
        timers = kzalloc(sizeof(struct mmtimer_node)*maxn, GFP_KERNEL);
-       if (timers == NULL) {
+       if (!timers) {
                printk(KERN_ERR "%s: failed to allocate memory for device\n",
                                MMTIMER_NAME);
                goto out3;
@@ -848,7 +848,6 @@ static int __init mmtimer_init(void)
        return 0;
 
 out3:
-       kfree(timers);
        misc_deregister(&mmtimer_miscdev);
 out2:
        free_irq(SGI_MMTIMER_VECTOR, NULL);
index 04a480f86c6c8e7a052f68ff9c4e813d61d5e5d9..cfdfe493c6af007a4d2455ab0315ef2611d8ebb3 100644 (file)
@@ -93,9 +93,9 @@ int button_del_callback (void (*callback) (void))
                        button_callback_list [lp].count = 0;
                        callback_count--;
                        return 0;
-               };
+               }
                lp--;
-       };
+       }
        return -EINVAL;
 }
 
index 0a484b4a1b02bdabfd231a2ed21b5446ccd95642..a6b8ddea222702ef1499152365848fb2c00fb80f 100644 (file)
@@ -891,6 +891,14 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty)
        int work = 0;
        struct mgsl_icount *icount = &info->icount;
 
+       if (!tty) {
+               /* tty is not available anymore */
+               issue_command(info, CHA, CMD_RXRESET);
+               if (debug_level >= DEBUG_LEVEL_ISR)
+                       printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__);
+               return;
+       }
+
        if (tcd) {
                /* early termination, get FIFO count from RBCL register */
                fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f);
@@ -980,7 +988,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty)
        else
 #endif
        {
-               if (tty->stopped || tty->hw_stopped) {
+               if (tty && (tty->stopped || tty->hw_stopped)) {
                        tx_stop(info);
                        return;
                }
@@ -1000,7 +1008,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty)
                if (!info->tx_active)
                        return;
        } else {
-               if (tty->stopped || tty->hw_stopped) {
+               if (tty && (tty->stopped || tty->hw_stopped)) {
                        tx_stop(info);
                        return;
                }
@@ -1050,13 +1058,12 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty)
        wake_up_interruptible(&info->status_event_wait_q);
        wake_up_interruptible(&info->event_wait_q);
 
-       if (info->port.flags & ASYNC_CTS_FLOW) {
+       if (tty && (info->port.flags & ASYNC_CTS_FLOW)) {
                if (tty->hw_stopped) {
                        if (info->serial_signals & SerialSignal_CTS) {
                                if (debug_level >= DEBUG_LEVEL_ISR)
                                        printk("CTS tx start...");
-                               if (tty)
-                                       tty->hw_stopped = 0;
+                               tty->hw_stopped = 0;
                                tx_start(info, tty);
                                info->pending_bh |= BH_TRANSMIT;
                                return;
@@ -1065,8 +1072,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty)
                        if (!(info->serial_signals & SerialSignal_CTS)) {
                                if (debug_level >= DEBUG_LEVEL_ISR)
                                        printk("CTS tx stop...");
-                               if (tty)
-                                       tty->hw_stopped = 1;
+                               tty->hw_stopped = 1;
                                tx_stop(info);
                        }
                }
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 af9437488b6c11353d1d0ff5737aecb7afff5c51..91470fdbab2a578610e4269e88a959e6694c6ef6 100644 (file)
@@ -411,7 +411,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
                case RTC_IRQP_READ:
                case RTC_IRQP_SET:
                        return -EINVAL;
-               };
+               }
        }
 #endif
 
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 cdf2f5451c767ff0584c3739e8a35e4327cc52e1..060a672ebb7bf3189bd8a7b0e872c1b437347635 100644 (file)
@@ -1941,7 +1941,17 @@ static int __init init(void)
        INIT_LIST_HEAD(&pdrvdata.consoles);
        INIT_LIST_HEAD(&pdrvdata.portdevs);
 
-       return register_virtio_driver(&virtio_console);
+       err = register_virtio_driver(&virtio_console);
+       if (err < 0) {
+               pr_err("Error %d registering virtio driver\n", err);
+               goto free;
+       }
+       return 0;
+free:
+       if (pdrvdata.debugfs_dir)
+               debugfs_remove_recursive(pdrvdata.debugfs_dir);
+       class_destroy(pdrvdata.class);
+       return err;
 }
 
 static void __exit fini(void)
index 98a442da892a23ae21f19f1ef548b536bac9ede4..99c73352c430c5aefc6f679853a3826c48f1b55c 100644 (file)
@@ -105,7 +105,7 @@ config ATMEL_TCB_CLKSRC_BLOCK
 
 config IBM_ASM
        tristate "Device driver for IBM RSA service processor"
-       depends on X86 && PCI && INPUT && EXPERIMENTAL
+       depends on X86 && PCI && INPUT
        ---help---
          This option enables device driver support for in-band access to the
          IBM RSA (Condor) service processor in eServer xSeries systems.
@@ -162,8 +162,8 @@ config SGI_IOC4
          Otherwise say N.
 
 config TIFM_CORE
-       tristate "TI Flash Media interface support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && PCI
+       tristate "TI Flash Media interface support"
+       depends on PCI
        help
          If you want support for Texas Instruments(R) Flash Media adapters
          you should select this option and then also choose an appropriate
@@ -178,8 +178,8 @@ config TIFM_CORE
          be called tifm_core.
 
 config TIFM_7XX1
-       tristate "TI Flash Media PCI74xx/PCI76xx host adapter support (EXPERIMENTAL)"
-       depends on PCI && TIFM_CORE && EXPERIMENTAL
+       tristate "TI Flash Media PCI74xx/PCI76xx host adapter support"
+       depends on PCI && TIFM_CORE
        default TIFM_CORE
        help
          This option enables support for Texas Instruments(R) PCI74xx and
@@ -192,7 +192,7 @@ config TIFM_7XX1
 
 config ICS932S401
        tristate "Integrated Circuits ICS932S401"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Integrated Circuits
          ICS932S401 clock control chips.
@@ -398,7 +398,7 @@ config EP93XX_PWM
 
 config DS1682
        tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Dallas Semiconductor
          DS1682 Total Elapsed Time Recorder.
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 33ee834e1b83e4e581f7e40822f9957a3310d99c..0dd690e61d3ce28b8e6638e58c41a38f1b285137 100644 (file)
@@ -3,8 +3,7 @@
 #
 
 menuconfig C2PORT
-       tristate "Silicon Labs C2 port support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       tristate "Silicon Labs C2 port support"
        default n
        help
          This option enables support for Silicon Labs C2 port used to
@@ -22,7 +21,7 @@ menuconfig C2PORT
 if C2PORT
 
 config C2PORT_DURAMAR_2150
-       tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)"
+       tristate "C2 port support for Eurotech's Duramar 2150"
        depends on X86
        default n
        help
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 701edf6589705cb42f290a04c233239f7248760a..c9e695ea7c9a21c04900916508cf746e6bc760e3 100644 (file)
@@ -50,7 +50,7 @@ config EEPROM_LEGACY
 
 config EEPROM_MAX6875
        tristate "Maxim MAX6874/5 power supply supervisor"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get read-only support for the user EEPROM of
          the Maxim MAX6874/5 EEPROM-programmable, quad power-supply
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 6df0da4085e3cbbed526ad84d78d2edc03229e17..12ccdf94e4fa1371889873c0e305669f0f30f7f4 100644 (file)
@@ -736,7 +736,14 @@ static void ilo_remove(struct pci_dev *pdev)
        free_irq(pdev->irq, ilo_hw);
        ilo_unmap_device(pdev, ilo_hw);
        pci_release_regions(pdev);
-       pci_disable_device(pdev);
+       /*
+        * pci_disable_device(pdev) used to be here. But this PCI device has
+        * two functions with interrupt lines connected to a single pin. The
+        * other one is a USB host controller. So when we disable the PIN here
+        * e.g. by rmmod hpilo, the controller stops working. It is because
+        * the interrupt link is disabled in ACPI since it is not refcounted
+        * yet. See acpi_pci_link_free_irq called from acpi_pci_irq_disable.
+        */
        kfree(ilo_hw);
        ilo_hwdev[(minor / max_ccb)] = 0;
 }
@@ -826,7 +833,7 @@ unmap:
 free_regions:
        pci_release_regions(pdev);
 disable:
-       pci_disable_device(pdev);
+/*     pci_disable_device(pdev);  see comment in ilo_remove */
 free:
        kfree(ilo_hw);
 out:
index a981e2a42f92a9427058d528fd784ed2798c6883..4a87e5c0a3200955e1889edfc441753655bc8b5a 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/miscdevice.h>
 #include <linux/pm_runtime.h>
 #include <linux/atomic.h>
+#include <linux/of_device.h>
 #include "lis3lv02d.h"
 
 #define DRIVER_NAME     "lis3lv02d"
 #define LIS3_SENSITIVITY_12B           ((LIS3_ACCURACY * 1000) / 1024)
 #define LIS3_SENSITIVITY_8B            (18 * LIS3_ACCURACY)
 
+/*
+ * LIS331DLH spec says 1LSBs corresponds 4G/4096 -> 1LSB is 1000/1024 mG.
+ * Below macros defines sensitivity values for +/-2G. Dataout bits for
+ * +/-2G range is 12 bits so 4 bits adjustment must be done to get 12bit
+ * data from 16bit value. Currently this driver supports only 2G range.
+ */
+#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 +145,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 lis331dlh_read_data(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 +218,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 +291,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 +422,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);
@@ -912,6 +944,154 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *lis3,
        }
 }
 
+#ifdef CONFIG_OF
+int lis3lv02d_init_dt(struct lis3lv02d *lis3)
+{
+       struct lis3lv02d_platform_data *pdata;
+       struct device_node *np = lis3->of_node;
+       u32 val;
+
+       if (!lis3->of_node)
+               return 0;
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
+
+       if (of_get_property(np, "st,click-single-x", NULL))
+               pdata->click_flags |= LIS3_CLICK_SINGLE_X;
+       if (of_get_property(np, "st,click-double-x", NULL))
+               pdata->click_flags |= LIS3_CLICK_DOUBLE_X;
+
+       if (of_get_property(np, "st,click-single-y", NULL))
+               pdata->click_flags |= LIS3_CLICK_SINGLE_Y;
+       if (of_get_property(np, "st,click-double-y", NULL))
+               pdata->click_flags |= LIS3_CLICK_DOUBLE_Y;
+
+       if (of_get_property(np, "st,click-single-z", NULL))
+               pdata->click_flags |= LIS3_CLICK_SINGLE_Z;
+       if (of_get_property(np, "st,click-double-z", NULL))
+               pdata->click_flags |= LIS3_CLICK_DOUBLE_Z;
+
+       if (!of_property_read_u32(np, "st,click-threshold-x", &val))
+               pdata->click_thresh_x = val;
+       if (!of_property_read_u32(np, "st,click-threshold-y", &val))
+               pdata->click_thresh_y = val;
+       if (!of_property_read_u32(np, "st,click-threshold-z", &val))
+               pdata->click_thresh_z = val;
+
+       if (!of_property_read_u32(np, "st,click-time-limit", &val))
+               pdata->click_time_limit = val;
+       if (!of_property_read_u32(np, "st,click-latency", &val))
+               pdata->click_latency = val;
+       if (!of_property_read_u32(np, "st,click-window", &val))
+               pdata->click_window = val;
+
+       if (of_get_property(np, "st,irq1-disable", NULL))
+               pdata->irq_cfg |= LIS3_IRQ1_DISABLE;
+       if (of_get_property(np, "st,irq1-ff-wu-1", NULL))
+               pdata->irq_cfg |= LIS3_IRQ1_FF_WU_1;
+       if (of_get_property(np, "st,irq1-ff-wu-2", NULL))
+               pdata->irq_cfg |= LIS3_IRQ1_FF_WU_2;
+       if (of_get_property(np, "st,irq1-data-ready", NULL))
+               pdata->irq_cfg |= LIS3_IRQ1_DATA_READY;
+       if (of_get_property(np, "st,irq1-click", NULL))
+               pdata->irq_cfg |= LIS3_IRQ1_CLICK;
+
+       if (of_get_property(np, "st,irq2-disable", NULL))
+               pdata->irq_cfg |= LIS3_IRQ2_DISABLE;
+       if (of_get_property(np, "st,irq2-ff-wu-1", NULL))
+               pdata->irq_cfg |= LIS3_IRQ2_FF_WU_1;
+       if (of_get_property(np, "st,irq2-ff-wu-2", NULL))
+               pdata->irq_cfg |= LIS3_IRQ2_FF_WU_2;
+       if (of_get_property(np, "st,irq2-data-ready", NULL))
+               pdata->irq_cfg |= LIS3_IRQ2_DATA_READY;
+       if (of_get_property(np, "st,irq2-click", NULL))
+               pdata->irq_cfg |= LIS3_IRQ2_CLICK;
+
+       if (of_get_property(np, "st,irq-open-drain", NULL))
+               pdata->irq_cfg |= LIS3_IRQ_OPEN_DRAIN;
+       if (of_get_property(np, "st,irq-active-low", NULL))
+               pdata->irq_cfg |= LIS3_IRQ_ACTIVE_LOW;
+
+       if (!of_property_read_u32(np, "st,wu-duration-1", &val))
+               pdata->duration1 = val;
+       if (!of_property_read_u32(np, "st,wu-duration-2", &val))
+               pdata->duration2 = val;
+
+       if (of_get_property(np, "st,wakeup-x-lo", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_X_LO;
+       if (of_get_property(np, "st,wakeup-x-hi", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_X_HI;
+       if (of_get_property(np, "st,wakeup-y-lo", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_Y_LO;
+       if (of_get_property(np, "st,wakeup-y-hi", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_Y_HI;
+       if (of_get_property(np, "st,wakeup-z-lo", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_Z_LO;
+       if (of_get_property(np, "st,wakeup-z-hi", NULL))
+               pdata->wakeup_flags |= LIS3_WAKEUP_Z_HI;
+
+       if (!of_property_read_u32(np, "st,highpass-cutoff-hz", &val)) {
+               switch (val) {
+               case 1:
+                       pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_1HZ;
+                       break;
+               case 2:
+                       pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_2HZ;
+                       break;
+               case 4:
+                       pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_4HZ;
+                       break;
+               case 8:
+                       pdata->hipass_ctrl = LIS3_HIPASS_CUTFF_8HZ;
+                       break;
+               }
+       }
+
+       if (of_get_property(np, "st,hipass1-disable", NULL))
+               pdata->hipass_ctrl |= LIS3_HIPASS1_DISABLE;
+       if (of_get_property(np, "st,hipass2-disable", NULL))
+               pdata->hipass_ctrl |= LIS3_HIPASS2_DISABLE;
+
+       if (of_get_property(np, "st,axis-x", &val))
+               pdata->axis_x = val;
+       if (of_get_property(np, "st,axis-y", &val))
+               pdata->axis_y = val;
+       if (of_get_property(np, "st,axis-z", &val))
+               pdata->axis_z = val;
+
+       if (of_get_property(np, "st,default-rate", NULL))
+               pdata->default_rate = val;
+
+       if (of_get_property(np, "st,min-limit-x", &val))
+               pdata->st_min_limits[0] = val;
+       if (of_get_property(np, "st,min-limit-y", &val))
+               pdata->st_min_limits[1] = val;
+       if (of_get_property(np, "st,min-limit-z", &val))
+               pdata->st_min_limits[2] = val;
+
+       if (of_get_property(np, "st,max-limit-x", &val))
+               pdata->st_max_limits[0] = val;
+       if (of_get_property(np, "st,max-limit-y", &val))
+               pdata->st_max_limits[1] = val;
+       if (of_get_property(np, "st,max-limit-z", &val))
+               pdata->st_max_limits[2] = val;
+
+
+       lis3->pdata = pdata;
+
+       return 0;
+}
+
+#else
+int lis3lv02d_init_dt(struct lis3lv02d *lis3)
+{
+       return 0;
+}
+#endif
+EXPORT_SYMBOL_GPL(lis3lv02d_init_dt);
+
 /*
  * Initialise the accelerometer and the various subsystems.
  * Should be rather independent of the bus system.
@@ -956,6 +1136,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 lis331dlh sensor found\n");
+               lis3->read_data = lis331dlh_read_data;
+               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..c439c827eea803b887b678bb00b8a42790413af8 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 {
+       LIS3LV02D,
+       LIS3DC,
+       HP3DC,
+       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,9 +310,14 @@ 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 */
+
+#ifdef CONFIG_OF
+       struct device_node      *of_node;
+#endif
 };
 
 int lis3lv02d_init_device(struct lis3lv02d *lis3);
@@ -290,5 +326,6 @@ void lis3lv02d_joystick_disable(struct lis3lv02d *lis3);
 void lis3lv02d_poweroff(struct lis3lv02d *lis3);
 int lis3lv02d_poweron(struct lis3lv02d *lis3);
 int lis3lv02d_remove_fs(struct lis3lv02d *lis3);
+int lis3lv02d_init_dt(struct lis3lv02d *lis3);
 
 extern struct lis3lv02d lis3_dev;
index e8c0019da97a81bb8643a10c6e956409b5569b82..60ec8689d6e3dd94403041456de3379246996508 100644 (file)
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
 #include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+
 #include "lis3lv02d.h"
 
 #define DRV_NAME       "lis3lv02d_i2c"
@@ -90,7 +94,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);
 }
 
@@ -98,12 +106,30 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 static union axis_conversion lis3lv02d_axis_map =
        { .as_array = { LIS3_DEV_X, LIS3_DEV_Y, LIS3_DEV_Z } };
 
+#ifdef CONFIG_OF
+static struct of_device_id lis3lv02d_i2c_dt_ids[] = {
+       { .compatible = "st,lis3lv02d" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, lis3lv02d_i2c_dt_ids);
+#endif
+
 static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
                                        const struct i2c_device_id *id)
 {
        int ret = 0;
        struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
+#ifdef CONFIG_OF
+       if (of_match_device(lis3lv02d_i2c_dt_ids, &client->dev)) {
+               lis3_dev.of_node = client->dev.of_node;
+               ret = lis3lv02d_init_dt(&lis3_dev);
+               if (ret)
+                       return ret;
+               pdata = lis3_dev.pdata;
+       }
+#endif
+
        if (pdata) {
                if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
                        (i2c_check_functionality(client->adapter,
@@ -231,7 +257,8 @@ static int lis3_i2c_runtime_resume(struct device *dev)
 #endif /* CONFIG_PM_RUNTIME */
 
 static const struct i2c_device_id lis3lv02d_id[] = {
-       {"lis3lv02d", 0 },
+       {"lis3lv02d", LIS3LV02D},
+       {"lis331dlh", LIS331DLH},
        {}
 };
 
@@ -250,6 +277,7 @@ static struct i2c_driver lis3lv02d_i2c_driver = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
                .pm     = &lis3_pm_ops,
+               .of_match_table = of_match_ptr(lis3lv02d_i2c_dt_ids),
        },
        .probe  = lis3lv02d_i2c_probe,
        .remove = __devexit_p(lis3lv02d_i2c_remove),
index 80880e984b4fea1c6b8ed23ef69fb29aeb3200cc..ccb6475fa05966eb81888c191ea97a592d3a9c99 100644 (file)
@@ -17,6 +17,9 @@
 #include <linux/workqueue.h>
 #include <linux/spi/spi.h>
 #include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
 
 #include "lis3lv02d.h"
 
@@ -58,6 +61,14 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
 static union axis_conversion lis3lv02d_axis_normal =
        { .as_array = { 1, 2, 3 } };
 
+#ifdef CONFIG_OF
+static struct of_device_id lis302dl_spi_dt_ids[] = {
+       { .compatible = "st,lis302dl-spi" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids);
+#endif
+
 static int __devinit lis302dl_spi_probe(struct spi_device *spi)
 {
        int ret;
@@ -75,6 +86,15 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi)
        lis3_dev.irq            = spi->irq;
        lis3_dev.ac             = lis3lv02d_axis_normal;
        lis3_dev.pdata          = spi->dev.platform_data;
+
+#ifdef CONFIG_OF
+       if (of_match_device(lis302dl_spi_dt_ids, &spi->dev)) {
+               lis3_dev.of_node = spi->dev.of_node;
+               ret = lis3lv02d_init_dt(&lis3_dev);
+               if (ret)
+                       return ret;
+       }
+#endif
        spi_set_drvdata(spi, &lis3_dev);
 
        return lis3lv02d_init_device(&lis3_dev);
@@ -121,6 +141,7 @@ static struct spi_driver lis302dl_spi_driver = {
                .name   = DRV_NAME,
                .owner  = THIS_MODULE,
                .pm     = &lis3lv02d_spi_pm,
+               .of_match_table = of_match_ptr(lis302dl_spi_dt_ids),
        },
        .probe  = lis302dl_spi_probe,
        .remove = __devexit_p(lis302dl_spi_remove),
index 47d78a72db2e6c4bec6c02a0d72fbd61e5007506..5a79ccde2fdf6ea5c93ba54f491d053fd18c5581 100644 (file)
@@ -1,6 +1,6 @@
 config INTEL_MEI
        tristate "Intel Management Engine Interface (Intel MEI)"
-       depends on X86 && PCI && EXPERIMENTAL && WATCHDOG_CORE
+       depends on X86 && PCI && WATCHDOG_CORE
        help
          The Intel Management Engine (Intel ME) provides Manageability,
          Security and Media services for system containing Intel chipsets.
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 */
This page took 0.109962 seconds and 5 git commands to generate.