Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: mmci: Add and implement a ->dma_setup() callback for qcom dml

As a first step to improve the variant specific code for mmci, add a
->dma_setup() callback to the struct mmci_host_ops.

To show its use, let's deploy the callback for the qcom dml, which involves
also to the assign the mmci_host_ops pointer from the variant ->init()
callback.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Ludovic Barre <ludovic.barre@st.com>

+20 -11
+3 -4
drivers/mmc/host/mmci.c
··· 208 208 .mmcimask1 = true, 209 209 .start_err = MCI_STARTBITERR, 210 210 .opendrain = MCI_ROD, 211 + .init = qcom_variant_init, 211 212 }; 212 213 213 214 /* Busy detection for the ST Micro variant */ ··· 418 417 static void mmci_dma_setup(struct mmci_host *host) 419 418 { 420 419 const char *rxname, *txname; 421 - struct variant_data *variant = host->variant; 422 420 423 421 host->dma_rx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "rx"); 424 422 host->dma_tx_channel = dma_request_slave_channel(mmc_dev(host->mmc), "tx"); ··· 465 465 host->mmc->max_seg_size = max_seg_size; 466 466 } 467 467 468 - if (variant->qcom_dml && host->dma_rx_channel && host->dma_tx_channel) 469 - if (dml_hw_init(host, host->mmc->parent->of_node)) 470 - variant->qcom_dml = false; 468 + if (host->ops && host->ops->dma_setup) 469 + host->ops->dma_setup(host); 471 470 } 472 471 473 472 /*
+1
drivers/mmc/host/mmci.h
··· 273 273 274 274 /* mmci variant callbacks */ 275 275 struct mmci_host_ops { 276 + void (*dma_setup)(struct mmci_host *host); 276 277 }; 277 278 278 279 struct mmci_host_next {
+14 -4
drivers/mmc/host/mmci_qcom_dml.c
··· 119 119 } 120 120 121 121 /* Initialize the dml hardware connected to SD Card controller */ 122 - int dml_hw_init(struct mmci_host *host, struct device_node *np) 122 + static void qcom_dma_setup(struct mmci_host *host) 123 123 { 124 124 u32 config; 125 125 void __iomem *base; 126 126 int consumer_id, producer_id; 127 + struct device_node *np = host->mmc->parent->of_node; 127 128 128 129 consumer_id = of_get_dml_pipe_index(np, "tx"); 129 130 producer_id = of_get_dml_pipe_index(np, "rx"); 130 131 131 - if (producer_id < 0 || consumer_id < 0) 132 - return -ENODEV; 132 + if (producer_id < 0 || consumer_id < 0) { 133 + host->variant->qcom_dml = false; 134 + return; 135 + } 133 136 134 137 base = host->base + DML_OFFSET; 135 138 ··· 175 172 176 173 /* Make sure dml initialization is finished */ 177 174 mb(); 175 + } 178 176 179 - return 0; 177 + static struct mmci_host_ops qcom_variant_ops = { 178 + .dma_setup = qcom_dma_setup, 179 + }; 180 + 181 + void qcom_variant_init(struct mmci_host *host) 182 + { 183 + host->ops = &qcom_variant_ops; 180 184 }
+2 -3
drivers/mmc/host/mmci_qcom_dml.h
··· 16 16 #define __MMC_QCOM_DML_H__ 17 17 18 18 #ifdef CONFIG_MMC_QCOM_DML 19 - int dml_hw_init(struct mmci_host *host, struct device_node *np); 19 + void qcom_variant_init(struct mmci_host *host); 20 20 void dml_start_xfer(struct mmci_host *host, struct mmc_data *data); 21 21 #else 22 - static inline int dml_hw_init(struct mmci_host *host, struct device_node *np) 22 + static inline void qcom_variant_init(struct mmci_host *host) 23 23 { 24 - return -ENOSYS; 25 24 } 26 25 static inline void dml_start_xfer(struct mmci_host *host, struct mmc_data *data) 27 26 {