aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/primecell.txt19
-rw-r--r--Documentation/devicetree/bindings/ata/pata-arasan.txt22
-rw-r--r--Documentation/devicetree/bindings/serial/pl011.txt17
-rw-r--r--Documentation/devicetree/bindings/spi/spi_pl022.txt36
-rw-r--r--arch/arm/boot/dts/spear1340.dtsi3
-rw-r--r--arch/arm/boot/dts/spear13xx.dtsi25
-rw-r--r--arch/arm/mach-spear/generic.h5
-rw-r--r--arch/arm/mach-spear/include/mach/spear.h2
-rw-r--r--arch/arm/mach-spear/spear1310.c30
-rw-r--r--arch/arm/mach-spear/spear1340.c32
-rw-r--r--arch/arm/mach-spear/spear13xx-dma.h128
-rw-r--r--arch/arm/mach-spear/spear13xx.c58
-rw-r--r--drivers/ata/pata_arasan_cf.c37
-rw-r--r--drivers/spi/spi-pl022.c43
-rw-r--r--drivers/tty/serial/amba-pl011.c62
-rw-r--r--include/linux/pata_arasan_cf_data.h2
16 files changed, 219 insertions, 302 deletions
diff --git a/Documentation/devicetree/bindings/arm/primecell.txt b/Documentation/devicetree/bindings/arm/primecell.txt
index 64fc82bc892..0df6acacfae 100644
--- a/Documentation/devicetree/bindings/arm/primecell.txt
+++ b/Documentation/devicetree/bindings/arm/primecell.txt
@@ -16,14 +16,31 @@ Optional properties:
- clocks : From common clock binding. First clock is phandle to clock for apb
pclk. Additional clocks are optional and specific to those peripherals.
- clock-names : From common clock binding. Shall be "apb_pclk" for first clock.
+- dmas : From common DMA binding. If present, refers to one or more dma channels.
+- dma-names : From common DMA binding, needs to match the 'dmas' property.
+ Devices with exactly one receive and transmit channel shall name
+ these "rx" and "tx", respectively.
+- pinctrl-<n> : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt
+- pinctrl-names : Names corresponding to the numbered pinctrl states
+- interrupts : one or more interrupt specifiers
+- interrupt-names : names corresponding to the interrupts properties
Example:
serial@fff36000 {
compatible = "arm,pl011", "arm,primecell";
arm,primecell-periphid = <0x00341011>;
+
clocks = <&pclk>;
clock-names = "apb_pclk";
-
+
+ dmas = <&dma-controller 4>, <&dma-controller 5>;
+ dma-names = "rx", "tx";
+
+ pinctrl-0 = <&uart0_default_mux>, <&uart0_default_mode>;
+ pinctrl-1 = <&uart0_sleep_mode>;
+ pinctrl-names = "default","sleep";
+
+ interrupts = <0 11 0x4>;
};
diff --git a/Documentation/devicetree/bindings/ata/pata-arasan.txt b/Documentation/devicetree/bindings/ata/pata-arasan.txt
index 95ec7f825ed..2aff154be84 100644
--- a/Documentation/devicetree/bindings/ata/pata-arasan.txt
+++ b/Documentation/devicetree/bindings/ata/pata-arasan.txt
@@ -6,6 +6,26 @@ Required properties:
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupt: Should contain the CF interrupt number
+- clock-frequency: Interface clock rate, in Hz, one of
+ 25000000
+ 33000000
+ 40000000
+ 50000000
+ 66000000
+ 75000000
+ 100000000
+ 125000000
+ 150000000
+ 166000000
+ 200000000
+
+Optional properties:
+- arasan,broken-udma: if present, UDMA mode is unusable
+- arasan,broken-mwdma: if present, MWDMA mode is unusable
+- arasan,broken-pio: if present, PIO mode is unusable
+- dmas: one DMA channel, as described in bindings/dma/dma.txt
+ required unless both UDMA and MWDMA mode are broken
+- dma-names: the corresponding channel name, must be "data"
Example:
@@ -14,4 +34,6 @@ Example:
reg = <0xfc000000 0x1000>;
interrupt-parent = <&vic1>;
interrupts = <12>;
+ dmas = <&dma-controller 23>;
+ dma-names = "data";
};
diff --git a/Documentation/devicetree/bindings/serial/pl011.txt b/Documentation/devicetree/bindings/serial/pl011.txt
new file mode 100644
index 00000000000..5d2e840ae65
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/pl011.txt
@@ -0,0 +1,17 @@
+* ARM AMBA Primecell PL011 serial UART
+
+Required properties:
+- compatible: must be "arm,primecell", "arm,pl011"
+- reg: exactly one register range with length 0x1000
+- interrupts: exactly one interrupt specifier
+
+Optional properties:
+- pinctrl: When present, must have one state named "sleep"
+ and one state named "default"
+- clocks: When present, must refer to exactly one clock named
+ "apb_pclk"
+- dmas: When present, may have one or two dma channels.
+ The first one must be named "rx", the second one
+ must be named "tx".
+
+See also bindings/arm/primecell.txt
diff --git a/Documentation/devicetree/bindings/spi/spi_pl022.txt b/Documentation/devicetree/bindings/spi/spi_pl022.txt
index f158fd31cfd..22ed6797216 100644
--- a/Documentation/devicetree/bindings/spi/spi_pl022.txt
+++ b/Documentation/devicetree/bindings/spi/spi_pl022.txt
@@ -16,6 +16,11 @@ Optional properties:
device will be suspended immediately
- pl022,rt : indicates the controller should run the message pump with realtime
priority to minimise the transfer latency on the bus (boolean)
+- dmas : Two or more 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.
SPI slave nodes must be children of the SPI master node and can
@@ -32,3 +37,34 @@ contain the following properties.
- pl022,wait-state : Microwire interface: Wait state
- pl022,duplex : Microwire interface: Full/Half duplex
+
+Example:
+
+ spi@e0100000 {
+ compatible = "arm,pl022", "arm,primecell";
+ reg = <0xe0100000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0 31 0x4>;
+ dmas = <&dma-controller 23 1>,
+ <&dma-controller 24 0>;
+ dma-names = "rx", "tx";
+
+ m25p80@1 {
+ compatible = "st,m25p80";
+ reg = <1>;
+ spi-max-frequency = <12000000>;
+ spi-cpol;
+ spi-cpha;
+ pl022,hierarchy = <0>;
+ pl022,interface = <0>;
+ pl022,slave-tx-disable;
+ pl022,com-mode = <0x2>;
+ pl022,rx-level-trig = <0>;
+ pl022,tx-level-trig = <0>;
+ pl022,ctrl-len = <0x11>;
+ pl022,wait-state = <0>;
+ pl022,duplex = <0>;
+ };
+ };
+
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi
index 34da11aa679..e1786a0b2fc 100644
--- a/arch/arm/boot/dts/spear1340.dtsi
+++ b/arch/arm/boot/dts/spear1340.dtsi
@@ -113,6 +113,9 @@
reg = <0xb4100000 0x1000>;
interrupts = <0 105 0x4>;
status = "disabled";
+ dmas = <&dwdma0 0x600 0 0 1>, /* 0xC << 11 */
+ <&dwdma0 0x680 0 1 0>; /* 0xD << 7 */
+ dma-names = "tx", "rx";
};
thermal@e07008c4 {
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi
index b4ca60f4eb4..45597fd9105 100644
--- a/arch/arm/boot/dts/spear13xx.dtsi
+++ b/arch/arm/boot/dts/spear13xx.dtsi
@@ -98,13 +98,24 @@
reg = <0xb2800000 0x1000>;
interrupts = <0 29 0x4>;
status = "disabled";
+ dmas = <&dwdma0 0 0 0 0>;
+ dma-names = "data";
};
- dma@ea800000 {
+ dwdma0: dma@ea800000 {
compatible = "snps,dma-spear1340";
reg = <0xea800000 0x1000>;
interrupts = <0 19 0x4>;
status = "disabled";
+
+ dma-channels = <8>;
+ #dma-cells = <3>;
+ dma-requests = <32>;
+ chan_allocation_order = <1>;
+ chan_priority = <1>;
+ block_size = <0xfff>;
+ dma-masters = <2>;
+ data_width = <3 3 0 0>;
};
dma@eb000000 {
@@ -112,6 +123,15 @@
reg = <0xeb000000 0x1000>;
interrupts = <0 59 0x4>;
status = "disabled";
+
+ dma-requests = <32>;
+ dma-channels = <8>;
+ dma-masters = <2>;
+ #dma-cells = <3>;
+ chan_allocation_order = <1>;
+ chan_priority = <1>;
+ block_size = <0xfff>;
+ data_width = <3 3 0 0>;
};
fsmc: flash@b0000000 {
@@ -261,6 +281,9 @@
#size-cells = <0>;
interrupts = <0 31 0x4>;
status = "disabled";
+ dmas = <&dwdma0 0x2000 0 0 0>, /* 0x4 << 11 */
+ <&dwdma0 0x0280 0 0 0>; /* 0x5 << 7 */
+ dma-names = "tx", "rx";
};
rtc@e0580000 {
diff --git a/arch/arm/mach-spear/generic.h b/arch/arm/mach-spear/generic.h
index 8ba7e75b648..a9fd45362fe 100644
--- a/arch/arm/mach-spear/generic.h
+++ b/arch/arm/mach-spear/generic.h
@@ -22,11 +22,6 @@ extern void spear13xx_timer_init(void);
extern void spear3xx_timer_init(void);
extern struct pl022_ssp_controller pl022_plat_data;
extern struct pl08x_platform_data pl080_plat_data;
-extern struct dw_dma_platform_data dmac_plat_data;
-extern struct dw_dma_slave cf_dma_priv;
-extern struct dw_dma_slave nand_read_dma_priv;
-extern struct dw_dma_slave nand_write_dma_priv;
-bool dw_dma_filter(struct dma_chan *chan, void *slave);
void __init spear_setup_of_timer(void);
void __init spear3xx_clk_init(void __iomem *misc_base,
diff --git a/arch/arm/mach-spear/include/mach/spear.h b/arch/arm/mach-spear/include/mach/spear.h
index 374ddc393df..cf3a5369eec 100644
--- a/arch/arm/mach-spear/include/mach/spear.h
+++ b/arch/arm/mach-spear/include/mach/spear.h
@@ -82,8 +82,6 @@
#define VA_L2CC_BASE IOMEM(UL(0xFB000000))
/* others */
-#define DMAC0_BASE UL(0xEA800000)
-#define DMAC1_BASE UL(0xEB000000)
#define MCIF_CF_BASE UL(0xB2800000)
/* Debug uart for linux, will be used for debug and uncompress messages */
diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c
index ed3b5c287a7..9eaac2c881e 100644
--- a/arch/arm/mach-spear/spear1310.c
+++ b/arch/arm/mach-spear/spear1310.c
@@ -23,40 +23,12 @@
#include <mach/spear.h>
/* Base addresses */
-#define SPEAR1310_SSP1_BASE UL(0x5D400000)
-#define SPEAR1310_SATA0_BASE UL(0xB1000000)
-#define SPEAR1310_SATA1_BASE UL(0xB1800000)
-#define SPEAR1310_SATA2_BASE UL(0xB4000000)
-
#define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000)
#define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000)
-static struct arasan_cf_pdata cf_pdata = {
- .cf_if_clk = CF_IF_CLK_166M,
- .quirk = CF_BROKEN_UDMA,
- .dma_priv = &cf_dma_priv,
-};
-
-/* ssp device registration */
-static struct pl022_ssp_controller ssp1_plat_data = {
- .enable_dma = 0,
-};
-
-/* Add SPEAr1310 auxdata to pass platform data */
-static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_pdata),
- OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
- OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
- OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
-
- OF_DEV_AUXDATA("arm,pl022", SPEAR1310_SSP1_BASE, NULL, &ssp1_plat_data),
- {}
-};
-
static void __init spear1310_dt_init(void)
{
- of_platform_populate(NULL, of_default_bus_match_table,
- spear1310_auxdata_lookup, NULL);
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char * const spear1310_dt_board_compat[] = {
diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c
index 75e38644bbf..a04a7fe76f7 100644
--- a/arch/arm/mach-spear/spear1340.c
+++ b/arch/arm/mach-spear/spear1340.c
@@ -16,18 +16,16 @@
#include <linux/ahci_platform.h>
#include <linux/amba/serial.h>
#include <linux/delay.h>
-#include <linux/dw_dmac.h>
#include <linux/of_platform.h>
#include <linux/irqchip.h>
#include <asm/mach/arch.h>
#include "generic.h"
#include <mach/spear.h>
-#include "spear13xx-dma.h"
+/* FIXME: Move SATA PHY code into a standalone driver */
/* Base addresses */
#define SPEAR1340_SATA_BASE UL(0xB1000000)
-#define SPEAR1340_UART1_BASE UL(0xB4100000)
/* Power Management Registers */
#define SPEAR1340_PCM_CFG (VA_MISC_BASE + 0x100)
@@ -79,28 +77,6 @@
(SPEAR1340_MIPHY_OSC_BYPASS_EXT | \
SPEAR1340_MIPHY_PLL_RATIO_TOP(25))
-static struct dw_dma_slave uart1_dma_param[] = {
- {
- /* Tx */
- .cfg_hi = DWC_CFGH_DST_PER(SPEAR1340_DMA_REQ_UART1_TX),
- .cfg_lo = 0,
- .src_master = DMA_MASTER_MEMORY,
- .dst_master = SPEAR1340_DMA_MASTER_UART1,
- }, {
- /* Rx */
- .cfg_hi = DWC_CFGH_SRC_PER(SPEAR1340_DMA_REQ_UART1_RX),
- .cfg_lo = 0,
- .src_master = SPEAR1340_DMA_MASTER_UART1,
- .dst_master = DMA_MASTER_MEMORY,
- }
-};
-
-static struct amba_pl011_data uart1_data = {
- .dma_filter = dw_dma_filter,
- .dma_tx_param = &uart1_dma_param[0],
- .dma_rx_param = &uart1_dma_param[1],
-};
-
/* SATA device registration */
static int sata_miphy_init(struct device *dev, void __iomem *addr)
{
@@ -159,14 +135,8 @@ static struct ahci_platform_data sata_pdata = {
/* Add SPEAr1340 auxdata to pass platform data */
static struct of_dev_auxdata spear1340_auxdata_lookup[] __initdata = {
- OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv),
- OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data),
- OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data),
- OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data),
-
OF_DEV_AUXDATA("snps,spear-ahci", SPEAR1340_SATA_BASE, NULL,
&sata_pdata),
- OF_DEV_AUXDATA("arm,pl011", SPEAR1340_UART1_BASE, NULL, &uart1_data),
{}
};
diff --git a/arch/arm/mach-spear/spear13xx-dma.h b/arch/arm/mach-spear/spear13xx-dma.h
deleted file mode 100644
index d50bdb60592..00000000000
--- a/arch/arm/mach-spear/spear13xx-dma.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * arch/arm/mach-spear13xx/include/mach/dma.h
- *
- * DMA information for SPEAr13xx machine family
- *
- * Copyright (C) 2012 ST Microelectronics
- * Viresh Kumar <viresh.linux@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_DMA_H
-#define __MACH_DMA_H
-
-/* request id of all the peripherals */
-enum dma_master_info {
- /* Accessible from only one master */
- DMA_MASTER_MCIF = 0,
- DMA_MASTER_FSMC = 1,
- /* Accessible from both 0 & 1 */
- DMA_MASTER_MEMORY = 0,
- DMA_MASTER_ADC = 0,
- DMA_MASTER_UART0 = 0,
- DMA_MASTER_SSP0 = 0,
- DMA_MASTER_I2C0 = 0,
-
-#ifdef CONFIG_MACH_SPEAR1310
- /* Accessible from only one master */
- SPEAR1310_DMA_MASTER_JPEG = 1,
-
- /* Accessible from both 0 & 1 */
- SPEAR1310_DMA_MASTER_I2S = 0,
- SPEAR1310_DMA_MASTER_UART1 = 0,
- SPEAR1310_DMA_MASTER_UART2 = 0,
- SPEAR1310_DMA_MASTER_UART3 = 0,
- SPEAR1310_DMA_MASTER_UART4 = 0,
- SPEAR1310_DMA_MASTER_UART5 = 0,
- SPEAR1310_DMA_MASTER_I2C1 = 0,
- SPEAR1310_DMA_MASTER_I2C2 = 0,
- SPEAR1310_DMA_MASTER_I2C3 = 0,
- SPEAR1310_DMA_MASTER_I2C4 = 0,
- SPEAR1310_DMA_MASTER_I2C5 = 0,
- SPEAR1310_DMA_MASTER_I2C6 = 0,
- SPEAR1310_DMA_MASTER_I2C7 = 0,
- SPEAR1310_DMA_MASTER_SSP1 = 0,
-#endif
-
-#ifdef CONFIG_MACH_SPEAR1340
- /* Accessible from only one master */
- SPEAR1340_DMA_MASTER_I2S_PLAY = 1,
- SPEAR1340_DMA_MASTER_I2S_REC = 1,
- SPEAR1340_DMA_MASTER_I2C1 = 1,
- SPEAR1340_DMA_MASTER_UART1 = 1,
-
- /* following are accessible from both master 0 & 1 */
- SPEAR1340_DMA_MASTER_SPDIF = 0,
- SPEAR1340_DMA_MASTER_CAM = 1,
- SPEAR1340_DMA_MASTER_VIDEO_IN = 0,
- SPEAR1340_DMA_MASTER_MALI = 0,
-#endif
-};
-
-enum request_id {
- DMA_REQ_ADC = 0,
- DMA_REQ_SSP0_TX = 4,
- DMA_REQ_SSP0_RX = 5,
- DMA_REQ_UART0_TX = 6,
- DMA_REQ_UART0_RX = 7,
- DMA_REQ_I2C0_TX = 8,
- DMA_REQ_I2C0_RX = 9,
-
-#ifdef CONFIG_MACH_SPEAR1310
- SPEAR1310_DMA_REQ_FROM_JPEG = 2,
- SPEAR1310_DMA_REQ_TO_JPEG = 3,
- SPEAR1310_DMA_REQ_I2S_TX = 10,
- SPEAR1310_DMA_REQ_I2S_RX = 11,
-
- SPEAR1310_DMA_REQ_I2C1_RX = 0,
- SPEAR1310_DMA_REQ_I2C1_TX = 1,
- SPEAR1310_DMA_REQ_I2C2_RX = 2,
- SPEAR1310_DMA_REQ_I2C2_TX = 3,
- SPEAR1310_DMA_REQ_I2C3_RX = 4,
- SPEAR1310_DMA_REQ_I2C3_TX = 5,
- SPEAR1310_DMA_REQ_I2C4_RX = 6,
- SPEAR1310_DMA_REQ_I2C4_TX = 7,
- SPEAR1310_DMA_REQ_I2C5_RX = 8,
- SPEAR1310_DMA_REQ_I2C5_TX = 9,
- SPEAR1310_DMA_REQ_I2C6_RX = 10,
- SPEAR1310_DMA_REQ_I2C6_TX = 11,
- SPEAR1310_DMA_REQ_UART1_RX = 12,
- SPEAR1310_DMA_REQ_UART1_TX = 13,
- SPEAR1310_DMA_REQ_UART2_RX = 14,
- SPEAR1310_DMA_REQ_UART2_TX = 15,
- SPEAR1310_DMA_REQ_UART5_RX = 16,
- SPEAR1310_DMA_REQ_UART5_TX = 17,
- SPEAR1310_DMA_REQ_SSP1_RX = 18,
- SPEAR1310_DMA_REQ_SSP1_TX = 19,
- SPEAR1310_DMA_REQ_I2C7_RX = 20,
- SPEAR1310_DMA_REQ_I2C7_TX = 21,
- SPEAR1310_DMA_REQ_UART3_RX = 28,
- SPEAR1310_DMA_REQ_UART3_TX = 29,
- SPEAR1310_DMA_REQ_UART4_RX = 30,
- SPEAR1310_DMA_REQ_UART4_TX = 31,
-#endif
-
-#ifdef CONFIG_MACH_SPEAR1340
- SPEAR1340_DMA_REQ_SPDIF_TX = 2,
- SPEAR1340_DMA_REQ_SPDIF_RX = 3,
- SPEAR1340_DMA_REQ_I2S_TX = 10,
- SPEAR1340_DMA_REQ_I2S_RX = 11,
- SPEAR1340_DMA_REQ_UART1_TX = 12,
- SPEAR1340_DMA_REQ_UART1_RX = 13,
- SPEAR1340_DMA_REQ_I2C1_TX = 14,
- SPEAR1340_DMA_REQ_I2C1_RX = 15,
- SPEAR1340_DMA_REQ_CAM0_EVEN = 0,
- SPEAR1340_DMA_REQ_CAM0_ODD = 1,
- SPEAR1340_DMA_REQ_CAM1_EVEN = 2,
- SPEAR1340_DMA_REQ_CAM1_ODD = 3,
- SPEAR1340_DMA_REQ_CAM2_EVEN = 4,
- SPEAR1340_DMA_REQ_CAM2_ODD = 5,
- SPEAR1340_DMA_REQ_CAM3_EVEN = 6,
- SPEAR1340_DMA_REQ_CAM3_ODD = 7,
-#endif
-};
-
-#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-spear/spear13xx.c b/arch/arm/mach-spear/spear13xx.c
index 1b97e862347..3975916666a 100644
--- a/arch/arm/mach-spear/spear13xx.c
+++ b/arch/arm/mach-spear/spear13xx.c
@@ -15,7 +15,6 @@
#include <linux/amba/pl022.h>
#include <linux/clk.h>
-#include <linux/dw_dmac.h>
#include <linux/err.h>
#include <linux/of.h>
#include <asm/hardware/cache-l2x0.h>
@@ -24,63 +23,6 @@
#include "generic.h"
#include <mach/spear.h>
-#include "spear13xx-dma.h"
-
-/* common dw_dma filter routine to be used by peripherals */
-bool dw_dma_filter(struct dma_chan *chan, void *slave)
-{
- struct dw_dma_slave *dws = (struct dw_dma_slave *)slave;
-
- if (chan->device->dev == dws->dma_dev) {
- chan->private = slave;
- return true;
- } else {
- return false;
- }
-}
-
-/* ssp device registration */
-static struct dw_dma_slave ssp_dma_param[] = {
- {
- /* Tx */
- .cfg_hi = DWC_CFGH_DST_PER(DMA_REQ_SSP0_TX),
- .cfg_lo = 0,
- .src_master = DMA_MASTER_MEMORY,
- .dst_master = DMA_MASTER_SSP0,
- }, {
- /* Rx */
- .cfg_hi = DWC_CFGH_SRC_PER(DMA_REQ_SSP0_RX),
- .cfg_lo = 0,
- .src_master = DMA_MASTER_SSP0,
- .dst_master = DMA_MASTER_MEMORY,
- }
-};
-
-struct pl022_ssp_controller pl022_plat_data = {
- .enable_dma = 1,
- .dma_filter = dw_dma_filter,
- .dma_rx_param = &ssp_dma_param[1],
- .dma_tx_param = &ssp_dma_param[0],
-};
-
-/* CF device registration */
-struct dw_dma_slave cf_dma_priv = {
- .cfg_hi = 0,
- .cfg_lo = 0,
- .src_master = 0,
- .dst_master = 0,
-};
-
-/* dmac device registeration */
-struct dw_dma_platform_data dmac_plat_data = {
- .nr_channels = 8,
- .chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
- .chan_priority = CHAN_PRIORITY_DESCENDING,
- .block_size = 4095U,
- .nr_masters = 2,
- .data_width = { 3, 3, 0, 0 },
-};
-
void __init spear13xx_l2x0_init(void)
{
/*
diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c
index 405022d302c..7638121cb5d 100644
--- a/drivers/ata/pata_arasan_cf.c
+++ b/drivers/ata/pata_arasan_cf.c
@@ -209,8 +209,6 @@ struct arasan_cf_dev {
struct dma_chan *dma_chan;
/* Mask for DMA transfers */
dma_cap_mask_t mask;
- /* dma channel private data */
- void *dma_priv;
/* DMA transfer work */
struct work_struct work;
/* DMA delayed finish work */
@@ -308,6 +306,7 @@ static void cf_card_detect(struct arasan_cf_dev *acdev, bool hotplugged)
static int cf_init(struct arasan_cf_dev *acdev)
{
struct arasan_cf_pdata *pdata = dev_get_platdata(acdev->host->dev);
+ unsigned int if_clk;
unsigned long flags;
int ret = 0;
@@ -325,8 +324,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
spin_lock_irqsave(&acdev->host->lock, flags);
/* configure CF interface clock */
- writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk :
- CF_IF_CLK_166M, acdev->vbase + CLK_CFG);
+ /* TODO: read from device tree */
+ if_clk = CF_IF_CLK_166M;
+ if (pdata && pdata->cf_if_clk <= CF_IF_CLK_200M)
+ if_clk = pdata->cf_if_clk;
+
+ writel(if_clk, acdev->vbase + CLK_CFG);
writel(TRUE_IDE_MODE | CFHOST_ENB, acdev->vbase + OP_MODE);
cf_interrupt_enable(acdev, CARD_DETECT_IRQ, 1);
@@ -357,12 +360,6 @@ static void dma_callback(void *dev)
complete(&acdev->dma_completion);
}
-static bool filter(struct dma_chan *chan, void *slave)
-{
- chan->private = slave;
- return true;
-}
-
static inline void dma_complete(struct arasan_cf_dev *acdev)
{
struct ata_queued_cmd *qc = acdev->qc;
@@ -530,8 +527,7 @@ static void data_xfer(struct work_struct *work)
/* request dma channels */
/* dma_request_channel may sleep, so calling from process context */
- acdev->dma_chan = dma_request_channel(acdev->mask, filter,
- acdev->dma_priv);
+ acdev->dma_chan = dma_request_slave_channel(acdev->host->dev, "data");
if (!acdev->dma_chan) {
dev_err(acdev->host->dev, "Unable to get dma_chan\n");
goto chan_request_fail;
@@ -798,6 +794,7 @@ static int arasan_cf_probe(struct platform_device *pdev)
struct ata_host *host;
struct ata_port *ap;
struct resource *res;
+ u32 quirk;
irq_handler_t irq_handler = NULL;
int ret = 0;
@@ -817,12 +814,17 @@ static int arasan_cf_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ if (pdata)
+ quirk = pdata->quirk;
+ else
+ quirk = CF_BROKEN_UDMA; /* as it is on spear1340 */
+
/* if irq is 0, support only PIO */
acdev->irq = platform_get_irq(pdev, 0);
if (acdev->irq)
irq_handler = arasan_cf_interrupt;
else
- pdata->quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA;
+ quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA;
acdev->pbase = res->start;
acdev->vbase = devm_ioremap_nocache(&pdev->dev, res->start,
@@ -859,17 +861,16 @@ static int arasan_cf_probe(struct platform_device *pdev)
INIT_WORK(&acdev->work, data_xfer);
INIT_DELAYED_WORK(&acdev->dwork, delayed_finish);
dma_cap_set(DMA_MEMCPY, acdev->mask);
- acdev->dma_priv = pdata->dma_priv;
/* Handle platform specific quirks */
- if (pdata->quirk) {
- if (pdata->quirk & CF_BROKEN_PIO) {
+ if (quirk) {
+ if (quirk & CF_BROKEN_PIO) {
ap->ops->set_piomode = NULL;
ap->pio_mask = 0;
}
- if (pdata->quirk & CF_BROKEN_MWDMA)
+ if (quirk & CF_BROKEN_MWDMA)
ap->mwdma_mask = 0;
- if (pdata->quirk & CF_BROKEN_UDMA)
+ if (quirk & CF_BROKEN_UDMA)
ap->udma_mask = 0;
}
ap->flags |= ATA_FLAG_PIO_POLLING | ATA_FLAG_NO_ATAPI;
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index b0fe393c882..371cc66f1a0 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1139,6 +1139,35 @@ err_no_rxchan:
return -ENODEV;
}
+static int pl022_dma_autoprobe(struct pl022 *pl022)
+{
+ struct device *dev = &pl022->adev->dev;
+
+ /* automatically configure DMA channels from platform, normally using DT */
+ pl022->dma_rx_channel = dma_request_slave_channel(dev, "rx");
+ if (!pl022->dma_rx_channel)
+ goto err_no_rxchan;
+
+ pl022->dma_tx_channel = dma_request_slave_channel(dev, "tx");
+ if (!pl022->dma_tx_channel)
+ goto err_no_txchan;
+
+ pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!pl022->dummypage)
+ goto err_no_dummypage;
+
+ return 0;
+
+err_no_dummypage:
+ dma_release_channel(pl022->dma_tx_channel);
+ pl022->dma_tx_channel = NULL;
+err_no_txchan:
+ dma_release_channel(pl022->dma_rx_channel);
+ pl022->dma_rx_channel = NULL;
+err_no_rxchan:
+ return -ENODEV;
+}
+
static void terminate_dma(struct pl022 *pl022)
{
struct dma_chan *rxchan = pl022->dma_rx_channel;
@@ -1167,6 +1196,11 @@ static inline int configure_dma(struct pl022 *pl022)
return -ENODEV;
}
+static inline int pl022_dma_autoprobe(struct pl022 *pl022)
+{
+ return 0;
+}
+
static inline int pl022_dma_probe(struct pl022 *pl022)
{
return 0;
@@ -2226,8 +2260,13 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
goto err_no_irq;
}
- /* Get DMA channels */
- if (platform_info->enable_dma) {
+ /* Get DMA channels, try autoconfiguration first */
+ status = pl022_dma_autoprobe(pl022);
+
+ /* If that failed, use channels from platform_info */
+ if (status == 0)
+ platform_info->enable_dma = 1;
+ else if (platform_info->enable_dma) {
status = pl022_dma_probe(pl022);
if (status != 0)
platform_info->enable_dma = 0;
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 3ea5408fcbe..c25b00ef9db 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -245,7 +245,7 @@ static void pl011_sgbuf_free(struct dma_chan *chan, struct pl011_sgbuf *sg,
}
}
-static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
+static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *uap)
{
/* DMA is the sole user of the platform data right now */
struct amba_pl011_data *plat = uap->port.dev->platform_data;
@@ -259,20 +259,25 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
struct dma_chan *chan;
dma_cap_mask_t mask;
- /* We need platform data */
- if (!plat || !plat->dma_filter) {
- dev_info(uap->port.dev, "no DMA platform data\n");
- return;
- }
+ chan = dma_request_slave_channel(dev, "tx");
- /* Try to acquire a generic DMA engine slave TX channel */
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- chan = dma_request_channel(mask, plat->dma_filter, plat->dma_tx_param);
if (!chan) {
- dev_err(uap->port.dev, "no TX DMA channel!\n");
- return;
+ /* We need platform data */
+ if (!plat || !plat->dma_filter) {
+ dev_info(uap->port.dev, "no DMA platform data\n");
+ return;
+ }
+
+ /* Try to acquire a generic DMA engine slave TX channel */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ chan = dma_request_channel(mask, plat->dma_filter,
+ plat->dma_tx_param);
+ if (!chan) {
+ dev_err(uap->port.dev, "no TX DMA channel!\n");
+ return;
+ }
}
dmaengine_slave_config(chan, &tx_conf);
@@ -282,7 +287,18 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
dma_chan_name(uap->dmatx.chan));
/* Optionally make use of an RX channel as well */
- if (plat->dma_rx_param) {
+ chan = dma_request_slave_channel(dev, "rx");
+
+ if (!chan && plat->dma_rx_param) {
+ chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
+
+ if (!chan) {
+ dev_err(uap->port.dev, "no RX DMA channel!\n");
+ return;
+ }
+ }
+
+ if (chan) {
struct dma_slave_config rx_conf = {
.src_addr = uap->port.mapbase + UART01x_DR,
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
@@ -291,12 +307,6 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
.device_fc = false,
};
- chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
- if (!chan) {
- dev_err(uap->port.dev, "no RX DMA channel!\n");
- return;
- }
-
dmaengine_slave_config(chan, &rx_conf);
uap->dmarx.chan = chan;
@@ -315,6 +325,7 @@ static void pl011_dma_probe_initcall(struct uart_amba_port *uap)
struct dma_uap {
struct list_head node;
struct uart_amba_port *uap;
+ struct device *dev;
};
static LIST_HEAD(pl011_dma_uarts);
@@ -325,7 +336,7 @@ static int __init pl011_dma_initcall(void)
list_for_each_safe(node, tmp, &pl011_dma_uarts) {
struct dma_uap *dmau = list_entry(node, struct dma_uap, node);
- pl011_dma_probe_initcall(dmau->uap);
+ pl011_dma_probe_initcall(dmau->dev, dmau->uap);
list_del(node);
kfree(dmau);
}
@@ -334,18 +345,19 @@ static int __init pl011_dma_initcall(void)
device_initcall(pl011_dma_initcall);
-static void pl011_dma_probe(struct uart_amba_port *uap)
+static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
{
struct dma_uap *dmau = kzalloc(sizeof(struct dma_uap), GFP_KERNEL);
if (dmau) {
dmau->uap = uap;
+ dmau->dev = dev;
list_add_tail(&dmau->node, &pl011_dma_uarts);
}
}
#else
-static void pl011_dma_probe(struct uart_amba_port *uap)
+static void pl011_dma_probe(struct device *dev, struct uart_amba_port *uap)
{
- pl011_dma_probe_initcall(uap);
+ pl011_dma_probe_initcall(dev, uap);
}
#endif
@@ -2020,7 +2032,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
uap->port.ops = &amba_pl011_pops;
uap->port.flags = UPF_BOOT_AUTOCONF;
uap->port.line = i;
- pl011_dma_probe(uap);
+ pl011_dma_probe(&dev->dev, uap);
/* Ensure interrupts from this UART are masked and cleared */
writew(0, uap->port.membase + UART011_IMSC);
diff --git a/include/linux/pata_arasan_cf_data.h b/include/linux/pata_arasan_cf_data.h
index a7b4fc386e6..3cc21c9cc1e 100644
--- a/include/linux/pata_arasan_cf_data.h
+++ b/include/linux/pata_arasan_cf_data.h
@@ -37,8 +37,6 @@ struct arasan_cf_pdata {
#define CF_BROKEN_PIO (1)
#define CF_BROKEN_MWDMA (1 << 1)
#define CF_BROKEN_UDMA (1 << 2)
- /* This is platform specific data for the DMA controller */
- void *dma_priv;
};
static inline void