static void dw_dma_isr(void *arg) { struct device *dev = (struct device *)arg; const struct dw_dma_dev_cfg *const dev_cfg = DEV_CFG(dev); struct dw_dma_dev_data *const dev_data = DEV_DATA(dev); struct dma_chan_data *chan_data; u32_t status_tfr = 0; u32_t status_block = 0; u32_t status_err = 0; u32_t status_intr; u32_t channel; status_intr = dw_read(dev_cfg->base, DW_INTR_STATUS); if (!status_intr) { SYS_LOG_ERR("status_intr = %d", status_intr); } /* get the source of our IRQ. */ status_block = dw_read(dev_cfg->base, DW_STATUS_BLOCK); status_tfr = dw_read(dev_cfg->base, DW_STATUS_TFR); /* TODO: handle errors, just clear them atm */ status_err = dw_read(dev_cfg->base, DW_STATUS_ERR); if (status_err) { SYS_LOG_ERR("status_err = %d\n", status_err); dw_write(dev_cfg->base, DW_CLEAR_ERR, status_err); } /* clear interrupts */ dw_write(dev_cfg->base, DW_CLEAR_BLOCK, status_block); dw_write(dev_cfg->base, DW_CLEAR_TFR, status_tfr); /* Dispatch ISRs for channels depending upon the bit set */ while (status_block) { channel = find_lsb_set(status_block) - 1; status_block &= ~(1 << channel); chan_data = &dev_data->chan[channel]; if (chan_data->dma_blkcallback) { /* Ensure the linked list (chan_data->lli) is * freed in the user callback function once * all the blocks are transferred. */ chan_data->dma_blkcallback(dev, channel, 0); } } while (status_tfr) { channel = find_lsb_set(status_tfr) - 1; status_tfr &= ~(1 << channel); chan_data = &dev_data->chan[channel]; k_free(chan_data->lli); chan_data->lli = NULL; if (chan_data->dma_tfrcallback) { chan_data->dma_tfrcallback(dev, channel, 0); } } }
static void dw_dma_setup(struct device *dev) { const struct dw_dma_dev_cfg *const dev_cfg = DEV_CFG(dev); struct dw_dma_dev_data *const dev_data = DEV_DATA(dev); struct dw_drv_plat_data *dp = dev_data->channel_data; int i; /* we cannot config DMAC if DMAC has been already enabled by host */ if (dw_read(dev_cfg->base, DW_DMA_CFG) != 0) { dw_write(dev_cfg->base, DW_DMA_CFG, 0x0); } /* now check that it's 0 */ for (i = DW_DMA_CFG_TRIES; i > 0; i--) { if (dw_read(dev_cfg->base, DW_DMA_CFG) == 0) { goto found; } } SYS_LOG_ERR("DW_DMA_CFG is non-zero\n"); return; found: for (i = 0; i < DW_MAX_CHAN; i++) { dw_read(dev_cfg->base, DW_DMA_CHAN_EN); } /* enable the DMA controller */ dw_write(dev_cfg->base, DW_DMA_CFG, 1); /* mask all interrupts for all 8 channels */ dw_write(dev_cfg->base, DW_MASK_TFR, INT_MASK_ALL); dw_write(dev_cfg->base, DW_MASK_BLOCK, INT_MASK_ALL); dw_write(dev_cfg->base, DW_MASK_SRC_TRAN, INT_MASK_ALL); dw_write(dev_cfg->base, DW_MASK_DST_TRAN, INT_MASK_ALL); dw_write(dev_cfg->base, DW_MASK_ERR, INT_MASK_ALL); /* set channel priorities */ for (i = 0; i < DW_MAX_CHAN; i++) { dw_write(dev_cfg->base, DW_CTRL_HIGH(i), DW_CFG_CLASS(dp->chan[i].class)); } }
static inline int gpio_dw_read(struct device *port, int access_op, uint32_t pin, uint32_t *value) { struct gpio_dw_config *config = port->config->config_info; uint32_t base_addr = config->base_addr; *value = dw_read(base_addr, EXT_PORTA); if (GPIO_ACCESS_BY_PIN == access_op) { *value = !!(*value & BIT(pin)); } return 0; }
void gpio_dw_isr(void *arg) { struct device *port = (struct device *)arg; struct gpio_dw_runtime *context = port->driver_data; struct gpio_dw_config *config = port->config->config_info; uint32_t base_addr = config->base_addr; uint32_t enabled_int, int_status, bit; int_status = dw_read(base_addr, INTSTATUS); #ifdef CONFIG_SHARED_IRQ /* If using with shared IRQ, this function will be called * by the shared IRQ driver. So check here if the interrupt * is coming from the GPIO controller (or somewhere else). */ if (!int_status) { return; } #endif dw_write(base_addr, PORTA_EOI, int_status); if (!context->callback) { return; } if (context->port_callback) { context->callback(port, int_status); return; } if (context->enabled_callbacks) { enabled_int = int_status & context->enabled_callbacks; for (bit = 0; bit < config->bits; bit++) { if (enabled_int & BIT(bit)) { context->callback(port, bit); } } } }