diff --git a/drivers/spi/Kconfig.dw b/drivers/spi/Kconfig.dw index 516c3870fda..4f823604d9d 100644 --- a/drivers/spi/Kconfig.dw +++ b/drivers/spi/Kconfig.dw @@ -23,33 +23,6 @@ config SPI_DW_ARC_AUX_REGS registers and thus their access is different than memory mapped registers. -choice -depends on SPI_DW -prompt "DesignWare SPI interrupt management logic" -default SPI_DW_INTERRUPT_SINGLE_LINE - -config SPI_DW_INTERRUPT_SINGLE_LINE - bool "Single interrupt line for all interrupts" - help - Only one line is used to trigger interrupts: RX, TX and ERROR - interrupt go all through that line, undifferentiated. -config SPI_DW_INTERRUPT_SEPARATED_LINES - bool "One line per-interrupt type (RX, TX and ERROR)" - help - Each interrupt gets a dedicated line -endchoice - -config SPI_DW_CLOCK_GATE - bool "Enable clock gating" - depends on SPI_DW && SOC_QUARK_SE_C1000 - select CLOCK_CONTROL - default n - -config SPI_DW_CLOCK_GATE_DRV_NAME - string - depends on SPI_DW_CLOCK_GATE - default "" - config SPI_DW_FIFO_DEPTH int "RX and TX FIFO Depth" help @@ -57,12 +30,54 @@ config SPI_DW_FIFO_DEPTH SSI_RX_FIFO_DEPTH of the DesignWare Synchronous Serial Interface. Depth ranges from 2-256. +if SPI_0 + +config SPI_DW_PORT_0_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_0_CLOCK_GATE + bool "Enable clock gating" + depends on CLOCK_CONTROL + default n + +if SPI_DW_PORT_0_CLOCK_GATE + +config SPI_DW_PORT_0_CLOCK_GATE_DRV_NAME + string + default "" + config SPI_DW_PORT_0_CLOCK_GATE_SUBSYS int "Clock controller's subsystem" - depends on SPI_DW_CLOCK_GATE + +endif # SPI_DW_PORT_0_CLOCK_GATE + +endif # SPI_0 + +if SPI_1 + +config SPI_DW_PORT_1_INTERRUPT_SINGLE_LINE + bool "Single interrupt line for all interrupts" + default y + +config SPI_DW_PORT_1_CLOCK_GATE + bool "Enable clock gating" + depends on CLOCK_CONTROL + default n + +if SPI_DW_PORT_1_CLOCK_GATE + +config SPI_DW_PORT_1_CLOCK_GATE_DRV_NAME + string + default "" config SPI_DW_PORT_1_CLOCK_GATE_SUBSYS int "Clock controller's subsystem" - depends on SPI_DW_CLOCK_GATE +endif # SPI_DW_PORT_1_CLOCK_GATE + +endif # SPI_1 endif # SPI_DW diff --git a/drivers/spi/spi_dw.c b/drivers/spi/spi_dw.c index 97e100c9243..db53da08bd2 100644 --- a/drivers/spi/spi_dw.c +++ b/drivers/spi/spi_dw.c @@ -462,9 +462,10 @@ struct spi_dw_data spi_dw_data_port_0 = { const struct spi_dw_config spi_dw_config_0 = { .regs = SPI_DW_PORT_0_REGS, -#ifdef CONFIG_SPI_DW_CLOCK_GATE - .clock_data = UINT_TO_POINTER(CONFIG_SPI_0_CLOCK_GATE_SUBSYS), -#endif /* CONFIG_SPI_DW_CLOCK_GATE */ +#ifdef CONFIG_SPI_DW_PORT_0_CLOCK_GATE + .clock_name = CONFIG_SPI_DW_PORT_1_CLOCK_GATE_DRV_NAME, + .clock_data = UINT_TO_POINTER(CONFIG_SPI_DW_PORT_0_CLOCK_GATE_SUBSYS), +#endif /* CONFIG_SPI_DW_PORT_0_CLOCK_GATE */ .config_func = spi_config_0_irq }; @@ -475,12 +476,12 @@ DEVICE_AND_API_INIT(spi_dw_port_0, CONFIG_SPI_0_NAME, spi_dw_init, void spi_config_0_irq(void) { -#ifdef CONFIG_SPI_DW_INTERRUPT_SINGLE_LINE +#ifdef CONFIG_SPI_DW_PORT_0_INTERRUPT_SINGLE_LINE IRQ_CONNECT(SPI_DW_PORT_0_IRQ, CONFIG_SPI_0_IRQ_PRI, spi_dw_isr, DEVICE_GET(spi_dw_port_0), SPI_DW_IRQ_FLAGS); irq_enable(SPI_DW_PORT_0_IRQ); _spi_int_unmask(SPI_DW_PORT_0_INT_MASK); -#else /* SPI_DW_INTERRUPT_SEPARATED_LINES */ +#else IRQ_CONNECT(IRQ_SPI0_RX_AVAIL, CONFIG_SPI_0_IRQ_PRI, spi_dw_isr, DEVICE_GET(spi_dw_port_0), SPI_DW_IRQ_FLAGS); IRQ_CONNECT(IRQ_SPI0_TX_REQ, CONFIG_SPI_0_IRQ_PRI, @@ -508,9 +509,10 @@ struct spi_dw_data spi_dw_data_port_1 = { static const struct spi_dw_config spi_dw_config_1 = { .regs = SPI_DW_PORT_1_REGS, -#ifdef CONFIG_SPI_DW_CLOCK_GATE - .clock_data = UINT_TO_POINTER(CONFIG_SPI_1_CLOCK_GATE_SUBSYS), -#endif /* CONFIG_SPI_DW_CLOCK_GATE */ +#ifdef CONFIG_SPI_DW_PORT_1_CLOCK_GATE + .clock_name = CONFIG_SPI_DW_PORT_1_CLOCK_GATE_DRV_NAME, + .clock_data = UINT_TO_POINTER(CONFIG_SPI_DW_PORT_1_CLOCK_GATE_SUBSYS), +#endif /* CONFIG_SPI_DW_PORT_1_CLOCK_GATE */ .config_func = spi_config_1_irq }; @@ -521,12 +523,12 @@ DEVICE_AND_API_INIT(spi_dw_port_1, CONFIG_SPI_1_NAME, spi_dw_init, void spi_config_1_irq(void) { -#ifdef CONFIG_SPI_DW_INTERRUPT_SINGLE_LINE +#ifdef CONFIG_SPI_DW_PORT_1_INTERRUPT_SINGLE_LINE IRQ_CONNECT(SPI_DW_PORT_1_IRQ, CONFIG_SPI_1_IRQ_PRI, spi_dw_isr, DEVICE_GET(spi_dw_port_1), SPI_DW_IRQ_FLAGS); irq_enable(SPI_DW_PORT_1_IRQ); _spi_int_unmask(SPI_DW_PORT_1_INT_MASK); -#else /* SPI_DW_INTERRUPT_SEPARATED_LINES */ +#else IRQ_CONNECT(IRQ_SPI1_RX_AVAIL, CONFIG_SPI_1_IRQ_PRI, spi_dw_isr, DEVICE_GET(spi_dw_port_1), SPI_DW_IRQ_FLAGS); IRQ_CONNECT(IRQ_SPI1_TX_REQ, CONFIG_SPI_1_IRQ_PRI, diff --git a/drivers/spi/spi_dw.h b/drivers/spi/spi_dw.h index 4f70030f173..24c990f3962 100644 --- a/drivers/spi/spi_dw.h +++ b/drivers/spi/spi_dw.h @@ -20,18 +20,19 @@ typedef void (*spi_dw_config_t)(void); /* Private structures */ struct spi_dw_config { u32_t regs; -#ifdef CONFIG_SPI_DW_CLOCK_GATE +#ifdef CONFIG_CLOCK_CONTROL + const char *clock_name; void *clock_data; -#endif /* CONFIG_SPI_DW_CLOCK_GATE */ +#endif /* CONFIG_CLOCK_CONTROL */ spi_dw_config_t config_func; }; #include "spi_context.h" struct spi_dw_data { -#ifdef CONFIG_SPI_DW_CLOCK_GATE +#ifdef CONFIG_CLOCK_CONTROL struct device *clock; -#endif /* CONFIG_SPI_DW_CLOCK_GATE */ +#endif /* CONFIG_CLOCK_CONTROL */ struct spi_context ctx; u8_t dfs; /* dfs in bytes: 1,2 or 4 */ u8_t fifo_diff; /* cannot be bigger than FIFO depth */ @@ -224,6 +225,52 @@ DEFINE_CLEAR_BIT_OP(ssienr, DW_SPI_REG_SSIENR, DW_SPI_SSIENR_SSIEN_BIT) 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 +static inline int _clock_config(struct device *dev) +{ + const struct spi_dw_config *info = dev->config->config_info; + struct spi_dw_data *spi = dev->driver_data; + + if (!info->clock_name || strlen(info->clock_name) == 0) { + spi->clock = NULL; + return 0; + } + + spi->clock = device_get_binding(info->clock_name); + if (!spi->clock) { + return -ENODEV; + } + + return 0; +} + +static inline void _clock_on(struct device *dev) +{ + struct spi_dw_data *spi = dev->driver_data; + + if (spi->clock) { + const struct spi_dw_config *info = dev->config->config_info; + + clock_control_on(spi->clock, info->clock_data); + } +} + +static inline void _clock_off(struct device *dev) +{ + struct spi_dw_data *spi = dev->driver_data; + + if (spi->clock) { + const struct spi_dw_config *info = dev->config->config_info; + + clock_control_off(spi->clock, info->clock_data); + } +} +#else +#define _clock_config(...) +#define _clock_on(...) +#define _clock_off(...) +#endif /* CONFIG_CLOCK_CONTROL */ + #ifdef __cplusplus } #endif diff --git a/drivers/spi/spi_dw_regs.h b/drivers/spi/spi_dw_regs.h index fbffb8c6191..471b571d03f 100644 --- a/drivers/spi/spi_dw_regs.h +++ b/drivers/spi/spi_dw_regs.h @@ -57,41 +57,6 @@ DEFINE_MM_REG_READ(ssi_comp_version, DW_SPI_REG_SSI_COMP_VERSION, 32) DEFINE_TEST_BIT_OP(icr, DW_SPI_REG_ICR, DW_SPI_SR_ICR_BIT) #define clear_interrupts(addr) test_bit_icr(addr) -#ifdef CONFIG_SPI_DW_CLOCK_GATE -static inline void _clock_config(struct device *dev) -{ - struct device *clk; - char *drv = CONFIG_SPI_DW_CLOCK_GATE_DRV_NAME; - - clk = device_get_binding(drv); - if (clk) { - struct spi_dw_data *spi = dev->driver_data; - - spi->clock = clk; - } -} - -static inline void _clock_on(struct device *dev) -{ - const struct spi_dw_config *info = dev->config->config_info; - struct spi_dw_data *spi = dev->driver_data; - - clock_control_on(spi->clock, info->clock_data); -} - -static inline void _clock_off(struct device *dev) -{ - const struct spi_dw_config *info = dev->config->config_info; - struct spi_dw_data *spi = dev->driver_data; - - clock_control_off(spi->clock, info->clock_data); -} -#else -#define _clock_config(...) -#define _clock_on(...) -#define _clock_off(...) -#endif /* CONFIG_SPI_DW_CLOCK_GATE */ - #ifdef __cplusplus } #endif