]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'char-misc/char-misc-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Mon, 27 May 2013 05:36:05 +0000 (15:36 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 27 May 2013 05:36:05 +0000 (15:36 +1000)
20 files changed:
Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt [new file with mode: 0644]
drivers/char/mspec.c
drivers/memory/Kconfig
drivers/memory/Makefile
drivers/memory/mvebu-devbus.c [new file with mode: 0644]
drivers/misc/arm-charlcd.c
drivers/misc/ep93xx_pwm.c
drivers/misc/mei/amthif.c
drivers/misc/mei/client.c
drivers/misc/mei/client.h
drivers/misc/mei/interrupt.c
drivers/misc/mei/mei_dev.h
drivers/misc/sram.c
drivers/misc/tsl2550.c
drivers/uio/uio_aec.c
drivers/uio/uio_cif.c
drivers/uio/uio_netx.c
drivers/uio/uio_pci_generic.c
drivers/uio/uio_sercos3.c
drivers/w1/masters/w1-gpio.c

diff --git a/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt b/Documentation/devicetree/bindings/memory-controllers/mvebu-devbus.txt
new file mode 100644 (file)
index 0000000..653c90c
--- /dev/null
@@ -0,0 +1,156 @@
+Device tree bindings for MVEBU Device Bus controllers
+
+The Device Bus controller available in some Marvell's SoC allows to control
+different types of standard memory and I/O devices such as NOR, NAND, and FPGA.
+The actual devices are instantiated from the child nodes of a Device Bus node.
+
+Required properties:
+
+ - compatible:          Currently only Armada 370/XP SoC are supported,
+                        with this compatible string:
+
+                        marvell,mvebu-devbus
+
+ - reg:                 A resource specifier for the register space.
+                        This is the base address of a chip select within
+                       the controller's register space.
+                        (see the example below)
+
+ - #address-cells:      Must be set to 1
+ - #size-cells:         Must be set to 1
+ - ranges:              Must be set up to reflect the memory layout with four
+                        integer values for each chip-select line in use:
+                        0 <physical address of mapping> <size>
+
+Mandatory timing properties for child nodes:
+
+Read parameters:
+
+ - devbus,turn-off-ps:  Defines the time during which the controller does not
+                        drive the AD bus after the completion of a device read.
+                        This prevents contentions on the Device Bus after a read
+                        cycle from a slow device.
+
+ - devbus,bus-width:    Defines the bus width (e.g. <16>)
+
+ - devbus,badr-skew-ps: Defines the time delay from from A[2:0] toggle,
+                        to read data sample. This parameter is useful for
+                        synchronous pipelined devices, where the address
+                        precedes the read data by one or two cycles.
+
+ - devbus,acc-first-ps: Defines the time delay from the negation of
+                        ALE[0] to the cycle that the first read data is sampled
+                        by the controller.
+
+ - devbus,acc-next-ps:  Defines the time delay between the cycle that
+                        samples data N and the cycle that samples data N+1
+                        (in burst accesses).
+
+ - devbus,rd-setup-ps:  Defines the time delay between DEV_CSn assertion to
+                       DEV_OEn assertion. If set to 0 (default),
+                        DEV_OEn and DEV_CSn are asserted at the same cycle.
+                        This parameter has no affect on <acc-first-ps> parameter
+                        (no affect on first data sample). Set <rd-setup-ps>
+                        to a value smaller than <acc-first-ps>.
+
+ - devbus,rd-hold-ps:   Defines the time between the last data sample to the
+                       de-assertion of DEV_CSn. If set to 0 (default),
+                       DEV_OEn and DEV_CSn are de-asserted at the same cycle
+                       (the cycle of the last data sample).
+                        This parameter has no affect on DEV_OEn de-assertion.
+                        DEV_OEn is always de-asserted the next cycle after
+                        last data sampled. Also this parameter has no
+                        affect on <turn-off-ps> parameter.
+                        Set <rd-hold-ps> to a value smaller than <turn-off-ps>.
+
+Write parameters:
+
+ - devbus,ale-wr-ps:    Defines the time delay from the ALE[0] negation cycle
+                       to the DEV_WEn assertion.
+
+ - devbus,wr-low-ps:    Defines the time during which DEV_WEn is active.
+                        A[2:0] and Data are kept valid as long as DEV_WEn
+                        is active. This parameter defines the setup time of
+                        address and data to DEV_WEn rise.
+
+ - devbus,wr-high-ps:   Defines the time during which DEV_WEn is kept
+                        inactive (high) between data beats of a burst write.
+                        DEV_A[2:0] and Data are kept valid (do not toggle) for
+                        <wr-high-ps> - <tick> ps.
+                       This parameter defines the hold time of address and
+                       data after DEV_WEn rise.
+
+ - devbus,sync-enable: Synchronous device enable.
+                       1: True
+                       0: False
+
+An example for an Armada XP GP board, with a 16 MiB NOR device as child
+is showed below. Note that the Device Bus driver is in charge of allocating
+the mbus address decoding window for each of its child devices.
+The window is created using the chip select specified in the child
+device node together with the base address and size specified in the ranges
+property. For instance, in the example below the allocated decoding window
+will start at base address 0xf0000000, with a size 0x1000000 (16 MiB)
+for chip select 0 (a.k.a DEV_BOOTCS).
+
+This address window handling is done in this mvebu-devbus only as a temporary
+solution. It will be removed when the support for mbus device tree binding is
+added.
+
+The reg property implicitly specifies the chip select as this:
+
+  0x10400: DEV_BOOTCS
+  0x10408: DEV_CS0
+  0x10410: DEV_CS1
+  0x10418: DEV_CS2
+  0x10420: DEV_CS3
+
+Example:
+
+       devbus-bootcs@d0010400 {
+               status = "okay";
+               ranges = <0 0xf0000000 0x1000000>; /* @addr 0xf0000000, size 0x1000000 */
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               /* Device Bus parameters are required */
+
+               /* Read parameters */
+               devbus,bus-width    = <8>;
+               devbus,turn-off-ps  = <60000>;
+               devbus,badr-skew-ps = <0>;
+               devbus,acc-first-ps = <124000>;
+               devbus,acc-next-ps  = <248000>;
+               devbus,rd-setup-ps  = <0>;
+               devbus,rd-hold-ps   = <0>;
+
+               /* Write parameters */
+               devbus,sync-enable = <0>;
+               devbus,wr-high-ps  = <60000>;
+               devbus,wr-low-ps   = <60000>;
+               devbus,ale-wr-ps   = <60000>;
+
+               flash@0 {
+                       compatible = "cfi-flash";
+
+                       /* 16 MiB */
+                       reg = <0 0x1000000>;
+                       bank-width = <2>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       /*
+                        * We split the 16 MiB in two partitions,
+                        * just as an example.
+                        */
+                       partition@0 {
+                               label = "First";
+                               reg = <0 0x800000>;
+                       };
+
+                       partition@800000 {
+                               label = "Second";
+                               reg = <0x800000 0x800000>;
+                       };
+               };
+       };
index e1f60f968fddc8e55b932f4d2ac185835871dfb3..f1d7fa45c2759b0ed97d9a54669d705f2547040c 100644 (file)
@@ -267,7 +267,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
        if ((vma->vm_flags & VM_WRITE) == 0)
                return -EPERM;
 
-       pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+       pages = vma_pages(vma);
        vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
        if (vdata_size <= PAGE_SIZE)
                vdata = kzalloc(vdata_size, GFP_KERNEL);
index 067f31174a0ea5aefea8a8f9c8cb10b70cf0d0e7..29a11db365bc5e6bae120a28bb92914f6b4ca990 100644 (file)
@@ -20,6 +20,16 @@ config TI_EMIF
          parameters and other settings during frequency, voltage and
          temperature changes
 
+config MVEBU_DEVBUS
+       bool "Marvell EBU Device Bus Controller"
+       default y
+       depends on PLAT_ORION && OF
+       help
+         This driver is for the Device Bus controller available in some
+         Marvell EBU SoCs such as Discovery (mv78xx0), Orion (88f5xxx) and
+         Armada 370 and Armada XP. This controller allows to handle flash
+         devices such as NOR, NAND, SRAM, and FPGA.
+
 config TEGRA20_MC
        bool "Tegra20 Memory Controller(MC) driver"
        default y
index 9cce5d70ed5218503f5e58b2310cde9570ae6de7..969d923dad93399b8d672f6077941c1dea0e3b3e 100644 (file)
@@ -6,5 +6,6 @@ ifeq ($(CONFIG_DDR),y)
 obj-$(CONFIG_OF)               += of_memory.o
 endif
 obj-$(CONFIG_TI_EMIF)          += emif.o
+obj-$(CONFIG_MVEBU_DEVBUS)     += mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)       += tegra20-mc.o
 obj-$(CONFIG_TEGRA30_MC)       += tegra30-mc.o
diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c
new file mode 100644 (file)
index 0000000..978e8e3
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * Marvell EBU SoC Device Bus Controller
+ * (memory controller for NOR/NAND/SRAM/FPGA devices)
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/mbus.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+/* Register definitions */
+#define DEV_WIDTH_BIT          30
+#define BADR_SKEW_BIT          28
+#define RD_HOLD_BIT            23
+#define ACC_NEXT_BIT           17
+#define RD_SETUP_BIT           12
+#define ACC_FIRST_BIT          6
+
+#define SYNC_ENABLE_BIT                24
+#define WR_HIGH_BIT            16
+#define WR_LOW_BIT             8
+
+#define READ_PARAM_OFFSET      0x0
+#define WRITE_PARAM_OFFSET     0x4
+
+static const char * const devbus_wins[] = {
+       "devbus-boot",
+       "devbus-cs0",
+       "devbus-cs1",
+       "devbus-cs2",
+       "devbus-cs3",
+};
+
+struct devbus_read_params {
+       u32 bus_width;
+       u32 badr_skew;
+       u32 turn_off;
+       u32 acc_first;
+       u32 acc_next;
+       u32 rd_setup;
+       u32 rd_hold;
+};
+
+struct devbus_write_params {
+       u32 sync_enable;
+       u32 wr_high;
+       u32 wr_low;
+       u32 ale_wr;
+};
+
+struct devbus {
+       struct device *dev;
+       void __iomem *base;
+       unsigned long tick_ps;
+};
+
+static int get_timing_param_ps(struct devbus *devbus,
+                              struct device_node *node,
+                              const char *name,
+                              u32 *ticks)
+{
+       u32 time_ps;
+       int err;
+
+       err = of_property_read_u32(node, name, &time_ps);
+       if (err < 0) {
+               dev_err(devbus->dev, "%s has no '%s' property\n",
+                       name, node->full_name);
+               return err;
+       }
+
+       *ticks = (time_ps + devbus->tick_ps - 1) / devbus->tick_ps;
+
+       dev_dbg(devbus->dev, "%s: %u ps -> 0x%x\n",
+               name, time_ps, *ticks);
+       return 0;
+}
+
+static int devbus_set_timing_params(struct devbus *devbus,
+                                   struct device_node *node)
+{
+       struct devbus_read_params r;
+       struct devbus_write_params w;
+       u32 value;
+       int err;
+
+       dev_dbg(devbus->dev, "Setting timing parameter, tick is %lu ps\n",
+               devbus->tick_ps);
+
+       /* Get read timings */
+       err = of_property_read_u32(node, "devbus,bus-width", &r.bus_width);
+       if (err < 0) {
+               dev_err(devbus->dev,
+                       "%s has no 'devbus,bus-width' property\n",
+                       node->full_name);
+               return err;
+       }
+       /* Convert bit width to byte width */
+       r.bus_width /= 8;
+
+       err = get_timing_param_ps(devbus, node, "devbus,badr-skew-ps",
+                                &r.badr_skew);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,turn-off-ps",
+                                &r.turn_off);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,acc-first-ps",
+                                &r.acc_first);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,acc-next-ps",
+                                &r.acc_next);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,rd-setup-ps",
+                                &r.rd_setup);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,rd-hold-ps",
+                                &r.rd_hold);
+       if (err < 0)
+               return err;
+
+       /* Get write timings */
+       err = of_property_read_u32(node, "devbus,sync-enable",
+                                 &w.sync_enable);
+       if (err < 0) {
+               dev_err(devbus->dev,
+                       "%s has no 'devbus,sync-enable' property\n",
+                       node->full_name);
+               return err;
+       }
+
+       err = get_timing_param_ps(devbus, node, "devbus,ale-wr-ps",
+                                &w.ale_wr);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,wr-low-ps",
+                                &w.wr_low);
+       if (err < 0)
+               return err;
+
+       err = get_timing_param_ps(devbus, node, "devbus,wr-high-ps",
+                                &w.wr_high);
+       if (err < 0)
+               return err;
+
+       /* Set read timings */
+       value = r.bus_width << DEV_WIDTH_BIT |
+               r.badr_skew << BADR_SKEW_BIT |
+               r.rd_hold   << RD_HOLD_BIT   |
+               r.acc_next  << ACC_NEXT_BIT  |
+               r.rd_setup  << RD_SETUP_BIT  |
+               r.acc_first << ACC_FIRST_BIT |
+               r.turn_off;
+
+       dev_dbg(devbus->dev, "read parameters register 0x%p = 0x%x\n",
+               devbus->base + READ_PARAM_OFFSET,
+               value);
+
+       writel(value, devbus->base + READ_PARAM_OFFSET);
+
+       /* Set write timings */
+       value = w.sync_enable  << SYNC_ENABLE_BIT |
+               w.wr_low       << WR_LOW_BIT      |
+               w.wr_high      << WR_HIGH_BIT     |
+               w.ale_wr;
+
+       dev_dbg(devbus->dev, "write parameters register: 0x%p = 0x%x\n",
+               devbus->base + WRITE_PARAM_OFFSET,
+               value);
+
+       writel(value, devbus->base + WRITE_PARAM_OFFSET);
+
+       return 0;
+}
+
+static int mvebu_devbus_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *node = pdev->dev.of_node;
+       struct device_node *parent;
+       struct devbus *devbus;
+       struct resource *res;
+       struct clk *clk;
+       unsigned long rate;
+       const __be32 *ranges;
+       int err, cs;
+       int addr_cells, p_addr_cells, size_cells;
+       int ranges_len, tuple_len;
+       u32 base, size;
+
+       devbus = devm_kzalloc(&pdev->dev, sizeof(struct devbus), GFP_KERNEL);
+       if (!devbus)
+               return -ENOMEM;
+
+       devbus->dev = dev;
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       devbus->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(devbus->base))
+               return PTR_ERR(devbus->base);
+
+       clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+       clk_prepare_enable(clk);
+
+       /*
+        * Obtain clock period in picoseconds,
+        * we need this in order to convert timing
+        * parameters from cycles to picoseconds.
+        */
+       rate = clk_get_rate(clk) / 1000;
+       devbus->tick_ps = 1000000000 / rate;
+
+       /* Read the device tree node and set the new timing parameters */
+       err = devbus_set_timing_params(devbus, node);
+       if (err < 0)
+               return err;
+
+       /*
+        * Allocate an address window for this device.
+        * If the device probing fails, then we won't be able to
+        * remove the allocated address decoding window.
+        *
+        * FIXME: This is only a temporary hack! We need to do this here
+        * because we still don't have device tree bindings for mbus.
+        * Once that support is added, we will declare these address windows
+        * statically in the device tree, and remove the window configuration
+        * from here.
+        */
+
+       /*
+        * Get the CS to choose the window string.
+        * This is a bit hacky, but it will be removed once the
+        * address windows are declared in the device tree.
+        */
+       cs = (((unsigned long)devbus->base) % 0x400) / 8;
+
+       /*
+        * Parse 'ranges' property to obtain a (base,size) window tuple.
+        * This will be removed once the address windows
+        * are declared in the device tree.
+        */
+       parent = of_get_parent(node);
+       if (!parent)
+               return -EINVAL;
+
+       p_addr_cells = of_n_addr_cells(parent);
+       of_node_put(parent);
+
+       addr_cells = of_n_addr_cells(node);
+       size_cells = of_n_size_cells(node);
+       tuple_len = (p_addr_cells + addr_cells + size_cells) * sizeof(__be32);
+
+       ranges = of_get_property(node, "ranges", &ranges_len);
+       if (ranges == NULL || ranges_len != tuple_len)
+               return -EINVAL;
+
+       base = of_translate_address(node, ranges + addr_cells);
+       if (base == OF_BAD_ADDR)
+               return -EINVAL;
+       size = of_read_number(ranges + addr_cells + p_addr_cells, size_cells);
+
+       /*
+        * Create an mbus address windows.
+        * FIXME: Remove this, together with the above code, once the
+        * address windows are declared in the device tree.
+        */
+       err = mvebu_mbus_add_window(devbus_wins[cs], base, size);
+       if (err < 0)
+               return err;
+
+       /*
+        * We need to create a child device explicitly from here to
+        * guarantee that the child will be probed after the timing
+        * parameters for the bus are written.
+        */
+       err = of_platform_populate(node, NULL, NULL, dev);
+       if (err < 0) {
+               mvebu_mbus_del_window(base, size);
+               return err;
+       }
+
+       return 0;
+}
+
+static const struct of_device_id mvebu_devbus_of_match[] = {
+       { .compatible = "marvell,mvebu-devbus" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, mvebu_devbus_of_match);
+
+static struct platform_driver mvebu_devbus_driver = {
+       .probe          = mvebu_devbus_probe,
+       .driver         = {
+               .name   = "mvebu-devbus",
+               .owner  = THIS_MODULE,
+               .of_match_table = mvebu_devbus_of_match,
+       },
+};
+
+static int __init mvebu_devbus_init(void)
+{
+       return platform_driver_register(&mvebu_devbus_driver);
+}
+module_init(mvebu_devbus_init);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
+MODULE_DESCRIPTION("Marvell EBU SoC Device Bus controller");
index 48651ef0028c16805652fd4898da515a1f229127..1256a4bf1c04aca6465bcdde05158ade90c7881e 100644 (file)
@@ -291,7 +291,7 @@ static int __init charlcd_probe(struct platform_device *pdev)
        lcd->virtbase = ioremap(lcd->phybase, lcd->physize);
        if (!lcd->virtbase) {
                ret = -ENOMEM;
-               goto out_no_remap;
+               goto out_no_memregion;
        }
 
        lcd->irq = platform_get_irq(pdev, 0);
@@ -320,8 +320,6 @@ static int __init charlcd_probe(struct platform_device *pdev)
 
 out_no_irq:
        iounmap(lcd->virtbase);
-out_no_remap:
-       platform_set_drvdata(pdev, NULL);
 out_no_memregion:
        release_mem_region(lcd->phybase, SZ_4K);
 out_no_resource:
@@ -337,7 +335,6 @@ static int __exit charlcd_remove(struct platform_device *pdev)
                free_irq(lcd->irq, lcd);
                iounmap(lcd->virtbase);
                release_mem_region(lcd->phybase, lcd->physize);
-               platform_set_drvdata(pdev, NULL);
                kfree(lcd);
        }
 
index 96787ec15caddb534efac6f2b2a9a162b6487617..9ba93f0fe1df32f9b6a4741938322e87610405e7 100644 (file)
@@ -347,7 +347,6 @@ static int __exit ep93xx_pwm_remove(struct platform_device *pdev)
        ep93xx_pwm_disable(pwm);
        clk_disable(pwm->clk);
        clk_put(pwm->clk);
-       platform_set_drvdata(pdev, NULL);
        sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
        iounmap(pwm->mmio_base);
        release_mem_region(res->start, resource_size(res));
index b3e50984d2c8b444ef823254b6d7f39556b74da1..749452f8e2f67c90140de2f30a88b9cd522724b5 100644 (file)
@@ -443,11 +443,11 @@ unsigned int mei_amthif_poll(struct mei_device *dev,
  *
  * returns 0, OK; otherwise, error.
  */
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-                       struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
+int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+                                 s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+       struct mei_device *dev = cl->dev;
        struct mei_msg_hdr mei_hdr;
-       struct mei_cl *cl = cb->cl;
        size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
        u32 msg_slots = mei_data2slots(len);
 
index e310ca6ed1a34b2f78e8e02de45cb9cf222614ac..c2534ca5c6f17b66f7eeb360e8fa5222d7721533 100644 (file)
@@ -785,6 +785,32 @@ err:
 }
 
 
+/**
+ * mei_cl_complete - processes completed operation for a client
+ *
+ * @cl: private data of the file object.
+ * @cb: callback block.
+ */
+void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
+{
+       if (cb->fop_type == MEI_FOP_WRITE) {
+               mei_io_cb_free(cb);
+               cb = NULL;
+               cl->writing_state = MEI_WRITE_COMPLETE;
+               if (waitqueue_active(&cl->tx_wait))
+                       wake_up_interruptible(&cl->tx_wait);
+
+       } else if (cb->fop_type == MEI_FOP_READ &&
+                       MEI_READING == cl->reading_state) {
+               cl->reading_state = MEI_READ_COMPLETE;
+               if (waitqueue_active(&cl->rx_wait))
+                       wake_up_interruptible(&cl->rx_wait);
+               else
+                       mei_cl_bus_rx_event(cl);
+
+       }
+}
+
 
 /**
  * mei_cl_all_disconnect - disconnect forcefully all connected clients
index cfdb144526aa93cdca27d3c37da9ce590a4ec921..7dc2af7b6fba3281ecceebf71b8da46673954869 100644 (file)
@@ -89,6 +89,7 @@ int mei_cl_disconnect(struct mei_cl *cl);
 int mei_cl_connect(struct mei_cl *cl, struct file *file);
 int mei_cl_read_start(struct mei_cl *cl, size_t length);
 int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
+void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb);
 
 void mei_host_client_init(struct work_struct *work);
 
index 2ad736989410d475af90e7b8e6569283c07500b0..7d9509a094e99d76d879aa0b84030c9c3be63fb7 100644 (file)
 #include "client.h"
 
 
-/**
- * mei_cl_complete_handler - processes completed operation for a client
- *
- * @cl: private data of the file object.
- * @cb: callback block.
- */
-static void mei_cl_complete_handler(struct mei_cl *cl, struct mei_cl_cb *cb)
-{
-       if (cb->fop_type == MEI_FOP_WRITE) {
-               mei_io_cb_free(cb);
-               cb = NULL;
-               cl->writing_state = MEI_WRITE_COMPLETE;
-               if (waitqueue_active(&cl->tx_wait))
-                       wake_up_interruptible(&cl->tx_wait);
-
-       } else if (cb->fop_type == MEI_FOP_READ &&
-                       MEI_READING == cl->reading_state) {
-               cl->reading_state = MEI_READ_COMPLETE;
-               if (waitqueue_active(&cl->rx_wait))
-                       wake_up_interruptible(&cl->rx_wait);
-               else
-                       mei_cl_bus_rx_event(cl);
-
-       }
-}
-
 /**
  * mei_irq_compl_handler - dispatch complete handelers
  *     for the completed callbacks
@@ -78,7 +52,7 @@ void mei_irq_compl_handler(struct mei_device *dev, struct mei_cl_cb *compl_list)
                if (cl == &dev->iamthif_cl)
                        mei_amthif_complete(dev, cb);
                else
-                       mei_cl_complete_handler(cl, cb);
+                       mei_cl_complete(cl, cb);
        }
 }
 EXPORT_SYMBOL_GPL(mei_irq_compl_handler);
@@ -189,21 +163,21 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
 }
 
 /**
- * _mei_irq_thread_close - processes close related operation.
+ * mei_cl_irq_close - processes close related operation from
+ *     interrupt thread context - send disconnect request
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
-                               struct mei_cl_cb *cb_pos,
-                               struct mei_cl *cl,
-                               struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_close(struct mei_cl *cl, struct mei_cl_cb *cb,
+                       s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+       struct mei_device *dev = cl->dev;
+
        u32 msg_slots =
                mei_data2slots(sizeof(struct hbm_client_connect_request));
 
@@ -214,15 +188,15 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
 
        if (mei_hbm_cl_disconnect_req(dev, cl)) {
                cl->status = 0;
-               cb_pos->buf_idx = 0;
-               list_move_tail(&cb_pos->list, &cmpl_list->list);
+               cb->buf_idx = 0;
+               list_move_tail(&cb->list, &cmpl_list->list);
                return -EIO;
        }
 
        cl->state = MEI_FILE_DISCONNECTING;
        cl->status = 0;
-       cb_pos->buf_idx = 0;
-       list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
+       cb->buf_idx = 0;
+       list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
        cl->timer_count = MEI_CONNECT_TIMEOUT;
 
        return 0;
@@ -230,26 +204,26 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
 
 
 /**
- * _mei_irq_thread_read - processes read related operation.
+ * mei_cl_irq_close - processes client read related operation from the
+ *     interrupt thread context - request for flow control credits
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_read(struct mei_device *dev,        s32 *slots,
-                       struct mei_cl_cb *cb_pos,
-                       struct mei_cl *cl,
-                       struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
+                          s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+       struct mei_device *dev = cl->dev;
+
        u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
 
        if (*slots < msg_slots) {
                /* return the cancel routine */
-               list_del(&cb_pos->list);
+               list_del(&cb->list);
                return -EMSGSIZE;
        }
 
@@ -257,38 +231,38 @@ static int _mei_irq_thread_read(struct mei_device *dev,   s32 *slots,
 
        if (mei_hbm_cl_flow_control_req(dev, cl)) {
                cl->status = -ENODEV;
-               cb_pos->buf_idx = 0;
-               list_move_tail(&cb_pos->list, &cmpl_list->list);
+               cb->buf_idx = 0;
+               list_move_tail(&cb->list, &cmpl_list->list);
                return -ENODEV;
        }
-       list_move_tail(&cb_pos->list, &dev->read_list.list);
+       list_move_tail(&cb->list, &dev->read_list.list);
 
        return 0;
 }
 
 
 /**
- * _mei_irq_thread_ioctl - processes ioctl related operation.
+ * mei_cl_irq_ioctl - processes client ioctl related operation from the
+ *     interrupt thread context -   send connection request
  *
- * @dev: the device structure.
+ * @cl: client
+ * @cb: callback block.
  * @slots: free slots.
- * @cb_pos: callback block.
- * @cl: private data of the file object.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
-                       struct mei_cl_cb *cb_pos,
-                       struct mei_cl *cl,
-                       struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
+                          s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+       struct mei_device *dev = cl->dev;
+
        u32 msg_slots =
                mei_data2slots(sizeof(struct hbm_client_connect_request));
 
        if (*slots < msg_slots) {
                /* return the cancel routine */
-               list_del(&cb_pos->list);
+               list_del(&cb->list);
                return -EMSGSIZE;
        }
 
@@ -298,31 +272,31 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
 
        if (mei_hbm_cl_connect_req(dev, cl)) {
                cl->status = -ENODEV;
-               cb_pos->buf_idx = 0;
-               list_del(&cb_pos->list);
+               cb->buf_idx = 0;
+               list_del(&cb->list);
                return -ENODEV;
-       } else {
-               list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
-               cl->timer_count = MEI_CONNECT_TIMEOUT;
        }
+
+       list_move_tail(&cb->list, &dev->ctrl_rd_list.list);
+       cl->timer_count = MEI_CONNECT_TIMEOUT;
        return 0;
 }
 
 /**
- * mei_irq_thread_write_complete - write messages to device.
+ * mei_cl_irq_write_complete - write messages to device.
  *
- * @dev: the device structure.
- * @slots: free slots.
+ * @cl: client
  * @cb: callback block.
+ * @slots: free slots.
  * @cmpl_list: complete list.
  *
  * returns 0, OK; otherwise, error.
  */
-static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
-                       struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list)
+static int mei_cl_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+                                    s32 *slots, struct mei_cl_cb *cmpl_list)
 {
+       struct mei_device *dev = cl->dev;
        struct mei_msg_hdr mei_hdr;
-       struct mei_cl *cl = cb->cl;
        size_t len = cb->request_buffer.size - cb->buf_idx;
        u32 msg_slots = mei_data2slots(len);
 
@@ -481,7 +455,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
 {
 
        struct mei_cl *cl;
-       struct mei_cl_cb *pos = NULL, *next = NULL;
+       struct mei_cl_cb *cb, *next;
        struct mei_cl_cb *list;
        s32 slots;
        int ret;
@@ -498,19 +472,19 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
        dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
 
        list = &dev->write_waiting_list;
-       list_for_each_entry_safe(pos, next, &list->list, list) {
-               cl = pos->cl;
+       list_for_each_entry_safe(cb, next, &list->list, list) {
+               cl = cb->cl;
                if (cl == NULL)
                        continue;
 
                cl->status = 0;
-               list_del(&pos->list);
+               list_del(&cb->list);
                if (MEI_WRITING == cl->writing_state &&
-                   pos->fop_type == MEI_FOP_WRITE &&
+                   cb->fop_type == MEI_FOP_WRITE &&
                    cl != &dev->iamthif_cl) {
                        dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
                        cl->writing_state = MEI_WRITE_COMPLETE;
-                       list_add_tail(&pos->list, &cmpl_list->list);
+                       list_add_tail(&cb->list, &cmpl_list->list);
                }
                if (cl == &dev->iamthif_cl) {
                        dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
@@ -552,25 +526,23 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
 
        /* complete control write list CB */
        dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
-       list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) {
-               cl = pos->cl;
+       list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) {
+               cl = cb->cl;
                if (!cl) {
-                       list_del(&pos->list);
+                       list_del(&cb->list);
                        return -ENODEV;
                }
-               switch (pos->fop_type) {
+               switch (cb->fop_type) {
                case MEI_FOP_CLOSE:
                        /* send disconnect message */
-                       ret = _mei_irq_thread_close(dev, &slots, pos,
-                                               cl, cmpl_list);
+                       ret = mei_cl_irq_close(cl, cb, &slots, cmpl_list);
                        if (ret)
                                return ret;
 
                        break;
                case MEI_FOP_READ:
                        /* send flow control message */
-                       ret = _mei_irq_thread_read(dev, &slots, pos,
-                                               cl, cmpl_list);
+                       ret = mei_cl_irq_read(cl, cb, &slots, cmpl_list);
                        if (ret)
                                return ret;
 
@@ -579,8 +551,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
                        /* connect message */
                        if (mei_cl_is_other_connecting(cl))
                                continue;
-                       ret = _mei_irq_thread_ioctl(dev, &slots, pos,
-                                               cl, cmpl_list);
+                       ret = mei_cl_irq_ioctl(cl, cb, &slots, cmpl_list);
                        if (ret)
                                return ret;
 
@@ -593,8 +564,8 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
        }
        /* complete  write list CB */
        dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
-       list_for_each_entry_safe(pos, next, &dev->write_list.list, list) {
-               cl = pos->cl;
+       list_for_each_entry_safe(cb, next, &dev->write_list.list, list) {
+               cl = cb->cl;
                if (cl == NULL)
                        continue;
                if (mei_cl_flow_ctrl_creds(cl) <= 0) {
@@ -605,14 +576,13 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
                }
 
                if (cl == &dev->iamthif_cl)
-                       ret = mei_amthif_irq_write_complete(dev, &slots,
-                                                       pos, cmpl_list);
+                       ret = mei_amthif_irq_write_complete(cl, cb,
+                                               &slots, cmpl_list);
                else
-                       ret = mei_irq_thread_write_complete(dev, &slots, pos,
-                                               cmpl_list);
+                       ret = mei_cl_irq_write_complete(cl, cb,
+                                               &slots, cmpl_list);
                if (ret)
                        return ret;
-
        }
        return 0;
 }
index 4de5140e7379c7a01f295021717e1bc482634e50..197ba6481bf5799761183aa3fa4b0ae2c82f4eb6 100644 (file)
@@ -502,8 +502,8 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev,
 
 void mei_amthif_run_next_cmd(struct mei_device *dev);
 
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-                       struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
+int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
+                                 s32 *slots, struct mei_cl_cb *cmpl_list);
 
 void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
 int mei_amthif_irq_read_msg(struct mei_device *dev,
@@ -522,15 +522,6 @@ void mei_nfc_host_exit(void);
  */
 extern const uuid_le mei_nfc_guid;
 
-int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
-                       struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list);
-
-void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb);
-int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
-               struct mei_device *dev, struct mei_msg_hdr *mei_hdr);
-int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
-
-
 int mei_wd_send(struct mei_device *dev);
 int mei_wd_stop(struct mei_device *dev);
 int mei_wd_host_init(struct mei_device *dev);
index 437192e43006d49db726c828aace74062ed3929c..4a938860fec0210a052c4d6c9e9879604fdc9a12 100644 (file)
@@ -50,9 +50,10 @@ static int sram_probe(struct platform_device *pdev)
 
        size = resource_size(res);
 
-       virt_base = devm_request_and_ioremap(&pdev->dev, res);
-       if (!virt_base)
-               return -EADDRNOTAVAIL;
+       virt_base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(virt_base))
+               return PTR_ERR(virt_base);
+
 
        sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
        if (!sram)
index 1dfde4d543dbeef4526569f4fd6e201e3e2877ea..5bc10fa193de16e682e5bcc540193bd157e37b50 100644 (file)
@@ -204,7 +204,7 @@ static ssize_t tsl2550_store_power_state(struct device *dev,
        unsigned long val = simple_strtoul(buf, NULL, 10);
        int ret;
 
-       if (val < 0 || val > 1)
+       if (val > 1)
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
@@ -236,7 +236,7 @@ static ssize_t tsl2550_store_operating_mode(struct device *dev,
        unsigned long val = simple_strtoul(buf, NULL, 10);
        int ret;
 
-       if (val < 0 || val > 1)
+       if (val > 1)
                return -EINVAL;
 
        if (data->power_state == 0)
index 1548982db58ba4b802945b09ced045ff4b1e039f..f3611c2d83b681e1903d9bc502347108f50263bc 100644 (file)
@@ -160,17 +160,5 @@ static struct pci_driver pci_driver = {
        .remove = remove,
 };
 
-static int __init aectc_init(void)
-{
-       return pci_register_driver(&pci_driver);
-}
-
-static void __exit aectc_exit(void)
-{
-       pci_unregister_driver(&pci_driver);
-}
-
+module_pci_driver(pci_driver);
 MODULE_LICENSE("GPL");
-
-module_init(aectc_init);
-module_exit(aectc_exit);
index 7dd6fc60539de51a4165a7e35153a87212d56b8d..22cdf385ab33159cc99c37fd10946f96bbefdf85 100644 (file)
@@ -135,19 +135,7 @@ static struct pci_driver hilscher_pci_driver = {
        .remove = hilscher_pci_remove,
 };
 
-static int __init hilscher_init_module(void)
-{
-       return pci_register_driver(&hilscher_pci_driver);
-}
-
-static void __exit hilscher_exit_module(void)
-{
-       pci_unregister_driver(&hilscher_pci_driver);
-}
-
-module_init(hilscher_init_module);
-module_exit(hilscher_exit_module);
-
+module_pci_driver(hilscher_pci_driver);
 MODULE_DEVICE_TABLE(pci, hilscher_pci_ids);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger");
index 6a4ba5e83e376b7dd2994cb36b584eeab835dd22..28a766b9e198af4ded7bc8ddfe2c28181909ddea 100644 (file)
@@ -174,19 +174,7 @@ static struct pci_driver netx_pci_driver = {
        .remove = netx_pci_remove,
 };
 
-static int __init netx_init_module(void)
-{
-       return pci_register_driver(&netx_pci_driver);
-}
-
-static void __exit netx_exit_module(void)
-{
-       pci_unregister_driver(&netx_pci_driver);
-}
-
-module_init(netx_init_module);
-module_exit(netx_exit_module);
-
+module_pci_driver(netx_pci_driver);
 MODULE_DEVICE_TABLE(pci, netx_pci_ids);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Hans J. Koch, Manuel Traut");
index 14aa10c1f6defe37e73d7ff4b23054698a96f9c6..077ae12269ce3a99fcc35ee099e6453a102484de 100644 (file)
@@ -113,27 +113,14 @@ static void remove(struct pci_dev *pdev)
        kfree(gdev);
 }
 
-static struct pci_driver driver = {
+static struct pci_driver uio_pci_driver = {
        .name = "uio_pci_generic",
        .id_table = NULL, /* only dynamic id's */
        .probe = probe,
        .remove = remove,
 };
 
-static int __init init(void)
-{
-       pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
-       return pci_register_driver(&driver);
-}
-
-static void __exit cleanup(void)
-{
-       pci_unregister_driver(&driver);
-}
-
-module_init(init);
-module_exit(cleanup);
-
+module_pci_driver(uio_pci_driver);
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR(DRIVER_AUTHOR);
index 81a10a5631207144d8f34adc5a56f746983dd054..5419832170856b78b384659f8bc961c3a283f2ee 100644 (file)
@@ -226,19 +226,7 @@ static struct pci_driver sercos3_pci_driver = {
        .remove = sercos3_pci_remove,
 };
 
-static int __init sercos3_init_module(void)
-{
-       return pci_register_driver(&sercos3_pci_driver);
-}
-
-static void __exit sercos3_exit_module(void)
-{
-       pci_unregister_driver(&sercos3_pci_driver);
-}
-
-module_init(sercos3_init_module);
-module_exit(sercos3_exit_module);
-
+module_pci_driver(sercos3_pci_driver);
 MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card");
 MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>");
 MODULE_LICENSE("GPL v2");
index 46d97014342ef1f27f37046332e35d6e40a5b108..f54ece268c982d1dce13224c78efce9434dbffbb 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/gpio.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
-#include <linux/pinctrl/consumer.h>
 #include <linux/err.h>
 #include <linux/of.h>
 
@@ -78,13 +77,8 @@ static int w1_gpio_probe(struct platform_device *pdev)
 {
        struct w1_bus_master *master;
        struct w1_gpio_platform_data *pdata;
-       struct pinctrl *pinctrl;
        int err;
 
-       pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-       if (IS_ERR(pinctrl))
-               dev_warn(&pdev->dev, "unable to select pin group\n");
-
        if (of_have_populated_dt()) {
                err = w1_gpio_probe_dt(pdev);
                if (err < 0) {