summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2018-05-14 11:27:47 +0300
committerOlof Johansson <olof@lixom.net>2018-05-14 11:27:47 +0300
commit71fe67e0e23446074e61a10e1fec21dd297d49fa (patch)
treee2802ac4800ee69227da6c4b184dd620ed709f9b
parent10d8713429d345867fc8998d6193b233c0cab28c (diff)
parent1e0a601437a6111ecf384df010812c53cada6497 (diff)
downloadlinux-71fe67e0e23446074e61a10e1fec21dd297d49fa.tar.xz
Merge tag 'soc_drivers_for_4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into next/drivers
ARM: SOC driver update for 4.18 - AEMIF driver update to support board files and remove need of mach-davinci aemif code - Use percpu counters for qmss datapath stats - License update for TI SCI * tag 'soc_drivers_for_4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone: firmware: ti_sci: Switch to SPDX Licensing soc: ti: knav_qmss: Use percpu instead atomic for stats counter memory: aemif: add support for board files memory: aemif: don't rely on kbuild for driver's name Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--drivers/firmware/ti_sci.c10
-rw-r--r--drivers/firmware/ti_sci.h30
-rw-r--r--drivers/memory/ti-aemif.c60
-rw-r--r--drivers/soc/ti/knav_qmss.h14
-rw-r--r--drivers/soc/ti/knav_qmss_queue.c60
-rw-r--r--include/linux/platform_data/ti-aemif.h25
-rw-r--r--include/linux/soc/ti/ti_sci_protocol.h10
7 files changed, 115 insertions, 94 deletions
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 5229036dcfbf..b74a533ef35b 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Texas Instruments System Control Interface Protocol Driver
*
* Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
* Nishanth Menon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#define pr_fmt(fmt) "%s: " fmt, __func__
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 9b611e9e6f6d..12bf316b68df 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: BSD-3-Clause
/*
* Texas Instruments System Control Interface (TISCI) Protocol
*
@@ -6,35 +7,6 @@
* See: http://processors.wiki.ti.com/index.php/TISCI for details
*
* Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- *
- * Neither the name of Texas Instruments Incorporated nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
#ifndef __TI_SCI_H
diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c
index 2744b1b91b57..31112f622b88 100644
--- a/drivers/memory/ti-aemif.c
+++ b/drivers/memory/ti-aemif.c
@@ -339,9 +339,6 @@ static int aemif_probe(struct platform_device *pdev)
struct aemif_platform_data *pdata;
struct of_dev_auxdata *dev_lookup;
- if (np == NULL)
- return 0;
-
aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL);
if (!aemif)
return -ENOMEM;
@@ -363,8 +360,10 @@ static int aemif_probe(struct platform_device *pdev)
aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC;
- if (of_device_is_compatible(np, "ti,da850-aemif"))
+ if (np && of_device_is_compatible(np, "ti,da850-aemif"))
aemif->cs_offset = 2;
+ else if (pdata)
+ aemif->cs_offset = pdata->cs_offset;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
aemif->base = devm_ioremap_resource(dev, res);
@@ -373,15 +372,23 @@ static int aemif_probe(struct platform_device *pdev)
goto error;
}
- /*
- * For every controller device node, there is a cs device node that
- * describe the bus configuration parameters. This functions iterate
- * over these nodes and update the cs data array.
- */
- for_each_available_child_of_node(np, child_np) {
- ret = of_aemif_parse_abus_config(pdev, child_np);
- if (ret < 0)
- goto error;
+ if (np) {
+ /*
+ * For every controller device node, there is a cs device node
+ * that describe the bus configuration parameters. This
+ * functions iterate over these nodes and update the cs data
+ * array.
+ */
+ for_each_available_child_of_node(np, child_np) {
+ ret = of_aemif_parse_abus_config(pdev, child_np);
+ if (ret < 0)
+ goto error;
+ }
+ } else if (pdata && pdata->num_abus_data > 0) {
+ for (i = 0; i < pdata->num_abus_data; i++, aemif->num_cs++) {
+ aemif->cs_data[i].cs = pdata->abus_data[i].cs;
+ aemif_get_hw_params(pdev, i);
+ }
}
for (i = 0; i < aemif->num_cs; i++) {
@@ -394,14 +401,25 @@ static int aemif_probe(struct platform_device *pdev)
}
/*
- * Create a child devices explicitly from here to
- * guarantee that the child will be probed after the AEMIF timing
- * parameters are set.
+ * Create a child devices explicitly from here to guarantee that the
+ * child will be probed after the AEMIF timing parameters are set.
*/
- for_each_available_child_of_node(np, child_np) {
- ret = of_platform_populate(child_np, NULL, dev_lookup, dev);
- if (ret < 0)
- goto error;
+ if (np) {
+ for_each_available_child_of_node(np, child_np) {
+ ret = of_platform_populate(child_np, NULL,
+ dev_lookup, dev);
+ if (ret < 0)
+ goto error;
+ }
+ } else {
+ for (i = 0; i < pdata->num_sub_devices; i++) {
+ pdata->sub_devices[i].dev.parent = dev;
+ ret = platform_device_register(&pdata->sub_devices[i]);
+ if (ret) {
+ dev_warn(dev, "Error register sub device %s\n",
+ pdata->sub_devices[i].name);
+ }
+ }
}
return 0;
@@ -422,7 +440,7 @@ static struct platform_driver aemif_driver = {
.probe = aemif_probe,
.remove = aemif_remove,
.driver = {
- .name = KBUILD_MODNAME,
+ .name = "ti-aemif",
.of_match_table = of_match_ptr(aemif_of_match),
},
};
diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h
index 905b974d1bdc..22f409b86107 100644
--- a/drivers/soc/ti/knav_qmss.h
+++ b/drivers/soc/ti/knav_qmss.h
@@ -19,6 +19,8 @@
#ifndef __KNAV_QMSS_H__
#define __KNAV_QMSS_H__
+#include <linux/percpu.h>
+
#define THRESH_GTE BIT(7)
#define THRESH_LT 0
@@ -162,11 +164,11 @@ struct knav_qmgr_info {
* notifies: notifier counts
*/
struct knav_queue_stats {
- atomic_t pushes;
- atomic_t pops;
- atomic_t push_errors;
- atomic_t pop_errors;
- atomic_t notifies;
+ unsigned int pushes;
+ unsigned int pops;
+ unsigned int push_errors;
+ unsigned int pop_errors;
+ unsigned int notifies;
};
/**
@@ -283,7 +285,7 @@ struct knav_queue_inst {
struct knav_queue {
struct knav_reg_queue __iomem *reg_push, *reg_pop, *reg_peek;
struct knav_queue_inst *inst;
- struct knav_queue_stats stats;
+ struct knav_queue_stats __percpu *stats;
knav_queue_notify_fn notifier_fn;
void *notifier_fn_arg;
atomic_t notifier_enabled;
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c
index 77d6b5c03aae..384d70bd8605 100644
--- a/drivers/soc/ti/knav_qmss_queue.c
+++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -83,7 +83,7 @@ void knav_queue_notify(struct knav_queue_inst *inst)
continue;
if (WARN_ON(!qh->notifier_fn))
continue;
- atomic_inc(&qh->stats.notifies);
+ this_cpu_inc(qh->stats->notifies);
qh->notifier_fn(qh->notifier_fn_arg);
}
rcu_read_unlock();
@@ -214,6 +214,12 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
if (!qh)
return ERR_PTR(-ENOMEM);
+ qh->stats = alloc_percpu(struct knav_queue_stats);
+ if (!qh->stats) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
qh->flags = flags;
qh->inst = inst;
id = inst->id - inst->qmgr->start_queue;
@@ -229,13 +235,17 @@ static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
if (range->ops && range->ops->open_queue)
ret = range->ops->open_queue(range, inst, flags);
- if (ret) {
- devm_kfree(inst->kdev->dev, qh);
- return ERR_PTR(ret);
- }
+ if (ret)
+ goto err;
}
list_add_tail_rcu(&qh->list, &inst->handles);
return qh;
+
+err:
+ if (qh->stats)
+ free_percpu(qh->stats);
+ devm_kfree(inst->kdev->dev, qh);
+ return ERR_PTR(ret);
}
static struct knav_queue *
@@ -411,6 +421,12 @@ static void knav_queue_debug_show_instance(struct seq_file *s,
{
struct knav_device *kdev = inst->kdev;
struct knav_queue *qh;
+ int cpu = 0;
+ int pushes = 0;
+ int pops = 0;
+ int push_errors = 0;
+ int pop_errors = 0;
+ int notifies = 0;
if (!knav_queue_is_busy(inst))
return;
@@ -418,19 +434,22 @@ static void knav_queue_debug_show_instance(struct seq_file *s,
seq_printf(s, "\tqueue id %d (%s)\n",
kdev->base_id + inst->id, inst->name);
for_each_handle_rcu(qh, inst) {
- seq_printf(s, "\t\thandle %p: ", qh);
- seq_printf(s, "pushes %8d, ",
- atomic_read(&qh->stats.pushes));
- seq_printf(s, "pops %8d, ",
- atomic_read(&qh->stats.pops));
- seq_printf(s, "count %8d, ",
- knav_queue_get_count(qh));
- seq_printf(s, "notifies %8d, ",
- atomic_read(&qh->stats.notifies));
- seq_printf(s, "push errors %8d, ",
- atomic_read(&qh->stats.push_errors));
- seq_printf(s, "pop errors %8d\n",
- atomic_read(&qh->stats.pop_errors));
+ for_each_possible_cpu(cpu) {
+ pushes += per_cpu_ptr(qh->stats, cpu)->pushes;
+ pops += per_cpu_ptr(qh->stats, cpu)->pops;
+ push_errors += per_cpu_ptr(qh->stats, cpu)->push_errors;
+ pop_errors += per_cpu_ptr(qh->stats, cpu)->pop_errors;
+ notifies += per_cpu_ptr(qh->stats, cpu)->notifies;
+ }
+
+ seq_printf(s, "\t\thandle %p: pushes %8d, pops %8d, count %8d, notifies %8d, push errors %8d, pop errors %8d\n",
+ qh,
+ pushes,
+ pops,
+ knav_queue_get_count(qh),
+ notifies,
+ push_errors,
+ pop_errors);
}
}
@@ -547,6 +566,7 @@ void knav_queue_close(void *qhandle)
if (range->ops && range->ops->close_queue)
range->ops->close_queue(range, inst);
}
+ free_percpu(qh->stats);
devm_kfree(inst->kdev->dev, qh);
}
EXPORT_SYMBOL_GPL(knav_queue_close);
@@ -620,7 +640,7 @@ int knav_queue_push(void *qhandle, dma_addr_t dma,
val = (u32)dma | ((size / 16) - 1);
writel_relaxed(val, &qh->reg_push[0].ptr_size_thresh);
- atomic_inc(&qh->stats.pushes);
+ this_cpu_inc(qh->stats->pushes);
return 0;
}
EXPORT_SYMBOL_GPL(knav_queue_push);
@@ -658,7 +678,7 @@ dma_addr_t knav_queue_pop(void *qhandle, unsigned *size)
if (size)
*size = ((val & DESC_SIZE_MASK) + 1) * 16;
- atomic_inc(&qh->stats.pops);
+ this_cpu_inc(qh->stats->pops);
return dma;
}
EXPORT_SYMBOL_GPL(knav_queue_pop);
diff --git a/include/linux/platform_data/ti-aemif.h b/include/linux/platform_data/ti-aemif.h
index ac72e115093c..e6407bafcbf8 100644
--- a/include/linux/platform_data/ti-aemif.h
+++ b/include/linux/platform_data/ti-aemif.h
@@ -16,8 +16,33 @@
#include <linux/of_platform.h>
+/**
+ * struct aemif_abus_data - Async bus configuration parameters.
+ *
+ * @cs - Chip-select number.
+ */
+struct aemif_abus_data {
+ u32 cs;
+};
+
+/**
+ * struct aemif_platform_data - Data to set up the TI aemif driver.
+ *
+ * @dev_lookup: of_dev_auxdata passed to of_platform_populate() for aemif
+ * subdevices.
+ * @cs_offset: Lowest allowed chip-select number.
+ * @abus_data: Array of async bus configuration entries.
+ * @num_abus_data: Number of abus entries.
+ * @sub_devices: Array of platform subdevices.
+ * @num_sub_devices: Number of subdevices.
+ */
struct aemif_platform_data {
struct of_dev_auxdata *dev_lookup;
+ u32 cs_offset;
+ struct aemif_abus_data *abus_data;
+ size_t num_abus_data;
+ struct platform_device *sub_devices;
+ size_t num_sub_devices;
};
#endif /* __TI_DAVINCI_AEMIF_DATA_H__ */
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 0ccbc138c26a..18435e5c6364 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -1,17 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Texas Instruments System Control Interface Protocol
*
* Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
* Nishanth Menon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef __TISCI_PROTOCOL_H