struct platform_device *__init at32_add_device_mci(unsigned int id, struct mci_platform_data *data) { struct platform_device *pdev; struct mci_dma_data *slave; u32 pioa_mask; u32 piob_mask; if (id != 0 || !data) return NULL; /* Must have at least one usable slot */ if (!data->slot[0].bus_width && !data->slot[1].bus_width) return NULL; pdev = platform_device_alloc("atmel_mci", id); if (!pdev) goto fail; if (platform_device_add_resources(pdev, atmel_mci0_resource, ARRAY_SIZE(atmel_mci0_resource))) goto fail; slave = kzalloc(sizeof(struct mci_dma_data), GFP_KERNEL); if (!slave) goto fail; slave->sdata.dma_dev = &dw_dmac0_device.dev; slave->sdata.cfg_hi = (DWC_CFGH_SRC_PER(0) | DWC_CFGH_DST_PER(1)); slave->sdata.cfg_lo &= ~(DWC_CFGL_HS_DST_POL | DWC_CFGL_HS_SRC_POL); data->dma_slave = slave; if (platform_device_add_data(pdev, data, sizeof(struct mci_platform_data))) goto fail_free; /* CLK line is common to both slots */ pioa_mask = 1 << 10; switch (data->slot[0].bus_width) { case 4: pioa_mask |= 1 << 13; /* DATA1 */ pioa_mask |= 1 << 14; /* DATA2 */ pioa_mask |= 1 << 15; /* DATA3 */ /* fall through */ case 1: pioa_mask |= 1 << 11; /* CMD */ pioa_mask |= 1 << 12; /* DATA0 */ if (gpio_is_valid(data->slot[0].detect_pin)) at32_select_gpio(data->slot[0].detect_pin, 0); if (gpio_is_valid(data->slot[0].wp_pin)) at32_select_gpio(data->slot[0].wp_pin, 0); break; case 0: /* Slot is unused */ break; default: goto fail_free; } select_peripheral(PIOA, pioa_mask, PERIPH_A, 0); piob_mask = 0; switch (data->slot[1].bus_width) { case 4: piob_mask |= 1 << 8; /* DATA1 */ piob_mask |= 1 << 9; /* DATA2 */ piob_mask |= 1 << 10; /* DATA3 */ /* fall through */ case 1: piob_mask |= 1 << 6; /* CMD */ piob_mask |= 1 << 7; /* DATA0 */ select_peripheral(PIOB, piob_mask, PERIPH_B, 0); if (gpio_is_valid(data->slot[1].detect_pin)) at32_select_gpio(data->slot[1].detect_pin, 0); if (gpio_is_valid(data->slot[1].wp_pin)) at32_select_gpio(data->slot[1].wp_pin, 0); break; case 0: /* Slot is unused */ break; default: if (!data->slot[0].bus_width)
int imapx200_dma_devconfig(int channel, enum imapx200_dmafc source, unsigned long devaddr) { struct imapx200_dma_chan *chan = imap_dma_lookup_channel(channel); u32 peripheral; u32 ctlx = 0; u32 intrx = 0; u32 cfg_hi = 0; u32 cfg_lo = 0; pr_debug("%s: channel %d, source %d, dev %08lx, chan %p\n", __func__, channel, source, devaddr, chan); WARN_ON(!chan); if (!chan) return -EINVAL; peripheral = (chan->peripheral & 0x7); chan->source = source; chan->dev_addr = devaddr; pr_debug("%s: peripheral %d\n", __func__, peripheral); ctlx = chan_readl(chan,CTL_LO); pr_debug("devconfig_1\n"); ctlx &= ~DWC_CTLL_FC_MASK; cfg_hi = chan_readl(chan,CFG_HI); pr_debug("CFG_HI is %x\n", cfg_hi); cfg_lo = chan_readl(chan,CFG_LO); pr_debug("devconfig_3\n"); switch (source) { case IMAPX200_DMA_M2M: ctlx |= DWC_CTLL_FC_M2M; break; case IMAPX200_DMA_M2P: ctlx |= DWC_CTLL_FC_M2P; cfg_lo &= ~DWC_CFGL_HS_DST; cfg_hi |= DWC_CFGH_DST_PER(chan->client->handshake); break; case IMAPX200_DMA_P2M: ctlx |= DWC_CTLL_FC_P2M; cfg_lo &= ~DWC_CFGL_HS_SRC; cfg_hi |= DWC_CFGH_SRC_PER(chan->client->handshake); break; default: printk(KERN_ERR "%s: bad source\n", __func__); return -EINVAL; } /*set dma flow control bit*/ chan_writel(chan,CTL_LO,ctlx); pr_debug("devconfig_4\n"); chan_writel(chan,CFG_LO,cfg_lo); pr_debug("devconfig_5\n"); chan_writel(chan,CFG_HI,cfg_hi); // cfg_hi = chan_readl(chan,CFG_HI); // pr_debug("CFG_HI is %x\n", cfg_hi); /* allow TC and ERR interrupts */ intrx = 1<<(chan->number); pr_debug("devconfig_6\n"); dma_set_bit(chan->dmac,MASK.XFER,intrx); pr_debug("devconfig_7\n"); dma_set_bit(chan->dmac,MASK.BLOCK,intrx); dma_set_bit(chan->dmac,MASK.ERROR,intrx); pr_debug("devconfig_8\n"); return 0; }