- 30 Aug, 2017 40 commits
-
-
Hu Ziji authored
Add Xenon specific system-level suspend and resume support. Especially during resume, re-configure Xenon specific registers since registers setting will be lost in suspend if Xenon is power off. Signed-off-by: Hu Ziji <huziji@marvell.com> Signed-off-by: Zhoujie Wu <zjwu@marvell.com> Tested-by: Jisheng Zhang <jszhang@marvell.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Addy Ke authored
Per the databook of designware mmc controller 2.70a, table 3-2, cmd done interrupt should be fired as soon as the the cmd is sent via cmd line. And the response timeout interrupt should be generated unconditioinally as well if the controller doesn't receive the resp. However that doesn't seem to meet the fact of rockchip specified Soc platforms using dwmmc. We have continuously found the the cmd done or response timeout interrupt missed somehow which took us a long time to understand what was happening. Finally we narrow down the root to the reconstruction of sample circuit for dwmmc IP introduced by rockchip and the buggy design sweeps over all the existing rockchip Socs using dwmmc disastrously. It seems no way to work around this bug without the proper break-out mechanism so that we seek for a parallel pair the same as the handling for missing data response timeout, namely dto timer. Adding this cto timer seems easily to handle this bug but it's hard to restrict the code under the rockchip specified context. So after merging this patch, it sets up the cto timer for all the platforms using dwmmc IP which isn't ideal but at least we don't advertise new quirk here. Fortunately, no obvious performance regression was found by test and the pre-existing similar catch-all timer for sdhci has proved it's an acceptant way to make the code as robust as possible. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196321Signed-off-by: Addy Ke <addy.ke@rock-chips.com> Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com> [shawn.lin: rewrite the code and the commit msg throughout] Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
liwei authored
Add sd card support for hi3660 soc Signed-off-by: Li Wei <liwei213@huawei.com> Signed-off-by: Chen Jun <chenjun14@huawei.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
liwei authored
This commit modifies dw_mci_probe(), it moves reset assertion before drv_data->init(host) Some driver needs to access controller registers in its .init() ops. So, in order to make such access safe, we should do controller reset before .init() being called. Signed-off-by: Wei Li <liwei213@huawei.com> Signed-off-by: Guodong Xu <guodong.xu@linaro.org> Signed-off-by: Chen Jun <chenjun14@huawei.com> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Arvind Yadav authored
clk_prepare_enable() can fail here and we must check its return value. Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Arvind Yadav authored
clk_prepare_enable() can fail here and we must check its return value. Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Srinivas Kandagatla authored
Programming legacy HOST SDMA Buffer Boundary bits in Block Size Register (0x04) is not supported in Qualcomm sdhci controllers. Writing to this would cause the controller not to transfer last block in case block size is 4 bytes or less. This issue was noticed while testing sdio wlan card on Qcom DB410c board. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Srinivas Kandagatla authored
This patch adds sdma_boundary member to struct sdhci_host to give more flexibility to drivers to control the sdma boundary buffer value and also to fix issue on some sdhci controllers which are broken when HOST SDMA Buffer Boundary is programmed in Block Size Register (0x04) when using ADMA. Qualcomm sdhci controller is one of such type, writing to this bits is un-supported. Default value of sdma_boundary is set to SDHCI_DEFAULT_BOUNDARY_ARG. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The structure renesas_sdhi_internal_dmac_dma_ops is only passed as the second argument to renesas_sdhi_probe, which is const, so renesas_sdhi_internal_dmac_dma_ops can be const too. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The sdhci_pltfm_data structure is only passed as the second argument of sdhci_pltfm_init, which is const, so the sdhci_pltfm_data structure can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The sdhci_pltfm_data structure is only passed as the second argument of sdhci_pltfm_init, which is const, while the sdhci_ops structure is only stored in the ops field of a sdhci_pltfm_data structure, which is also const. Thus both kinds of structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Acked-by: Michal Simek <michal.simek@xilinx.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The sdhci_pltfm_data structure is only passed as the second argument of sdhci_pltfm_init, which is const, while the sdhci_ops structure is only stored in the ops field of a sdhci_pltfm_data structure, which is also const. Thus both kinds of structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The sdhci_pltfm_data structure is only passed as the second argument of sdhci_pltfm_init, which is const, while the sdhci_ops structure is only stored in the ops field of a sdhci_pltfm_data structure, which is also const. Thus both kinds of structures can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The sdhci_pltfm_data structure is only passed as the second argument of sdhci_pltfm_init, which is const, so the sdhci_pltfm_data structure can be const as well. Done with the help of Coccinelle. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Shawn Lin authored
Per the SD physical layer simplified specification V4.10, section 4.6.2, CSD version 1.0 SD card should use taac, nsac and r2w_factor for calculating the data access time. But the taac and nsac for SDHC(CSD version 2.0) are always fixed and the software should use the recommended value for timeout. When parsing the CSD, we sanely set them to zero for SDHC(CSD version 2.0), all the calculation for timeout_ns and timeout_clk is zero as well. So what we actually want to limit here is either SDHC case or unreasonable timeout reported by the cards. In principle we should at least be able to remove the bogus check for the mmc_card_blockaddr. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Zhoujie Wu authored
One issue was found on a removable high speed sd card with runtime pm enabled. When SD card is unplugged, it keep printing "Switching to 3.3V signalling voltage failed". And found below sequence triggers the error. mmc_rescan -> mmc_sd_detect -> mmc_power_off -- mmc->ios.vdd is updated to 0. -> mmc_claim_host -> sdhci_runtime_resume_host -> sdhci_start_signal_voltage_switch -> mmc_regulator_set_vqmmc -> mmc_ocrbitnum_to_vdd When mmc_ocrbitnum_to_vdd is called, the mmc->ios.vdd is 0, so it always return -EINVAL. The signal switch will always fail and print out warning. Ignore restoring the I/O state when runtime resume if MMC_POWER_OFF. Signed-off-by: Zhoujie Wu <zjwu@marvell.com> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Icenowy Zheng authored
The A83T MMC support code introduces the timings mode switch, however such a switch doesn't exist on new SoCs with only new timings mode. Only execute the switch if the SoC really have the timings mode switch, to fix the regression shown on new timings mode only SoCs (A64, H5, etc). Signed-off-by: Icenowy Zheng <icenowy@aosc.io> Reviewed-by: Chen-Yu Tsai <wens@csie.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
Some SoCs do not support clk delays for MMC in the clock control unit. These include the old controllers in A10/A10s/A13/R8, and the new eMMC controller in A64. The config structure for these controllers do not specify clk_delays, but the check for this was replaced in change "mmc: sunxi: Support controllers that can use both old and new timings". This patch adds back the check for clk_delays, and also adds comments for both checks in sunxi_mmc_clk_set_phase(). Signed-off-by: Chen-Yu Tsai <wens@csie.org> Tested-by: Icenowy Zheng <icenowy@aosc.io> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
The third MMC controller (MMC2) on the Allwinner A83T SoC is slightly different. It supports a wider 8-bit bus, has a dedicated controllable reset pin for eMMC, and a "new timing mode" which is supposed to deliver better signals and thus better performance. Add a compatible for this one to use the new timing mode not found in the other controllers. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Rob Herring <robh@kernel.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
The MMC controller can support DDR52 transfers under the new timing mode. According to the BSP kernel, the module clock has to be double the card clock, regardless of the bus width. The default timings in the hardware can be used. This also reworks the code setting the internal divider, getting rid of a extra conditional. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
On the SoCs that introduced the new timing mode for MMC controllers, both the old (where the clock delays are set in the CCU) and new (where the clock delays are set in the MMC controller) timing modes are available, and we have to support them both. However there are two bits that control which mode is active. One is in the CCU, the other is in the MMC controller. The settings on both sides must be the same, or nothing will work. The sunxi-ng clock driver provides an API to query and set the active timing mode. At probe time, we try to set the active mode to the "new timing mode". If it succeeds, we can then use the MMC controller in the new mode. If not, we fall back to the old mode. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
The MMC2 clock supports a new timing mode. When the new mode is active, the output clock rate is halved. This patch sets the feature flag for the new timing mode, and adds a pre-divider based on the mode bit. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
All of our MMC clocks are of the MP clock type. A few MMC clocks on some SoCs, such as MMC2 on the A83T, support new/old timing mode switching. >From a clock rate point of view, when the new timing mode is active. the output clock rate is halved. This patch adds a special wrapper class of clocks, MP_MMC, around the generic MP type clocks. The rate related callbacks in ccu_mp_mmc_ops for this class look at the timing mode bit and apply the /2 post-divider when needed, before passing it through to the generic class ops, ccu_mp_ops. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Chen-Yu Tsai authored
Starting with the A83T SoC, Allwinner introduced a new timing mode for its MMC clocks. The new mode changes how the MMC controller sample and output clocks are delayed to match chip and board specifics. There are two controls for this, one on the CCU side controlling how the clocks behave, and one in the MMC controller controlling what inputs to take and how to route them. In the old mode, the MMC clock had 2 child clocks providing the output and sample clocks, which could be delayed by a number of clock cycles measured from the MMC clock's parent. With the new mode, the 2 delay clocks are no longer active. Instead, the delays and associated controls are moved into the MMC controller. The output of the MMC clock is also halved. The difference in how things are wired between the modes means that the clock controls and the MMC controls must match. To achieve this in a clear, explicit way, we introduce two functions for the MMC driver to use: one queries the hardware for the current mode set, and the other allows the MMC driver to request a mode. Signed-off-by: Chen-Yu Tsai <wens@csie.org> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Simon Horman authored
Provide a whitelist for Gen3 SoC ES versions for both the SYS DMAC and internal DMAC variants of the SDHI driver. This is to allow drivers to only initialise for Gen3 SoC ES versions for which they are the appropriate DMAC implementation. Currently internal DMAC is the appropriate implementation for all supported Gen3 SoC ES versions. Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Shawn Lin authored
Per the spec of JESD84-B51, section 7.3, replace tacc with taac to fix the obvious typo. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Masahiro Yamada authored
Detected by sparse. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Masahiro Yamada authored
Sparse reports "warning: cast to restricted __be32". Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Acked-by: Stefan Wahren <stefan.wahren@i2se.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-
Julia Lawall authored
The mmc_host_ops structure is only stored in the ops field of an mmc_host structure, which is declared as const. Thus the mmc_host_ops structure itself can be const. Done with the help of Coccinelle. // <smpl> @r disable optional_qualifier@ identifier i; position p; @@ static struct mmc_host_ops i@p = { ... }; @ok1@ struct mmc_host *mmc; identifier r.i; position p; @@ mmc->ops = &i@p @bad@ position p != {r.p,ok1.p}; identifier r.i; struct mmc_host_ops e; @@ e@i@p @depends on !bad disable optional_qualifier@ identifier r.i; @@ static +const struct mmc_host_ops i = { ... }; // </smpl> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-