Commit 8aeab58e authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/qspi',...

Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/qspi', 'spi/topic/s3c24xx', 'spi/topic/s3c64xx', 'spi/topic/sh', 'spi/topic/tegra114', 'spi/topic/tegra20-sflash', 'spi/topic/tegra20-slink', 'spi/topic/txx9' and 'spi/topic/xcomm' into spi-linus
...@@ -3,6 +3,11 @@ TI QSPI controller. ...@@ -3,6 +3,11 @@ TI QSPI controller.
Required properties: Required properties:
- compatible : should be "ti,dra7xxx-qspi" or "ti,am4372-qspi". - compatible : should be "ti,dra7xxx-qspi" or "ti,am4372-qspi".
- reg: Should contain QSPI registers location and length. - reg: Should contain QSPI registers location and length.
- reg-names: Should contain the resource reg names.
- qspi_base: Qspi configuration register Address space
- qspi_mmap: Memory mapped Address space
- (optional) qspi_ctrlmod: Control module Address space
- interrupts: should contain the qspi interrupt number.
- #address-cells, #size-cells : Must be present if the device has sub-nodes - #address-cells, #size-cells : Must be present if the device has sub-nodes
- ti,hwmods: Name of the hwmod associated to the QSPI - ti,hwmods: Name of the hwmod associated to the QSPI
...@@ -14,7 +19,8 @@ Example: ...@@ -14,7 +19,8 @@ Example:
qspi: qspi@4b300000 { qspi: qspi@4b300000 {
compatible = "ti,dra7xxx-qspi"; compatible = "ti,dra7xxx-qspi";
reg = <0x4b300000 0x100>; reg = <0x47900000 0x100>, <0x30000000 0x3ffffff>;
reg-names = "qspi_base", "qspi_mmap";
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
spi-max-frequency = <25000000>; spi-max-frequency = <25000000>;
......
...@@ -723,6 +723,7 @@ config ARCH_S3C64XX ...@@ -723,6 +723,7 @@ config ARCH_S3C64XX
bool "Samsung S3C64XX" bool "Samsung S3C64XX"
select ARCH_HAS_CPUFREQ select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC select ARM_VIC
select CLKDEV_LOOKUP select CLKDEV_LOOKUP
select CLKSRC_SAMSUNG_PWM select CLKSRC_SAMSUNG_PWM
......
...@@ -17,9 +17,10 @@ config CPU_S3C6410 ...@@ -17,9 +17,10 @@ config CPU_S3C6410
help help
Enable S3C6410 CPU support Enable S3C6410 CPU support
config S3C64XX_DMA config S3C64XX_PL080
bool "S3C64XX DMA" bool "S3C64XX DMA using generic PL08x driver"
select S3C_DMA select AMBA_PL08X
select SAMSUNG_DMADEV
config S3C64XX_SETUP_SDHCI config S3C64XX_SETUP_SDHCI
bool bool
......
...@@ -26,7 +26,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o ...@@ -26,7 +26,7 @@ obj-$(CONFIG_CPU_IDLE) += cpuidle.o
# DMA support # DMA support
obj-$(CONFIG_S3C64XX_DMA) += dma.o obj-$(CONFIG_S3C64XX_PL080) += pl080.o
# Device support # Device support
......
...@@ -58,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void); ...@@ -58,4 +58,9 @@ int __init s3c64xx_pm_late_initcall(void);
static inline int s3c64xx_pm_late_initcall(void) { return 0; } static inline int s3c64xx_pm_late_initcall(void) { return 0; }
#endif #endif
#ifdef CONFIG_S3C64XX_PL080
extern struct pl08x_platform_data s3c64xx_dma0_plat_data;
extern struct pl08x_platform_data s3c64xx_dma1_plat_data;
#endif
#endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */ #endif /* __ARCH_ARM_MACH_S3C64XX_COMMON_H */
This diff is collapsed.
...@@ -11,51 +11,48 @@ ...@@ -11,51 +11,48 @@
#ifndef __ASM_ARCH_DMA_H #ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__ #define __ASM_ARCH_DMA_H __FILE__
#define S3C_DMA_CHANNELS (16) #define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
/* DMA0/SDMA0 */
#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
/* DMA1/SDMA1 */
#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
/* see mach-s3c2410/dma.h for notes on dma channel numbers */
/* Note, for the S3C64XX architecture we keep the DMACH_
* defines in the order they are allocated to [S]DMA0/[S]DMA1
* so that is easy to do DHACH_ -> DMA controller conversion
*/
enum dma_ch { enum dma_ch {
/* DMA0/SDMA0 */ DMACH_MAX = 32
DMACH_UART0 = 0, };
DMACH_UART0_SRC2,
DMACH_UART1,
DMACH_UART1_SRC2,
DMACH_UART2,
DMACH_UART2_SRC2,
DMACH_UART3,
DMACH_UART3_SRC2,
DMACH_PCM0_TX,
DMACH_PCM0_RX,
DMACH_I2S0_OUT,
DMACH_I2S0_IN,
DMACH_SPI0_TX,
DMACH_SPI0_RX,
DMACH_HSI_I2SV40_TX,
DMACH_HSI_I2SV40_RX,
/* DMA1/SDMA1 */ struct s3c2410_dma_client {
DMACH_PCM1_TX = 16, char *name;
DMACH_PCM1_RX,
DMACH_I2S1_OUT,
DMACH_I2S1_IN,
DMACH_SPI1_TX,
DMACH_SPI1_RX,
DMACH_AC97_PCMOUT,
DMACH_AC97_PCMIN,
DMACH_AC97_MICIN,
DMACH_PWM,
DMACH_IRDA,
DMACH_EXTERNAL,
DMACH_RES1,
DMACH_RES2,
DMACH_SECURITY_RX, /* SDMA1 only */
DMACH_SECURITY_TX, /* SDMA1 only */
DMACH_MAX /* the end */
}; };
static inline bool samsung_dma_has_circular(void) static inline bool samsung_dma_has_circular(void)
...@@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void) ...@@ -65,67 +62,10 @@ static inline bool samsung_dma_has_circular(void)
static inline bool samsung_dma_is_dmadev(void) static inline bool samsung_dma_is_dmadev(void)
{ {
return false; return true;
} }
#define S3C2410_DMAF_CIRCULAR (1 << 0)
#include <plat/dma.h>
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
struct s3c64xx_dma_buff;
/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
* @next: Pointer to next buffer in queue or ring.
* @pw: Client provided identifier
* @lli: Pointer to hardware descriptor this buffer is associated with.
* @lli_dma: Hardare address of the descriptor.
*/
struct s3c64xx_dma_buff {
struct s3c64xx_dma_buff *next;
void *pw;
struct pl080s_lli *lli;
dma_addr_t lli_dma;
};
struct s3c64xx_dmac;
struct s3c2410_dma_chan {
unsigned char number; /* number of this dma channel */
unsigned char in_use; /* channel allocated */
unsigned char bit; /* bit for enable/disable/etc */
unsigned char hw_width;
unsigned char peripheral;
unsigned int flags;
enum dma_data_direction source;
dma_addr_t dev_addr;
struct s3c2410_dma_client *client;
struct s3c64xx_dmac *dmac; /* pointer to controller */
void __iomem *regs;
/* cdriver callbacks */
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
s3c2410_dma_opfn_t op_fn; /* channel op callback */
/* buffer list and information */
struct s3c64xx_dma_buff *curr; /* current dma buffer */
struct s3c64xx_dma_buff *next; /* next buffer to load */
struct s3c64xx_dma_buff *end; /* end of queue */
/* note, when channel is running in circular mode, curr is the
* first buffer enqueued, end is the last and curr is where the
* last buffer-done event is set-at. The buffers are not freed
* and the last buffer hardware descriptor points back to the
* first.
*/
};
#include <plat/dma-core.h> #include <linux/amba/pl08x.h>
#include <plat/dma-ops.h>
#endif /* __ASM_ARCH_IRQ_H */ #endif /* __ASM_ARCH_IRQ_H */
/*
* Samsung's S3C64XX generic DMA support using amba-pl08x driver.
*
* Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl080.h>
#include <linux/amba/pl08x.h>
#include <linux/of.h>
#include <mach/irqs.h>
#include <mach/map.h>
#include "regs-sys.h"
static int pl08x_get_xfer_signal(const struct pl08x_channel_data *cd)
{
return cd->min_signal;
}
static void pl08x_put_xfer_signal(const struct pl08x_channel_data *cd, int ch)
{
}
/*
* DMA0
*/
static struct pl08x_channel_data s3c64xx_dma0_info[] = {
{
.bus_id = "uart0_tx",
.min_signal = 0,
.max_signal = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart0_rx",
.min_signal = 1,
.max_signal = 1,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_tx",
.min_signal = 2,
.max_signal = 2,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_rx",
.min_signal = 3,
.max_signal = 3,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_tx",
.min_signal = 4,
.max_signal = 4,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_rx",
.min_signal = 5,
.max_signal = 5,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart3_tx",
.min_signal = 6,
.max_signal = 6,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart3_rx",
.min_signal = 7,
.max_signal = 7,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm0_tx",
.min_signal = 8,
.max_signal = 8,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm0_rx",
.min_signal = 9,
.max_signal = 9,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s0_tx",
.min_signal = 10,
.max_signal = 10,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s0_rx",
.min_signal = 11,
.max_signal = 11,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi0_tx",
.min_signal = 12,
.max_signal = 12,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi0_rx",
.min_signal = 13,
.max_signal = 13,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s2_tx",
.min_signal = 14,
.max_signal = 14,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s2_rx",
.min_signal = 15,
.max_signal = 15,
.periph_buses = PL08X_AHB2,
}
};
struct pl08x_platform_data s3c64xx_dma0_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
.cctl_memcpy =
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS),
},
.lli_buses = PL08X_AHB1,
.mem_buses = PL08X_AHB1,
.get_xfer_signal = pl08x_get_xfer_signal,
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma0_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma0_info),
};
static AMBA_AHB_DEVICE(s3c64xx_dma0, "dma-pl080s.0", 0,
0x75000000, {IRQ_DMA0}, &s3c64xx_dma0_plat_data);
/*
* DMA1
*/
static struct pl08x_channel_data s3c64xx_dma1_info[] = {
{
.bus_id = "pcm1_tx",
.min_signal = 0,
.max_signal = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pcm1_rx",
.min_signal = 1,
.max_signal = 1,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s1_tx",
.min_signal = 2,
.max_signal = 2,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s1_rx",
.min_signal = 3,
.max_signal = 3,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi1_tx",
.min_signal = 4,
.max_signal = 4,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "spi1_rx",
.min_signal = 5,
.max_signal = 5,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_out",
.min_signal = 6,
.max_signal = 6,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_in",
.min_signal = 7,
.max_signal = 7,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ac97_mic",
.min_signal = 8,
.max_signal = 8,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "pwm",
.min_signal = 9,
.max_signal = 9,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "irda",
.min_signal = 10,
.max_signal = 10,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "external",
.min_signal = 11,
.max_signal = 11,
.periph_buses = PL08X_AHB2,
},
};
struct pl08x_platform_data s3c64xx_dma1_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
.cctl_memcpy =
(PL080_BSIZE_4 << PL080_CONTROL_SB_SIZE_SHIFT |
PL080_BSIZE_4 << PL080_CONTROL_DB_SIZE_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT |
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT |
PL080_CONTROL_PROT_BUFF | PL080_CONTROL_PROT_CACHE |
PL080_CONTROL_PROT_SYS),
},
.lli_buses = PL08X_AHB1,
.mem_buses = PL08X_AHB1,
.get_xfer_signal = pl08x_get_xfer_signal,
.put_xfer_signal = pl08x_put_xfer_signal,
.slave_channels = s3c64xx_dma1_info,
.num_slave_channels = ARRAY_SIZE(s3c64xx_dma1_info),
};
static AMBA_AHB_DEVICE(s3c64xx_dma1, "dma-pl080s.1", 0,
0x75100000, {IRQ_DMA1}, &s3c64xx_dma1_plat_data);
static int __init s3c64xx_pl080_init(void)
{
/* Set all DMA configuration to be DMA, not SDMA */
writel(0xffffff, S3C64XX_SDMA_SEL);
if (of_have_populated_dt())
return 0;
amba_device_register(&s3c64xx_dma0_device, &iomem_resource);
amba_device_register(&s3c64xx_dma1_device, &iomem_resource);
return 0;
}
arch_initcall(s3c64xx_pl080_init);
...@@ -1468,6 +1468,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, ...@@ -1468,6 +1468,8 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio;
#if defined(CONFIG_PL330_DMA) #if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter; pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#elif defined(CONFIG_S3C24XX_DMAC) #elif defined(CONFIG_S3C24XX_DMAC)
pd.filter = s3c24xx_dma_filter; pd.filter = s3c24xx_dma_filter;
#endif #endif
...@@ -1509,8 +1511,10 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, ...@@ -1509,8 +1511,10 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs; pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr; pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio;
#ifdef CONFIG_PL330_DMA #if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter; pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif #endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1);
...@@ -1550,8 +1554,10 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, ...@@ -1550,8 +1554,10 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr,
pd.num_cs = num_cs; pd.num_cs = num_cs;
pd.src_clk_nr = src_clk_nr; pd.src_clk_nr = src_clk_nr;
pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio;
#ifdef CONFIG_PL330_DMA #if defined(CONFIG_PL330_DMA)
pd.filter = pl330_filter; pd.filter = pl330_filter;
#elif defined(CONFIG_S3C64XX_PL080)
pd.filter = pl08x_filter_id;
#endif #endif
s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2);
......
...@@ -18,6 +18,12 @@ ...@@ -18,6 +18,12 @@
#include <mach/dma.h> #include <mach/dma.h>
#if defined(CONFIG_PL330_DMA)
#define dma_filter pl330_filter
#elif defined(CONFIG_S3C64XX_PL080)
#define dma_filter pl08x_filter_id
#endif
static unsigned samsung_dmadev_request(enum dma_ch dma_ch, static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
struct samsung_dma_req *param, struct samsung_dma_req *param,
struct device *dev, char *ch_name) struct device *dev, char *ch_name)
...@@ -30,7 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch, ...@@ -30,7 +36,7 @@ static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
if (dev->of_node) if (dev->of_node)
return (unsigned)dma_request_slave_channel(dev, ch_name); return (unsigned)dma_request_slave_channel(dev, ch_name);
else else
return (unsigned)dma_request_channel(mask, pl330_filter, return (unsigned)dma_request_channel(mask, dma_filter,
(void *)dma_ch); (void *)dma_ch);
} }
......
/* linux/arch/arm/plat-samsung/include/plat/fiq.h
*
* Copyright (c) 2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Header file for S3C24XX CPU FIQ support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
extern int s3c24xx_set_fiq(unsigned int irq, bool on);
...@@ -331,8 +331,8 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = { ...@@ -331,8 +331,8 @@ static struct samsung_clock_alias s3c64xx_clock_aliases[] = {
ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"), ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"), ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"), ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
ALIAS(HCLK_DMA1, NULL, "dma1"), ALIAS(HCLK_DMA1, "dma-pl080s.1", "apb_pclk"),
ALIAS(HCLK_DMA0, NULL, "dma0"), ALIAS(HCLK_DMA0, "dma-pl080s.0", "apb_pclk"),
ALIAS(HCLK_CAMIF, "s3c-camif", "camif"), ALIAS(HCLK_CAMIF, "s3c-camif", "camif"),
ALIAS(HCLK_LCD, "s3c-fb", "lcd"), ALIAS(HCLK_LCD, "s3c-fb", "lcd"),
ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"), ALIAS(PCLK_SPI1, "s3c6410-spi.1", "spi"),
......
...@@ -402,7 +402,7 @@ config SPI_S3C24XX_FIQ ...@@ -402,7 +402,7 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI" tristate "Samsung S3C64XX series type SPI"
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select S3C64XX_DMA if ARCH_S3C64XX select S3C64XX_PL080 if ARCH_S3C64XX
help help
SPI driver for Samsung S3C64XX and newer SoCs. SPI driver for Samsung S3C64XX and newer SoCs.
......
...@@ -1268,7 +1268,7 @@ static void pxa2xx_spi_shutdown(struct platform_device *pdev) ...@@ -1268,7 +1268,7 @@ static void pxa2xx_spi_shutdown(struct platform_device *pdev)
dev_err(&pdev->dev, "shutdown failed with %d\n", status); dev_err(&pdev->dev, "shutdown failed with %d\n", status);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int pxa2xx_spi_suspend(struct device *dev) static int pxa2xx_spi_suspend(struct device *dev)
{ {
struct driver_data *drv_data = dev_get_drvdata(dev); struct driver_data *drv_data = dev_get_drvdata(dev);
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <plat/regs-spi.h> #include <plat/regs-spi.h>
#include <plat/fiq.h>
#include <asm/fiq.h> #include <asm/fiq.h>
#include "spi-s3c24xx-fiq.h" #include "spi-s3c24xx-fiq.h"
...@@ -78,14 +77,12 @@ struct s3c24xx_spi { ...@@ -78,14 +77,12 @@ struct s3c24xx_spi {
unsigned char *rx; unsigned char *rx;
struct clk *clk; struct clk *clk;
struct resource *ioarea;
struct spi_master *master; struct spi_master *master;
struct spi_device *curdev; struct spi_device *curdev;
struct device *dev; struct device *dev;
struct s3c2410_spi_info *pdata; struct s3c2410_spi_info *pdata;
}; };
#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) #define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
...@@ -517,8 +514,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) ...@@ -517,8 +514,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
if (master == NULL) { if (master == NULL) {
dev_err(&pdev->dev, "No memory for spi_master\n"); dev_err(&pdev->dev, "No memory for spi_master\n");
err = -ENOMEM; return -ENOMEM;
goto err_nomem;
} }
hw = spi_master_get_devdata(master); hw = spi_master_get_devdata(master);
...@@ -562,48 +558,32 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) ...@@ -562,48 +558,32 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
/* find and map our resources */ /* find and map our resources */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) { hw->regs = devm_ioremap_resource(&pdev->dev, res);
dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); if (IS_ERR(hw->regs)) {
err = -ENOENT; err = PTR_ERR(hw->regs);
goto err_no_iores; goto err_no_pdata;
}
hw->ioarea = request_mem_region(res->start, resource_size(res),
pdev->name);
if (hw->ioarea == NULL) {
dev_err(&pdev->dev, "Cannot reserve region\n");
err = -ENXIO;
goto err_no_iores;
}
hw->regs = ioremap(res->start, resource_size(res));
if (hw->regs == NULL) {
dev_err(&pdev->dev, "Cannot map IO\n");
err = -ENXIO;
goto err_no_iomap;
} }
hw->irq = platform_get_irq(pdev, 0); hw->irq = platform_get_irq(pdev, 0);
if (hw->irq < 0) { if (hw->irq < 0) {
dev_err(&pdev->dev, "No IRQ specified\n"); dev_err(&pdev->dev, "No IRQ specified\n");
err = -ENOENT; err = -ENOENT;
goto err_no_irq; goto err_no_pdata;
} }
err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); err = devm_request_irq(&pdev->dev, hw->irq, s3c24xx_spi_irq, 0,
pdev->name, hw);
if (err) { if (err) {
dev_err(&pdev->dev, "Cannot claim IRQ\n"); dev_err(&pdev->dev, "Cannot claim IRQ\n");
goto err_no_irq; goto err_no_pdata;
} }
hw->clk = clk_get(&pdev->dev, "spi"); hw->clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(hw->clk)) { if (IS_ERR(hw->clk)) {
dev_err(&pdev->dev, "No clock for device\n"); dev_err(&pdev->dev, "No clock for device\n");
err = PTR_ERR(hw->clk); err = PTR_ERR(hw->clk);
goto err_no_clk; goto err_no_pdata;
} }
/* setup any gpio we can */ /* setup any gpio we can */
...@@ -615,7 +595,8 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) ...@@ -615,7 +595,8 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
goto err_register; goto err_register;
} }
err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); err = devm_gpio_request(&pdev->dev, pdata->pin_cs,
dev_name(&pdev->dev));
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to get gpio for cs\n"); dev_err(&pdev->dev, "Failed to get gpio for cs\n");
goto err_register; goto err_register;
...@@ -639,27 +620,10 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) ...@@ -639,27 +620,10 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
return 0; return 0;
err_register: err_register:
if (hw->set_cs == s3c24xx_spi_gpiocs)
gpio_free(pdata->pin_cs);
clk_disable(hw->clk); clk_disable(hw->clk);
clk_put(hw->clk);
err_no_clk:
free_irq(hw->irq, hw);
err_no_irq:
iounmap(hw->regs);
err_no_iomap:
release_resource(hw->ioarea);
kfree(hw->ioarea);
err_no_iores:
err_no_pdata: err_no_pdata:
spi_master_put(hw->master); spi_master_put(hw->master);
err_nomem:
return err; return err;
} }
...@@ -668,19 +632,7 @@ static int s3c24xx_spi_remove(struct platform_device *dev) ...@@ -668,19 +632,7 @@ static int s3c24xx_spi_remove(struct platform_device *dev)
struct s3c24xx_spi *hw = platform_get_drvdata(dev); struct s3c24xx_spi *hw = platform_get_drvdata(dev);
spi_bitbang_stop(&hw->bitbang); spi_bitbang_stop(&hw->bitbang);
clk_disable(hw->clk); clk_disable(hw->clk);
clk_put(hw->clk);
free_irq(hw->irq, hw);
iounmap(hw->regs);
if (hw->set_cs == s3c24xx_spi_gpiocs)
gpio_free(hw->pdata->pin_cs);
release_resource(hw->ioarea);
kfree(hw->ioarea);
spi_master_put(hw->master); spi_master_put(hw->master);
return 0; return 0;
} }
......
...@@ -890,7 +890,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, ...@@ -890,7 +890,7 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
unsigned long flags; unsigned long flags;
int use_dma; int use_dma;
reinit_completion(&sdd->xfer_completion); reinit_completion(&sdd->xfer_completion);
/* Only BPW and Speed may change across transfers */ /* Only BPW and Speed may change across transfers */
bpw = xfer->bits_per_word; bpw = xfer->bits_per_word;
...@@ -927,9 +927,6 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, ...@@ -927,9 +927,6 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
/* Start the signals */ /* Start the signals */
writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
/* Start the signals */
writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL);
spin_unlock_irqrestore(&sdd->lock, flags); spin_unlock_irqrestore(&sdd->lock, flags);
status = wait_for_xfer(sdd, xfer, use_dma); status = wait_for_xfer(sdd, xfer, use_dma);
......
...@@ -171,7 +171,6 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, ...@@ -171,7 +171,6 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg,
int remain = t->len; int remain = t->len;
int cur_len; int cur_len;
unsigned char *data; unsigned char *data;
unsigned long tmp;
long ret; long ret;
if (t->len) if (t->len)
...@@ -213,9 +212,7 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, ...@@ -213,9 +212,7 @@ static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg,
} }
if (list_is_last(&t->transfer_list, &mesg->transfers)) { if (list_is_last(&t->transfer_list, &mesg->transfers)) {
tmp = spi_sh_read(ss, SPI_SH_CR1); spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1);
tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB);
spi_sh_write(ss, tmp, SPI_SH_CR1);
spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1);
ss->cr1 &= ~SPI_SH_TBE; ss->cr1 &= ~SPI_SH_TBE;
...@@ -239,7 +236,6 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, ...@@ -239,7 +236,6 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg,
int remain = t->len; int remain = t->len;
int cur_len; int cur_len;
unsigned char *data; unsigned char *data;
unsigned long tmp;
long ret; long ret;
if (t->len > SPI_SH_MAX_BYTE) if (t->len > SPI_SH_MAX_BYTE)
...@@ -247,9 +243,7 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, ...@@ -247,9 +243,7 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg,
else else
spi_sh_write(ss, t->len, SPI_SH_CR3); spi_sh_write(ss, t->len, SPI_SH_CR3);
tmp = spi_sh_read(ss, SPI_SH_CR1); spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1);
tmp = tmp & ~(SPI_SH_SSD | SPI_SH_SSDB);
spi_sh_write(ss, tmp, SPI_SH_CR1);
spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1);
spi_sh_wait_write_buffer_empty(ss); spi_sh_wait_write_buffer_empty(ss);
......
This diff is collapsed.
...@@ -148,14 +148,14 @@ struct tegra_sflash_data { ...@@ -148,14 +148,14 @@ struct tegra_sflash_data {
static int tegra_sflash_runtime_suspend(struct device *dev); static int tegra_sflash_runtime_suspend(struct device *dev);
static int tegra_sflash_runtime_resume(struct device *dev); static int tegra_sflash_runtime_resume(struct device *dev);
static inline unsigned long tegra_sflash_readl(struct tegra_sflash_data *tsd, static inline u32 tegra_sflash_readl(struct tegra_sflash_data *tsd,
unsigned long reg) unsigned long reg)
{ {
return readl(tsd->base + reg); return readl(tsd->base + reg);
} }
static inline void tegra_sflash_writel(struct tegra_sflash_data *tsd, static inline void tegra_sflash_writel(struct tegra_sflash_data *tsd,
unsigned long val, unsigned long reg) u32 val, unsigned long reg)
{ {
writel(val, tsd->base + reg); writel(val, tsd->base + reg);
} }
...@@ -185,7 +185,7 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf( ...@@ -185,7 +185,7 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(
struct tegra_sflash_data *tsd, struct spi_transfer *t) struct tegra_sflash_data *tsd, struct spi_transfer *t)
{ {
unsigned nbytes; unsigned nbytes;
unsigned long status; u32 status;
unsigned max_n_32bit = tsd->curr_xfer_words; unsigned max_n_32bit = tsd->curr_xfer_words;
u8 *tx_buf = (u8 *)t->tx_buf + tsd->cur_tx_pos; u8 *tx_buf = (u8 *)t->tx_buf + tsd->cur_tx_pos;
...@@ -196,11 +196,11 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf( ...@@ -196,11 +196,11 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(
status = tegra_sflash_readl(tsd, SPI_STATUS); status = tegra_sflash_readl(tsd, SPI_STATUS);
while (!(status & SPI_TXF_FULL)) { while (!(status & SPI_TXF_FULL)) {
int i; int i;
unsigned int x = 0; u32 x = 0;
for (i = 0; nbytes && (i < tsd->bytes_per_word); for (i = 0; nbytes && (i < tsd->bytes_per_word);
i++, nbytes--) i++, nbytes--)
x |= ((*tx_buf++) << i*8); x |= (u32)(*tx_buf++) << (i * 8);
tegra_sflash_writel(tsd, x, SPI_TX_FIFO); tegra_sflash_writel(tsd, x, SPI_TX_FIFO);
if (!nbytes) if (!nbytes)
break; break;
...@@ -214,16 +214,14 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf( ...@@ -214,16 +214,14 @@ static unsigned tegra_sflash_fill_tx_fifo_from_client_txbuf(
static int tegra_sflash_read_rx_fifo_to_client_rxbuf( static int tegra_sflash_read_rx_fifo_to_client_rxbuf(
struct tegra_sflash_data *tsd, struct spi_transfer *t) struct tegra_sflash_data *tsd, struct spi_transfer *t)
{ {
unsigned long status; u32 status;
unsigned int read_words = 0; unsigned int read_words = 0;
u8 *rx_buf = (u8 *)t->rx_buf + tsd->cur_rx_pos; u8 *rx_buf = (u8 *)t->rx_buf + tsd->cur_rx_pos;
status = tegra_sflash_readl(tsd, SPI_STATUS); status = tegra_sflash_readl(tsd, SPI_STATUS);
while (!(status & SPI_RXF_EMPTY)) { while (!(status & SPI_RXF_EMPTY)) {
int i; int i;
unsigned long x; u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO);
x = tegra_sflash_readl(tsd, SPI_RX_FIFO);
for (i = 0; (i < tsd->bytes_per_word); i++) for (i = 0; (i < tsd->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
read_words++; read_words++;
...@@ -236,7 +234,7 @@ static int tegra_sflash_read_rx_fifo_to_client_rxbuf( ...@@ -236,7 +234,7 @@ static int tegra_sflash_read_rx_fifo_to_client_rxbuf(
static int tegra_sflash_start_cpu_based_transfer( static int tegra_sflash_start_cpu_based_transfer(
struct tegra_sflash_data *tsd, struct spi_transfer *t) struct tegra_sflash_data *tsd, struct spi_transfer *t)
{ {
unsigned long val = 0; u32 val = 0;
unsigned cur_words; unsigned cur_words;
if (tsd->cur_direction & DATA_DIR_TX) if (tsd->cur_direction & DATA_DIR_TX)
...@@ -266,7 +264,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi, ...@@ -266,7 +264,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi,
{ {
struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master); struct tegra_sflash_data *tsd = spi_master_get_devdata(spi->master);
u32 speed; u32 speed;
unsigned long command; u32 command;
speed = t->speed_hz; speed = t->speed_hz;
if (speed != tsd->cur_speed) { if (speed != tsd->cur_speed) {
...@@ -313,7 +311,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi, ...@@ -313,7 +311,7 @@ static int tegra_sflash_start_transfer_one(struct spi_device *spi,
tegra_sflash_writel(tsd, command, SPI_COMMAND); tegra_sflash_writel(tsd, command, SPI_COMMAND);
tsd->command_reg = command; tsd->command_reg = command;
return tegra_sflash_start_cpu_based_transfer(tsd, t); return tegra_sflash_start_cpu_based_transfer(tsd, t);
} }
static int tegra_sflash_setup(struct spi_device *spi) static int tegra_sflash_setup(struct spi_device *spi)
......
...@@ -196,7 +196,7 @@ struct tegra_slink_data { ...@@ -196,7 +196,7 @@ struct tegra_slink_data {
u32 rx_status; u32 rx_status;
u32 status_reg; u32 status_reg;
bool is_packed; bool is_packed;
unsigned long packed_size; u32 packed_size;
u32 command_reg; u32 command_reg;
u32 command2_reg; u32 command2_reg;
...@@ -220,14 +220,14 @@ struct tegra_slink_data { ...@@ -220,14 +220,14 @@ struct tegra_slink_data {
static int tegra_slink_runtime_suspend(struct device *dev); static int tegra_slink_runtime_suspend(struct device *dev);
static int tegra_slink_runtime_resume(struct device *dev); static int tegra_slink_runtime_resume(struct device *dev);
static inline unsigned long tegra_slink_readl(struct tegra_slink_data *tspi, static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi,
unsigned long reg) unsigned long reg)
{ {
return readl(tspi->base + reg); return readl(tspi->base + reg);
} }
static inline void tegra_slink_writel(struct tegra_slink_data *tspi, static inline void tegra_slink_writel(struct tegra_slink_data *tspi,
unsigned long val, unsigned long reg) u32 val, unsigned long reg)
{ {
writel(val, tspi->base + reg); writel(val, tspi->base + reg);
...@@ -238,38 +238,30 @@ static inline void tegra_slink_writel(struct tegra_slink_data *tspi, ...@@ -238,38 +238,30 @@ static inline void tegra_slink_writel(struct tegra_slink_data *tspi,
static void tegra_slink_clear_status(struct tegra_slink_data *tspi) static void tegra_slink_clear_status(struct tegra_slink_data *tspi)
{ {
unsigned long val; u32 val_write;
unsigned long val_write = 0;
val = tegra_slink_readl(tspi, SLINK_STATUS); tegra_slink_readl(tspi, SLINK_STATUS);
/* Write 1 to clear status register */ /* Write 1 to clear status register */
val_write = SLINK_RDY | SLINK_FIFO_ERROR; val_write = SLINK_RDY | SLINK_FIFO_ERROR;
tegra_slink_writel(tspi, val_write, SLINK_STATUS); tegra_slink_writel(tspi, val_write, SLINK_STATUS);
} }
static unsigned long tegra_slink_get_packed_size(struct tegra_slink_data *tspi, static u32 tegra_slink_get_packed_size(struct tegra_slink_data *tspi,
struct spi_transfer *t) struct spi_transfer *t)
{ {
unsigned long val;
switch (tspi->bytes_per_word) { switch (tspi->bytes_per_word) {
case 0: case 0:
val = SLINK_PACK_SIZE_4; return SLINK_PACK_SIZE_4;
break;
case 1: case 1:
val = SLINK_PACK_SIZE_8; return SLINK_PACK_SIZE_8;
break;
case 2: case 2:
val = SLINK_PACK_SIZE_16; return SLINK_PACK_SIZE_16;
break;
case 4: case 4:
val = SLINK_PACK_SIZE_32; return SLINK_PACK_SIZE_32;
break;
default: default:
val = 0; return 0;
} }
return val;
} }
static unsigned tegra_slink_calculate_curr_xfer_param( static unsigned tegra_slink_calculate_curr_xfer_param(
...@@ -312,10 +304,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( ...@@ -312,10 +304,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
{ {
unsigned nbytes; unsigned nbytes;
unsigned tx_empty_count; unsigned tx_empty_count;
unsigned long fifo_status; u32 fifo_status;
unsigned max_n_32bit; unsigned max_n_32bit;
unsigned i, count; unsigned i, count;
unsigned long x;
unsigned int written_words; unsigned int written_words;
unsigned fifo_words_left; unsigned fifo_words_left;
u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;
...@@ -329,9 +320,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( ...@@ -329,9 +320,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
nbytes = written_words * tspi->bytes_per_word; nbytes = written_words * tspi->bytes_per_word;
max_n_32bit = DIV_ROUND_UP(nbytes, 4); max_n_32bit = DIV_ROUND_UP(nbytes, 4);
for (count = 0; count < max_n_32bit; count++) { for (count = 0; count < max_n_32bit; count++) {
x = 0; u32 x = 0;
for (i = 0; (i < 4) && nbytes; i++, nbytes--) for (i = 0; (i < 4) && nbytes; i++, nbytes--)
x |= (*tx_buf++) << (i*8); x |= (u32)(*tx_buf++) << (i * 8);
tegra_slink_writel(tspi, x, SLINK_TX_FIFO); tegra_slink_writel(tspi, x, SLINK_TX_FIFO);
} }
} else { } else {
...@@ -339,10 +330,10 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( ...@@ -339,10 +330,10 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf(
written_words = max_n_32bit; written_words = max_n_32bit;
nbytes = written_words * tspi->bytes_per_word; nbytes = written_words * tspi->bytes_per_word;
for (count = 0; count < max_n_32bit; count++) { for (count = 0; count < max_n_32bit; count++) {
x = 0; u32 x = 0;
for (i = 0; nbytes && (i < tspi->bytes_per_word); for (i = 0; nbytes && (i < tspi->bytes_per_word);
i++, nbytes--) i++, nbytes--)
x |= ((*tx_buf++) << i*8); x |= (u32)(*tx_buf++) << (i * 8);
tegra_slink_writel(tspi, x, SLINK_TX_FIFO); tegra_slink_writel(tspi, x, SLINK_TX_FIFO);
} }
} }
...@@ -354,9 +345,8 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( ...@@ -354,9 +345,8 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
struct tegra_slink_data *tspi, struct spi_transfer *t) struct tegra_slink_data *tspi, struct spi_transfer *t)
{ {
unsigned rx_full_count; unsigned rx_full_count;
unsigned long fifo_status; u32 fifo_status;
unsigned i, count; unsigned i, count;
unsigned long x;
unsigned int read_words = 0; unsigned int read_words = 0;
unsigned len; unsigned len;
u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos; u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos;
...@@ -366,7 +356,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( ...@@ -366,7 +356,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
if (tspi->is_packed) { if (tspi->is_packed) {
len = tspi->curr_dma_words * tspi->bytes_per_word; len = tspi->curr_dma_words * tspi->bytes_per_word;
for (count = 0; count < rx_full_count; count++) { for (count = 0; count < rx_full_count; count++) {
x = tegra_slink_readl(tspi, SLINK_RX_FIFO); u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
for (i = 0; len && (i < 4); i++, len--) for (i = 0; len && (i < 4); i++, len--)
*rx_buf++ = (x >> i*8) & 0xFF; *rx_buf++ = (x >> i*8) & 0xFF;
} }
...@@ -374,7 +364,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( ...@@ -374,7 +364,7 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
read_words += tspi->curr_dma_words; read_words += tspi->curr_dma_words;
} else { } else {
for (count = 0; count < rx_full_count; count++) { for (count = 0; count < rx_full_count; count++) {
x = tegra_slink_readl(tspi, SLINK_RX_FIFO); u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO);
for (i = 0; (i < tspi->bytes_per_word); i++) for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
} }
...@@ -387,27 +377,24 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( ...@@ -387,27 +377,24 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf(
static void tegra_slink_copy_client_txbuf_to_spi_txbuf( static void tegra_slink_copy_client_txbuf_to_spi_txbuf(
struct tegra_slink_data *tspi, struct spi_transfer *t) struct tegra_slink_data *tspi, struct spi_transfer *t)
{ {
unsigned len;
/* Make the dma buffer to read by cpu */ /* Make the dma buffer to read by cpu */
dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys, dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys,
tspi->dma_buf_size, DMA_TO_DEVICE); tspi->dma_buf_size, DMA_TO_DEVICE);
if (tspi->is_packed) { if (tspi->is_packed) {
len = tspi->curr_dma_words * tspi->bytes_per_word; unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;
memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len); memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len);
} else { } else {
unsigned int i; unsigned int i;
unsigned int count; unsigned int count;
u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos;
unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word; unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word;
unsigned int x;
for (count = 0; count < tspi->curr_dma_words; count++) { for (count = 0; count < tspi->curr_dma_words; count++) {
x = 0; u32 x = 0;
for (i = 0; consume && (i < tspi->bytes_per_word); for (i = 0; consume && (i < tspi->bytes_per_word);
i++, consume--) i++, consume--)
x |= ((*tx_buf++) << i * 8); x |= (u32)(*tx_buf++) << (i * 8);
tspi->tx_dma_buf[count] = x; tspi->tx_dma_buf[count] = x;
} }
} }
...@@ -434,14 +421,10 @@ static void tegra_slink_copy_spi_rxbuf_to_client_rxbuf( ...@@ -434,14 +421,10 @@ static void tegra_slink_copy_spi_rxbuf_to_client_rxbuf(
unsigned int i; unsigned int i;
unsigned int count; unsigned int count;
unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos; unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos;
unsigned int x; u32 rx_mask = ((u32)1 << t->bits_per_word) - 1;
unsigned int rx_mask, bits_per_word;
bits_per_word = t->bits_per_word;
rx_mask = (1 << bits_per_word) - 1;
for (count = 0; count < tspi->curr_dma_words; count++) { for (count = 0; count < tspi->curr_dma_words; count++) {
x = tspi->rx_dma_buf[count]; u32 x = tspi->rx_dma_buf[count] & rx_mask;
x &= rx_mask;
for (i = 0; (i < tspi->bytes_per_word); i++) for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
} }
...@@ -501,17 +484,16 @@ static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len) ...@@ -501,17 +484,16 @@ static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len)
static int tegra_slink_start_dma_based_transfer( static int tegra_slink_start_dma_based_transfer(
struct tegra_slink_data *tspi, struct spi_transfer *t) struct tegra_slink_data *tspi, struct spi_transfer *t)
{ {
unsigned long val; u32 val;
unsigned long test_val;
unsigned int len; unsigned int len;
int ret = 0; int ret = 0;
unsigned long status; u32 status;
/* Make sure that Rx and Tx fifo are empty */ /* Make sure that Rx and Tx fifo are empty */
status = tegra_slink_readl(tspi, SLINK_STATUS); status = tegra_slink_readl(tspi, SLINK_STATUS);
if ((status & SLINK_FIFO_EMPTY) != SLINK_FIFO_EMPTY) { if ((status & SLINK_FIFO_EMPTY) != SLINK_FIFO_EMPTY) {
dev_err(tspi->dev, dev_err(tspi->dev, "Rx/Tx fifo are not empty status 0x%08x\n",
"Rx/Tx fifo are not empty status 0x%08lx\n", status); (unsigned)status);
return -EIO; return -EIO;
} }
...@@ -551,9 +533,9 @@ static int tegra_slink_start_dma_based_transfer( ...@@ -551,9 +533,9 @@ static int tegra_slink_start_dma_based_transfer(
} }
/* Wait for tx fifo to be fill before starting slink */ /* Wait for tx fifo to be fill before starting slink */
test_val = tegra_slink_readl(tspi, SLINK_STATUS); status = tegra_slink_readl(tspi, SLINK_STATUS);
while (!(test_val & SLINK_TX_FULL)) while (!(status & SLINK_TX_FULL))
test_val = tegra_slink_readl(tspi, SLINK_STATUS); status = tegra_slink_readl(tspi, SLINK_STATUS);
} }
if (tspi->cur_direction & DATA_DIR_RX) { if (tspi->cur_direction & DATA_DIR_RX) {
...@@ -587,7 +569,7 @@ static int tegra_slink_start_dma_based_transfer( ...@@ -587,7 +569,7 @@ static int tegra_slink_start_dma_based_transfer(
static int tegra_slink_start_cpu_based_transfer( static int tegra_slink_start_cpu_based_transfer(
struct tegra_slink_data *tspi, struct spi_transfer *t) struct tegra_slink_data *tspi, struct spi_transfer *t)
{ {
unsigned long val; u32 val;
unsigned cur_words; unsigned cur_words;
val = tspi->packed_size; val = tspi->packed_size;
...@@ -714,8 +696,8 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, ...@@ -714,8 +696,8 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
u8 bits_per_word; u8 bits_per_word;
unsigned total_fifo_words; unsigned total_fifo_words;
int ret; int ret;
unsigned long command; u32 command;
unsigned long command2; u32 command2;
bits_per_word = t->bits_per_word; bits_per_word = t->bits_per_word;
speed = t->speed_hz; speed = t->speed_hz;
...@@ -762,17 +744,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, ...@@ -762,17 +744,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
static int tegra_slink_setup(struct spi_device *spi) static int tegra_slink_setup(struct spi_device *spi)
{ {
struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); static const u32 cs_pol_bit[MAX_CHIP_SELECT] = {
unsigned long val;
unsigned long flags;
int ret;
unsigned int cs_pol_bit[MAX_CHIP_SELECT] = {
SLINK_CS_POLARITY, SLINK_CS_POLARITY,
SLINK_CS_POLARITY1, SLINK_CS_POLARITY1,
SLINK_CS_POLARITY2, SLINK_CS_POLARITY2,
SLINK_CS_POLARITY3, SLINK_CS_POLARITY3,
}; };
struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master);
u32 val;
unsigned long flags;
int ret;
dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n", dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",
spi->bits_per_word, spi->bits_per_word,
spi->mode & SPI_CPOL ? "" : "~", spi->mode & SPI_CPOL ? "" : "~",
......
...@@ -46,6 +46,8 @@ struct ti_qspi { ...@@ -46,6 +46,8 @@ struct ti_qspi {
struct spi_master *master; struct spi_master *master;
void __iomem *base; void __iomem *base;
void __iomem *ctrl_base;
void __iomem *mmap_base;
struct clk *fclk; struct clk *fclk;
struct device *dev; struct device *dev;
...@@ -54,6 +56,8 @@ struct ti_qspi { ...@@ -54,6 +56,8 @@ struct ti_qspi {
u32 spi_max_frequency; u32 spi_max_frequency;
u32 cmd; u32 cmd;
u32 dc; u32 dc;
bool ctrl_mod;
}; };
#define QSPI_PID (0x0) #define QSPI_PID (0x0)
...@@ -204,53 +208,36 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t) ...@@ -204,53 +208,36 @@ static int qspi_write_msg(struct ti_qspi *qspi, struct spi_transfer *t)
txbuf = t->tx_buf; txbuf = t->tx_buf;
cmd = qspi->cmd | QSPI_WR_SNGL; cmd = qspi->cmd | QSPI_WR_SNGL;
count = t->len; count = t->len;
wlen = t->bits_per_word; wlen = t->bits_per_word >> 3; /* in bytes */
while (count) { while (count) {
switch (wlen) { switch (wlen) {
case 8: case 1:
dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n", dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %02x\n",
cmd, qspi->dc, *txbuf); cmd, qspi->dc, *txbuf);
writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG); writeb(*txbuf, qspi->base + QSPI_SPI_DATA_REG);
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
ret = wait_for_completion_timeout(&qspi->transfer_complete,
QSPI_COMPLETION_TIMEOUT);
if (ret == 0) {
dev_err(qspi->dev, "write timed out\n");
return -ETIMEDOUT;
}
txbuf += 1;
count -= 1;
break; break;
case 16: case 2:
dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n", dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %04x\n",
cmd, qspi->dc, *txbuf); cmd, qspi->dc, *txbuf);
writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); writew(*((u16 *)txbuf), qspi->base + QSPI_SPI_DATA_REG);
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
ret = wait_for_completion_timeout(&qspi->transfer_complete,
QSPI_COMPLETION_TIMEOUT);
if (ret == 0) {
dev_err(qspi->dev, "write timed out\n");
return -ETIMEDOUT;
}
txbuf += 2;
count -= 2;
break; break;
case 32: case 4:
dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n", dev_dbg(qspi->dev, "tx cmd %08x dc %08x data %08x\n",
cmd, qspi->dc, *txbuf); cmd, qspi->dc, *txbuf);
writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG); writel(*((u32 *)txbuf), qspi->base + QSPI_SPI_DATA_REG);
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
ret = wait_for_completion_timeout(&qspi->transfer_complete,
QSPI_COMPLETION_TIMEOUT);
if (ret == 0) {
dev_err(qspi->dev, "write timed out\n");
return -ETIMEDOUT;
}
txbuf += 4;
count -= 4;
break; break;
} }
ti_qspi_write(qspi, cmd, QSPI_SPI_CMD_REG);
ret = wait_for_completion_timeout(&qspi->transfer_complete,
QSPI_COMPLETION_TIMEOUT);
if (ret == 0) {
dev_err(qspi->dev, "write timed out\n");
return -ETIMEDOUT;
}
txbuf += wlen;
count -= wlen;
} }
return 0; return 0;
...@@ -276,7 +263,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) ...@@ -276,7 +263,7 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)
break; break;
} }
count = t->len; count = t->len;
wlen = t->bits_per_word; wlen = t->bits_per_word >> 3; /* in bytes */
while (count) { while (count) {
dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc); dev_dbg(qspi->dev, "rx cmd %08x dc %08x\n", cmd, qspi->dc);
...@@ -288,22 +275,18 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t) ...@@ -288,22 +275,18 @@ static int qspi_read_msg(struct ti_qspi *qspi, struct spi_transfer *t)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
switch (wlen) { switch (wlen) {
case 8: case 1:
*rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG); *rxbuf = readb(qspi->base + QSPI_SPI_DATA_REG);
rxbuf += 1;
count -= 1;
break; break;
case 16: case 2:
*((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG); *((u16 *)rxbuf) = readw(qspi->base + QSPI_SPI_DATA_REG);
rxbuf += 2;
count -= 2;
break; break;
case 32: case 4:
*((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG); *((u32 *)rxbuf) = readl(qspi->base + QSPI_SPI_DATA_REG);
rxbuf += 4;
count -= 4;
break; break;
} }
rxbuf += wlen;
count -= wlen;
} }
return 0; return 0;
...@@ -435,7 +418,7 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -435,7 +418,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
{ {
struct ti_qspi *qspi; struct ti_qspi *qspi;
struct spi_master *master; struct spi_master *master;
struct resource *r; struct resource *r, *res_ctrl, *res_mmap;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
u32 max_freq; u32 max_freq;
int ret = 0, num_cs, irq; int ret = 0, num_cs, irq;
...@@ -462,7 +445,35 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -462,7 +445,35 @@ static int ti_qspi_probe(struct platform_device *pdev)
qspi->dev = &pdev->dev; qspi->dev = &pdev->dev;
platform_set_drvdata(pdev, qspi); platform_set_drvdata(pdev, qspi);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base");
if (r == NULL) {
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (r == NULL) {
dev_err(&pdev->dev, "missing platform data\n");
return -ENODEV;
}
}
res_mmap = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qspi_mmap");
if (res_mmap == NULL) {
res_mmap = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (res_mmap == NULL) {
dev_err(&pdev->dev,
"memory mapped resource not required\n");
return -ENODEV;
}
}
res_ctrl = platform_get_resource_byname(pdev,
IORESOURCE_MEM, "qspi_ctrlmod");
if (res_ctrl == NULL) {
res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (res_ctrl == NULL) {
dev_dbg(&pdev->dev,
"control module resources not required\n");
}
}
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
...@@ -478,6 +489,23 @@ static int ti_qspi_probe(struct platform_device *pdev) ...@@ -478,6 +489,23 @@ static int ti_qspi_probe(struct platform_device *pdev)
goto free_master; goto free_master;
} }
if (res_ctrl) {
qspi->ctrl_mod = true;
qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl);
if (IS_ERR(qspi->ctrl_base)) {
ret = PTR_ERR(qspi->ctrl_base);
goto free_master;
}
}
if (res_mmap) {
qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap);
if (IS_ERR(qspi->mmap_base)) {
ret = PTR_ERR(qspi->mmap_base);
goto free_master;
}
}
ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0, ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,
dev_name(&pdev->dev), qspi); dev_name(&pdev->dev), qspi);
if (ret < 0) { if (ret < 0) {
...@@ -539,7 +567,7 @@ static struct platform_driver ti_qspi_driver = { ...@@ -539,7 +567,7 @@ static struct platform_driver ti_qspi_driver = {
.probe = ti_qspi_probe, .probe = ti_qspi_probe,
.remove = ti_qspi_remove, .remove = ti_qspi_remove,
.driver = { .driver = {
.name = "ti,dra7xxx-qspi", .name = "ti-qspi",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.pm = &ti_qspi_pm_ops, .pm = &ti_qspi_pm_ops,
.of_match_table = ti_qspi_match, .of_match_table = ti_qspi_match,
...@@ -551,3 +579,4 @@ module_platform_driver(ti_qspi_driver); ...@@ -551,3 +579,4 @@ module_platform_driver(ti_qspi_driver);
MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>"); MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("TI QSPI controller driver"); MODULE_DESCRIPTION("TI QSPI controller driver");
MODULE_ALIAS("platform:ti-qspi");
...@@ -348,7 +348,7 @@ static int txx9spi_probe(struct platform_device *dev) ...@@ -348,7 +348,7 @@ static int txx9spi_probe(struct platform_device *dev)
INIT_LIST_HEAD(&c->queue); INIT_LIST_HEAD(&c->queue);
init_waitqueue_head(&c->waitq); init_waitqueue_head(&c->waitq);
c->clk = clk_get(&dev->dev, "spi-baseclk"); c->clk = devm_clk_get(&dev->dev, "spi-baseclk");
if (IS_ERR(c->clk)) { if (IS_ERR(c->clk)) {
ret = PTR_ERR(c->clk); ret = PTR_ERR(c->clk);
c->clk = NULL; c->clk = NULL;
...@@ -356,7 +356,6 @@ static int txx9spi_probe(struct platform_device *dev) ...@@ -356,7 +356,6 @@ static int txx9spi_probe(struct platform_device *dev)
} }
ret = clk_enable(c->clk); ret = clk_enable(c->clk);
if (ret) { if (ret) {
clk_put(c->clk);
c->clk = NULL; c->clk = NULL;
goto exit; goto exit;
} }
...@@ -415,10 +414,8 @@ static int txx9spi_probe(struct platform_device *dev) ...@@ -415,10 +414,8 @@ static int txx9spi_probe(struct platform_device *dev)
exit: exit:
if (c->workqueue) if (c->workqueue)
destroy_workqueue(c->workqueue); destroy_workqueue(c->workqueue);
if (c->clk) { if (c->clk)
clk_disable(c->clk); clk_disable(c->clk);
clk_put(c->clk);
}
spi_master_put(master); spi_master_put(master);
return ret; return ret;
} }
...@@ -430,7 +427,6 @@ static int txx9spi_remove(struct platform_device *dev) ...@@ -430,7 +427,6 @@ static int txx9spi_remove(struct platform_device *dev)
destroy_workqueue(c->workqueue); destroy_workqueue(c->workqueue);
clk_disable(c->clk); clk_disable(c->clk);
clk_put(c->clk);
return 0; return 0;
} }
......
...@@ -231,22 +231,13 @@ static int spi_xcomm_probe(struct i2c_client *i2c, ...@@ -231,22 +231,13 @@ static int spi_xcomm_probe(struct i2c_client *i2c,
master->dev.of_node = i2c->dev.of_node; master->dev.of_node = i2c->dev.of_node;
i2c_set_clientdata(i2c, master); i2c_set_clientdata(i2c, master);
ret = spi_register_master(master); ret = devm_spi_register_master(&i2c->dev, master);
if (ret < 0) if (ret < 0)
spi_master_put(master); spi_master_put(master);
return ret; return ret;
} }
static int spi_xcomm_remove(struct i2c_client *i2c)
{
struct spi_master *master = i2c_get_clientdata(i2c);
spi_unregister_master(master);
return 0;
}
static const struct i2c_device_id spi_xcomm_ids[] = { static const struct i2c_device_id spi_xcomm_ids[] = {
{ "spi-xcomm" }, { "spi-xcomm" },
{ }, { },
...@@ -259,7 +250,6 @@ static struct i2c_driver spi_xcomm_driver = { ...@@ -259,7 +250,6 @@ static struct i2c_driver spi_xcomm_driver = {
}, },
.id_table = spi_xcomm_ids, .id_table = spi_xcomm_ids,
.probe = spi_xcomm_probe, .probe = spi_xcomm_probe,
.remove = spi_xcomm_remove,
}; };
module_i2c_driver(spi_xcomm_driver); module_i2c_driver(spi_xcomm_driver);
......
...@@ -23,4 +23,6 @@ struct s3c2410_spi_info { ...@@ -23,4 +23,6 @@ struct s3c2410_spi_info {
void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
}; };
extern int s3c24xx_set_fiq(unsigned int irq, bool on);
#endif /* __LINUX_SPI_S3C24XX_H */ #endif /* __LINUX_SPI_S3C24XX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment