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:
Tomasz Bursztyka 2018-02-27 09:25:50 +01:00 committed by Carles Cufí
commit a863494463
4 changed files with 162 additions and 4 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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(...)

View file

@ -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;