mmc: mmci: Initial support to manage variant specific callbacks
authorUlf Hansson <ulf.hansson@linaro.org>
Fri, 13 Jul 2018 11:15:23 +0000 (13:15 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 30 Jul 2018 13:07:43 +0000 (15:07 +0200)
To be able to better support different mmci variants, we need to be able to
use variant specific callbacks, rather than continue to sprinkle the code
with additional variant data. To move in this direction, let's add an
optional ->init() callback to the variant data struct, which variants shall
use to assign the mmci_host_ops pointer.

Using an ->init() callback enables us to partition the code between
different files. To allow separate mmci variant files to implement the
variant specifics, let's also move the definition of the struct
variant_data to the common mmci header file.

Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Ludovic Barre <ludovic.barre@st.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h

index f1849775e47e2726ef2addb357016418a246469b..e907a0a866da71186aa54bc7aea4a33390029911 100644 (file)
 
 static unsigned int fmax = 515633;
 
-/**
- * struct variant_data - MMCI variant-specific quirks
- * @clkreg: default value for MCICLOCK register
- * @clkreg_enable: enable value for MMCICLOCK register
- * @clkreg_8bit_bus_enable: enable value for 8 bit bus
- * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
- * @datalength_bits: number of bits in the MMCIDATALENGTH register
- * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
- *           is asserted (likewise for RX)
- * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
- *               is asserted (likewise for RX)
- * @data_cmd_enable: enable value for data commands.
- * @st_sdio: enable ST specific SDIO logic
- * @st_clkdiv: true if using a ST-specific clock divider algorithm
- * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
- * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
- * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
- *                  register
- * @datactrl_mask_sdio: SDIO enable mask in datactrl register
- * @pwrreg_powerup: power up value for MMCIPOWER register
- * @f_max: maximum clk frequency supported by the controller.
- * @signal_direction: input/out direction of bus signals can be indicated
- * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
- * @busy_detect: true if the variant supports busy detection on DAT0.
- * @busy_dpsm_flag: bitmask enabling busy detection in the DPSM
- * @busy_detect_flag: bitmask identifying the bit in the MMCISTATUS register
- *                   indicating that the card is busy
- * @busy_detect_mask: bitmask identifying the bit in the MMCIMASK0 to mask for
- *                   getting busy end detection interrupts
- * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
- * @explicit_mclk_control: enable explicit mclk control in driver.
- * @qcom_fifo: enables qcom specific fifo pio read logic.
- * @qcom_dml: enables qcom specific dma glue for dma transfers.
- * @reversed_irq_handling: handle data irq before cmd irq.
- * @mmcimask1: true if variant have a MMCIMASK1 register.
- * @start_err: bitmask identifying the STARTBITERR bit inside MMCISTATUS
- *            register.
- * @opendrain: bitmask identifying the OPENDRAIN bit inside MMCIPOWER register
- */
-struct variant_data {
-       unsigned int            clkreg;
-       unsigned int            clkreg_enable;
-       unsigned int            clkreg_8bit_bus_enable;
-       unsigned int            clkreg_neg_edge_enable;
-       unsigned int            datalength_bits;
-       unsigned int            fifosize;
-       unsigned int            fifohalfsize;
-       unsigned int            data_cmd_enable;
-       unsigned int            datactrl_mask_ddrmode;
-       unsigned int            datactrl_mask_sdio;
-       bool                    st_sdio;
-       bool                    st_clkdiv;
-       bool                    blksz_datactrl16;
-       bool                    blksz_datactrl4;
-       u32                     pwrreg_powerup;
-       u32                     f_max;
-       bool                    signal_direction;
-       bool                    pwrreg_clkgate;
-       bool                    busy_detect;
-       u32                     busy_dpsm_flag;
-       u32                     busy_detect_flag;
-       u32                     busy_detect_mask;
-       bool                    pwrreg_nopower;
-       bool                    explicit_mclk_control;
-       bool                    qcom_fifo;
-       bool                    qcom_dml;
-       bool                    reversed_irq_handling;
-       bool                    mmcimask1;
-       u32                     start_err;
-       u32                     opendrain;
-};
-
 static struct variant_data variant_arm = {
        .fifosize               = 16 * 4,
        .fifohalfsize           = 8 * 4,
@@ -1706,6 +1634,9 @@ static int mmci_probe(struct amba_device *dev,
                goto clk_disable;
        }
 
+       if (variant->init)
+               variant->init(host);
+
        /*
         * The ARM and ST versions of the block have slightly different
         * clock divider equations which means that the minimum divider
index f91cdf7f6dae766e7e76fd98626cb401f190cd61..f2eff0cc6934a981fcaad5263d6957326320d58d 100644 (file)
 #define MMCI_PINCTRL_STATE_OPENDRAIN "opendrain"
 
 struct clk;
-struct variant_data;
 struct dma_chan;
+struct mmci_host;
+
+/**
+ * struct variant_data - MMCI variant-specific quirks
+ * @clkreg: default value for MCICLOCK register
+ * @clkreg_enable: enable value for MMCICLOCK register
+ * @clkreg_8bit_bus_enable: enable value for 8 bit bus
+ * @clkreg_neg_edge_enable: enable value for inverted data/cmd output
+ * @datalength_bits: number of bits in the MMCIDATALENGTH register
+ * @fifosize: number of bytes that can be written when MMCI_TXFIFOEMPTY
+ *           is asserted (likewise for RX)
+ * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
+ *               is asserted (likewise for RX)
+ * @data_cmd_enable: enable value for data commands.
+ * @st_sdio: enable ST specific SDIO logic
+ * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @datactrl_mask_ddrmode: ddr mode mask in datactrl register.
+ * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
+ * @blksz_datactrl4: true if Block size is at b4..b16 position in datactrl
+ *                  register
+ * @datactrl_mask_sdio: SDIO enable mask in datactrl register
+ * @pwrreg_powerup: power up value for MMCIPOWER register
+ * @f_max: maximum clk frequency supported by the controller.
+ * @signal_direction: input/out direction of bus signals can be indicated
+ * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock
+ * @busy_detect: true if the variant supports busy detection on DAT0.
+ * @busy_dpsm_flag: bitmask enabling busy detection in the DPSM
+ * @busy_detect_flag: bitmask identifying the bit in the MMCISTATUS register
+ *                   indicating that the card is busy
+ * @busy_detect_mask: bitmask identifying the bit in the MMCIMASK0 to mask for
+ *                   getting busy end detection interrupts
+ * @pwrreg_nopower: bits in MMCIPOWER don't controls ext. power supply
+ * @explicit_mclk_control: enable explicit mclk control in driver.
+ * @qcom_fifo: enables qcom specific fifo pio read logic.
+ * @qcom_dml: enables qcom specific dma glue for dma transfers.
+ * @reversed_irq_handling: handle data irq before cmd irq.
+ * @mmcimask1: true if variant have a MMCIMASK1 register.
+ * @start_err: bitmask identifying the STARTBITERR bit inside MMCISTATUS
+ *            register.
+ * @opendrain: bitmask identifying the OPENDRAIN bit inside MMCIPOWER register
+ */
+struct variant_data {
+       unsigned int            clkreg;
+       unsigned int            clkreg_enable;
+       unsigned int            clkreg_8bit_bus_enable;
+       unsigned int            clkreg_neg_edge_enable;
+       unsigned int            datalength_bits;
+       unsigned int            fifosize;
+       unsigned int            fifohalfsize;
+       unsigned int            data_cmd_enable;
+       unsigned int            datactrl_mask_ddrmode;
+       unsigned int            datactrl_mask_sdio;
+       bool                    st_sdio;
+       bool                    st_clkdiv;
+       bool                    blksz_datactrl16;
+       bool                    blksz_datactrl4;
+       u32                     pwrreg_powerup;
+       u32                     f_max;
+       bool                    signal_direction;
+       bool                    pwrreg_clkgate;
+       bool                    busy_detect;
+       u32                     busy_dpsm_flag;
+       u32                     busy_detect_flag;
+       u32                     busy_detect_mask;
+       bool                    pwrreg_nopower;
+       bool                    explicit_mclk_control;
+       bool                    qcom_fifo;
+       bool                    qcom_dml;
+       bool                    reversed_irq_handling;
+       bool                    mmcimask1;
+       u32                     start_err;
+       u32                     opendrain;
+       void (*init)(struct mmci_host *host);
+};
+
+/* mmci variant callbacks */
+struct mmci_host_ops {
+};
 
 struct mmci_host_next {
        struct dma_async_tx_descriptor  *dma_desc;
@@ -228,6 +305,7 @@ struct mmci_host {
        u32                     mask1_reg;
        bool                    vqmmc_enabled;
        struct mmci_platform_data *plat;
+       struct mmci_host_ops    *ops;
        struct variant_data     *variant;
        struct pinctrl          *pinctrl;
        struct pinctrl_state    *pins_default;