Merge 3.19-rc5 into char-misc-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Jan 2015 22:56:57 +0000 (06:56 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Jan 2015 22:56:57 +0000 (06:56 +0800)
We want the 3.19-rc5 fixes in here for our testing.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
42 files changed:
Documentation/devicetree/bindings/powerpc/fsl/lbc.txt
Documentation/stable_kernel_rules.txt
MAINTAINERS
arch/powerpc/include/asm/fsl_lbc.h
drivers/char/Kconfig
drivers/char/mem.c
drivers/coresight/coresight-etb10.c
drivers/coresight/coresight-etm3x.c
drivers/coresight/coresight-funnel.c
drivers/coresight/coresight-tmc.c
drivers/coresight/coresight-tpiu.c
drivers/coresight/of_coresight.c
drivers/hv/channel_mgmt.c
drivers/hv/connection.c
drivers/misc/ad525x_dpot-spi.c
drivers/misc/ad525x_dpot.c
drivers/misc/genwqe/card_base.h
drivers/misc/genwqe/card_sysfs.c
drivers/misc/ioc4.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c
drivers/misc/mei/mei_dev.h
drivers/misc/ti-st/st_core.c
drivers/misc/ti-st/st_kim.c
drivers/misc/ti-st/st_ll.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/rsrc_pci.c [new file with mode: 0644]
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio_fsl_elbc_gpcm.c [new file with mode: 0644]
drivers/uio/uio_pci_generic.c
drivers/vme/vme.c
include/linux/coresight.h
include/linux/mei_cl_bus.h
include/linux/ti_wilink_st.h
tools/hv/Makefile
tools/hv/hv_kvp_daemon.c

index 3300fec501c540288663e93949faf2722f4fd730..1c80fcedebb52049721fbd61c4dd4c57133bd47c 100644 (file)
@@ -16,20 +16,28 @@ Example:
                           "fsl,pq2-localbus";
                #address-cells = <2>;
                #size-cells = <1>;
-               reg = <f0010100 40>;
+               reg = <0xf0010100 0x40>;
 
-               ranges = <0 0 fe000000 02000000
-                         1 0 f4500000 00008000>;
+               ranges = <0x0 0x0 0xfe000000 0x02000000
+                         0x1 0x0 0xf4500000 0x00008000
+                         0x2 0x0 0xfd810000 0x00010000>;
 
                flash@0,0 {
                        compatible = "jedec-flash";
-                       reg = <0 0 2000000>;
+                       reg = <0x0 0x0 0x2000000>;
                        bank-width = <4>;
                        device-width = <1>;
                };
 
                board-control@1,0 {
-                       reg = <1 0 20>;
+                       reg = <0x1 0x0 0x20>;
                        compatible = "fsl,mpc8272ads-bcsr";
                };
+
+               simple-periph@2,0 {
+                       compatible = "fsl,elbc-gpcm-uio";
+                       reg = <0x2 0x0 0x10000>;
+                       elbc-gpcm-br = <0xfd810800>;
+                       elbc-gpcm-or = <0xffff09f7>;
+               };
        };
index aee73e78c7d42a8aa7d9c1f630c705ddb6c3838c..02f8331edb8bfd54bf39b2ae150609ae158f2686 100644 (file)
@@ -32,18 +32,42 @@ Procedure for submitting patches to the -stable tree:
  - If the patch covers files in net/ or drivers/net please follow netdev stable
    submission guidelines as described in
    Documentation/networking/netdev-FAQ.txt
- - Send the patch, after verifying that it follows the above rules, to
-   stable@vger.kernel.org.  You must note the upstream commit ID in the
-   changelog of your submission, as well as the kernel version you wish
-   it to be applied to.
- - To have the patch automatically included in the stable tree, add the tag
+ - Security patches should not be handled (solely) by the -stable review
+   process but should follow the procedures in Documentation/SecurityBugs.
+
+For all other submissions, choose one of the following procedures:
+
+   --- Option 1 ---
+
+   To have the patch automatically included in the stable tree, add the tag
      Cc: stable@vger.kernel.org
    in the sign-off area. Once the patch is merged it will be applied to
    the stable tree without anything else needing to be done by the author
    or subsystem maintainer.
- - If the patch requires other patches as prerequisites which can be
-   cherry-picked, then this can be specified in the following format in
-   the sign-off area:
+
+   --- Option 2 ---
+
+   After the patch has been merged to Linus' tree, send an email to
+   stable@vger.kernel.org containing the subject of the patch, the commit ID,
+   why you think it should be applied, and what kernel version you wish it to
+   be applied to.
+
+   --- Option 3 ---
+
+   Send the patch, after verifying that it follows the above rules, to
+   stable@vger.kernel.org.  You must note the upstream commit ID in the
+   changelog of your submission, as well as the kernel version you wish
+   it to be applied to.
+
+Option 1 is probably the easiest and most common. Options 2 and 3 are more
+useful if the patch isn't deemed worthy at the time it is applied to a public
+git tree (for instance, because it deserves more regression testing first).
+Option 3 is especially useful if the patch needs some special handling to apply
+to an older kernel (e.g., if API's have changed in the meantime).
+
+Additionally, some patches submitted via Option 1 may have additional patch
+prerequisites which can be cherry-picked. This can be specified in the following
+format in the sign-off area:
 
      Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
      Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
@@ -57,13 +81,13 @@ Procedure for submitting patches to the -stable tree:
      git cherry-pick fd21073
      git cherry-pick <this commit>
 
+Following the submission:
+
  - The sender will receive an ACK when the patch has been accepted into the
    queue, or a NAK if the patch is rejected.  This response might take a few
    days, according to the developer's schedules.
  - If accepted, the patch will be added to the -stable queue, for review by
    other developers and by the relevant subsystem maintainer.
- - Security patches should not be sent to this alias, but instead to the
-   documented security@kernel.org address.
 
 
 Review cycle:
index 2fa38532124537dec0a9d9e019471b628be6f58c..b00535f1e74c415ed998d46bf1b74a62302e2e3c 100644 (file)
@@ -3013,6 +3013,7 @@ F:        drivers/platform/x86/dell-laptop.c
 
 DELL LAPTOP SMM DRIVER
 M:     Guenter Roeck <linux@roeck-us.net>
+S:     Maintained
 F:     drivers/char/i8k.c
 F:     include/uapi/linux/i8k.h
 
index 067fb0dca549b86fc4ad02cca3b180718c2a9593..c7240a024b96662bb81bf26f80314e3ce8aff42a 100644 (file)
@@ -95,6 +95,9 @@ struct fsl_lbc_bank {
 #define OR_FCM_TRLX_SHIFT                2
 #define OR_FCM_EHTR             0x00000002
 #define OR_FCM_EHTR_SHIFT                1
+
+#define OR_GPCM_AM             0xFFFF8000
+#define OR_GPCM_AM_SHIFT               15
 };
 
 struct fsl_lbc_regs {
index efefd12a0f7bd97b2d6a3970eb068250bce257c2..a4af8221751e4d6905d37cefc628409f1fb30b7e 100644 (file)
@@ -6,6 +6,15 @@ menu "Character devices"
 
 source "drivers/tty/Kconfig"
 
+config DEVMEM
+       bool "/dev/mem virtual device support"
+       default y
+       help
+         Say Y here if you want to support the /dev/mem device.
+         The /dev/mem device is used to access areas of physical
+         memory.
+         When in doubt, say "Y".
+
 config DEVKMEM
        bool "/dev/kmem virtual device support"
        default y
index 4c58333b42570d233ccfaa83dac3c67f69e73b49..080273287c48842ab95b1d84f1c55bf13f0ae327 100644 (file)
@@ -28,7 +28,7 @@
 #include <linux/io.h>
 #include <linux/aio.h>
 
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 
 #ifdef CONFIG_IA64
 # include <linux/efi.h>
@@ -341,7 +341,6 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)
        return 0;
 }
 
-#ifdef CONFIG_DEVKMEM
 static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
 {
        unsigned long pfn;
@@ -362,9 +361,7 @@ static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
        vma->vm_pgoff = pfn;
        return mmap_mem(file, vma);
 }
-#endif
 
-#ifdef CONFIG_DEVKMEM
 /*
  * This function reads the *virtual* memory as seen by the kernel.
  */
@@ -544,9 +541,7 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
        *ppos = p;
        return virtr + wrote ? : err;
 }
-#endif
 
-#ifdef CONFIG_DEVPORT
 static ssize_t read_port(struct file *file, char __user *buf,
                         size_t count, loff_t *ppos)
 {
@@ -575,6 +570,7 @@ static ssize_t write_port(struct file *file, const char __user *buf,
                return -EFAULT;
        while (count-- > 0 && i < 65536) {
                char c;
+
                if (__get_user(c, tmp)) {
                        if (tmp > buf)
                                break;
@@ -587,7 +583,6 @@ static ssize_t write_port(struct file *file, const char __user *buf,
        *ppos = i;
        return tmp-buf;
 }
-#endif
 
 static ssize_t read_null(struct file *file, char __user *buf,
                         size_t count, loff_t *ppos)
@@ -631,6 +626,7 @@ static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
 
        while (iov_iter_count(iter)) {
                size_t chunk = iov_iter_count(iter), n;
+
                if (chunk > PAGE_SIZE)
                        chunk = PAGE_SIZE;      /* Just for latency reasons */
                n = iov_iter_zero(chunk, iter);
@@ -715,7 +711,7 @@ static int open_port(struct inode *inode, struct file *filp)
 #define open_mem       open_port
 #define open_kmem      open_mem
 
-static const struct file_operations mem_fops = {
+static const struct file_operations __maybe_unused mem_fops = {
        .llseek         = memory_lseek,
        .read           = read_mem,
        .write          = write_mem,
@@ -724,8 +720,7 @@ static const struct file_operations mem_fops = {
        .get_unmapped_area = get_unmapped_area_mem,
 };
 
-#ifdef CONFIG_DEVKMEM
-static const struct file_operations kmem_fops = {
+static const struct file_operations __maybe_unused kmem_fops = {
        .llseek         = memory_lseek,
        .read           = read_kmem,
        .write          = write_kmem,
@@ -733,7 +728,6 @@ static const struct file_operations kmem_fops = {
        .open           = open_kmem,
        .get_unmapped_area = get_unmapped_area_mem,
 };
-#endif
 
 static const struct file_operations null_fops = {
        .llseek         = null_lseek,
@@ -744,14 +738,12 @@ static const struct file_operations null_fops = {
        .splice_write   = splice_write_null,
 };
 
-#ifdef CONFIG_DEVPORT
-static const struct file_operations port_fops = {
+static const struct file_operations __maybe_unused port_fops = {
        .llseek         = memory_lseek,
        .read           = read_port,
        .write          = write_port,
        .open           = open_port,
 };
-#endif
 
 static const struct file_operations zero_fops = {
        .llseek         = zero_lseek,
@@ -785,7 +777,9 @@ static const struct memdev {
        const struct file_operations *fops;
        struct backing_dev_info *dev_info;
 } devlist[] = {
+#ifdef CONFIG_DEVMEM
         [1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
+#endif
 #ifdef CONFIG_DEVKMEM
         [2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
 #endif
index c922d4aded8a3dadd3c91140b573f8f4eed7191f..a1da7020201bfb488e0ce3a22f4675883c87a718 100644 (file)
@@ -521,17 +521,7 @@ static struct amba_driver etb_driver = {
        .id_table       = etb_ids,
 };
 
-static int __init etb_init(void)
-{
-       return amba_driver_register(&etb_driver);
-}
-module_init(etb_init);
-
-static void __exit etb_exit(void)
-{
-       amba_driver_unregister(&etb_driver);
-}
-module_exit(etb_exit);
+module_amba_driver(etb_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver");
index d9e3ed6aa857b47469759cb32c486a885112e8a2..73c36696f1b686f94069aac7c35573e510d33531 100644 (file)
@@ -573,7 +573,8 @@ static ssize_t mode_store(struct device *dev,
        if (drvdata->mode & ETM_MODE_STALL) {
                if (!(drvdata->etmccr & ETMCCR_FIFOFULL)) {
                        dev_warn(drvdata->dev, "stall mode not supported\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto err_unlock;
                }
                drvdata->ctrl |= ETMCR_STALL_MODE;
         } else
@@ -582,7 +583,8 @@ static ssize_t mode_store(struct device *dev,
        if (drvdata->mode & ETM_MODE_TIMESTAMP) {
                if (!(drvdata->etmccer & ETMCCER_TIMESTAMP)) {
                        dev_warn(drvdata->dev, "timestamp not supported\n");
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto err_unlock;
                }
                drvdata->ctrl |= ETMCR_TIMESTAMP_EN;
        } else
@@ -595,6 +597,10 @@ static ssize_t mode_store(struct device *dev,
        spin_unlock(&drvdata->spinlock);
 
        return size;
+
+err_unlock:
+       spin_unlock(&drvdata->spinlock);
+       return ret;
 }
 static DEVICE_ATTR_RW(mode);
 
@@ -1743,7 +1749,11 @@ static void etm_init_arch_data(void *info)
 
 static void etm_init_default_data(struct etm_drvdata *drvdata)
 {
-       static int etm3x_traceid;
+       /*
+        * A trace ID of value 0 is invalid, so let's start at some
+        * random value that fits in 7 bits and will be just as good.
+        */
+       static int etm3x_traceid = 0x10;
 
        u32 flags = (1 << 0 | /* instruction execute*/
                     3 << 3 | /* ARM instruction */
index 2108edffe1f4f5cceda529fd8049ca6a3caaddfd..3db36f70b6662f3be300df2a4270df7edaecd09e 100644 (file)
@@ -252,17 +252,7 @@ static struct amba_driver funnel_driver = {
        .id_table       = funnel_ids,
 };
 
-static int __init funnel_init(void)
-{
-       return amba_driver_register(&funnel_driver);
-}
-module_init(funnel_init);
-
-static void __exit funnel_exit(void)
-{
-       amba_driver_unregister(&funnel_driver);
-}
-module_exit(funnel_exit);
+module_amba_driver(funnel_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("CoreSight Funnel driver");
index ce2c293f17074eea85ba9c1a9bb537ac22a230b7..3ff232f9ddf78c5a3c4f6146b1ec2dac7aef87b0 100644 (file)
@@ -760,17 +760,7 @@ static struct amba_driver tmc_driver = {
        .id_table       = tmc_ids,
 };
 
-static int __init tmc_init(void)
-{
-       return amba_driver_register(&tmc_driver);
-}
-module_init(tmc_init);
-
-static void __exit tmc_exit(void)
-{
-       amba_driver_unregister(&tmc_driver);
-}
-module_exit(tmc_exit);
+module_amba_driver(tmc_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("CoreSight Trace Memory Controller driver");
index ae101082791a2c36a26644b6263a5cbf2d0eb416..3b33af2416bb4da64d2037b96edb6699affe17e9 100644 (file)
@@ -201,17 +201,7 @@ static struct amba_driver tpiu_driver = {
        .id_table       = tpiu_ids,
 };
 
-static int __init tpiu_init(void)
-{
-       return amba_driver_register(&tpiu_driver);
-}
-module_init(tpiu_init);
-
-static void __exit tpiu_exit(void)
-{
-       amba_driver_unregister(&tpiu_driver);
-}
-module_exit(tpiu_exit);
+module_amba_driver(tpiu_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("CoreSight Trace Port Interface Unit driver");
index 5030c073450831a7f37f89b12c35934bdb1d9f97..9a5ff56f34d9b87882373a82834a988547ed50ee 100644 (file)
@@ -93,7 +93,7 @@ static int of_coresight_alloc_memory(struct device *dev,
        if (!pdata->outports)
                return -ENOMEM;
 
-       /* Children connected to this component via @outport */
+       /* Children connected to this component via @outports */
         pdata->child_names = devm_kzalloc(dev, pdata->nr_outport *
                                          sizeof(*pdata->child_names),
                                          GFP_KERNEL);
@@ -126,7 +126,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
        if (!pdata)
                return ERR_PTR(-ENOMEM);
 
-       /* Use device name as debugfs handle */
+       /* Use device name as sysfs handle */
        pdata->name = dev_name(dev);
 
        /* Get the number of input and output port for this component */
@@ -174,7 +174,7 @@ struct coresight_platform_data *of_get_coresight_platform_data(
                                continue;
 
                        rdev = of_coresight_get_endpoint_device(rparent);
-                       if (!dev)
+                       if (!rdev)
                                continue;
 
                        pdata->child_names[i] = dev_name(rdev);
index 2c59f030546b0cf8beef508cdbedb96298484744..1d7df2576b1c10cb3f4b1deaed889aa1238c086d 100644 (file)
@@ -815,7 +815,7 @@ cleanup:
 struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
 {
        struct list_head *cur, *tmp;
-       int cur_cpu = hv_context.vp_index[smp_processor_id()];
+       int cur_cpu;
        struct vmbus_channel *cur_channel;
        struct vmbus_channel *outgoing_channel = primary;
        int cpu_distance, new_cpu_distance;
@@ -823,6 +823,8 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
        if (list_empty(&primary->sc_list))
                return outgoing_channel;
 
+       cur_cpu = hv_context.vp_index[get_cpu()];
+       put_cpu();
        list_for_each_safe(cur, tmp, &primary->sc_list) {
                cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
                if (cur_channel->state != CHANNEL_OPENED_STATE)
index e206619b946e577ff79b65a7273cfe5784964649..a63a795300b9ebbec393154fdfdce27e38ad3b0c 100644 (file)
@@ -80,8 +80,10 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
        msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
        msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
        msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
-       if (version == VERSION_WIN8_1)
-               msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
+       if (version == VERSION_WIN8_1) {
+               msg->target_vcpu = hv_context.vp_index[get_cpu()];
+               put_cpu();
+       }
 
        /*
         * Add to list before we send the request since we may
index 9da04ede04f356aaef1495bd0cf01408e6556da5..f4c82eafa8e57a15cda2da73c6f276fb09f5c0b9 100644 (file)
 static int write8(void *client, u8 val)
 {
        u8 data = val;
+
        return spi_write(client, &data, 1);
 }
 
 static int write16(void *client, u8 reg, u8 val)
 {
        u8 data[2] = {reg, val};
+
        return spi_write(client, data, 2);
 }
 
 static int write24(void *client, u8 reg, u16 val)
 {
        u8 data[3] = {reg, val >> 8, val};
+
        return spi_write(client, data, 3);
 }
 
@@ -34,6 +37,7 @@ static int read8(void *client)
 {
        int ret;
        u8 data;
+
        ret = spi_read(client, &data, 1);
        if (ret < 0)
                return ret;
index a43053daad0ec6698e39475f02499b955a12f66a..15e88078ba1e6a70ec82b3c713fd8c19ebb425d7 100644 (file)
@@ -176,6 +176,7 @@ static s32 dpot_read_i2c(struct dpot_data *dpot, u8 reg)
 {
        int value;
        unsigned ctrl = 0;
+
        switch (dpot->uid) {
        case DPOT_UID(AD5246_ID):
        case DPOT_UID(AD5247_ID):
@@ -333,7 +334,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
        case DPOT_UID(AD5246_ID):
        case DPOT_UID(AD5247_ID):
                return dpot_write_d8(dpot, value);
-               break;
 
        case DPOT_UID(AD5245_ID):
        case DPOT_UID(AD5241_ID):
@@ -345,7 +345,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
                        0 : DPOT_AD5282_RDAC_AB;
                return dpot_write_r8d8(dpot, ctrl, value);
-               break;
        case DPOT_UID(AD5171_ID):
        case DPOT_UID(AD5273_ID):
                if (reg & DPOT_ADDR_OTP) {
@@ -355,7 +354,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
                        ctrl = DPOT_AD5273_FUSE;
                }
                return dpot_write_r8d8(dpot, ctrl, value);
-               break;
        case DPOT_UID(AD5172_ID):
        case DPOT_UID(AD5173_ID):
                ctrl = ((reg & DPOT_RDAC_MASK) == DPOT_RDAC0) ?
@@ -367,7 +365,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
                        ctrl |= DPOT_AD5170_2_3_FUSE;
                }
                return dpot_write_r8d8(dpot, ctrl, value);
-               break;
        case DPOT_UID(AD5170_ID):
                if (reg & DPOT_ADDR_OTP) {
                        tmp = dpot_read_r8d16(dpot, tmp);
@@ -376,7 +373,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
                        ctrl = DPOT_AD5170_2_3_FUSE;
                }
                return dpot_write_r8d8(dpot, ctrl, value);
-               break;
        case DPOT_UID(AD5272_ID):
        case DPOT_UID(AD5274_ID):
                dpot_write_r8d8(dpot, DPOT_AD5270_1_2_4_CTRLREG << 2,
@@ -391,7 +387,6 @@ static s32 dpot_write_i2c(struct dpot_data *dpot, u8 reg, u16 value)
 
                return dpot_write_r8d8(dpot, (DPOT_AD5270_1_2_4_RDAC << 2) |
                                       (value >> 8), value & 0xFF);
-               break;
        default:
                if (reg & DPOT_ADDR_CMD)
                        return dpot_write_d8(dpot, reg);
index c64d7cad10855eaa15ffcaca562b514deade7a97..e7353449874ba9d584d28d8601314521536489e5 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/semaphore.h>
 #include <linux/uaccess.h>
 #include <linux/io.h>
-#include <linux/version.h>
 #include <linux/debugfs.h>
 #include <linux/slab.h>
 
index 2c33fbca9225ef0ed92f2c3be4d468aa751718f9..6ab31eff0536a2a2572bb6e39a952931959c958d 100644 (file)
@@ -24,7 +24,6 @@
  * debugging, please also see the debugfs interfaces of this driver.
  */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/module.h>
index 3336ddca45acc7e775794e4b239d2da113f354ef..8758d033db23d7b84c7be8b2170f6702b1c979a3 100644 (file)
@@ -144,9 +144,9 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
 {
        union ioc4_int_out int_out;
        union ioc4_gpcr gpcr;
-       unsigned int state, last_state = 1;
+       unsigned int state, last_state;
        uint64_t start, end, period;
-       unsigned int count = 0;
+       unsigned int count;
 
        /* Enable output */
        gpcr.raw = 0;
@@ -167,19 +167,20 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
        mmiowb();
 
        /* Check square wave period averaged over some number of cycles */
-       do {
-               int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
-               state = int_out.fields.int_out;
-               if (!last_state && state) {
-                       count++;
-                       if (count == IOC4_CALIBRATE_END) {
-                               end = ktime_get_ns();
-                               break;
-                       } else if (count == IOC4_CALIBRATE_DISCARD)
-                               start = ktime_get_ns();
-               }
-               last_state = state;
-       } while (1);
+       start = ktime_get_ns();
+       state = 1; /* make sure the first read isn't a rising edge */
+       for (count = 0; count <= IOC4_CALIBRATE_END; count++) {
+               do { /* wait for a rising edge */
+                       last_state = state;
+                       int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
+                       state = int_out.fields.int_out;
+               } while (last_state || !state);
+
+               /* discard the first few cycles */
+               if (count == IOC4_CALIBRATE_DISCARD)
+                       start = ktime_get_ns();
+       }
+       end = ktime_get_ns();
 
        /* Calculation rearranged to preserve intermediate precision.
         * Logically:
index b3a72bca5242ab0e5a65efda16e304f6b8181851..31164dd14bd0d81337839d0d30ab85d0f0d5ec7b 100644 (file)
@@ -224,13 +224,13 @@ void mei_cl_driver_unregister(struct mei_cl_driver *driver)
 }
 EXPORT_SYMBOL_GPL(mei_cl_driver_unregister);
 
-static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
+static ssize_t ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
                        bool blocking)
 {
        struct mei_device *dev;
        struct mei_me_client *me_cl;
        struct mei_cl_cb *cb;
-       int rets;
+       ssize_t rets;
 
        if (WARN_ON(!cl || !cl->dev))
                return -ENODEV;
@@ -271,12 +271,12 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
        return rets;
 }
 
-int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
+ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
 {
        struct mei_device *dev;
        struct mei_cl_cb *cb;
        size_t r_length;
-       int err;
+       ssize_t rets;
 
        if (WARN_ON(!cl || !cl->dev))
                return -ENODEV;
@@ -286,11 +286,9 @@ int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
        mutex_lock(&dev->device_lock);
 
        if (!cl->read_cb) {
-               err = mei_cl_read_start(cl, length);
-               if (err < 0) {
-                       mutex_unlock(&dev->device_lock);
-                       return err;
-               }
+               rets = mei_cl_read_start(cl, length);
+               if (rets < 0)
+                       goto out;
        }
 
        if (cl->reading_state != MEI_READ_COMPLETE &&
@@ -313,13 +311,13 @@ int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
        cb = cl->read_cb;
 
        if (cl->reading_state != MEI_READ_COMPLETE) {
-               r_length = 0;
+               rets = 0;
                goto out;
        }
 
        r_length = min_t(size_t, length, cb->buf_idx);
-
        memcpy(buf, cb->response_buffer.data, r_length);
+       rets = r_length;
 
        mei_io_cb_free(cb);
        cl->reading_state = MEI_IDLE;
@@ -328,20 +326,20 @@ int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
 out:
        mutex_unlock(&dev->device_lock);
 
-       return r_length;
+       return rets;
 }
 
-inline int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length)
+inline ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length)
 {
        return ___mei_cl_send(cl, buf, length, 0);
 }
 
-inline int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
+inline ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length)
 {
        return ___mei_cl_send(cl, buf, length, 1);
 }
 
-int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length)
+ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length)
 {
        struct mei_cl *cl = device->cl;
 
@@ -355,7 +353,7 @@ int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length)
 }
 EXPORT_SYMBOL_GPL(mei_cl_send);
 
-int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length)
+ssize_t mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length)
 {
        struct mei_cl *cl =  device->cl;
 
index 1382d551d7ed676f2c0eeb0d417382c1ca9fac33..3be18b7951e5fd43dc4014ed7f3fc97e994f3c0d 100644 (file)
@@ -704,7 +704,7 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
        if (cl->mei_flow_ctrl_creds > 0)
                return 1;
 
-       me_cl = mei_me_cl_by_id(dev, cl->me_client_id);
+       me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
        if (!me_cl) {
                cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
                return -ENOENT;
@@ -738,7 +738,7 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
 
        dev = cl->dev;
 
-       me_cl = mei_me_cl_by_id(dev, cl->me_client_id);
+       me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id);
        if (!me_cl) {
                cl_err(dev, cl, "no such me client %d\n", cl->me_client_id);
                return -ENOENT;
index 3dad74a8d496697a968c3cb21724cf5c15ba0c98..7f350af2ee10b201629659f6d5afcd8959824c87 100644 (file)
@@ -345,9 +345,9 @@ struct mei_cl_device *mei_cl_add_device(struct mei_device *dev,
                                        struct mei_cl_ops *ops);
 void mei_cl_remove_device(struct mei_cl_device *device);
 
-int __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length);
-int __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length);
-int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
+ssize_t __mei_cl_async_send(struct mei_cl *cl, u8 *buf, size_t length);
+ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length);
+ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length);
 void mei_cl_bus_rx_event(struct mei_cl *cl);
 void mei_cl_bus_remove_devices(struct mei_device *dev);
 int mei_cl_bus_init(void);
index 54be83d3efdd682e8025577c5464f2c3807739c0..c8c6a363069cc189b799bcf376fcf6991cc05e6e 100644 (file)
@@ -343,12 +343,26 @@ void st_int_recv(void *disc_data,
                        /* Unknow packet? */
                default:
                        type = *ptr;
-                       if (st_gdata->list[type] == NULL) {
-                               pr_err("chip/interface misbehavior dropping"
-                                       " frame starting with 0x%02x", type);
-                               goto done;
 
+                       /* Default case means non-HCILL packets,
+                        * possibilities are packets for:
+                        * (a) valid protocol -  Supported Protocols within
+                        *     the ST_MAX_CHANNELS.
+                        * (b) registered protocol - Checked by
+                        *     "st_gdata->list[type] == NULL)" are supported
+                        *     protocols only.
+                        *  Rules out any invalid protocol and
+                        *  unregistered protocols with channel ID < 16.
+                        */
+
+                       if ((type >= ST_MAX_CHANNELS) ||
+                                       (st_gdata->list[type] == NULL)) {
+                               pr_err("chip/interface misbehavior: "
+                                               "dropping frame starting "
+                                               "with 0x%02x\n", type);
+                               goto done;
                        }
+
                        st_gdata->rx_skb = alloc_skb(
                                        st_gdata->list[type]->max_frame_size,
                                        GFP_ATOMIC);
@@ -893,5 +907,3 @@ void st_core_exit(struct st_data_s *st_gdata)
                kfree(st_gdata);
        }
 }
-
-
index e4b7ee4f57b845a32af6e2778baebc13b9836dba..7109d28518d3306629ad11ad718de8827db899a8 100644 (file)
@@ -36,7 +36,8 @@
 #include <linux/skbuff.h>
 #include <linux/ti_wilink_st.h>
 #include <linux/module.h>
-
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #define MAX_ST_DEVICES 3       /* Imagine 1 on each UART for now */
 static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
@@ -44,6 +45,9 @@ static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
 /**********************************************************************/
 /* internal functions */
 
+struct ti_st_plat_data *dt_pdata;
+static struct ti_st_plat_data *get_platform_data(struct device *dev);
+
 /**
  * st_get_plat_device -
  *     function which returns the reference to the platform device
@@ -462,7 +466,12 @@ long st_kim_start(void *kim_data)
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
 
        pr_info(" %s", __func__);
-       pdata = kim_gdata->kim_pdev->dev.platform_data;
+       if (kim_gdata->kim_pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = kim_gdata->kim_pdev->dev.platform_data;
+       }
 
        do {
                /* platform specific enabling code here */
@@ -522,12 +531,18 @@ long st_kim_stop(void *kim_data)
 {
        long err = 0;
        struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
-       struct ti_st_plat_data  *pdata =
-               kim_gdata->kim_pdev->dev.platform_data;
+       struct ti_st_plat_data  *pdata;
        struct tty_struct       *tty = kim_gdata->core_data->tty;
 
        reinit_completion(&kim_gdata->ldisc_installed);
 
+       if (kim_gdata->kim_pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else
+               pdata = kim_gdata->kim_pdev->dev.platform_data;
+
+
        if (tty) {      /* can be called before ldisc is installed */
                /* Flush any pending characters in the driver and discipline. */
                tty_ldisc_flush(tty);
@@ -676,12 +691,16 @@ void st_kim_ref(struct st_data_s **core_data, int id)
        struct kim_data_s       *kim_gdata;
        /* get kim_gdata reference from platform device */
        pdev = st_get_plat_device(id);
-       if (!pdev) {
-               *core_data = NULL;
-               return;
-       }
+       if (!pdev)
+               goto err;
        kim_gdata = platform_get_drvdata(pdev);
+       if (!kim_gdata)
+               goto err;
+
        *core_data = kim_gdata->core_data;
+       return;
+err:
+       *core_data = NULL;
 }
 
 static int kim_version_open(struct inode *i, struct file *f)
@@ -715,13 +734,53 @@ static const struct file_operations list_debugfs_fops = {
  * board-*.c file
  */
 
+static const struct of_device_id kim_of_match[] = {
+{
+       .compatible = "kim",
+       },
+       {}
+};
+MODULE_DEVICE_TABLE(of, kim_of_match);
+
+static struct ti_st_plat_data *get_platform_data(struct device *dev)
+{
+       struct device_node *np = dev->of_node;
+       const u32 *dt_property;
+       int len;
+
+       dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
+
+       if (!dt_pdata)
+               pr_err("Can't allocate device_tree platform data\n");
+
+       dt_property = of_get_property(np, "dev_name", &len);
+       if (dt_property)
+               memcpy(&dt_pdata->dev_name, dt_property, len);
+       of_property_read_u32(np, "nshutdown_gpio",
+                            (u32 *)&dt_pdata->nshutdown_gpio);
+       of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
+       of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
+
+       return dt_pdata;
+}
+
 static struct dentry *kim_debugfs_dir;
 static int kim_probe(struct platform_device *pdev)
 {
        struct kim_data_s       *kim_gdata;
-       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
+       struct ti_st_plat_data  *pdata;
        int err;
 
+       if (pdev->dev.of_node)
+               pdata = get_platform_data(&pdev->dev);
+       else
+               pdata = pdev->dev.platform_data;
+
+       if (pdata == NULL) {
+               dev_err(&pdev->dev, "Platform Data is missing\n");
+               return -ENXIO;
+       }
+
        if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
                /* multiple devices could exist */
                st_kim_devices[pdev->id] = pdev;
@@ -781,8 +840,7 @@ static int kim_probe(struct platform_device *pdev)
        kim_debugfs_dir = debugfs_create_dir("ti-st", NULL);
        if (!kim_debugfs_dir) {
                pr_err(" debugfs entries creation failed ");
-               err = -EIO;
-               goto err_debugfs_dir;
+               return 0;
        }
 
        debugfs_create_file("version", S_IRUGO, kim_debugfs_dir,
@@ -791,9 +849,6 @@ static int kim_probe(struct platform_device *pdev)
                                kim_gdata, &list_debugfs_fops);
        return 0;
 
-err_debugfs_dir:
-       sysfs_remove_group(&pdev->dev.kobj, &uim_attr_grp);
-
 err_sysfs_group:
        st_core_exit(kim_gdata->core_data);
 
@@ -806,9 +861,16 @@ err_core_init:
 static int kim_remove(struct platform_device *pdev)
 {
        /* free the GPIOs requested */
-       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
+       struct ti_st_plat_data  *pdata;
        struct kim_data_s       *kim_gdata;
 
+       if (pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = pdev->dev.platform_data;
+       }
+
        kim_gdata = platform_get_drvdata(pdev);
 
        /* Free the Bluetooth/FM/GPIO
@@ -826,27 +888,44 @@ static int kim_remove(struct platform_device *pdev)
 
        kfree(kim_gdata);
        kim_gdata = NULL;
+       kfree(dt_pdata);
+       dt_pdata = NULL;
+
        return 0;
 }
 
 static int kim_suspend(struct platform_device *pdev, pm_message_t state)
 {
-       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
+       struct ti_st_plat_data  *pdata;
+
+       if (pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = pdev->dev.platform_data;
+       }
 
        if (pdata->suspend)
                return pdata->suspend(pdev, state);
 
-       return -EOPNOTSUPP;
+       return 0;
 }
 
 static int kim_resume(struct platform_device *pdev)
 {
-       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
+       struct ti_st_plat_data  *pdata;
+
+       if (pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = pdev->dev.platform_data;
+       }
 
        if (pdata->resume)
                return pdata->resume(pdev);
 
-       return -EOPNOTSUPP;
+       return 0;
 }
 
 /**********************************************************************/
@@ -858,6 +937,8 @@ static struct platform_driver kim_platform_driver = {
        .resume = kim_resume,
        .driver = {
                .name = "kim",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(kim_of_match),
        },
 };
 
index 93b4d67cc4a3a6bc30197acf709d4f73faaad070..518e1b7f2f95a58c2611cb20640de7228e8a8504 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/ti_wilink_st.h>
 
 /**********************************************************************/
+
 /* internal functions */
 static void send_ll_cmd(struct st_data_s *st_data,
        unsigned char cmd)
@@ -53,7 +54,13 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
 
        /* communicate to platform about chip asleep */
        kim_data = st_data->kim_data;
-       pdata = kim_data->kim_pdev->dev.platform_data;
+       if (kim_data->kim_pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = kim_data->kim_pdev->dev.platform_data;
+       }
+
        if (pdata->chip_asleep)
                pdata->chip_asleep(NULL);
 }
@@ -86,7 +93,13 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
 
        /* communicate to platform about chip wakeup */
        kim_data = st_data->kim_data;
-       pdata = kim_data->kim_pdev->dev.platform_data;
+       if (kim_data->kim_pdev->dev.of_node) {
+               pr_debug("use device tree data");
+               pdata = dt_pdata;
+       } else {
+               pdata = kim_data->kim_pdev->dev.platform_data;
+       }
+
        if (pdata->chip_awake)
                pdata->chip_awake(NULL);
 }
index 910e90bf16c6f2a8a0bb685a688d498d89067b05..8843a678f2008d32f250a4fb694b30886c2dfaef 100644 (file)
@@ -69,7 +69,8 @@ config YENTA
        tristate "CardBus yenta-compatible bridge support"
        depends on PCI
        select CARDBUS if !EXPERT
-       select PCCARD_NONSTATIC if PCMCIA != n
+       select PCCARD_NONSTATIC if PCMCIA != n && ISA
+       select PCCARD_PCI if PCMCIA !=n && !ISA
        ---help---
          This option enables support for CardBus host bridges.  Virtually
          all modern PCMCIA bridges are CardBus compatible.  A "bridge" is
@@ -109,7 +110,8 @@ config YENTA_TOSHIBA
 config PD6729
        tristate "Cirrus PD6729 compatible bridge support"
        depends on PCMCIA && PCI
-       select PCCARD_NONSTATIC
+       select PCCARD_NONSTATIC if PCMCIA != n && ISA
+       select PCCARD_PCI if PCMCIA !=n && !ISA
        help
          This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge
          device, found in some older laptops and PCMCIA card readers.
@@ -117,7 +119,8 @@ config PD6729
 config I82092
        tristate "i82092 compatible bridge support"
        depends on PCMCIA && PCI
-       select PCCARD_NONSTATIC
+       select PCCARD_NONSTATIC if PCMCIA != n && ISA
+       select PCCARD_PCI if PCMCIA !=n && !ISA
        help
          This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
          found in some older laptops and more commonly in evaluation boards for the
@@ -287,6 +290,9 @@ config ELECTRA_CF
          Say Y here to support the CompactFlash controller on the
          PA Semi Electra eval board.
 
+config PCCARD_PCI
+       bool
+
 config PCCARD_NONSTATIC
        bool
 
index 27e94b30cf9625b8da99d67b74308651b8077dc6..f1a7ca04d89e9b743fc3f82e545c52521fedef81 100644 (file)
@@ -12,6 +12,7 @@ obj-$(CONFIG_PCMCIA)                          += pcmcia.o
 pcmcia_rsrc-y                                  += rsrc_mgr.o
 pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC)         += rsrc_nonstatic.o
 pcmcia_rsrc-$(CONFIG_PCCARD_IODYN)             += rsrc_iodyn.o
+pcmcia_rsrc-$(CONFIG_PCCARD_PCI)               += rsrc_pci.o
 obj-$(CONFIG_PCCARD)                           += pcmcia_rsrc.o
 
 
index 884a984216febe247dee1bdcad69d47d1cd1adf2..64d0515b76bd5ade5136b46a566f78d9c23ba831 100644 (file)
@@ -168,9 +168,12 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
        } else {
                u_int inc = 1, card_offset, flags;
 
-               if (addr > CISTPL_MAX_CIS_SIZE)
+               if (addr > CISTPL_MAX_CIS_SIZE) {
                        dev_dbg(&s->dev,
                                "attempt to read CIS mem at addr %#x", addr);
+                       memset(ptr, 0xff, len);
+                       return -1;
+               }
 
                flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
                if (attr) {
@@ -1383,7 +1386,7 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
        if (!s)
                return -EINVAL;
 
-       if (s->functions) {
+       if (s->functions || !(s->state & SOCKET_PRESENT)) {
                WARN_ON(1);
                return -EINVAL;
        }
@@ -1448,10 +1451,26 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
 done:
        /* invalidate CIS cache on failure */
        if (!dev_ok || !ident_ok || !count) {
-               mutex_lock(&s->ops_mutex);
-               destroy_cis_cache(s);
-               mutex_unlock(&s->ops_mutex);
-               ret = -EIO;
+#if defined(CONFIG_MTD_PCMCIA_ANONYMOUS)
+               /* Set up as an anonymous card. If we don't have anonymous
+                  memory support then just error the card as there is no
+                  point trying to second guess.
+
+                  Note: some cards have just a device entry, it may be
+                  worth extending support to cover these in future */
+               if (!dev_ok || !ident_ok) {
+                       dev_info(&s->dev, "no CIS, assuming an anonymous memory card.\n");
+                       pcmcia_replace_cis(s, "\xFF", 1);
+                       count = 1;
+                       ret = 0;
+               } else
+#endif
+               {
+                       mutex_lock(&s->ops_mutex);
+                       destroy_cis_cache(s);
+                       mutex_unlock(&s->ops_mutex);
+                       ret = -EIO;
+               }
        }
 
        if (info)
index 7f1953f78b12b906421a4c8f130d4094e49c6d74..e86cd6b31773ba7fdc9d9b3662bc4fc97b0c4d00 100644 (file)
@@ -80,9 +80,9 @@ struct pccard_resource_ops {
  * Stuff internal to module "pcmcia_rsrc":
  */
 extern int static_init(struct pcmcia_socket *s);
-extern struct resource *pcmcia_make_resource(unsigned long start,
-                                       unsigned long end,
-                                       int flags, const char *name);
+extern struct resource *pcmcia_make_resource(resource_size_t start,
+                                       resource_size_t end,
+                                       unsigned long flags, const char *name);
 
 /*
  * Stuff internal to module "pcmcia_core":
index 757119b87146cbc5219527c8e7c584795c34174e..d3baf0bfca9f0692f9a2789465f727c911e0f7f2 100644 (file)
@@ -667,6 +667,9 @@ static void pcmcia_requery(struct pcmcia_socket *s)
 {
        int has_pfc;
 
+       if (!(s->state & SOCKET_PRESENT))
+               return;
+
        if (s->functions == 0) {
                pcmcia_card_add(s);
                return;
index aa628ed0e9f48178ca3ac9b1fbba39a370877228..df2cb70aef5b6791ad5b9989af76805f64346722 100644 (file)
@@ -30,8 +30,9 @@ int static_init(struct pcmcia_socket *s)
        return 0;
 }
 
-struct resource *pcmcia_make_resource(unsigned long start, unsigned long end,
-                               int flags, const char *name)
+struct resource *pcmcia_make_resource(resource_size_t start,
+                                       resource_size_t end,
+                                       unsigned long flags, const char *name)
 {
        struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
diff --git a/drivers/pcmcia/rsrc_pci.c b/drivers/pcmcia/rsrc_pci.c
new file mode 100644 (file)
index 0000000..21c3683
--- /dev/null
@@ -0,0 +1,173 @@
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+#include <pcmcia/ss.h>
+#include <pcmcia/cistpl.h>
+#include "cs_internal.h"
+
+
+struct pcmcia_align_data {
+       unsigned long   mask;
+       unsigned long   offset;
+};
+
+static resource_size_t pcmcia_align(void *align_data,
+                               const struct resource *res,
+                               resource_size_t size, resource_size_t align)
+{
+       struct pcmcia_align_data *data = align_data;
+       resource_size_t start;
+
+       start = (res->start & ~data->mask) + data->offset;
+       if (start < res->start)
+               start += data->mask + 1;
+       return start;
+}
+
+static struct resource *find_io_region(struct pcmcia_socket *s,
+                                       unsigned long base, int num,
+                                       unsigned long align)
+{
+       struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
+                                               dev_name(&s->dev));
+       struct pcmcia_align_data data;
+       int ret;
+
+       data.mask = align - 1;
+       data.offset = base & data.mask;
+
+       ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
+                                            base, 0, pcmcia_align, &data);
+       if (ret != 0) {
+               kfree(res);
+               res = NULL;
+       }
+       return res;
+}
+
+static int res_pci_find_io(struct pcmcia_socket *s, unsigned int attr,
+                       unsigned int *base, unsigned int num,
+                       unsigned int align, struct resource **parent)
+{
+       int i, ret = 0;
+
+       /* Check for an already-allocated window that must conflict with
+        * what was asked for.  It is a hack because it does not catch all
+        * potential conflicts, just the most obvious ones.
+        */
+       for (i = 0; i < MAX_IO_WIN; i++) {
+               if (!s->io[i].res)
+                       continue;
+
+               if (!*base)
+                       continue;
+
+               if ((s->io[i].res->start & (align-1)) == *base)
+                       return -EBUSY;
+       }
+
+       for (i = 0; i < MAX_IO_WIN; i++) {
+               struct resource *res = s->io[i].res;
+               unsigned int try;
+
+               if (res && (res->flags & IORESOURCE_BITS) !=
+                       (attr & IORESOURCE_BITS))
+                       continue;
+
+               if (!res) {
+                       if (align == 0)
+                               align = 0x10000;
+
+                       res = s->io[i].res = find_io_region(s, *base, num,
+                                                               align);
+                       if (!res)
+                               return -EINVAL;
+
+                       *base = res->start;
+                       s->io[i].res->flags =
+                               ((res->flags & ~IORESOURCE_BITS) |
+                                       (attr & IORESOURCE_BITS));
+                       s->io[i].InUse = num;
+                       *parent = res;
+                       return 0;
+               }
+
+               /* Try to extend top of window */
+               try = res->end + 1;
+               if ((*base == 0) || (*base == try)) {
+                       ret = adjust_resource(s->io[i].res, res->start,
+                                             resource_size(res) + num);
+                       if (ret)
+                               continue;
+                       *base = try;
+                       s->io[i].InUse += num;
+                       *parent = res;
+                       return 0;
+               }
+
+               /* Try to extend bottom of window */
+               try = res->start - num;
+               if ((*base == 0) || (*base == try)) {
+                       ret = adjust_resource(s->io[i].res,
+                                             res->start - num,
+                                             resource_size(res) + num);
+                       if (ret)
+                               continue;
+                       *base = try;
+                       s->io[i].InUse += num;
+                       *parent = res;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static struct resource *res_pci_find_mem(u_long base, u_long num,
+               u_long align, int low, struct pcmcia_socket *s)
+{
+       struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
+                                               dev_name(&s->dev));
+       struct pcmcia_align_data data;
+       unsigned long min;
+       int ret;
+
+       if (align < 0x20000)
+               align = 0x20000;
+       data.mask = align - 1;
+       data.offset = base & data.mask;
+
+       min = 0;
+       if (!low)
+               min = 0x100000UL;
+
+       ret = pci_bus_alloc_resource(s->cb_dev->bus,
+                       res, num, 1, min, 0,
+                       pcmcia_align, &data);
+
+       if (ret != 0) {
+               kfree(res);
+               res = NULL;
+       }
+       return res;
+}
+
+
+static int res_pci_init(struct pcmcia_socket *s)
+{
+       if (!s->cb_dev || (!s->features & SS_CAP_PAGE_REGS)) {
+               dev_err(&s->dev, "not supported by res_pci\n");
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+struct pccard_resource_ops pccard_nonstatic_ops = {
+       .validate_mem = NULL,
+       .find_io = res_pci_find_io,
+       .find_mem = res_pci_find_mem,
+       .init = res_pci_init,
+       .exit = NULL,
+};
+EXPORT_SYMBOL(pccard_nonstatic_ops);
index 5a90914d856d21648027de61e9f9123d9ead9a6d..8a15c323c030f566a03ae56502b0fe331fd09d04 100644 (file)
@@ -104,6 +104,26 @@ config UIO_NETX
          To compile this driver as a module, choose M here; the module
          will be called uio_netx.
 
+config UIO_FSL_ELBC_GPCM
+       tristate "eLBC/GPCM driver"
+       depends on FSL_LBC
+       help
+         Generic driver for accessing a peripheral connected to an eLBC port
+         that is running in GPCM mode. GPCM is an interface for simple lower
+         performance memories and memory-mapped devices. For devices using
+         FCM or UPM eLBC modes, other device-specific drivers are available.
+
+config UIO_FSL_ELBC_GPCM_NETX5152
+       bool "eLBC/GPCM netX 51/52 support"
+       depends on UIO_FSL_ELBC_GPCM
+       help
+         This will add support for netX 51/52 devices connected via eLBC/GPCM.
+         In particular, it implements interrupt handling. This can be used
+         together with the userspace netX stack from Hilscher.
+
+         Information about this hardware can be found at:
+         http://www.hilscher.com/netx
+
 config UIO_PRUSS
        tristate "Texas Instruments PRUSS driver"
        depends on ARCH_DAVINCI_DA850
index d3218bde3aeb658948a8675ac62f0ebbbfcaec9b..8560dad52d0f2934d4c67b7aac8d96e929de458a 100644 (file)
@@ -8,3 +8,4 @@ obj-$(CONFIG_UIO_PCI_GENERIC)   += uio_pci_generic.o
 obj-$(CONFIG_UIO_NETX) += uio_netx.o
 obj-$(CONFIG_UIO_PRUSS)         += uio_pruss.o
 obj-$(CONFIG_UIO_MF624)         += uio_mf624.o
+obj-$(CONFIG_UIO_FSL_ELBC_GPCM)        += uio_fsl_elbc_gpcm.o
diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c
new file mode 100644 (file)
index 0000000..b6cac91
--- /dev/null
@@ -0,0 +1,499 @@
+/* uio_fsl_elbc_gpcm: UIO driver for eLBC/GPCM peripherals
+
+   Copyright (C) 2014 Linutronix GmbH
+     Author: John Ogness <john.ogness@linutronix.de>
+
+   This driver provides UIO access to memory of a peripheral connected
+   to the Freescale enhanced local bus controller (eLBC) interface
+   using the general purpose chip-select mode (GPCM).
+
+   Here is an example of the device tree entries:
+
+       localbus@ffe05000 {
+               ranges = <0x2 0x0 0x0 0xff810000 0x10000>;
+
+               dpm@2,0 {
+                       compatible = "fsl,elbc-gpcm-uio";
+                       reg = <0x2 0x0 0x10000>;
+                       elbc-gpcm-br = <0xff810800>;
+                       elbc-gpcm-or = <0xffff09f7>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <4 1>;
+                       device_type = "netx5152";
+                       uio_name = "netx_custom";
+                       netx5152,init-win0-offset = <0x0>;
+               };
+       };
+
+   Only the entries reg (to identify bank) and elbc-gpcm-* (initial BR/OR
+   values) are required. The entries interrupt*, device_type, and uio_name
+   are optional (as well as any type-specific options such as
+   netx5152,init-win0-offset). As long as no interrupt handler is needed,
+   this driver can be used without any type-specific implementation.
+
+   The netx5152 type has been tested to work with the netX 51/52 hardware
+   from Hilscher using the Hilscher userspace netX stack.
+
+   The netx5152 type should serve as a model to add new type-specific
+   devices as needed.
+*/
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include <asm/fsl_lbc.h>
+
+#define MAX_BANKS 8
+
+struct fsl_elbc_gpcm {
+       struct device *dev;
+       struct fsl_lbc_regs __iomem *lbc;
+       u32 bank;
+       const char *name;
+
+       void (*init)(struct uio_info *info);
+       void (*shutdown)(struct uio_info *info, bool init_err);
+       irqreturn_t (*irq_handler)(int irq, struct uio_info *info);
+};
+
+static ssize_t reg_show(struct device *dev, struct device_attribute *attr,
+                       char *buf);
+static ssize_t reg_store(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count);
+
+DEVICE_ATTR(reg_br, S_IRUGO|S_IWUSR|S_IWGRP, reg_show, reg_store);
+DEVICE_ATTR(reg_or, S_IRUGO|S_IWUSR|S_IWGRP, reg_show, reg_store);
+
+static ssize_t reg_show(struct device *dev, struct device_attribute *attr,
+                       char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct uio_info *info = platform_get_drvdata(pdev);
+       struct fsl_elbc_gpcm *priv = info->priv;
+       struct fsl_lbc_bank *bank = &priv->lbc->bank[priv->bank];
+
+       if (attr == &dev_attr_reg_br) {
+               return scnprintf(buf, PAGE_SIZE, "0x%08x\n",
+                                in_be32(&bank->br));
+
+       } else if (attr == &dev_attr_reg_or) {
+               return scnprintf(buf, PAGE_SIZE, "0x%08x\n",
+                                in_be32(&bank->or));
+       }
+
+       return 0;
+}
+
+static ssize_t reg_store(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct uio_info *info = platform_get_drvdata(pdev);
+       struct fsl_elbc_gpcm *priv = info->priv;
+       struct fsl_lbc_bank *bank = &priv->lbc->bank[priv->bank];
+       unsigned long val;
+       u32 reg_br_cur;
+       u32 reg_or_cur;
+       u32 reg_new;
+
+       /* parse use input */
+       if (kstrtoul(buf, 0, &val) != 0)
+               return -EINVAL;
+       reg_new = (u32)val;
+
+       /* read current values */
+       reg_br_cur = in_be32(&bank->br);
+       reg_or_cur = in_be32(&bank->or);
+
+       if (attr == &dev_attr_reg_br) {
+               /* not allowed to change effective base address */
+               if ((reg_br_cur & reg_or_cur & BR_BA) !=
+                   (reg_new & reg_or_cur & BR_BA)) {
+                       return -EINVAL;
+               }
+
+               /* not allowed to change mode */
+               if ((reg_new & BR_MSEL) != BR_MS_GPCM)
+                       return -EINVAL;
+
+               /* write new value (force valid) */
+               out_be32(&bank->br, reg_new | BR_V);
+
+       } else if (attr == &dev_attr_reg_or) {
+               /* not allowed to change access mask */
+               if ((reg_or_cur & OR_GPCM_AM) != (reg_new & OR_GPCM_AM))
+                       return -EINVAL;
+
+               /* write new value */
+               out_be32(&bank->or, reg_new);
+
+       } else {
+               return -EINVAL;
+       }
+
+       return count;
+}
+
+#ifdef CONFIG_UIO_FSL_ELBC_GPCM_NETX5152
+#define DPM_HOST_WIN0_OFFSET   0xff00
+#define DPM_HOST_INT_STAT0     0xe0
+#define DPM_HOST_INT_EN0       0xf0
+#define DPM_HOST_INT_MASK      0xe600ffff
+#define DPM_HOST_INT_GLOBAL_EN 0x80000000
+
+static irqreturn_t netx5152_irq_handler(int irq, struct uio_info *info)
+{
+       void __iomem *reg_int_en = info->mem[0].internal_addr +
+                                       DPM_HOST_WIN0_OFFSET +
+                                       DPM_HOST_INT_EN0;
+       void __iomem *reg_int_stat = info->mem[0].internal_addr +
+                                       DPM_HOST_WIN0_OFFSET +
+                                       DPM_HOST_INT_STAT0;
+
+       /* check if an interrupt is enabled and active */
+       if ((ioread32(reg_int_en) & ioread32(reg_int_stat) &
+            DPM_HOST_INT_MASK) == 0) {
+               return IRQ_NONE;
+       }
+
+       /* disable interrupts */
+       iowrite32(ioread32(reg_int_en) & ~DPM_HOST_INT_GLOBAL_EN, reg_int_en);
+
+       return IRQ_HANDLED;
+}
+
+static void netx5152_init(struct uio_info *info)
+{
+       unsigned long win0_offset = DPM_HOST_WIN0_OFFSET;
+       struct fsl_elbc_gpcm *priv = info->priv;
+       const void *prop;
+
+       /* get an optional initial win0 offset */
+       prop = of_get_property(priv->dev->of_node,
+                              "netx5152,init-win0-offset", NULL);
+       if (prop)
+               win0_offset = of_read_ulong(prop, 1);
+
+       /* disable interrupts */
+       iowrite32(0, info->mem[0].internal_addr + win0_offset +
+                    DPM_HOST_INT_EN0);
+}
+
+static void netx5152_shutdown(struct uio_info *info, bool init_err)
+{
+       if (init_err)
+               return;
+
+       /* disable interrupts */
+       iowrite32(0, info->mem[0].internal_addr + DPM_HOST_WIN0_OFFSET +
+                    DPM_HOST_INT_EN0);
+}
+#endif
+
+static void setup_periph(struct fsl_elbc_gpcm *priv,
+                                  const char *type)
+{
+#ifdef CONFIG_UIO_FSL_ELBC_GPCM_NETX5152
+       if (strcmp(type, "netx5152") == 0) {
+               priv->irq_handler = netx5152_irq_handler;
+               priv->init = netx5152_init;
+               priv->shutdown = netx5152_shutdown;
+               priv->name = "netX 51/52";
+               return;
+       }
+#endif
+}
+
+static int check_of_data(struct fsl_elbc_gpcm *priv,
+                                  struct resource *res,
+                                  u32 reg_br, u32 reg_or)
+{
+       /* check specified bank */
+       if (priv->bank >= MAX_BANKS) {
+               dev_err(priv->dev, "invalid bank\n");
+               return -ENODEV;
+       }
+
+       /* check specified mode (BR_MS_GPCM is 0) */
+       if ((reg_br & BR_MSEL) != BR_MS_GPCM) {
+               dev_err(priv->dev, "unsupported mode\n");
+               return -ENODEV;
+       }
+
+       /* check specified mask vs. resource size */
+       if ((~(reg_or & OR_GPCM_AM) + 1) != resource_size(res)) {
+               dev_err(priv->dev, "address mask / size mismatch\n");
+               return -ENODEV;
+       }
+
+       /* check specified address */
+       if ((reg_br & reg_or & BR_BA) != fsl_lbc_addr(res->start)) {
+               dev_err(priv->dev, "base address mismatch\n");
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+static int get_of_data(struct fsl_elbc_gpcm *priv, struct device_node *node,
+                      struct resource *res, u32 *reg_br,
+                      u32 *reg_or, unsigned int *irq, char **name)
+{
+       const char *dt_name;
+       const char *type;
+       int ret;
+
+       /* get the memory resource */
+       ret = of_address_to_resource(node, 0, res);
+       if (ret) {
+               dev_err(priv->dev, "failed to get resource\n");
+               return ret;
+       }
+
+       /* get the bank number */
+       ret = of_property_read_u32(node, "reg", &priv->bank);
+       if (ret) {
+               dev_err(priv->dev, "failed to get bank number\n");
+               return ret;
+       }
+
+       /* get BR value to set */
+       ret = of_property_read_u32(node, "elbc-gpcm-br", reg_br);
+       if (ret) {
+               dev_err(priv->dev, "missing elbc-gpcm-br value\n");
+               return ret;
+       }
+
+       /* get OR value to set */
+       ret = of_property_read_u32(node, "elbc-gpcm-or", reg_or);
+       if (ret) {
+               dev_err(priv->dev, "missing elbc-gpcm-or value\n");
+               return ret;
+       }
+
+       /* get optional peripheral type */
+       priv->name = "generic";
+       if (of_property_read_string(node, "device_type", &type) == 0)
+               setup_periph(priv, type);
+
+       /* get optional irq value */
+       *irq = irq_of_parse_and_map(node, 0);
+
+       /* sanity check device tree data */
+       ret = check_of_data(priv, res, *reg_br, *reg_or);
+       if (ret)
+               return ret;
+
+       /* get optional uio name */
+       if (of_property_read_string(node, "uio_name", &dt_name) != 0)
+               dt_name = "eLBC_GPCM";
+       *name = kstrdup(dt_name, GFP_KERNEL);
+       if (!*name)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev)
+{
+       struct device_node *node = pdev->dev.of_node;
+       struct fsl_elbc_gpcm *priv;
+       struct uio_info *info;
+       char *uio_name = NULL;
+       struct resource res;
+       unsigned int irq;
+       u32 reg_br_cur;
+       u32 reg_or_cur;
+       u32 reg_br_new;
+       u32 reg_or_new;
+       int ret;
+
+       if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs)
+               return -ENODEV;
+
+       /* allocate private data */
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       priv->dev = &pdev->dev;
+       priv->lbc = fsl_lbc_ctrl_dev->regs;
+
+       /* get device tree data */
+       ret = get_of_data(priv, node, &res, &reg_br_new, &reg_or_new,
+                         &irq, &uio_name);
+       if (ret)
+               goto out_err0;
+
+       /* allocate UIO structure */
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info) {
+               ret = -ENOMEM;
+               goto out_err0;
+       }
+
+       /* get current BR/OR values */
+       reg_br_cur = in_be32(&priv->lbc->bank[priv->bank].br);
+       reg_or_cur = in_be32(&priv->lbc->bank[priv->bank].or);
+
+       /* if bank already configured, make sure it matches */
+       if ((reg_br_cur & BR_V)) {
+               if ((reg_br_cur & BR_MSEL) != BR_MS_GPCM ||
+                   (reg_br_cur & reg_or_cur & BR_BA)
+                    != fsl_lbc_addr(res.start)) {
+                       dev_err(priv->dev,
+                               "bank in use by another peripheral\n");
+                       ret = -ENODEV;
+                       goto out_err1;
+               }
+
+               /* warn if behavior settings changing */
+               if ((reg_br_cur & ~(BR_BA | BR_V)) !=
+                   (reg_br_new & ~(BR_BA | BR_V))) {
+                       dev_warn(priv->dev,
+                                "modifying BR settings: 0x%08x -> 0x%08x",
+                                reg_br_cur, reg_br_new);
+               }
+               if ((reg_or_cur & ~OR_GPCM_AM) != (reg_or_new & ~OR_GPCM_AM)) {
+                       dev_warn(priv->dev,
+                                "modifying OR settings: 0x%08x -> 0x%08x",
+                                reg_or_cur, reg_or_new);
+               }
+       }
+
+       /* configure the bank (force base address and GPCM) */
+       reg_br_new &= ~(BR_BA | BR_MSEL);
+       reg_br_new |= fsl_lbc_addr(res.start) | BR_MS_GPCM | BR_V;
+       out_be32(&priv->lbc->bank[priv->bank].or, reg_or_new);
+       out_be32(&priv->lbc->bank[priv->bank].br, reg_br_new);
+
+       /* map the memory resource */
+       info->mem[0].internal_addr = ioremap(res.start, resource_size(&res));
+       if (!info->mem[0].internal_addr) {
+               dev_err(priv->dev, "failed to map chip region\n");
+               ret = -ENODEV;
+               goto out_err1;
+       }
+
+       /* set all UIO data */
+       if (node->name)
+               info->mem[0].name = kstrdup(node->name, GFP_KERNEL);
+       info->mem[0].addr = res.start;
+       info->mem[0].size = resource_size(&res);
+       info->mem[0].memtype = UIO_MEM_PHYS;
+       info->priv = priv;
+       info->name = uio_name;
+       info->version = "0.0.1";
+       if (irq != NO_IRQ) {
+               if (priv->irq_handler) {
+                       info->irq = irq;
+                       info->irq_flags = IRQF_SHARED;
+                       info->handler = priv->irq_handler;
+               } else {
+                       irq = NO_IRQ;
+                       dev_warn(priv->dev, "ignoring irq, no handler\n");
+               }
+       }
+
+       if (priv->init)
+               priv->init(info);
+
+       /* register UIO device */
+       if (uio_register_device(priv->dev, info) != 0) {
+               dev_err(priv->dev, "UIO registration failed\n");
+               ret = -ENODEV;
+               goto out_err2;
+       }
+
+       /* store private data */
+       platform_set_drvdata(pdev, info);
+
+       /* create sysfs files */
+       ret = device_create_file(priv->dev, &dev_attr_reg_br);
+       if (ret)
+               goto out_err3;
+       ret = device_create_file(priv->dev, &dev_attr_reg_or);
+       if (ret)
+               goto out_err4;
+
+       dev_info(priv->dev,
+                "eLBC/GPCM device (%s) at 0x%llx, bank %d, irq=%d\n",
+                priv->name, (unsigned long long)res.start, priv->bank,
+                irq != NO_IRQ ? irq : -1);
+
+       return 0;
+out_err4:
+       device_remove_file(priv->dev, &dev_attr_reg_br);
+out_err3:
+       platform_set_drvdata(pdev, NULL);
+       uio_unregister_device(info);
+out_err2:
+       if (priv->shutdown)
+               priv->shutdown(info, true);
+       iounmap(info->mem[0].internal_addr);
+out_err1:
+       kfree(info->mem[0].name);
+       kfree(info);
+out_err0:
+       kfree(uio_name);
+       kfree(priv);
+       return ret;
+}
+
+static int uio_fsl_elbc_gpcm_remove(struct platform_device *pdev)
+{
+       struct uio_info *info = platform_get_drvdata(pdev);
+       struct fsl_elbc_gpcm *priv = info->priv;
+
+       device_remove_file(priv->dev, &dev_attr_reg_or);
+       device_remove_file(priv->dev, &dev_attr_reg_br);
+       platform_set_drvdata(pdev, NULL);
+       uio_unregister_device(info);
+       if (priv->shutdown)
+               priv->shutdown(info, false);
+       iounmap(info->mem[0].internal_addr);
+       kfree(info->mem[0].name);
+       kfree(info->name);
+       kfree(info);
+       kfree(priv);
+
+       return 0;
+
+}
+
+static const struct of_device_id uio_fsl_elbc_gpcm_match[] = {
+       { .compatible = "fsl,elbc-gpcm-uio", },
+       {}
+};
+
+static struct platform_driver uio_fsl_elbc_gpcm_driver = {
+       .driver = {
+               .name = "fsl,elbc-gpcm-uio",
+               .owner = THIS_MODULE,
+               .of_match_table = uio_fsl_elbc_gpcm_match,
+       },
+       .probe = uio_fsl_elbc_gpcm_probe,
+       .remove = uio_fsl_elbc_gpcm_remove,
+};
+
+static int __init uio_fsl_elbc_gpcm_init(void)
+{
+       return platform_driver_register(&uio_fsl_elbc_gpcm_driver);
+}
+
+static void __exit uio_fsl_elbc_gpcm_exit(void)
+{
+       platform_driver_unregister(&uio_fsl_elbc_gpcm_driver);
+}
+
+module_init(uio_fsl_elbc_gpcm_init);
+module_exit(uio_fsl_elbc_gpcm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>");
+MODULE_DESCRIPTION("Freescale Enhanced Local Bus Controller GPCM driver");
index 077ae12269ce3a99fcc35ee099e6453a102484de..d0b508b68f3c3e4969bf46036510255d01ae7dd9 100644 (file)
@@ -91,7 +91,8 @@ static int probe(struct pci_dev *pdev,
        gdev->info.handler = irqhandler;
        gdev->pdev = pdev;
 
-       if (uio_register_device(&pdev->dev, &gdev->info))
+       err = uio_register_device(&pdev->dev, &gdev->info);
+       if (err)
                goto err_register;
        pci_set_drvdata(pdev, gdev);
 
index 7516030037a16e18082908b41af76a7308c85cb9..d95fb848dd03368c26c4d0b59020e5ac02a0b893 100644 (file)
@@ -502,7 +502,7 @@ int vme_master_get(struct vme_resource *resource, int *enabled,
        image = list_entry(resource->entry, struct vme_master_resource, list);
 
        if (bridge->master_get == NULL) {
-               printk(KERN_WARNING "vme_master_set not supported\n");
+               printk(KERN_WARNING "%s not supported\n", __func__);
                return -EINVAL;
        }
 
index 5d3c54311f7a30f16fe37e9c5dc8edd2d48100eb..cd6d4c384ca316bb5861dd304144f136f1df8ddc 100644 (file)
@@ -179,15 +179,6 @@ struct coresight_device {
 #define sink_ops(csdev)                csdev->ops->sink_ops
 #define link_ops(csdev)                csdev->ops->link_ops
 
-#define CORESIGHT_DEBUGFS_ENTRY(__name, __entry_name,                  \
-                                __mode, __get, __set, __fmt)           \
-DEFINE_SIMPLE_ATTRIBUTE(__name ## _ops, __get, __set, __fmt);          \
-static const struct coresight_ops_entry __name ## _entry = {           \
-       .name = __entry_name,                                           \
-       .mode = __mode,                                                 \
-       .ops  = &__name ## _ops                                         \
-}
-
 /**
  * struct coresight_ops_sink - basic operations for a sink
  * Operations available for sinks
@@ -239,10 +230,6 @@ extern void coresight_disable(struct coresight_device *csdev);
 extern int coresight_is_bit_set(u32 val, int position, int value);
 extern int coresight_timeout(void __iomem *addr, u32 offset,
                             int position, int value);
-#ifdef CONFIG_OF
-extern struct coresight_platform_data *of_get_coresight_platform_data(
-                               struct device *dev, struct device_node *node);
-#endif
 #else
 static inline struct coresight_device *
 coresight_register(struct coresight_desc *desc) { return NULL; }
@@ -254,10 +241,14 @@ static inline int coresight_is_bit_set(u32 val, int position, int value)
                                         { return 0; }
 static inline int coresight_timeout(void __iomem *addr, u32 offset,
                                     int position, int value) { return 1; }
+#endif
+
 #ifdef CONFIG_OF
+extern struct coresight_platform_data *of_get_coresight_platform_data(
+                               struct device *dev, struct device_node *node);
+#else
 static inline struct coresight_platform_data *of_get_coresight_platform_data(
        struct device *dev, struct device_node *node) { return NULL; }
 #endif
-#endif
 
 #endif
index 164aad1f9f12172a3969035f9d484d501758157d..0819d36a3a742f63670f4ae953c5a3a66a3fa9d0 100644 (file)
@@ -25,8 +25,8 @@ int __mei_cl_driver_register(struct mei_cl_driver *driver,
 
 void mei_cl_driver_unregister(struct mei_cl_driver *driver);
 
-int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length);
-int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length);
+ssize_t mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length);
+ssize_t  mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length);
 
 typedef void (*mei_cl_event_cb_t)(struct mei_cl_device *device,
                               u32 events, void *context);
index 884d6263e962499483f40b4dd29e9d99393ad799..9072d9f95cfffd53f73657aa00e953e44f312ff9 100644 (file)
@@ -86,6 +86,7 @@ struct st_proto_s {
 extern long st_register(struct st_proto_s *);
 extern long st_unregister(struct st_proto_s *);
 
+extern struct ti_st_plat_data   *dt_pdata;
 
 /*
  * header information used by st_core.c
index bd22f786a60c7738fac9c79843b003fe408b889b..99ffe61051a702ab386a45a13c364bc1a77f0f25 100644 (file)
@@ -5,9 +5,9 @@ PTHREAD_LIBS = -lpthread
 WARNINGS = -Wall -Wextra
 CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS)
 
-all: hv_kvp_daemon hv_vss_daemon
+all: hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
 %: %.c
        $(CC) $(CFLAGS) -o $@ $^
 
 clean:
-       $(RM) hv_kvp_daemon hv_vss_daemon
+       $(RM) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
index 6a6432a20a1dacced175e006f36fed4265e919a2..4b3ee3521bde296d98b1eb6d49f74c026665c264 100644 (file)
@@ -1308,16 +1308,17 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
        if (error)
                goto setval_error;
 
+       /*
+        * The dhcp_enabled flag is only for IPv4. In the case the host only
+        * injects an IPv6 address, the flag is true, but we still need to
+        * proceed to parse and pass the IPv6 information to the
+        * disto-specific script hv_set_ifconfig.
+        */
        if (new_val->dhcp_enabled) {
                error = kvp_write_file(file, "BOOTPROTO", "", "dhcp");
                if (error)
                        goto setval_error;
 
-               /*
-                * We are done!.
-                */
-               goto setval_done;
-
        } else {
                error = kvp_write_file(file, "BOOTPROTO", "", "none");
                if (error)
@@ -1345,7 +1346,6 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
        if (error)
                goto setval_error;
 
-setval_done:
        fclose(file);
 
        /*