drivers/spi: Enable port 3 and 4 on DW driver
This will be useful on Quark_SE ARC core which can access x86 core SPI controller. Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
29f8b23bfd
commit
a863494463
4 changed files with 162 additions and 4 deletions
|
@ -80,4 +80,59 @@ config SPI_DW_PORT_1_CLOCK_GATE_SUBSYS
|
|||
endif # SPI_DW_PORT_1_CLOCK_GATE
|
||||
|
||||
endif # SPI_1
|
||||
|
||||
if SPI_2
|
||||
|
||||
config SPI_DW_PORT_2_INTERRUPT_SINGLE_LINE
|
||||
bool "Single interrupt line for all interrupts"
|
||||
default y
|
||||
help
|
||||
Only one line is used to trigger interrupts: RX, TX and ERROR
|
||||
interrupt go all through that line, undifferentiated.
|
||||
|
||||
config SPI_DW_PORT_2_CLOCK_GATE
|
||||
bool "Enable clock gating"
|
||||
depends on CLOCK_CONTROL
|
||||
default n
|
||||
|
||||
if SPI_DW_PORT_2_CLOCK_GATE
|
||||
|
||||
config SPI_DW_PORT_2_CLOCK_GATE_DRV_NAME
|
||||
string
|
||||
default ""
|
||||
|
||||
config SPI_DW_PORT_2_CLOCK_GATE_SUBSYS
|
||||
int "Clock controller's subsystem"
|
||||
|
||||
endif # SPI_DW_PORT_2_CLOCK_GATE
|
||||
|
||||
endif # SPI_2
|
||||
|
||||
if SPI_3
|
||||
|
||||
config SPI_DW_PORT_3_INTERRUPT_SINGLE_LINE
|
||||
bool "Single interrupt line for all interrupts"
|
||||
default y
|
||||
help
|
||||
Only one line is used to trigger interrupts: RX, TX and ERROR
|
||||
interrupt go all through that line, undifferentiated.
|
||||
|
||||
config SPI_DW_PORT_3_CLOCK_GATE
|
||||
bool "Enable clock gating"
|
||||
depends on CLOCK_CONTROL
|
||||
default n
|
||||
|
||||
if SPI_DW_PORT_3_CLOCK_GATE
|
||||
|
||||
config SPI_DW_PORT_3_CLOCK_GATE_DRV_NAME
|
||||
string
|
||||
default ""
|
||||
|
||||
config SPI_DW_PORT_3_CLOCK_GATE_SUBSYS
|
||||
int "Clock controller's subsystem"
|
||||
|
||||
endif # SPI_DW_PORT_3_CLOCK_GATE
|
||||
|
||||
endif # SPI_3
|
||||
|
||||
endif # SPI_DW
|
||||
|
|
|
@ -546,3 +546,97 @@ void spi_config_1_irq(void)
|
|||
#endif
|
||||
}
|
||||
#endif /* CONFIG_SPI_1 */
|
||||
#ifdef CONFIG_SPI_2
|
||||
void spi_config_2_irq(void);
|
||||
|
||||
struct spi_dw_data spi_dw_data_port_2 = {
|
||||
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_2, ctx),
|
||||
SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_2, ctx),
|
||||
};
|
||||
|
||||
static const struct spi_dw_config spi_dw_config_2 = {
|
||||
.regs = SPI_DW_PORT_2_REGS,
|
||||
#ifdef CONFIG_SPI_DW_PORT_2_CLOCK_GATE
|
||||
.clock_name = CONFIG_SPI_DW_PORT_2_CLOCK_GATE_DRV_NAME,
|
||||
.clock_data = UINT_TO_POINTER(CONFIG_SPI_DW_PORT_2_CLOCK_GATE_SUBSYS),
|
||||
#endif /* CONFIG_SPI_DW_PORT_2_CLOCK_GATE */
|
||||
.config_func = spi_config_2_irq
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(spi_dw_port_2, CONFIG_SPI_2_NAME, spi_dw_init,
|
||||
&spi_dw_data_port_2, &spi_dw_config_2,
|
||||
POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
|
||||
&dw_spi_api);
|
||||
|
||||
void spi_config_2_irq(void)
|
||||
{
|
||||
#ifdef CONFIG_SPI_DW_PORT_2_INTERRUPT_SINGLE_LINE
|
||||
IRQ_CONNECT(SPI_DW_PORT_2_IRQ, CONFIG_SPI_2_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_2), SPI_DW_IRQ_FLAGS);
|
||||
irq_enable(SPI_DW_PORT_2_IRQ);
|
||||
_spi_int_unmask(SPI_DW_PORT_2_INT_MASK);
|
||||
#else
|
||||
IRQ_CONNECT(IRQ_SPI2_RX_AVAIL, CONFIG_SPI_2_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_2), SPI_DW_IRQ_FLAGS);
|
||||
IRQ_CONNECT(IRQ_SPI2_TX_REQ, CONFIG_SPI_2_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_2), SPI_DW_IRQ_FLAGS);
|
||||
IRQ_CONNECT(IRQ_SPI2_ERR_INT, CONFIG_SPI_2_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_2), SPI_DW_IRQ_FLAGS);
|
||||
|
||||
irq_enable(IRQ_SPI2_RX_AVAIL);
|
||||
irq_enable(IRQ_SPI2_TX_REQ);
|
||||
irq_enable(IRQ_SPI2_ERR_INT);
|
||||
|
||||
_spi_int_unmask(SPI_DW_PORT_2_RX_INT_MASK);
|
||||
_spi_int_unmask(SPI_DW_PORT_2_TX_INT_MASK);
|
||||
_spi_int_unmask(SPI_DW_PORT_2_ERROR_INT_MASK);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_SPI_2 */
|
||||
#ifdef CONFIG_SPI_3
|
||||
void spi_config_3_irq(void);
|
||||
|
||||
struct spi_dw_data spi_dw_data_port_3 = {
|
||||
SPI_CONTEXT_INIT_LOCK(spi_dw_data_port_3, ctx),
|
||||
SPI_CONTEXT_INIT_SYNC(spi_dw_data_port_3, ctx),
|
||||
};
|
||||
|
||||
static const struct spi_dw_config spi_dw_config_3 = {
|
||||
.regs = SPI_DW_PORT_3_REGS,
|
||||
#ifdef CONFIG_SPI_DW_PORT_3_CLOCK_GATE
|
||||
.clock_name = CONFIG_SPI_DW_PORT_3_CLOCK_GATE_DRV_NAME,
|
||||
.clock_data = UINT_TO_POINTER(CONFIG_SPI_DW_PORT_3_CLOCK_GATE_SUBSYS),
|
||||
#endif /* CONFIG_SPI_DW_PORT_3_CLOCK_GATE */
|
||||
.config_func = spi_config_3_irq
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(spi_dw_port_3, CONFIG_SPI_3_NAME, spi_dw_init,
|
||||
&spi_dw_data_port_3, &spi_dw_config_3,
|
||||
POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,
|
||||
&dw_spi_api);
|
||||
|
||||
void spi_config_3_irq(void)
|
||||
{
|
||||
#ifdef CONFIG_SPI_DW_PORT_3_INTERRUPT_SINGLE_LINE
|
||||
IRQ_CONNECT(SPI_DW_PORT_3_IRQ, CONFIG_SPI_3_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_3), SPI_DW_IRQ_FLAGS);
|
||||
irq_enable(SPI_DW_PORT_3_IRQ);
|
||||
_spi_int_unmask(SPI_DW_PORT_3_INT_MASK);
|
||||
#else
|
||||
IRQ_CONNECT(IRQ_SPI3_RX_AVAIL, CONFIG_SPI_3_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_3), SPI_DW_IRQ_FLAGS);
|
||||
IRQ_CONNECT(IRQ_SPI3_TX_REQ, CONFIG_SPI_3_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_3), SPI_DW_IRQ_FLAGS);
|
||||
IRQ_CONNECT(IRQ_SPI3_ERR_INT, CONFIG_SPI_3_IRQ_PRI,
|
||||
spi_dw_isr, DEVICE_GET(spi_dw_port_3), SPI_DW_IRQ_FLAGS);
|
||||
|
||||
irq_enable(IRQ_SPI3_RX_AVAIL);
|
||||
irq_enable(IRQ_SPI3_TX_REQ);
|
||||
irq_enable(IRQ_SPI3_ERR_INT);
|
||||
|
||||
_spi_int_unmask(SPI_DW_PORT_3_RX_INT_MASK);
|
||||
_spi_int_unmask(SPI_DW_PORT_3_TX_INT_MASK);
|
||||
_spi_int_unmask(SPI_DW_PORT_3_ERROR_INT_MASK);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_SPI_3 */
|
||||
|
|
|
@ -195,6 +195,10 @@ struct spi_dw_data {
|
|||
#include "spi_dw_quark_se_ss_regs.h"
|
||||
#else
|
||||
#include "spi_dw_regs.h"
|
||||
|
||||
#define _extra_clock_on(...)
|
||||
#define _extra_clock_off(...)
|
||||
|
||||
#endif
|
||||
|
||||
/* Interrupt mask
|
||||
|
@ -226,6 +230,9 @@ DEFINE_TEST_BIT_OP(ssienr, DW_SPI_REG_SSIENR, DW_SPI_SSIENR_SSIEN_BIT)
|
|||
DEFINE_TEST_BIT_OP(sr_busy, DW_SPI_REG_SR, DW_SPI_SR_BUSY_BIT)
|
||||
|
||||
#ifdef CONFIG_CLOCK_CONTROL
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static inline int _clock_config(struct device *dev)
|
||||
{
|
||||
const struct spi_dw_config *info = dev->config->config_info;
|
||||
|
@ -253,6 +260,8 @@ static inline void _clock_on(struct device *dev)
|
|||
|
||||
clock_control_on(spi->clock, info->clock_data);
|
||||
}
|
||||
|
||||
_extra_clock_on(dev);
|
||||
}
|
||||
|
||||
static inline void _clock_off(struct device *dev)
|
||||
|
@ -264,6 +273,8 @@ static inline void _clock_off(struct device *dev)
|
|||
|
||||
clock_control_off(spi->clock, info->clock_data);
|
||||
}
|
||||
|
||||
_extra_clock_off(dev);
|
||||
}
|
||||
#else
|
||||
#define _clock_config(...)
|
||||
|
|
|
@ -132,16 +132,14 @@ static inline u32_t read_dr(u32_t addr)
|
|||
DEFINE_SET_BIT_OP(clk_ena, DW_SPI_REG_CTRLR0, DW_SPI_CTRLR0_CLK_ENA_BIT)
|
||||
DEFINE_CLEAR_BIT_OP(clk_ena, DW_SPI_REG_CTRLR0, DW_SPI_CTRLR0_CLK_ENA_BIT)
|
||||
|
||||
#define _clock_config(...)
|
||||
|
||||
static inline void _clock_on(struct device *dev)
|
||||
static inline void _extra_clock_on(struct device *dev)
|
||||
{
|
||||
const struct spi_dw_config *info = dev->config->config_info;
|
||||
|
||||
set_bit_clk_ena(info->regs);
|
||||
}
|
||||
|
||||
static inline void _clock_off(struct device *dev)
|
||||
static inline void _extra_clock_off(struct device *dev)
|
||||
{
|
||||
const struct spi_dw_config *info = dev->config->config_info;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue