mirror of https://github.com/hak5/openwrt.git
ipq806x: update bleeding-edge kernel from 4.0 to 4.1
Default kernel doesn't change and stays on 3.18 for now. Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org> SVN-Revision: 46554lede-17.01
parent
991e641a76
commit
4d1656e813
|
@ -4,8 +4,9 @@ CONFIG_ALIGNMENT_TRAP=y
|
|||
CONFIG_APQ_GCC_8084=y
|
||||
CONFIG_APQ_MMCC_8084=y
|
||||
CONFIG_AR8216_PHY=y
|
||||
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||
# CONFIG_ARCH_ALPINE is not set
|
||||
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
CONFIG_ARCH_HAS_SG_CHAIN=y
|
||||
CONFIG_ARCH_HAS_TICK_BROADCAST=y
|
||||
|
@ -38,6 +39,10 @@ CONFIG_ARM_APPENDED_DTB=y
|
|||
CONFIG_ARM_ARCH_TIMER=y
|
||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
|
||||
# CONFIG_ARM_ATAG_DTB_COMPAT is not set
|
||||
CONFIG_ARM_CCI=y
|
||||
CONFIG_ARM_CCI400_COMMON=y
|
||||
CONFIG_ARM_CCI400_PMU=y
|
||||
# CONFIG_ARM_CPUIDLE is not set
|
||||
CONFIG_ARM_CPU_SUSPEND=y
|
||||
CONFIG_ARM_GIC=y
|
||||
CONFIG_ARM_HAS_SG_CHAIN=y
|
||||
|
@ -107,8 +112,6 @@ CONFIG_CRC16=y
|
|||
# CONFIG_CRC32_SARWATE is not set
|
||||
CONFIG_CRC32_SLICEBY8=y
|
||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
|
||||
# CONFIG_CRYPTO_SHA512_ARM_NEON is not set
|
||||
CONFIG_CRYPTO_XZ=y
|
||||
CONFIG_DCACHE_WORD_ACCESS=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
|
@ -124,7 +127,6 @@ CONFIG_DMA_ENGINE=y
|
|||
CONFIG_DMA_OF=y
|
||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
|
||||
CONFIG_DTC=y
|
||||
# CONFIG_DW_DMAC_CORE is not set
|
||||
# CONFIG_DW_DMAC_PCI is not set
|
||||
CONFIG_DYNAMIC_DEBUG=y
|
||||
CONFIG_ETHERNET_PACKET_MANGLE=y
|
||||
|
@ -134,11 +136,11 @@ CONFIG_GENERIC_ALLOCATOR=y
|
|||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
|
||||
CONFIG_GENERIC_CPUFREQ_KRAIT=y
|
||||
CONFIG_GENERIC_IDLE_POLL_SETUP=y
|
||||
CONFIG_GENERIC_IO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
|
@ -147,6 +149,7 @@ CONFIG_GENERIC_SCHED_CLOCK=y
|
|||
CONFIG_GENERIC_SMP_IDLE_THREAD=y
|
||||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
|
||||
CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIOLIB_IRQCHIP=y
|
||||
CONFIG_GPIO_DEVRES=y
|
||||
|
@ -208,6 +211,7 @@ CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
|
|||
CONFIG_HIGHMEM=y
|
||||
CONFIG_HIGHPTE=y
|
||||
CONFIG_HOTPLUG_CPU=y
|
||||
# CONFIG_HSU_DMA_PCI is not set
|
||||
CONFIG_HWMON=y
|
||||
CONFIG_HW_RANDOM=y
|
||||
CONFIG_HW_RANDOM_MSM=y
|
||||
|
@ -254,6 +258,7 @@ CONFIG_MIGHT_HAVE_PCI=y
|
|||
CONFIG_MIGRATION=y
|
||||
CONFIG_MODULES_USE_ELF_REL=y
|
||||
CONFIG_MSM_GCC_8660=y
|
||||
# CONFIG_MSM_GCC_8916 is not set
|
||||
CONFIG_MSM_GCC_8960=y
|
||||
CONFIG_MSM_GCC_8974=y
|
||||
# CONFIG_MSM_LCC_8960 is not set
|
||||
|
@ -296,6 +301,7 @@ CONFIG_PCI=y
|
|||
CONFIG_PCIEAER=y
|
||||
CONFIG_PCIEPORTBUS=y
|
||||
CONFIG_PCIE_DW=y
|
||||
# CONFIG_PCIE_IPROC is not set
|
||||
CONFIG_PCIE_PME=y
|
||||
CONFIG_PCIE_QCOM=y
|
||||
CONFIG_PCI_DEBUG=y
|
||||
|
@ -304,10 +310,13 @@ CONFIG_PCI_DOMAINS_GENERIC=y
|
|||
CONFIG_PCI_MSI=y
|
||||
CONFIG_PERF_EVENTS=y
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
CONFIG_PGTABLE_LEVELS=2
|
||||
CONFIG_PHYLIB=y
|
||||
# CONFIG_PHY_QCOM_APQ8064_SATA is not set
|
||||
CONFIG_PHY_QCOM_IPQ806X_SATA=y
|
||||
# CONFIG_PHY_QCOM_UFS is not set
|
||||
CONFIG_PINCTRL=y
|
||||
# CONFIG_PINCTRL_AMD is not set
|
||||
CONFIG_PINCTRL_APQ8064=y
|
||||
# CONFIG_PINCTRL_APQ8084 is not set
|
||||
CONFIG_PINCTRL_IPQ8064=y
|
||||
|
@ -330,6 +339,7 @@ CONFIG_POWER_RESET=y
|
|||
# CONFIG_POWER_RESET_LTC2952 is not set
|
||||
CONFIG_POWER_RESET_MSM=y
|
||||
# CONFIG_POWER_RESET_SYSCON is not set
|
||||
# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
CONFIG_PREEMPT=y
|
||||
CONFIG_PREEMPT_COUNT=y
|
||||
|
@ -342,9 +352,11 @@ CONFIG_QCOM_GSBI=y
|
|||
CONFIG_QCOM_HFPLL=y
|
||||
CONFIG_QCOM_SCM=y
|
||||
CONFIG_QCOM_WDT=y
|
||||
# CONFIG_QORIQ_CPUFREQ is not set
|
||||
CONFIG_RAS=y
|
||||
# CONFIG_RCU_BOOST is not set
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=21
|
||||
# CONFIG_RCU_EXPEDITE_BOOT is not set
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RD_GZIP=y
|
||||
CONFIG_REGMAP=y
|
||||
|
@ -405,6 +417,7 @@ CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
|
|||
CONFIG_UNINLINE_SPIN_UNLOCK=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USE_OF=y
|
||||
CONFIG_VDSO=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VFP=y
|
||||
CONFIG_VFPv3=y
|
|
@ -1,522 +0,0 @@
|
|||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: spi: qup: Add DMA capabilities
|
||||
From: Andy Gross <agross@codeaurora.org>
|
||||
X-Patchwork-Id: 4432401
|
||||
Message-Id: <1403816781-31008-1-git-send-email-agross@codeaurora.org>
|
||||
To: Mark Brown <broonie@kernel.org>
|
||||
Cc: linux-spi@vger.kernel.org, Sagar Dharia <sdharia@codeaurora.org>,
|
||||
Daniel Sneddon <dsneddon@codeaurora.org>,
|
||||
Bjorn Andersson <bjorn.andersson@sonymobile.com>,
|
||||
"Ivan T. Ivanov" <iivanov@mm-sol.com>,
|
||||
linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
|
||||
linux-arm-msm@vger.kernel.org, Andy Gross <agross@codeaurora.org>
|
||||
Date: Thu, 26 Jun 2014 16:06:21 -0500
|
||||
|
||||
This patch adds DMA capabilities to the spi-qup driver. If DMA channels are
|
||||
present, the QUP will use DMA instead of block mode for transfers to/from SPI
|
||||
peripherals for transactions larger than the length of a block.
|
||||
|
||||
Signed-off-by: Andy Gross <agross@codeaurora.org>
|
||||
|
||||
---
|
||||
.../devicetree/bindings/spi/qcom,spi-qup.txt | 10 +
|
||||
drivers/spi/spi-qup.c | 361 ++++++++++++++++++--
|
||||
2 files changed, 350 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
|
||||
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt
|
||||
@@ -27,6 +27,11 @@ Optional properties:
|
||||
- spi-max-frequency: Specifies maximum SPI clock frequency,
|
||||
Units - Hz. Definition as per
|
||||
Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
+- dmas : Two DMA channel specifiers following the convention outlined
|
||||
+ in bindings/dma/dma.txt
|
||||
+- dma-names: Names for the dma channels, if present. There must be at
|
||||
+ least one channel named "tx" for transmit and named "rx" for
|
||||
+ receive.
|
||||
- num-cs: total number of chipselects
|
||||
- cs-gpios: should specify GPIOs used for chipselects.
|
||||
The gpios will be referred to as reg = <index> in the SPI child
|
||||
@@ -51,6 +56,10 @@ Example:
|
||||
clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
|
||||
clock-names = "core", "iface";
|
||||
|
||||
+ dmas = <&blsp2_bam 2>,
|
||||
+ <&blsp2_bam 3>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi8_default>;
|
||||
|
||||
--- a/drivers/spi/spi-qup.c
|
||||
+++ b/drivers/spi/spi-qup.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spi/spi.h>
|
||||
+#include <linux/dmaengine.h>
|
||||
+#include <linux/dma-mapping.h>
|
||||
|
||||
#define QUP_CONFIG 0x0000
|
||||
#define QUP_STATE 0x0004
|
||||
@@ -116,6 +118,8 @@
|
||||
|
||||
#define SPI_NUM_CHIPSELECTS 4
|
||||
|
||||
+#define SPI_MAX_XFER (SZ_64K - 64)
|
||||
+
|
||||
/* high speed mode is when bus rate is greater then 26MHz */
|
||||
#define SPI_HS_MIN_RATE 26000000
|
||||
#define SPI_MAX_RATE 50000000
|
||||
@@ -143,6 +147,17 @@ struct spi_qup {
|
||||
int tx_bytes;
|
||||
int rx_bytes;
|
||||
int qup_v1;
|
||||
+
|
||||
+ int use_dma;
|
||||
+
|
||||
+ struct dma_chan *rx_chan;
|
||||
+ struct dma_slave_config rx_conf;
|
||||
+ struct dma_chan *tx_chan;
|
||||
+ struct dma_slave_config tx_conf;
|
||||
+ dma_addr_t rx_dma;
|
||||
+ dma_addr_t tx_dma;
|
||||
+ void *dummy;
|
||||
+ atomic_t dma_outstanding;
|
||||
};
|
||||
|
||||
|
||||
@@ -266,6 +281,221 @@ static void spi_qup_fifo_write(struct sp
|
||||
}
|
||||
}
|
||||
|
||||
+static void qup_dma_callback(void *data)
|
||||
+{
|
||||
+ struct spi_qup *controller = data;
|
||||
+
|
||||
+ if (atomic_dec_and_test(&controller->dma_outstanding))
|
||||
+ complete(&controller->done);
|
||||
+}
|
||||
+
|
||||
+static int spi_qup_do_dma(struct spi_qup *controller, struct spi_transfer *xfer)
|
||||
+{
|
||||
+ struct dma_async_tx_descriptor *rxd, *txd;
|
||||
+ dma_cookie_t rx_cookie, tx_cookie;
|
||||
+ u32 xfer_len, rx_align = 0, tx_align = 0, n_words;
|
||||
+ struct scatterlist tx_sg[2], rx_sg[2];
|
||||
+ int ret = 0;
|
||||
+ u32 bytes_to_xfer = xfer->len;
|
||||
+ u32 offset = 0;
|
||||
+ u32 rx_nents = 0, tx_nents = 0;
|
||||
+ dma_addr_t rx_dma = 0, tx_dma = 0, rx_dummy_dma = 0, tx_dummy_dma = 0;
|
||||
+
|
||||
+
|
||||
+ if (xfer->rx_buf) {
|
||||
+ rx_dma = dma_map_single(controller->dev, xfer->rx_buf,
|
||||
+ xfer->len, DMA_FROM_DEVICE);
|
||||
+
|
||||
+ if (dma_mapping_error(controller->dev, rx_dma)) {
|
||||
+ ret = -ENOMEM;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* check to see if we need dummy buffer for leftover bytes */
|
||||
+ rx_align = xfer->len % controller->in_blk_sz;
|
||||
+ if (rx_align) {
|
||||
+ rx_dummy_dma = dma_map_single(controller->dev,
|
||||
+ controller->dummy, controller->in_fifo_sz,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+
|
||||
+ if (dma_mapping_error(controller->dev, rx_dummy_dma)) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_map_rx_dummy;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (xfer->tx_buf) {
|
||||
+ tx_dma = dma_map_single(controller->dev,
|
||||
+ (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
|
||||
+
|
||||
+ if (dma_mapping_error(controller->dev, tx_dma)) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_map_tx;
|
||||
+ }
|
||||
+
|
||||
+ /* check to see if we need dummy buffer for leftover bytes */
|
||||
+ tx_align = xfer->len % controller->out_blk_sz;
|
||||
+ if (tx_align) {
|
||||
+ memcpy(controller->dummy + SZ_1K,
|
||||
+ xfer->tx_buf + xfer->len - tx_align,
|
||||
+ tx_align);
|
||||
+ memset(controller->dummy + SZ_1K + tx_align, 0,
|
||||
+ controller->out_blk_sz - tx_align);
|
||||
+
|
||||
+ tx_dummy_dma = dma_map_single(controller->dev,
|
||||
+ controller->dummy + SZ_1K,
|
||||
+ controller->out_blk_sz, DMA_TO_DEVICE);
|
||||
+
|
||||
+ if (dma_mapping_error(controller->dev, tx_dummy_dma)) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_map_tx_dummy;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ atomic_set(&controller->dma_outstanding, 0);
|
||||
+
|
||||
+ while (bytes_to_xfer > 0) {
|
||||
+ xfer_len = min_t(u32, bytes_to_xfer, SPI_MAX_XFER);
|
||||
+ n_words = DIV_ROUND_UP(xfer_len, controller->w_size);
|
||||
+
|
||||
+ /* write out current word count to controller */
|
||||
+ writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
|
||||
+ writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
|
||||
+
|
||||
+ reinit_completion(&controller->done);
|
||||
+
|
||||
+ if (xfer->tx_buf) {
|
||||
+ /* recalc align for each transaction */
|
||||
+ tx_align = xfer_len % controller->out_blk_sz;
|
||||
+
|
||||
+ if (tx_align)
|
||||
+ tx_nents = 2;
|
||||
+ else
|
||||
+ tx_nents = 1;
|
||||
+
|
||||
+ /* initialize scatterlists */
|
||||
+ sg_init_table(tx_sg, tx_nents);
|
||||
+ sg_dma_len(&tx_sg[0]) = xfer_len - tx_align;
|
||||
+ sg_dma_address(&tx_sg[0]) = tx_dma + offset;
|
||||
+
|
||||
+ /* account for non block size transfer */
|
||||
+ if (tx_align) {
|
||||
+ sg_dma_len(&tx_sg[1]) = controller->out_blk_sz;
|
||||
+ sg_dma_address(&tx_sg[1]) = tx_dummy_dma;
|
||||
+ }
|
||||
+
|
||||
+ txd = dmaengine_prep_slave_sg(controller->tx_chan,
|
||||
+ tx_sg, tx_nents, DMA_MEM_TO_DEV, 0);
|
||||
+ if (!txd) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+
|
||||
+ atomic_inc(&controller->dma_outstanding);
|
||||
+
|
||||
+ txd->callback = qup_dma_callback;
|
||||
+ txd->callback_param = controller;
|
||||
+
|
||||
+ tx_cookie = dmaengine_submit(txd);
|
||||
+
|
||||
+ dma_async_issue_pending(controller->tx_chan);
|
||||
+ }
|
||||
+
|
||||
+ if (xfer->rx_buf) {
|
||||
+ /* recalc align for each transaction */
|
||||
+ rx_align = xfer_len % controller->in_blk_sz;
|
||||
+
|
||||
+ if (rx_align)
|
||||
+ rx_nents = 2;
|
||||
+ else
|
||||
+ rx_nents = 1;
|
||||
+
|
||||
+ /* initialize scatterlists */
|
||||
+ sg_init_table(rx_sg, rx_nents);
|
||||
+ sg_dma_address(&rx_sg[0]) = rx_dma + offset;
|
||||
+ sg_dma_len(&rx_sg[0]) = xfer_len - rx_align;
|
||||
+
|
||||
+ /* account for non block size transfer */
|
||||
+ if (rx_align) {
|
||||
+ sg_dma_len(&rx_sg[1]) = controller->in_blk_sz;
|
||||
+ sg_dma_address(&rx_sg[1]) = rx_dummy_dma;
|
||||
+ }
|
||||
+
|
||||
+ rxd = dmaengine_prep_slave_sg(controller->rx_chan,
|
||||
+ rx_sg, rx_nents, DMA_DEV_TO_MEM, 0);
|
||||
+ if (!rxd) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+
|
||||
+ atomic_inc(&controller->dma_outstanding);
|
||||
+
|
||||
+ rxd->callback = qup_dma_callback;
|
||||
+ rxd->callback_param = controller;
|
||||
+
|
||||
+ rx_cookie = dmaengine_submit(rxd);
|
||||
+
|
||||
+ dma_async_issue_pending(controller->rx_chan);
|
||||
+ }
|
||||
+
|
||||
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+
|
||||
+ if (!wait_for_completion_timeout(&controller->done,
|
||||
+ msecs_to_jiffies(1000))) {
|
||||
+ ret = -ETIMEDOUT;
|
||||
+
|
||||
+ /* clear out all the DMA transactions */
|
||||
+ if (xfer->tx_buf)
|
||||
+ dmaengine_terminate_all(controller->tx_chan);
|
||||
+ if (xfer->rx_buf)
|
||||
+ dmaengine_terminate_all(controller->rx_chan);
|
||||
+
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+
|
||||
+ if (rx_align)
|
||||
+ memcpy(xfer->rx_buf + offset + xfer->len - rx_align,
|
||||
+ controller->dummy, rx_align);
|
||||
+
|
||||
+ /* adjust remaining bytes to transfer */
|
||||
+ bytes_to_xfer -= xfer_len;
|
||||
+ offset += xfer_len;
|
||||
+
|
||||
+
|
||||
+ /* reset mini-core state so we can program next transaction */
|
||||
+ if (spi_qup_set_state(controller, QUP_STATE_RESET)) {
|
||||
+ dev_err(controller->dev, "cannot set RESET state\n");
|
||||
+ goto err_unmap;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+
|
||||
+err_unmap:
|
||||
+ if (tx_align)
|
||||
+ dma_unmap_single(controller->dev, tx_dummy_dma,
|
||||
+ controller->out_fifo_sz, DMA_TO_DEVICE);
|
||||
+err_map_tx_dummy:
|
||||
+ if (xfer->tx_buf)
|
||||
+ dma_unmap_single(controller->dev, tx_dma, xfer->len,
|
||||
+ DMA_TO_DEVICE);
|
||||
+err_map_tx:
|
||||
+ if (rx_align)
|
||||
+ dma_unmap_single(controller->dev, rx_dummy_dma,
|
||||
+ controller->in_fifo_sz, DMA_FROM_DEVICE);
|
||||
+err_map_rx_dummy:
|
||||
+ if (xfer->rx_buf)
|
||||
+ dma_unmap_single(controller->dev, rx_dma, xfer->len,
|
||||
+ DMA_FROM_DEVICE);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static irqreturn_t spi_qup_qup_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_qup *controller = dev_id;
|
||||
@@ -315,11 +545,13 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
error = -EIO;
|
||||
}
|
||||
|
||||
- if (opflags & QUP_OP_IN_SERVICE_FLAG)
|
||||
- spi_qup_fifo_read(controller, xfer);
|
||||
+ if (!controller->use_dma) {
|
||||
+ if (opflags & QUP_OP_IN_SERVICE_FLAG)
|
||||
+ spi_qup_fifo_read(controller, xfer);
|
||||
|
||||
- if (opflags & QUP_OP_OUT_SERVICE_FLAG)
|
||||
- spi_qup_fifo_write(controller, xfer);
|
||||
+ if (opflags & QUP_OP_OUT_SERVICE_FLAG)
|
||||
+ spi_qup_fifo_write(controller, xfer);
|
||||
+ }
|
||||
|
||||
spin_lock_irqsave(&controller->lock, flags);
|
||||
controller->error = error;
|
||||
@@ -339,6 +571,8 @@ static int spi_qup_io_config(struct spi_
|
||||
struct spi_qup *controller = spi_master_get_devdata(spi->master);
|
||||
u32 config, iomode, mode, control;
|
||||
int ret, n_words, w_size;
|
||||
+ size_t dma_align = dma_get_cache_alignment();
|
||||
+ u32 dma_available = 0;
|
||||
|
||||
if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
|
||||
dev_err(controller->dev, "too big size for loopback %d > %d\n",
|
||||
@@ -367,6 +601,11 @@ static int spi_qup_io_config(struct spi_
|
||||
n_words = xfer->len / w_size;
|
||||
controller->w_size = w_size;
|
||||
|
||||
+ if (controller->rx_chan &&
|
||||
+ IS_ALIGNED((size_t)xfer->tx_buf, dma_align) &&
|
||||
+ IS_ALIGNED((size_t)xfer->rx_buf, dma_align))
|
||||
+ dma_available = 1;
|
||||
+
|
||||
if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
|
||||
mode = QUP_IO_M_MODE_FIFO;
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
|
||||
@@ -374,19 +613,31 @@ static int spi_qup_io_config(struct spi_
|
||||
/* must be zero for FIFO */
|
||||
writel_relaxed(0, controller->base + QUP_MX_INPUT_CNT);
|
||||
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
|
||||
- } else {
|
||||
+ controller->use_dma = 0;
|
||||
+ } else if (!dma_available) {
|
||||
mode = QUP_IO_M_MODE_BLOCK;
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
|
||||
/* must be zero for BLOCK and BAM */
|
||||
writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
|
||||
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
|
||||
+ controller->use_dma = 0;
|
||||
+ } else {
|
||||
+ mode = QUP_IO_M_MODE_DMOV;
|
||||
+ writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
|
||||
+ writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
|
||||
+ controller->use_dma = 1;
|
||||
}
|
||||
|
||||
iomode = readl_relaxed(controller->base + QUP_IO_M_MODES);
|
||||
/* Set input and output transfer mode */
|
||||
iomode &= ~(QUP_IO_M_INPUT_MODE_MASK | QUP_IO_M_OUTPUT_MODE_MASK);
|
||||
- iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
|
||||
+
|
||||
+ if (!controller->use_dma)
|
||||
+ iomode &= ~(QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN);
|
||||
+ else
|
||||
+ iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
|
||||
+
|
||||
iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
|
||||
iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
|
||||
|
||||
@@ -428,6 +679,14 @@ static int spi_qup_io_config(struct spi_
|
||||
config &= ~(QUP_CONFIG_NO_INPUT | QUP_CONFIG_NO_OUTPUT | QUP_CONFIG_N);
|
||||
config |= xfer->bits_per_word - 1;
|
||||
config |= QUP_CONFIG_SPI_MODE;
|
||||
+
|
||||
+ if (controller->use_dma) {
|
||||
+ if (!xfer->tx_buf)
|
||||
+ config |= QUP_CONFIG_NO_OUTPUT;
|
||||
+ if (!xfer->rx_buf)
|
||||
+ config |= QUP_CONFIG_NO_INPUT;
|
||||
+ }
|
||||
+
|
||||
writel_relaxed(config, controller->base + QUP_CONFIG);
|
||||
|
||||
/* only write to OPERATIONAL_MASK when register is present */
|
||||
@@ -461,25 +720,29 @@ static int spi_qup_transfer_one(struct s
|
||||
controller->tx_bytes = 0;
|
||||
spin_unlock_irqrestore(&controller->lock, flags);
|
||||
|
||||
- if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
- dev_warn(controller->dev, "cannot set RUN state\n");
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (controller->use_dma) {
|
||||
+ ret = spi_qup_do_dma(controller, xfer);
|
||||
+ } else {
|
||||
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
+ dev_warn(controller->dev, "cannot set RUN state\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
- if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
|
||||
- dev_warn(controller->dev, "cannot set PAUSE state\n");
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (spi_qup_set_state(controller, QUP_STATE_PAUSE)) {
|
||||
+ dev_warn(controller->dev, "cannot set PAUSE state\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
- spi_qup_fifo_write(controller, xfer);
|
||||
+ spi_qup_fifo_write(controller, xfer);
|
||||
|
||||
- if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
- dev_warn(controller->dev, "cannot set EXECUTE state\n");
|
||||
- goto exit;
|
||||
- }
|
||||
+ if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
+ dev_warn(controller->dev, "cannot set EXECUTE state\n");
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
- if (!wait_for_completion_timeout(&controller->done, timeout))
|
||||
- ret = -ETIMEDOUT;
|
||||
+ if (!wait_for_completion_timeout(&controller->done, timeout))
|
||||
+ ret = -ETIMEDOUT;
|
||||
+ }
|
||||
exit:
|
||||
spi_qup_set_state(controller, QUP_STATE_RESET);
|
||||
spin_lock_irqsave(&controller->lock, flags);
|
||||
@@ -563,6 +826,7 @@ static int spi_qup_probe(struct platform
|
||||
master->transfer_one = spi_qup_transfer_one;
|
||||
master->dev.of_node = pdev->dev.of_node;
|
||||
master->auto_runtime_pm = true;
|
||||
+ master->dma_alignment = dma_get_cache_alignment();
|
||||
|
||||
platform_set_drvdata(pdev, master);
|
||||
|
||||
@@ -628,6 +892,56 @@ static int spi_qup_probe(struct platform
|
||||
QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
|
||||
base + QUP_ERROR_FLAGS_EN);
|
||||
|
||||
+ /* allocate dma resources, if available */
|
||||
+ controller->rx_chan = dma_request_slave_channel(&pdev->dev, "rx");
|
||||
+ if (controller->rx_chan) {
|
||||
+ controller->tx_chan =
|
||||
+ dma_request_slave_channel(&pdev->dev, "tx");
|
||||
+
|
||||
+ if (!controller->tx_chan) {
|
||||
+ dev_err(&pdev->dev, "Failed to allocate dma tx chan");
|
||||
+ dma_release_channel(controller->rx_chan);
|
||||
+ }
|
||||
+
|
||||
+ /* set DMA parameters */
|
||||
+ controller->rx_conf.device_fc = 1;
|
||||
+ controller->rx_conf.src_addr = res->start + QUP_INPUT_FIFO;
|
||||
+ controller->rx_conf.src_maxburst = controller->in_blk_sz;
|
||||
+
|
||||
+ controller->tx_conf.device_fc = 1;
|
||||
+ controller->tx_conf.dst_addr = res->start + QUP_OUTPUT_FIFO;
|
||||
+ controller->tx_conf.dst_maxburst = controller->out_blk_sz;
|
||||
+
|
||||
+ if (dmaengine_slave_config(controller->rx_chan,
|
||||
+ &controller->rx_conf)) {
|
||||
+ dev_err(&pdev->dev, "failed to configure RX channel\n");
|
||||
+
|
||||
+ dma_release_channel(controller->rx_chan);
|
||||
+ dma_release_channel(controller->tx_chan);
|
||||
+ controller->tx_chan = NULL;
|
||||
+ controller->rx_chan = NULL;
|
||||
+ } else if (dmaengine_slave_config(controller->tx_chan,
|
||||
+ &controller->tx_conf)) {
|
||||
+ dev_err(&pdev->dev, "failed to configure TX channel\n");
|
||||
+
|
||||
+ dma_release_channel(controller->rx_chan);
|
||||
+ dma_release_channel(controller->tx_chan);
|
||||
+ controller->tx_chan = NULL;
|
||||
+ controller->rx_chan = NULL;
|
||||
+ }
|
||||
+
|
||||
+ controller->dummy = devm_kmalloc(controller->dev, PAGE_SIZE,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ if (!controller->dummy) {
|
||||
+ dma_release_channel(controller->rx_chan);
|
||||
+ dma_release_channel(controller->tx_chan);
|
||||
+ controller->tx_chan = NULL;
|
||||
+ controller->rx_chan = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
writel_relaxed(0, base + SPI_CONFIG);
|
||||
writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);
|
||||
|
||||
@@ -740,6 +1054,11 @@ static int spi_qup_remove(struct platfor
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ if (controller->rx_chan)
|
||||
+ dma_release_channel(controller->rx_chan);
|
||||
+ if (controller->tx_chan)
|
||||
+ dma_release_channel(controller->tx_chan);
|
||||
+
|
||||
clk_disable_unprepare(controller->cclk);
|
||||
clk_disable_unprepare(controller->iclk);
|
||||
|
|
@ -1,376 +0,0 @@
|
|||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [v3] spi: qup: Fix incorrect block transfers
|
||||
From: Andy Gross <agross@codeaurora.org>
|
||||
X-Patchwork-Id: 5007321
|
||||
Message-Id: <1412112088-25928-1-git-send-email-agross@codeaurora.org>
|
||||
To: Mark Brown <broonie@kernel.org>
|
||||
Cc: linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
|
||||
linux-arm-kernel@lists.infradead.org, linux-arm-msm@vger.kernel.org,
|
||||
"Ivan T. Ivanov" <iivanov@mm-sol.com>,
|
||||
Bjorn Andersson <bjorn.andersson@sonymobile.com>,
|
||||
Kumar Gala <galak@codeaurora.org>, Andy Gross <agross@codeaurora.org>
|
||||
Date: Tue, 30 Sep 2014 16:21:28 -0500
|
||||
|
||||
This patch fixes a number of errors with the QUP block transfer mode. Errors
|
||||
manifested themselves as input underruns, output overruns, and timed out
|
||||
transactions.
|
||||
|
||||
The block mode does not require the priming that occurs in FIFO mode. At the
|
||||
moment that the QUP is placed into the RUN state, the QUP will immediately raise
|
||||
an interrupt if the request is a write. Therefore, there is no need to prime
|
||||
the pump.
|
||||
|
||||
In addition, the block transfers require that whole blocks of data are
|
||||
read/written at a time. The last block of data that completes a transaction may
|
||||
contain less than a full blocks worth of data.
|
||||
|
||||
Each block of data results in an input/output service interrupt accompanied with
|
||||
a input/output block flag set. Additional block reads/writes require clearing
|
||||
of the service flag. It is ok to check for additional blocks of data in the
|
||||
ISR, but you have to ack every block you transfer. Imbalanced acks result in
|
||||
early return from complete transactions with pending interrupts that still have
|
||||
to be ack'd. The next transaction can be affected by these interrupts.
|
||||
Transactions are deemed complete when the MAX_INPUT or MAX_OUTPUT flag are set.
|
||||
|
||||
Changes from v2:
|
||||
- Added in additional completion check so that transaction done is not
|
||||
prematurely signaled.
|
||||
- Fixed various review comments.
|
||||
|
||||
Changes from v1:
|
||||
- Split out read/write block function.
|
||||
- Removed extraneous checks for transfer length
|
||||
|
||||
Signed-off-by: Andy Gross <agross@codeaurora.org>
|
||||
|
||||
---
|
||||
drivers/spi/spi-qup.c | 201 ++++++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 148 insertions(+), 53 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi-qup.c
|
||||
+++ b/drivers/spi/spi-qup.c
|
||||
@@ -82,6 +82,8 @@
|
||||
#define QUP_IO_M_MODE_BAM 3
|
||||
|
||||
/* QUP_OPERATIONAL fields */
|
||||
+#define QUP_OP_IN_BLOCK_READ_REQ BIT(13)
|
||||
+#define QUP_OP_OUT_BLOCK_WRITE_REQ BIT(12)
|
||||
#define QUP_OP_MAX_INPUT_DONE_FLAG BIT(11)
|
||||
#define QUP_OP_MAX_OUTPUT_DONE_FLAG BIT(10)
|
||||
#define QUP_OP_IN_SERVICE_FLAG BIT(9)
|
||||
@@ -147,6 +149,7 @@ struct spi_qup {
|
||||
int tx_bytes;
|
||||
int rx_bytes;
|
||||
int qup_v1;
|
||||
+ int mode;
|
||||
|
||||
int use_dma;
|
||||
|
||||
@@ -213,30 +216,14 @@ static int spi_qup_set_state(struct spi_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-
|
||||
-static void spi_qup_fifo_read(struct spi_qup *controller,
|
||||
- struct spi_transfer *xfer)
|
||||
+static void spi_qup_fill_read_buffer(struct spi_qup *controller,
|
||||
+ struct spi_transfer *xfer, u32 data)
|
||||
{
|
||||
u8 *rx_buf = xfer->rx_buf;
|
||||
- u32 word, state;
|
||||
- int idx, shift, w_size;
|
||||
-
|
||||
- w_size = controller->w_size;
|
||||
-
|
||||
- while (controller->rx_bytes < xfer->len) {
|
||||
-
|
||||
- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
|
||||
- if (0 == (state & QUP_OP_IN_FIFO_NOT_EMPTY))
|
||||
- break;
|
||||
-
|
||||
- word = readl_relaxed(controller->base + QUP_INPUT_FIFO);
|
||||
-
|
||||
- if (!rx_buf) {
|
||||
- controller->rx_bytes += w_size;
|
||||
- continue;
|
||||
- }
|
||||
+ int idx, shift;
|
||||
|
||||
- for (idx = 0; idx < w_size; idx++, controller->rx_bytes++) {
|
||||
+ if (rx_buf)
|
||||
+ for (idx = 0; idx < controller->w_size; idx++) {
|
||||
/*
|
||||
* The data format depends on bytes per SPI word:
|
||||
* 4 bytes: 0x12345678
|
||||
@@ -244,41 +231,139 @@ static void spi_qup_fifo_read(struct spi
|
||||
* 1 byte : 0x00000012
|
||||
*/
|
||||
shift = BITS_PER_BYTE;
|
||||
- shift *= (w_size - idx - 1);
|
||||
- rx_buf[controller->rx_bytes] = word >> shift;
|
||||
+ shift *= (controller->w_size - idx - 1);
|
||||
+ rx_buf[controller->rx_bytes + idx] = data >> shift;
|
||||
+ }
|
||||
+
|
||||
+ controller->rx_bytes += controller->w_size;
|
||||
+}
|
||||
+
|
||||
+static void spi_qup_prepare_write_data(struct spi_qup *controller,
|
||||
+ struct spi_transfer *xfer, u32 *data)
|
||||
+{
|
||||
+ const u8 *tx_buf = xfer->tx_buf;
|
||||
+ u32 val;
|
||||
+ int idx;
|
||||
+
|
||||
+ *data = 0;
|
||||
+
|
||||
+ if (tx_buf)
|
||||
+ for (idx = 0; idx < controller->w_size; idx++) {
|
||||
+ val = tx_buf[controller->tx_bytes + idx];
|
||||
+ *data |= val << (BITS_PER_BYTE * (3 - idx));
|
||||
}
|
||||
+
|
||||
+ controller->tx_bytes += controller->w_size;
|
||||
+}
|
||||
+
|
||||
+static void spi_qup_fifo_read(struct spi_qup *controller,
|
||||
+ struct spi_transfer *xfer)
|
||||
+{
|
||||
+ u32 data;
|
||||
+
|
||||
+ /* clear service request */
|
||||
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
|
||||
+ controller->base + QUP_OPERATIONAL);
|
||||
+
|
||||
+ while (controller->rx_bytes < xfer->len) {
|
||||
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
+ QUP_OP_IN_FIFO_NOT_EMPTY))
|
||||
+ break;
|
||||
+
|
||||
+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
|
||||
+
|
||||
+ spi_qup_fill_read_buffer(controller, xfer, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void spi_qup_fifo_write(struct spi_qup *controller,
|
||||
- struct spi_transfer *xfer)
|
||||
+ struct spi_transfer *xfer)
|
||||
{
|
||||
- const u8 *tx_buf = xfer->tx_buf;
|
||||
- u32 word, state, data;
|
||||
- int idx, w_size;
|
||||
+ u32 data;
|
||||
|
||||
- w_size = controller->w_size;
|
||||
+ /* clear service request */
|
||||
+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
|
||||
+ controller->base + QUP_OPERATIONAL);
|
||||
|
||||
while (controller->tx_bytes < xfer->len) {
|
||||
|
||||
- state = readl_relaxed(controller->base + QUP_OPERATIONAL);
|
||||
- if (state & QUP_OP_OUT_FIFO_FULL)
|
||||
+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
+ QUP_OP_OUT_FIFO_FULL)
|
||||
break;
|
||||
|
||||
- word = 0;
|
||||
- for (idx = 0; idx < w_size; idx++, controller->tx_bytes++) {
|
||||
+ spi_qup_prepare_write_data(controller, xfer, &data);
|
||||
+ writel_relaxed(data, controller->base + QUP_OUTPUT_FIFO);
|
||||
|
||||
- if (!tx_buf) {
|
||||
- controller->tx_bytes += w_size;
|
||||
- break;
|
||||
- }
|
||||
+ }
|
||||
+}
|
||||
|
||||
- data = tx_buf[controller->tx_bytes];
|
||||
- word |= data << (BITS_PER_BYTE * (3 - idx));
|
||||
- }
|
||||
+static void spi_qup_block_read(struct spi_qup *controller,
|
||||
+ struct spi_transfer *xfer)
|
||||
+{
|
||||
+ u32 data;
|
||||
+ u32 reads_per_blk = controller->in_blk_sz >> 2;
|
||||
+ u32 num_words = (xfer->len - controller->rx_bytes) / controller->w_size;
|
||||
+ int i;
|
||||
+
|
||||
+ do {
|
||||
+ /* ACK by clearing service flag */
|
||||
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
|
||||
+ controller->base + QUP_OPERATIONAL);
|
||||
+
|
||||
+ /* transfer up to a block size of data in a single pass */
|
||||
+ for (i = 0; num_words && i < reads_per_blk; i++, num_words--) {
|
||||
+
|
||||
+ /* read data and fill up rx buffer */
|
||||
+ data = readl_relaxed(controller->base + QUP_INPUT_FIFO);
|
||||
+ spi_qup_fill_read_buffer(controller, xfer, data);
|
||||
+ }
|
||||
+
|
||||
+ /* check to see if next block is ready */
|
||||
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
+ QUP_OP_IN_BLOCK_READ_REQ))
|
||||
+ break;
|
||||
|
||||
- writel_relaxed(word, controller->base + QUP_OUTPUT_FIFO);
|
||||
- }
|
||||
+ } while (num_words);
|
||||
+
|
||||
+ /*
|
||||
+ * Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
|
||||
+ * reads, it has to be cleared again at the very end
|
||||
+ */
|
||||
+ if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
+ QUP_OP_MAX_INPUT_DONE_FLAG)
|
||||
+ writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
|
||||
+ controller->base + QUP_OPERATIONAL);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void spi_qup_block_write(struct spi_qup *controller,
|
||||
+ struct spi_transfer *xfer)
|
||||
+{
|
||||
+ u32 data;
|
||||
+ u32 writes_per_blk = controller->out_blk_sz >> 2;
|
||||
+ u32 num_words = (xfer->len - controller->tx_bytes) / controller->w_size;
|
||||
+ int i;
|
||||
+
|
||||
+ do {
|
||||
+ /* ACK by clearing service flag */
|
||||
+ writel_relaxed(QUP_OP_OUT_SERVICE_FLAG,
|
||||
+ controller->base + QUP_OPERATIONAL);
|
||||
+
|
||||
+ /* transfer up to a block size of data in a single pass */
|
||||
+ for (i = 0; num_words && i < writes_per_blk; i++, num_words--) {
|
||||
+
|
||||
+ /* swizzle the bytes for output and write out */
|
||||
+ spi_qup_prepare_write_data(controller, xfer, &data);
|
||||
+ writel_relaxed(data,
|
||||
+ controller->base + QUP_OUTPUT_FIFO);
|
||||
+ }
|
||||
+
|
||||
+ /* check to see if next block is ready */
|
||||
+ if (!(readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
+ QUP_OP_OUT_BLOCK_WRITE_REQ))
|
||||
+ break;
|
||||
+
|
||||
+ } while (num_words);
|
||||
}
|
||||
|
||||
static void qup_dma_callback(void *data)
|
||||
@@ -515,9 +600,9 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
|
||||
writel_relaxed(qup_err, controller->base + QUP_ERROR_FLAGS);
|
||||
writel_relaxed(spi_err, controller->base + SPI_ERROR_FLAGS);
|
||||
- writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
|
||||
|
||||
if (!xfer) {
|
||||
+ writel_relaxed(opflags, controller->base + QUP_OPERATIONAL);
|
||||
dev_err_ratelimited(controller->dev, "unexpected irq %08x %08x %08x\n",
|
||||
qup_err, spi_err, opflags);
|
||||
return IRQ_HANDLED;
|
||||
@@ -546,11 +631,19 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
}
|
||||
|
||||
if (!controller->use_dma) {
|
||||
- if (opflags & QUP_OP_IN_SERVICE_FLAG)
|
||||
- spi_qup_fifo_read(controller, xfer);
|
||||
+ if (opflags & QUP_OP_IN_SERVICE_FLAG) {
|
||||
+ if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
|
||||
+ spi_qup_block_read(controller, xfer);
|
||||
+ else
|
||||
+ spi_qup_fifo_read(controller, xfer);
|
||||
+ }
|
||||
|
||||
- if (opflags & QUP_OP_OUT_SERVICE_FLAG)
|
||||
- spi_qup_fifo_write(controller, xfer);
|
||||
+ if (opflags & QUP_OP_OUT_SERVICE_FLAG) {
|
||||
+ if (opflags & QUP_OP_OUT_BLOCK_WRITE_REQ)
|
||||
+ spi_qup_block_write(controller, xfer);
|
||||
+ else
|
||||
+ spi_qup_fifo_write(controller, xfer);
|
||||
+ }
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&controller->lock, flags);
|
||||
@@ -558,7 +651,8 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
controller->xfer = xfer;
|
||||
spin_unlock_irqrestore(&controller->lock, flags);
|
||||
|
||||
- if (controller->rx_bytes == xfer->len || error)
|
||||
+ if ((controller->rx_bytes == xfer->len &&
|
||||
+ (opflags & QUP_OP_MAX_INPUT_DONE_FLAG)) || error)
|
||||
complete(&controller->done);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@@ -569,7 +663,7 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
|
||||
{
|
||||
struct spi_qup *controller = spi_master_get_devdata(spi->master);
|
||||
- u32 config, iomode, mode, control;
|
||||
+ u32 config, iomode, control;
|
||||
int ret, n_words, w_size;
|
||||
size_t dma_align = dma_get_cache_alignment();
|
||||
u32 dma_available = 0;
|
||||
@@ -607,7 +701,7 @@ static int spi_qup_io_config(struct spi_
|
||||
dma_available = 1;
|
||||
|
||||
if (n_words <= (controller->in_fifo_sz / sizeof(u32))) {
|
||||
- mode = QUP_IO_M_MODE_FIFO;
|
||||
+ controller->mode = QUP_IO_M_MODE_FIFO;
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_READ_CNT);
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_WRITE_CNT);
|
||||
/* must be zero for FIFO */
|
||||
@@ -615,7 +709,7 @@ static int spi_qup_io_config(struct spi_
|
||||
writel_relaxed(0, controller->base + QUP_MX_OUTPUT_CNT);
|
||||
controller->use_dma = 0;
|
||||
} else if (!dma_available) {
|
||||
- mode = QUP_IO_M_MODE_BLOCK;
|
||||
+ controller->mode = QUP_IO_M_MODE_BLOCK;
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_INPUT_CNT);
|
||||
writel_relaxed(n_words, controller->base + QUP_MX_OUTPUT_CNT);
|
||||
/* must be zero for BLOCK and BAM */
|
||||
@@ -623,7 +717,7 @@ static int spi_qup_io_config(struct spi_
|
||||
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
|
||||
controller->use_dma = 0;
|
||||
} else {
|
||||
- mode = QUP_IO_M_MODE_DMOV;
|
||||
+ controller->mode = QUP_IO_M_MODE_DMOV;
|
||||
writel_relaxed(0, controller->base + QUP_MX_READ_CNT);
|
||||
writel_relaxed(0, controller->base + QUP_MX_WRITE_CNT);
|
||||
controller->use_dma = 1;
|
||||
@@ -638,8 +732,8 @@ static int spi_qup_io_config(struct spi_
|
||||
else
|
||||
iomode |= QUP_IO_M_PACK_EN | QUP_IO_M_UNPACK_EN;
|
||||
|
||||
- iomode |= (mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
|
||||
- iomode |= (mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
|
||||
+ iomode |= (controller->mode << QUP_IO_M_OUTPUT_MODE_MASK_SHIFT);
|
||||
+ iomode |= (controller->mode << QUP_IO_M_INPUT_MODE_MASK_SHIFT);
|
||||
|
||||
writel_relaxed(iomode, controller->base + QUP_IO_M_MODES);
|
||||
|
||||
@@ -733,7 +827,8 @@ static int spi_qup_transfer_one(struct s
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- spi_qup_fifo_write(controller, xfer);
|
||||
+ if (controller->mode == QUP_IO_M_MODE_FIFO)
|
||||
+ spi_qup_fifo_write(controller, xfer);
|
||||
|
||||
if (spi_qup_set_state(controller, QUP_STATE_RUN)) {
|
||||
dev_warn(controller->dev, "cannot set EXECUTE state\n");
|
||||
@@ -750,6 +845,7 @@ exit:
|
||||
if (!ret)
|
||||
ret = controller->error;
|
||||
spin_unlock_irqrestore(&controller->lock, flags);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
From 4faba89e3ffbb1c5f6232651375b9b3212b50f02 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Gross <agross@codeaurora.org>
|
||||
Date: Thu, 15 Jan 2015 17:56:02 -0800
|
||||
Subject: [PATCH] spi: qup: Ensure done detection
|
||||
|
||||
This patch fixes an issue where a SPI transaction has completed, but the done
|
||||
condition is missed. This occurs because at the time of interrupt the
|
||||
MAX_INPUT_DONE_FLAG is not asserted. However, in the process of reading blocks
|
||||
of data from the FIFO, the last portion of data comes in.
|
||||
|
||||
The opflags read at the beginning of the irq handler no longer matches the
|
||||
current opflag state. To get around this condition, the block read function
|
||||
should update the opflags so that done detection is correct after the return.
|
||||
|
||||
Change-Id: If109e0eeb432f96000d765c4b34dbb2269f8093f
|
||||
Signed-off-by: Andy Gross <agross@codeaurora.org>
|
||||
---
|
||||
drivers/spi/spi-qup.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/spi/spi-qup.c
|
||||
+++ b/drivers/spi/spi-qup.c
|
||||
@@ -298,7 +298,7 @@ static void spi_qup_fifo_write(struct sp
|
||||
}
|
||||
|
||||
static void spi_qup_block_read(struct spi_qup *controller,
|
||||
- struct spi_transfer *xfer)
|
||||
+ struct spi_transfer *xfer, u32 *opflags)
|
||||
{
|
||||
u32 data;
|
||||
u32 reads_per_blk = controller->in_blk_sz >> 2;
|
||||
@@ -327,10 +327,12 @@ static void spi_qup_block_read(struct sp
|
||||
|
||||
/*
|
||||
* Due to extra stickiness of the QUP_OP_IN_SERVICE_FLAG during block
|
||||
- * reads, it has to be cleared again at the very end
|
||||
+ * reads, it has to be cleared again at the very end. However, be sure
|
||||
+ * to refresh opflags value because MAX_INPUT_DONE_FLAG may now be
|
||||
+ * present and this is used to determine if transaction is complete
|
||||
*/
|
||||
- if (readl_relaxed(controller->base + QUP_OPERATIONAL) &
|
||||
- QUP_OP_MAX_INPUT_DONE_FLAG)
|
||||
+ *opflags = readl_relaxed(controller->base + QUP_OPERATIONAL);
|
||||
+ if (*opflags & QUP_OP_MAX_INPUT_DONE_FLAG)
|
||||
writel_relaxed(QUP_OP_IN_SERVICE_FLAG,
|
||||
controller->base + QUP_OPERATIONAL);
|
||||
|
||||
@@ -633,7 +635,7 @@ static irqreturn_t spi_qup_qup_irq(int i
|
||||
if (!controller->use_dma) {
|
||||
if (opflags & QUP_OP_IN_SERVICE_FLAG) {
|
||||
if (opflags & QUP_OP_IN_BLOCK_READ_REQ)
|
||||
- spi_qup_block_read(controller, xfer);
|
||||
+ spi_qup_block_read(controller, xfer, &opflags);
|
||||
else
|
||||
spi_qup_fifo_read(controller, xfer);
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
From fded70251b1b58f68de1d3757ece9965f0b75452 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Thu, 19 Feb 2015 20:19:30 -0800
|
||||
Subject: [PATCH 1/3] watchdog: qcom: use timer devicetree binding
|
||||
|
||||
MSM watchdog configuration happens in the same register block as the
|
||||
timer, so we'll use the same binding as the existing timer.
|
||||
|
||||
The qcom-wdt will now be probed when devicetree has an entry compatible
|
||||
with "qcom,kpss-timer" or "qcom-scss-timer".
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/watchdog/qcom-wdt.c | 21 +++++++++++++++------
|
||||
1 file changed, 15 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/watchdog/qcom-wdt.c
|
||||
+++ b/drivers/watchdog/qcom-wdt.c
|
||||
@@ -20,9 +20,9 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/watchdog.h>
|
||||
|
||||
-#define WDT_RST 0x0
|
||||
-#define WDT_EN 0x8
|
||||
-#define WDT_BITE_TIME 0x24
|
||||
+#define WDT_RST 0x38
|
||||
+#define WDT_EN 0x40
|
||||
+#define WDT_BITE_TIME 0x5C
|
||||
|
||||
struct qcom_wdt {
|
||||
struct watchdog_device wdd;
|
||||
@@ -117,6 +117,8 @@ static int qcom_wdt_probe(struct platfor
|
||||
{
|
||||
struct qcom_wdt *wdt;
|
||||
struct resource *res;
|
||||
+ struct device_node *np = pdev->dev.of_node;
|
||||
+ u32 percpu_offset;
|
||||
int ret;
|
||||
|
||||
wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
|
||||
@@ -124,6 +126,14 @@ static int qcom_wdt_probe(struct platfor
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+
|
||||
+ /* We use CPU0's DGT for the watchdog */
|
||||
+ if (of_property_read_u32(np, "cpu-offset", &percpu_offset))
|
||||
+ percpu_offset = 0;
|
||||
+
|
||||
+ res->start += percpu_offset;
|
||||
+ res->end += percpu_offset;
|
||||
+
|
||||
wdt->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(wdt->base))
|
||||
return PTR_ERR(wdt->base);
|
||||
@@ -203,9 +213,8 @@ static int qcom_wdt_remove(struct platfo
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_wdt_of_table[] = {
|
||||
- { .compatible = "qcom,kpss-wdt-msm8960", },
|
||||
- { .compatible = "qcom,kpss-wdt-apq8064", },
|
||||
- { .compatible = "qcom,kpss-wdt-ipq8064", },
|
||||
+ { .compatible = "qcom,kpss-timer" },
|
||||
+ { .compatible = "qcom,scss-timer" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_wdt_of_table);
|
|
@ -1,48 +0,0 @@
|
|||
From 297cf8136ecd6a56520888fd28948393766b8ee7 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Thu, 19 Feb 2015 20:27:39 -0800
|
||||
Subject: [PATCH 2/3] ARM: qcom: add description of KPSS WDT for IPQ8064
|
||||
|
||||
Add the watchdog related entries to the Krait Processor Sub-system
|
||||
(KPSS) timer IPQ8064 devicetree section. Also, add a fixed-clock
|
||||
description of SLEEP_CLK, which will do for now.
|
||||
|
||||
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
arch/arm/boot/dts/qcom-ipq8064.dtsi | 14 +++++++++++++-
|
||||
1 file changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
@@ -60,6 +60,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ clocks {
|
||||
+ sleep_clk: sleep_clk {
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-frequency = <32768>;
|
||||
+ #clock-cells = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
soc: soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@@ -89,10 +97,14 @@
|
||||
compatible = "qcom,kpss-timer", "qcom,msm-timer";
|
||||
interrupts = <1 1 0x301>,
|
||||
<1 2 0x301>,
|
||||
- <1 3 0x301>;
|
||||
+ <1 3 0x301>,
|
||||
+ <1 4 0x301>,
|
||||
+ <1 5 0x301>;
|
||||
reg = <0x0200a000 0x100>;
|
||||
clock-frequency = <25000000>,
|
||||
<32768>;
|
||||
+ clocks = <&sleep_clk>;
|
||||
+ clock-names = "sleep";
|
||||
cpu-offset = <0x80000>;
|
||||
};
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From e535f01dffb6dd9e09934fa219be52af3437a8f6 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Thu, 19 Feb 2015 20:36:27 -0800
|
||||
Subject: [PATCH 3/3] ARM: msm: add watchdog entries to DT timer binding doc
|
||||
|
||||
The watchdog has been reworked to use the same DT node as the timer.
|
||||
This change is updating the device tree doc accordingly.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/arm/msm/timer.txt | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/arm/msm/timer.txt
|
||||
+++ b/Documentation/devicetree/bindings/arm/msm/timer.txt
|
||||
@@ -9,11 +9,17 @@ Properties:
|
||||
"qcom,scss-timer" - scorpion subsystem
|
||||
|
||||
- interrupts : Interrupts for the debug timer, the first general purpose
|
||||
- timer, and optionally a second general purpose timer in that
|
||||
- order.
|
||||
+ timer, and optionally a second general purpose timer, and
|
||||
+ optionally as well, 2 watchdog interrupts, in that order.
|
||||
|
||||
- reg : Specifies the base address of the timer registers.
|
||||
|
||||
+- clocks: Reference to the parent clocks, one per output clock. The parents
|
||||
+ must appear in the same order as the clock names.
|
||||
+
|
||||
+- clock-names: The name of the clocks as free-form strings. They should be in
|
||||
+ the same order as the clocks.
|
||||
+
|
||||
- clock-frequency : The frequency of the debug timer and the general purpose
|
||||
timer(s) in Hz in that order.
|
||||
|
||||
@@ -29,9 +35,13 @@ Example:
|
||||
compatible = "qcom,scss-timer", "qcom,msm-timer";
|
||||
interrupts = <1 1 0x301>,
|
||||
<1 2 0x301>,
|
||||
- <1 3 0x301>;
|
||||
+ <1 3 0x301>,
|
||||
+ <1 4 0x301>,
|
||||
+ <1 5 0x301>;
|
||||
reg = <0x0200a000 0x100>;
|
||||
clock-frequency = <19200000>,
|
||||
<32768>;
|
||||
+ clocks = <&sleep_clk>;
|
||||
+ clock-names = "sleep";
|
||||
cpu-offset = <0x40000>;
|
||||
};
|
|
@ -1,71 +0,0 @@
|
|||
From 4d54b0adfa67476e6509bc8646b9dbac642e8a29 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Cartwright <joshc@codeaurora.org>
|
||||
Date: Thu, 26 Mar 2015 11:29:26 -0700
|
||||
Subject: [PATCH] mfd: qcom_rpm: Add support for IPQ8064
|
||||
|
||||
The IPQ8064 also includes an RPM following the same message structure as
|
||||
other chips. In addition, it supports a few new resource types to
|
||||
support the NSS fabric clocks and the SMB208/SMB209 regulators found on
|
||||
the reference boards.
|
||||
|
||||
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
Signed-off-by: Lee Jones <lee.jones@linaro.org>
|
||||
---
|
||||
drivers/mfd/qcom_rpm.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 41 insertions(+)
|
||||
|
||||
--- a/drivers/mfd/qcom_rpm.c
|
||||
+++ b/drivers/mfd/qcom_rpm.c
|
||||
@@ -323,10 +323,51 @@ static const struct qcom_rpm_data msm896
|
||||
.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
|
||||
};
|
||||
|
||||
+static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
|
||||
+ [QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
|
||||
+ [QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
|
||||
+ [QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 },
|
||||
+ [QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
|
||||
+ [QCOM_RPM_NSS_FABRIC_0_CLK] = { 29, 13, 10, 1 },
|
||||
+ [QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
|
||||
+ [QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 },
|
||||
+ [QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 },
|
||||
+ [QCOM_RPM_NSS_FABRIC_1_CLK] = { 33, 17, 14, 1 },
|
||||
+ [QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 },
|
||||
+ [QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 2 },
|
||||
+ [QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 3 },
|
||||
+ [QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 },
|
||||
+ [QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 },
|
||||
+ [QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 2 },
|
||||
+ [QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 3 },
|
||||
+ [QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 },
|
||||
+ [QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 },
|
||||
+ [QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 2 },
|
||||
+ [QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 3 },
|
||||
+ [QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 },
|
||||
+ [QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 2 },
|
||||
+ [QCOM_RPM_CXO_BUFFERS] = { 209, 33, 31, 1 },
|
||||
+ [QCOM_RPM_USB_OTG_SWITCH] = { 210, 34, 32, 1 },
|
||||
+ [QCOM_RPM_HDMI_SWITCH] = { 211, 35, 33, 1 },
|
||||
+ [QCOM_RPM_DDR_DMM] = { 212, 36, 34, 2 },
|
||||
+ [QCOM_RPM_VDDMIN_GPIO] = { 215, 40, 39, 1 },
|
||||
+ [QCOM_RPM_SMB208_S1a] = { 216, 41, 90, 2 },
|
||||
+ [QCOM_RPM_SMB208_S1b] = { 218, 43, 91, 2 },
|
||||
+ [QCOM_RPM_SMB208_S2a] = { 220, 45, 92, 2 },
|
||||
+ [QCOM_RPM_SMB208_S2b] = { 222, 47, 93, 2 },
|
||||
+};
|
||||
+
|
||||
+static const struct qcom_rpm_data ipq806x_template = {
|
||||
+ .version = 3,
|
||||
+ .resource_table = ipq806x_rpm_resource_table,
|
||||
+ .n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id qcom_rpm_of_match[] = {
|
||||
{ .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
|
||||
{ .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
|
||||
{ .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
|
||||
+ { .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);
|
|
@ -1,42 +0,0 @@
|
|||
From 30bc3aa5c4ed3072bdff7d915772df1b91307ed4 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Cartwright <joshc@codeaurora.org>
|
||||
Date: Thu, 26 Mar 2015 11:29:25 -0700
|
||||
Subject: [PATCH] mfd: devicetree: qcom_rpm: Document IPQ8064 resources
|
||||
|
||||
The IPQ8064 SoC has several RPM-controlled resources, an NSS fabrick
|
||||
clock and four regulator resources. Provide definitions for them.
|
||||
|
||||
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
|
||||
[sboyd@codeaurora.org: Drop regulator part of binding]
|
||||
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
||||
Signed-off-by: Lee Jones <lee.jones@linaro.org>
|
||||
---
|
||||
Documentation/devicetree/bindings/mfd/qcom-rpm.txt | 1 +
|
||||
include/dt-bindings/mfd/qcom-rpm.h | 6 ++++++
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
--- a/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
|
||||
+++ b/Documentation/devicetree/bindings/mfd/qcom-rpm.txt
|
||||
@@ -12,6 +12,7 @@ frequencies.
|
||||
"qcom,rpm-apq8064"
|
||||
"qcom,rpm-msm8660"
|
||||
"qcom,rpm-msm8960"
|
||||
+ "qcom,rpm-ipq8064"
|
||||
|
||||
- reg:
|
||||
Usage: required
|
||||
--- a/include/dt-bindings/mfd/qcom-rpm.h
|
||||
+++ b/include/dt-bindings/mfd/qcom-rpm.h
|
||||
@@ -141,6 +141,12 @@
|
||||
#define QCOM_RPM_SYS_FABRIC_MODE 131
|
||||
#define QCOM_RPM_USB_OTG_SWITCH 132
|
||||
#define QCOM_RPM_VDDMIN_GPIO 133
|
||||
+#define QCOM_RPM_NSS_FABRIC_0_CLK 134
|
||||
+#define QCOM_RPM_NSS_FABRIC_1_CLK 135
|
||||
+#define QCOM_RPM_SMB208_S1a 136
|
||||
+#define QCOM_RPM_SMB208_S1b 137
|
||||
+#define QCOM_RPM_SMB208_S2a 138
|
||||
+#define QCOM_RPM_SMB208_S2b 139
|
||||
|
||||
/*
|
||||
* Constants used to select force mode for regulators.
|
|
@ -1,175 +0,0 @@
|
|||
From df944689d491e6af533173bf2ef448c3dd334f15 Mon Sep 17 00:00:00 2001
|
||||
From: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
Date: Mon, 11 May 2015 15:15:25 -0700
|
||||
Subject: [PATCH 6/8] net: stmmac: create one debugfs dir per net-device
|
||||
|
||||
stmmac DebugFS entries are currently global to the driver. As a result,
|
||||
having more than one stmmac device in the system creates the following
|
||||
error:
|
||||
* ERROR stmmaceth, debugfs create directory failed
|
||||
* stmmac_hw_setup: failed debugFS registration
|
||||
|
||||
This also results in being able to access the debugfs information for
|
||||
the first registered device only.
|
||||
|
||||
This patch changes the debugfs structure to have one sub-directory per
|
||||
net-device. Files under "/sys/kernel/debug/stmmaceth" will now show-up
|
||||
under /sys/kernel/debug/stmmaceth/ethN/.
|
||||
|
||||
Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
||||
---
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 6 ++
|
||||
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 76 ++++++++++++++++-------
|
||||
2 files changed, 59 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
|
||||
@@ -116,6 +116,12 @@ struct stmmac_priv {
|
||||
int use_riwt;
|
||||
int irq_wake;
|
||||
spinlock_t ptp_lock;
|
||||
+
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+ struct dentry *dbgfs_dir;
|
||||
+ struct dentry *dbgfs_rings_status;
|
||||
+ struct dentry *dbgfs_dma_cap;
|
||||
+#endif
|
||||
};
|
||||
|
||||
int stmmac_mdio_unregister(struct net_device *ndev);
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
|
||||
@@ -119,7 +119,7 @@ static irqreturn_t stmmac_interrupt(int
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int stmmac_init_fs(struct net_device *dev);
|
||||
-static void stmmac_exit_fs(void);
|
||||
+static void stmmac_exit_fs(struct net_device *dev);
|
||||
#endif
|
||||
|
||||
#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
|
||||
@@ -1918,7 +1918,7 @@ static int stmmac_release(struct net_dev
|
||||
netif_carrier_off(dev);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
- stmmac_exit_fs();
|
||||
+ stmmac_exit_fs(dev);
|
||||
#endif
|
||||
|
||||
stmmac_release_ptp(priv);
|
||||
@@ -2510,8 +2510,6 @@ static int stmmac_ioctl(struct net_devic
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static struct dentry *stmmac_fs_dir;
|
||||
-static struct dentry *stmmac_rings_status;
|
||||
-static struct dentry *stmmac_dma_cap;
|
||||
|
||||
static void sysfs_display_ring(void *head, int size, int extend_desc,
|
||||
struct seq_file *seq)
|
||||
@@ -2650,36 +2648,39 @@ static const struct file_operations stmm
|
||||
|
||||
static int stmmac_init_fs(struct net_device *dev)
|
||||
{
|
||||
- /* Create debugfs entries */
|
||||
- stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ /* Create per netdev entries */
|
||||
+ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir);
|
||||
|
||||
- if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
||||
- pr_err("ERROR %s, debugfs create directory failed\n",
|
||||
- STMMAC_RESOURCE_NAME);
|
||||
+ if (!priv->dbgfs_dir || IS_ERR(priv->dbgfs_dir)) {
|
||||
+ pr_err("ERROR %s/%s, debugfs create directory failed\n",
|
||||
+ STMMAC_RESOURCE_NAME, dev->name);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Entry to report DMA RX/TX rings */
|
||||
- stmmac_rings_status = debugfs_create_file("descriptors_status",
|
||||
- S_IRUGO, stmmac_fs_dir, dev,
|
||||
- &stmmac_rings_status_fops);
|
||||
+ priv->dbgfs_rings_status =
|
||||
+ debugfs_create_file("descriptors_status", S_IRUGO,
|
||||
+ priv->dbgfs_dir, dev,
|
||||
+ &stmmac_rings_status_fops);
|
||||
|
||||
- if (!stmmac_rings_status || IS_ERR(stmmac_rings_status)) {
|
||||
+ if (!priv->dbgfs_rings_status || IS_ERR(priv->dbgfs_rings_status)) {
|
||||
pr_info("ERROR creating stmmac ring debugfs file\n");
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Entry to report the DMA HW features */
|
||||
- stmmac_dma_cap = debugfs_create_file("dma_cap", S_IRUGO, stmmac_fs_dir,
|
||||
- dev, &stmmac_dma_cap_fops);
|
||||
+ priv->dbgfs_dma_cap = debugfs_create_file("dma_cap", S_IRUGO,
|
||||
+ priv->dbgfs_dir,
|
||||
+ dev, &stmmac_dma_cap_fops);
|
||||
|
||||
- if (!stmmac_dma_cap || IS_ERR(stmmac_dma_cap)) {
|
||||
+ if (!priv->dbgfs_dma_cap || IS_ERR(priv->dbgfs_dma_cap)) {
|
||||
pr_info("ERROR creating stmmac MMC debugfs file\n");
|
||||
- debugfs_remove(stmmac_rings_status);
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -2687,11 +2688,11 @@ static int stmmac_init_fs(struct net_dev
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void stmmac_exit_fs(void)
|
||||
+static void stmmac_exit_fs(struct net_device *dev)
|
||||
{
|
||||
- debugfs_remove(stmmac_rings_status);
|
||||
- debugfs_remove(stmmac_dma_cap);
|
||||
- debugfs_remove(stmmac_fs_dir);
|
||||
+ struct stmmac_priv *priv = netdev_priv(dev);
|
||||
+
|
||||
+ debugfs_remove_recursive(priv->dbgfs_dir);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
@@ -3136,6 +3137,35 @@ err:
|
||||
__setup("stmmaceth=", stmmac_cmdline_opt);
|
||||
#endif /* MODULE */
|
||||
|
||||
+static int __init stmmac_init(void)
|
||||
+{
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+ /* Create debugfs main directory if it doesn't exist yet */
|
||||
+ if (stmmac_fs_dir == NULL) {
|
||||
+ stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL);
|
||||
+
|
||||
+ if (!stmmac_fs_dir || IS_ERR(stmmac_fs_dir)) {
|
||||
+ pr_err("ERROR %s, debugfs create directory failed\n",
|
||||
+ STMMAC_RESOURCE_NAME);
|
||||
+
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit stmmac_exit(void)
|
||||
+{
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+ debugfs_remove_recursive(stmmac_fs_dir);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+module_init(stmmac_init)
|
||||
+module_exit(stmmac_exit)
|
||||
+
|
||||
MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet device driver");
|
||||
MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -17,27 +17,27 @@
|
|||
i2c4_pins: i2c4_pinmux {
|
||||
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
@@ -140,7 +140,7 @@
|
||||
ranges;
|
||||
status = "disabled";
|
||||
@@ -159,7 +159,7 @@
|
||||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
- serial@12490000 {
|
||||
+ uart2: serial@12490000 {
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x12490000 0x1000>,
|
||||
<0x12480000 0x1000>;
|
||||
@@ -175,7 +175,7 @@
|
||||
ranges;
|
||||
status = "disabled";
|
||||
@@ -197,7 +197,7 @@
|
||||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
- serial@16340000 {
|
||||
+ uart4: serial@16340000 {
|
||||
compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm";
|
||||
reg = <0x16340000 0x1000>,
|
||||
<0x16300000 0x1000>;
|
||||
@@ -209,7 +209,7 @@
|
||||
ranges;
|
||||
status = "disabled";
|
||||
@@ -234,7 +234,7 @@
|
||||
|
||||
syscon-tcsr = <&tcsr>;
|
||||
|
||||
- serial@1a240000 {
|
||||
+ uart5: serial@1a240000 {
|
|
@ -15,7 +15,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
|
||||
--- a/arch/arm/boot/dts/Makefile
|
||||
+++ b/arch/arm/boot/dts/Makefile
|
||||
@@ -438,6 +438,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||
@@ -451,6 +451,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
|
||||
qcom-apq8084-ifc6540.dtb \
|
||||
qcom-apq8084-mtp.dtb \
|
||||
qcom-ipq8064-ap148.dtb \
|
|
@ -24,7 +24,7 @@
|
|||
gsbi5: gsbi@1a200000 {
|
||||
--- a/drivers/clk/qcom/gcc-ipq806x.c
|
||||
+++ b/drivers/clk/qcom/gcc-ipq806x.c
|
||||
@@ -805,7 +805,7 @@ static struct clk_rcg gsbi7_qup_src = {
|
||||
@@ -807,7 +807,7 @@ static struct clk_rcg gsbi7_qup_src = {
|
||||
.parent_names = gcc_pxo_pll8,
|
||||
.num_parents = 2,
|
||||
.ops = &clk_rcg_ops,
|
||||
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
},
|
||||
};
|
||||
@@ -821,7 +821,7 @@ static struct clk_branch gsbi7_qup_clk =
|
||||
@@ -823,7 +823,7 @@ static struct clk_branch gsbi7_qup_clk =
|
||||
.parent_names = (const char *[]){ "gsbi7_qup_src" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch_ops,
|
||||
|
@ -42,7 +42,7 @@
|
|||
},
|
||||
},
|
||||
};
|
||||
@@ -869,7 +869,7 @@ static struct clk_branch gsbi4_h_clk = {
|
||||
@@ -871,7 +871,7 @@ static struct clk_branch gsbi4_h_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gsbi4_h_clk",
|
||||
.ops = &clk_branch_ops,
|
|
@ -34,7 +34,7 @@ MAINTAINERS | 7 +
|
|||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -7511,6 +7511,13 @@ L: linux-pci@vger.kernel.org
|
||||
@@ -7599,6 +7599,13 @@ L: linux-pci@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/pci/host/*spear*
|
||||
|
||||
|
@ -50,9 +50,9 @@ MAINTAINERS | 7 +
|
|||
L: linux-pcmcia@lists.infradead.org
|
||||
--- a/drivers/pci/host/Kconfig
|
||||
+++ b/drivers/pci/host/Kconfig
|
||||
@@ -106,4 +106,13 @@ config PCI_VERSATILE
|
||||
bool "ARM Versatile PB PCI controller"
|
||||
depends on ARCH_VERSATILE
|
||||
@@ -125,4 +125,13 @@ config PCIE_IPROC_PLATFORM
|
||||
Say Y here if you want to use the Broadcom iProc PCIe controller
|
||||
through the generic platform bus interface
|
||||
|
||||
+config PCIE_QCOM
|
||||
+ bool "Qualcomm PCIe controller"
|
||||
|
@ -746,8 +746,8 @@ MAINTAINERS | 7 +
|
|||
+MODULE_ALIAS("platform:qcom-pcie");
|
||||
--- a/drivers/pci/host/Makefile
|
||||
+++ b/drivers/pci/host/Makefile
|
||||
@@ -13,3 +13,4 @@ obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx
|
||||
obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
|
||||
obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
|
||||
@@ -15,3 +15,4 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-laye
|
||||
obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
|
||||
obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
|
||||
obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
|
||||
+obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
|
|
@ -120,20 +120,19 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
};
|
||||
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "skeleton.dtsi"
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
|
||||
#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
|
||||
#include <dt-bindings/soc/qcom,gsbi.h>
|
||||
+#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
|
||||
+#include <include/dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
/ {
|
||||
model = "Qualcomm IPQ8064";
|
||||
@@ -291,5 +293,128 @@
|
||||
#clock-cells = <1>;
|
||||
@@ -329,5 +331,128 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
+
|
||||
|
||||
+ pcie0: pci@1b500000 {
|
||||
+ compatible = "qcom,pcie-v0";
|
||||
+ reg = <0x1b500000 0x1000
|
||||
|
@ -256,5 +255,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
};
|
||||
};
|
|
@ -5,12 +5,12 @@
|
|||
#include "skeleton.dtsi"
|
||||
#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
|
||||
+#include <dt-bindings/mfd/qcom-rpm.h>
|
||||
#include <dt-bindings/clock/qcom,lcc-ipq806x.h>
|
||||
#include <dt-bindings/soc/qcom,gsbi.h>
|
||||
#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
|
||||
#include <include/dt-bindings/interrupt-controller/arm-gic.h>
|
||||
@@ -76,6 +77,63 @@
|
||||
ranges;
|
||||
compatible = "simple-bus";
|
||||
@@ -92,6 +93,63 @@
|
||||
reg-names = "lpass-lpaif";
|
||||
};
|
||||
|
||||
+ rpm@108000 {
|
||||
+ compatible = "qcom,rpm-ipq8064";
|
||||
|
@ -72,7 +72,7 @@
|
|||
qcom_pinmux: pinmux@800000 {
|
||||
compatible = "qcom,ipq8064-pinctrl";
|
||||
reg = <0x800000 0x4000>;
|
||||
@@ -120,6 +178,12 @@
|
||||
@@ -136,6 +194,12 @@
|
||||
reg = <0x02098000 0x1000>, <0x02008000 0x1000>;
|
||||
};
|
||||
|
|
@ -47,7 +47,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
|
|||
|
||||
--- a/drivers/clk/clk.c
|
||||
+++ b/drivers/clk/clk.c
|
||||
@@ -1696,21 +1696,24 @@ static struct clk_core *clk_propagate_ra
|
||||
@@ -1743,21 +1743,24 @@ static struct clk_core *clk_propagate_ra
|
||||
* walk down a subtree and set the new rates notifying the rate
|
||||
* change on the way
|
||||
*/
|
||||
|
@ -79,16 +79,16 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
|
|||
|
||||
if (clk->new_parent && clk->new_parent != clk->parent) {
|
||||
old_parent = __clk_set_parent_before(clk, clk->new_parent);
|
||||
@@ -1730,7 +1733,7 @@ static void clk_change_rate(struct clk_c
|
||||
if (!skip_set_rate && clk->ops->set_rate)
|
||||
clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
|
||||
@@ -1783,7 +1786,7 @@ static void clk_change_rate(struct clk_c
|
||||
|
||||
trace_clk_set_rate_complete(clk, clk->new_rate);
|
||||
|
||||
- clk->rate = clk_recalc(clk, best_parent_rate);
|
||||
+ clk->rate = clk->new_rate;
|
||||
|
||||
if (clk->notifier_count && old_rate != clk->rate)
|
||||
__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
|
||||
@@ -1743,12 +1746,13 @@ static void clk_change_rate(struct clk_c
|
||||
@@ -1796,12 +1799,13 @@ static void clk_change_rate(struct clk_c
|
||||
/* Skip children who will be reparented to another clock */
|
||||
if (child->new_parent && child->new_parent != clk)
|
||||
continue;
|
||||
|
@ -105,7 +105,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
|
|||
}
|
||||
|
||||
static int clk_core_set_rate_nolock(struct clk_core *clk,
|
||||
@@ -1757,6 +1761,7 @@ static int clk_core_set_rate_nolock(stru
|
||||
@@ -1810,6 +1814,7 @@ static int clk_core_set_rate_nolock(stru
|
||||
struct clk_core *top, *fail_clk;
|
||||
unsigned long rate = req_rate;
|
||||
int ret = 0;
|
||||
|
@ -113,7 +113,7 @@ drivers/clk/clk.c | 34 ++++++++++++++++++++++------------
|
|||
|
||||
if (!clk)
|
||||
return 0;
|
||||
@@ -1782,8 +1787,13 @@ static int clk_core_set_rate_nolock(stru
|
||||
@@ -1835,8 +1840,13 @@ static int clk_core_set_rate_nolock(stru
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
struct clk_core *new_parent;
|
||||
struct clk_core *new_child;
|
||||
unsigned long flags;
|
||||
@@ -1557,7 +1560,8 @@ out:
|
||||
@@ -1595,7 +1598,8 @@ out:
|
||||
static void clk_calc_subtree(struct clk_core *clk, unsigned long new_rate,
|
||||
struct clk_core *new_parent, u8 p_index)
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
|
||||
clk->new_rate = new_rate;
|
||||
clk->new_parent = new_parent;
|
||||
@@ -1567,6 +1571,18 @@ static void clk_calc_subtree(struct clk_
|
||||
@@ -1605,6 +1609,18 @@ static void clk_calc_subtree(struct clk_
|
||||
if (new_parent && new_parent != clk->parent)
|
||||
new_parent->new_child = clk;
|
||||
|
||||
|
@ -76,7 +76,7 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
hlist_for_each_entry(child, &clk->children, child_node) {
|
||||
child->new_rate = clk_recalc(child, new_rate);
|
||||
clk_calc_subtree(child, child->new_rate, NULL, 0);
|
||||
@@ -1662,14 +1678,43 @@ static struct clk_core *clk_propagate_ra
|
||||
@@ -1709,14 +1725,43 @@ static struct clk_core *clk_propagate_ra
|
||||
unsigned long event)
|
||||
{
|
||||
struct clk_core *child, *tmp_clk, *fail_clk = NULL;
|
||||
|
@ -123,7 +123,7 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
fail_clk = clk;
|
||||
}
|
||||
|
||||
@@ -1715,7 +1760,8 @@ clk_change_rate(struct clk_core *clk, un
|
||||
@@ -1762,7 +1807,8 @@ clk_change_rate(struct clk_core *clk, un
|
||||
|
||||
old_rate = clk->rate;
|
||||
|
||||
|
@ -131,9 +131,9 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
+ if (clk->new_parent && clk->new_parent != clk->parent &&
|
||||
+ !clk->safe_parent) {
|
||||
old_parent = __clk_set_parent_before(clk, clk->new_parent);
|
||||
trace_clk_set_parent(clk, clk->new_parent);
|
||||
|
||||
if (clk->ops->set_rate_and_parent) {
|
||||
@@ -1735,9 +1781,6 @@ clk_change_rate(struct clk_core *clk, un
|
||||
@@ -1788,9 +1834,6 @@ clk_change_rate(struct clk_core *clk, un
|
||||
|
||||
clk->rate = clk->new_rate;
|
||||
|
||||
|
@ -143,7 +143,7 @@ handles that problem on Krait, but on other platforms it won't work.
|
|||
/*
|
||||
* Use safe iteration, as change_rate can actually swap parents
|
||||
* for certain clock types.
|
||||
@@ -1797,6 +1840,8 @@ static int clk_core_set_rate_nolock(stru
|
||||
@@ -1850,6 +1893,8 @@ static int clk_core_set_rate_nolock(stru
|
||||
|
||||
clk->req_rate = req_rate;
|
||||
|
|
@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ };
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -88,3 +88,11 @@ config MSM_MMCC_8974
|
||||
@@ -97,3 +97,11 @@ config MSM_MMCC_8974
|
||||
Support for the multimedia clock controller on msm8974 devices.
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ such as MSM8974, APQ8084, etc.
|
||||
--- a/drivers/clk/qcom/Makefile
|
||||
+++ b/drivers/clk/qcom/Makefile
|
||||
@@ -21,3 +21,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
|
||||
@@ -22,3 +22,4 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
|
||||
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
|
|
@ -115,10 +115,10 @@ drivers/clk/qcom/gcc-ipq806x.c | 83 ++++++++++++++++++++++++++++++++++++++++++
|
|||
static struct clk_pll pll14 = {
|
||||
.l_reg = 0x31c4,
|
||||
.m_reg = 0x31c8,
|
||||
@@ -2273,6 +2353,9 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
[USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
|
||||
[USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
|
||||
@@ -2307,6 +2387,9 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
[USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
|
||||
[EBI2_CLK] = &ebi2_clk.clkr,
|
||||
[EBI2_AON_CLK] = &ebi2_aon_clk.clkr,
|
||||
+ [PLL9] = &hfpll0.clkr,
|
||||
+ [PLL10] = &hfpll1.clkr,
|
||||
+ [PLL12] = &hfpll_l2.clkr,
|
|
@ -30,7 +30,7 @@ drivers/clk/qcom/Kconfig | 4 ++
|
|||
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -96,3 +96,7 @@ config QCOM_HFPLL
|
||||
@@ -105,3 +105,7 @@ config QCOM_HFPLL
|
||||
Support for the high-frequency PLLs present on Qualcomm devices.
|
||||
Say Y if you want to support CPU frequency scaling on devices
|
||||
such as MSM8974, APQ8084, etc.
|
|
@ -82,7 +82,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ };
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -97,6 +97,14 @@ config QCOM_HFPLL
|
||||
@@ -106,6 +106,14 @@ config QCOM_HFPLL
|
||||
Say Y if you want to support CPU frequency scaling on devices
|
||||
such as MSM8974, APQ8084, etc.
|
||||
|
||||
|
@ -99,7 +99,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
select KRAIT_L2_ACCESSORS
|
||||
--- a/drivers/clk/qcom/Makefile
|
||||
+++ b/drivers/clk/qcom/Makefile
|
||||
@@ -22,4 +22,5 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
|
||||
@@ -23,4 +23,5 @@ obj-$(CONFIG_MSM_LCC_8960) += lcc-msm896
|
||||
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
|
|
@ -56,7 +56,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ };
|
||||
--- a/drivers/clk/qcom/Kconfig
|
||||
+++ b/drivers/clk/qcom/Kconfig
|
||||
@@ -105,6 +105,14 @@ config KPSS_XCC
|
||||
@@ -114,6 +114,14 @@ config KPSS_XCC
|
||||
if you want to support CPU frequency scaling on devices such
|
||||
as MSM8960, APQ8064, etc.
|
||||
|
||||
|
@ -73,7 +73,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
select KRAIT_L2_ACCESSORS
|
||||
--- a/drivers/clk/qcom/Makefile
|
||||
+++ b/drivers/clk/qcom/Makefile
|
||||
@@ -24,3 +24,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
|
||||
@@ -25,3 +25,4 @@ obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8
|
||||
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
|
||||
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
|
||||
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
|
|
@ -69,7 +69,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ };
|
||||
--- a/drivers/cpufreq/Kconfig.arm
|
||||
+++ b/drivers/cpufreq/Kconfig.arm
|
||||
@@ -137,6 +137,15 @@ config ARM_OMAP2PLUS_CPUFREQ
|
||||
@@ -146,6 +146,15 @@ config ARM_OMAP2PLUS_CPUFREQ
|
||||
depends on ARCH_OMAP2PLUS
|
||||
default ARCH_OMAP2PLUS
|
||||
|
||||
|
@ -87,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
help
|
||||
--- a/drivers/cpufreq/Makefile
|
||||
+++ b/drivers/cpufreq/Makefile
|
||||
@@ -65,6 +65,7 @@ obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += ki
|
||||
@@ -66,6 +66,7 @@ obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += ki
|
||||
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
|
||||
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
|
||||
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
|
|
@ -1,6 +1,6 @@
|
|||
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
@@ -24,6 +24,11 @@
|
||||
@@ -25,6 +25,11 @@
|
||||
next-level-cache = <&L2>;
|
||||
qcom,acc = <&acc0>;
|
||||
qcom,saw = <&saw0>;
|
||||
|
@ -12,7 +12,7 @@
|
|||
};
|
||||
|
||||
cpu@1 {
|
||||
@@ -34,11 +39,24 @@
|
||||
@@ -35,11 +40,24 @@
|
||||
next-level-cache = <&L2>;
|
||||
qcom,acc = <&acc1>;
|
||||
qcom,saw = <&saw1>;
|
||||
|
@ -37,7 +37,7 @@
|
|||
};
|
||||
};
|
||||
|
||||
@@ -71,6 +89,46 @@
|
||||
@@ -195,6 +213,46 @@
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -84,7 +84,7 @@
|
|||
soc: soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
@@ -171,11 +229,13 @@
|
||||
@@ -310,11 +368,13 @@
|
||||
acc0: clock-controller@2088000 {
|
||||
compatible = "qcom,kpss-acc-v1";
|
||||
reg = <0x02088000 0x1000>, <0x02008000 0x1000>;
|
|
@ -33,7 +33,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
|
||||
--- a/arch/arm/Kconfig
|
||||
+++ b/arch/arm/Kconfig
|
||||
@@ -314,7 +314,7 @@ config ARCH_MULTIPLATFORM
|
||||
@@ -320,7 +320,7 @@ config ARCH_MULTIPLATFORM
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select ARM_HAS_SG_CHAIN
|
||||
select ARM_PATCH_PHYS_VIRT
|
||||
|
@ -44,7 +44,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
select GENERIC_CLOCKEVENTS
|
||||
--- a/arch/arm/Makefile
|
||||
+++ b/arch/arm/Makefile
|
||||
@@ -241,9 +241,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac
|
||||
@@ -240,9 +240,11 @@ MACHINE := arch/arm/mach-$(word 1,$(mac
|
||||
else
|
||||
MACHINE :=
|
||||
endif
|
|
@ -16,7 +16,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
|
||||
--- a/drivers/clk/qcom/gcc-ipq806x.c
|
||||
+++ b/drivers/clk/qcom/gcc-ipq806x.c
|
||||
@@ -220,11 +220,46 @@ static struct clk_regmap pll14_vote = {
|
||||
@@ -220,12 +220,47 @@ static struct clk_regmap pll14_vote = {
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -53,26 +53,27 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+ },
|
||||
+};
|
||||
+
|
||||
#define P_PXO 0
|
||||
#define P_PLL8 1
|
||||
#define P_PLL3 1
|
||||
#define P_PLL0 2
|
||||
#define P_CXO 2
|
||||
+#define P_PLL14 3
|
||||
+#define P_PLL18 4
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL8,
|
||||
P_PLL3,
|
||||
P_PLL0,
|
||||
P_CXO,
|
||||
+ P_PLL14,
|
||||
+ P_PLL18,
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_map[] = {
|
||||
[P_PXO] = 0,
|
||||
@@ -275,6 +310,22 @@ static const char *gcc_pxo_pll8_pll0_map
|
||||
static const struct parent_map gcc_pxo_pll8_map[] = {
|
||||
@@ -277,6 +312,22 @@ static const char *gcc_pxo_pll8_pll0_map
|
||||
"pll0_vote",
|
||||
};
|
||||
|
||||
+static const u8 gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
|
||||
+ [P_PXO] = 0 ,
|
||||
+ [P_PLL8] = 4,
|
||||
+ [P_PLL0] = 2,
|
||||
+ [P_PLL14] = 5,
|
||||
+ [P_PLL18] = 1,
|
||||
+static const struct parent_map gcc_pxo_pll8_pll14_pll18_pll0_map[] = {
|
||||
+ { P_PXO, 0 },
|
||||
+ { P_PLL8, 4 },
|
||||
+ { P_PLL0, 2 },
|
||||
+ { P_PLL14, 5 },
|
||||
+ { P_PLL18, 1 },
|
||||
+};
|
||||
+
|
||||
+static const char *gcc_pxo_pll8_pll14_pll18_pll0[] = {
|
||||
|
@ -86,7 +87,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
static struct freq_tbl clk_tbl_gsbi_uart[] = {
|
||||
{ 1843200, P_PLL8, 2, 6, 625 },
|
||||
{ 3686400, P_PLL8, 2, 12, 625 },
|
||||
@@ -2250,6 +2301,472 @@ static struct clk_branch usb_fs1_h_clk =
|
||||
@@ -2282,6 +2333,472 @@ static struct clk_branch ebi2_aon_clk =
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -559,7 +560,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
static struct clk_regmap *gcc_ipq806x_clks[] = {
|
||||
[PLL0] = &pll0.clkr,
|
||||
[PLL0_VOTE] = &pll0_vote,
|
||||
@@ -2259,6 +2776,7 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
@@ -2291,6 +2808,7 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
[PLL8_VOTE] = &pll8_vote,
|
||||
[PLL14] = &pll14.clkr,
|
||||
[PLL14_VOTE] = &pll14_vote,
|
||||
|
@ -567,7 +568,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
[GSBI1_UART_SRC] = &gsbi1_uart_src.clkr,
|
||||
[GSBI1_UART_CLK] = &gsbi1_uart_clk.clkr,
|
||||
[GSBI2_UART_SRC] = &gsbi2_uart_src.clkr,
|
||||
@@ -2356,6 +2874,18 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
@@ -2390,6 +2908,18 @@ static struct clk_regmap *gcc_ipq806x_cl
|
||||
[PLL9] = &hfpll0.clkr,
|
||||
[PLL10] = &hfpll1.clkr,
|
||||
[PLL12] = &hfpll_l2.clkr,
|
||||
|
@ -586,7 +587,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_ipq806x_resets[] = {
|
||||
@@ -2474,6 +3004,48 @@ static const struct qcom_reset_map gcc_i
|
||||
@@ -2508,6 +3038,48 @@ static const struct qcom_reset_map gcc_i
|
||||
[USB30_1_PHY_RESET] = { 0x3b58, 0 },
|
||||
[NSSFB0_RESET] = { 0x3b60, 6 },
|
||||
[NSSFB1_RESET] = { 0x3b60, 7 },
|
||||
|
@ -635,7 +636,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
};
|
||||
|
||||
static const struct regmap_config gcc_ipq806x_regmap_config = {
|
||||
@@ -2502,6 +3074,8 @@ static int gcc_ipq806x_probe(struct plat
|
||||
@@ -2536,6 +3108,8 @@ static int gcc_ipq806x_probe(struct plat
|
||||
{
|
||||
struct clk *clk;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
@ -644,7 +645,7 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
|
||||
/* Temporary until RPM clocks supported */
|
||||
clk = clk_register_fixed_rate(dev, "cxo", NULL, CLK_IS_ROOT, 25000000);
|
||||
@@ -2512,7 +3086,25 @@ static int gcc_ipq806x_probe(struct plat
|
||||
@@ -2546,7 +3120,25 @@ static int gcc_ipq806x_probe(struct plat
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
|
@ -671,16 +672,6 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
}
|
||||
|
||||
static int gcc_ipq806x_remove(struct platform_device *pdev)
|
||||
--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
|
||||
+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
|
||||
@@ -288,5 +288,7 @@
|
||||
#define UBI32_CORE2_CLK_SRC 278
|
||||
#define UBI32_CORE1_CLK 279
|
||||
#define UBI32_CORE2_CLK 280
|
||||
+#define NSSTCM_CLK_SRC 281
|
||||
+#define NSSTCM_CLK 282
|
||||
|
||||
#endif
|
||||
--- a/include/dt-bindings/reset/qcom,gcc-ipq806x.h
|
||||
+++ b/include/dt-bindings/reset/qcom,gcc-ipq806x.h
|
||||
@@ -129,4 +129,47 @@
|
||||
|
@ -731,3 +722,13 @@ Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
|
|||
+#define NSS_SRDS_N_RESET 156
|
||||
+
|
||||
#endif
|
||||
--- a/include/dt-bindings/clock/qcom,gcc-ipq806x.h
|
||||
+++ b/include/dt-bindings/clock/qcom,gcc-ipq806x.h
|
||||
@@ -289,5 +289,7 @@
|
||||
#define UBI32_CORE1_CLK 279
|
||||
#define UBI32_CORE2_CLK 280
|
||||
#define EBI2_AON_CLK 281
|
||||
+#define NSSTCM_CLK_SRC 282
|
||||
+#define NSSTCM_CLK 283
|
||||
|
||||
#endif
|
|
@ -67,7 +67,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
pr_err("%s: Could not attach to PHY\n", dev->name);
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -27,6 +27,7 @@
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_device.h>
|
||||
|
@ -75,7 +75,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
|
||||
#include "stmmac.h"
|
||||
#include "stmmac_platform.h"
|
||||
@@ -167,13 +168,16 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -168,13 +169,16 @@ static int stmmac_probe_config_dt(struct
|
||||
/* Default to phy auto-detection */
|
||||
plat->phy_addr = -1;
|
||||
|
|
@ -17,7 +17,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -129,13 +129,18 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -130,13 +130,18 @@ static int stmmac_probe_config_dt(struct
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct stmmac_dma_cfg *dma_cfg;
|
||||
const struct of_device_id *device;
|
||||
|
@ -40,7 +40,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
|
||||
if (device->data) {
|
||||
const struct stmmac_of_data *data = device->data;
|
||||
@@ -231,8 +236,10 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -236,8 +241,10 @@ static int stmmac_probe_config_dt(struct
|
||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
|
@ -53,7 +53,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
dma_cfg->fixed_burst =
|
||||
@@ -250,6 +257,9 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -255,6 +262,9 @@ static int stmmac_probe_config_dt(struct
|
||||
}
|
||||
|
||||
return 0;
|
|
@ -29,7 +29,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
}
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -176,6 +176,14 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -177,6 +177,14 @@ static int stmmac_probe_config_dt(struct
|
||||
/* If we find a phy-handle property, use it as the PHY */
|
||||
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||
|
||||
|
@ -44,7 +44,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
|
||||
* and warn of its use. Remove this when phy node support is added.
|
||||
*/
|
||||
@@ -238,7 +246,7 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -243,7 +251,7 @@ static int stmmac_probe_config_dt(struct
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -53,7 +53,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
@@ -258,6 +266,8 @@ static int stmmac_probe_config_dt(struct
|
||||
@@ -263,6 +271,8 @@ static int stmmac_probe_config_dt(struct
|
||||
|
||||
return 0;
|
||||
|
|
@ -42,7 +42,7 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
stmmac-pci-objs:= stmmac_pci.o
|
||||
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
|
||||
@@ -42,6 +42,7 @@ static const struct of_device_id stmmac_
|
||||
@@ -43,6 +43,7 @@ static const struct of_device_id stmmac_
|
||||
{ .compatible = "st,stid127-dwmac", .data = &stid127_dwmac_data},
|
||||
{ .compatible = "st,stih407-dwmac", .data = &stih4xx_dwmac_data},
|
||||
{ .compatible = "altr,socfpga-stmmac", .data = &socfpga_gmac_data },
|
|
@ -116,11 +116,10 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
};
|
||||
--- a/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
+++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi
|
||||
@@ -540,5 +540,91 @@
|
||||
|
||||
@@ -578,5 +578,91 @@
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
|
||||
+ nss_common: syscon@03000000 {
|
||||
+ compatible = "syscon";
|
||||
+ reg = <0x03000000 0x0000FFFF>;
|
||||
|
@ -206,5 +205,6 @@ Signed-off-by: Mathieu Olivari <mathieu@codeaurora.org>
|
|||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue