On 15/05/14 17:57, Jaehoon Chung wrote: > Restore the platdata(property of dt) into host struct. > Then data's information is maintained and reused anywhere. > > Signed-off-by: Jaehoon Chung <jh80.ch...@samsung.com> > Tested-by: Lukasz Majewski <l.majew...@samsung.com> > Acked-by: Lukasz Majewski <l.majew...@samsung.com> > --- > drivers/mmc/exynos_dw_mmc.c | 205 > ++++++++++++++++++++++++++++--------------- > include/dwmmc.h | 2 + > 2 files changed, 135 insertions(+), 72 deletions(-) > > diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c > index de8cdcc..99047a7 100644 > --- a/drivers/mmc/exynos_dw_mmc.c > +++ b/drivers/mmc/exynos_dw_mmc.c > @@ -13,6 +13,8 @@ > #include <asm/arch/dwmmc.h> > #include <asm/arch/clk.h> > #include <asm/arch/pinmux.h> > +#include <asm/gpio.h> > +#include <asm-generic/errno.h> > > #define DWMMC_MAX_CH_NUM 4 > #define DWMMC_MAX_FREQ 52000000 > @@ -44,6 +46,13 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host) > & DWMCI_DIVRATIO_MASK) + 1; > sclk = get_mmc_clk(host->dev_index); > > + /* > + * Assume to know divider value. > + * When clock unit is broken, need to set "host->div" > + */ > + if (host->div) > + sclk /= (host->div + 1); > + > return sclk / clk_div;
then, it can be return sclk / clk_div / (host->div +1); > } > > @@ -60,45 +69,32 @@ static void exynos_dwmci_board_init(struct dwmci_host > *host) > } > } > > -/* > - * This function adds the mmc channel to be registered with mmc core. > - * index - mmc channel number. > - * regbase - register base address of mmc channel specified in 'index'. > - * bus_width - operating bus width of mmc channel specified in 'index'. > - * clksel - value to be written into CLKSEL register in case of FDT. > - * NULL in case od non-FDT. > - */ > -int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) > +static int exynos_dwmci_core_init(struct dwmci_host *host, int index) > { > - struct dwmci_host *host = NULL; > unsigned int div; > unsigned long freq, sclk; > - host = malloc(sizeof(struct dwmci_host)); > - if (!host) { > - printf("dwmci_host malloc fail!\n"); > - return 1; > - } > + > + if (host->bus_hz) > + freq = host->bus_hz; > + else > + freq = DWMMC_MAX_FREQ; > + > /* request mmc clock vlaue of 52MHz. */ > - freq = 52000000; > sclk = get_mmc_clk(index); > div = DIV_ROUND_UP(sclk, freq); > /* set the clock divisor for mmc */ > set_mmc_clk(index, div); > > host->name = "EXYNOS DWMMC"; > - host->ioaddr = (void *)regbase; > - host->buswidth = bus_width; > #ifdef CONFIG_EXYNOS5420 > host->quirks = DWMCI_QUIRK_DISABLE_SMU; > #endif > host->board_init = exynos_dwmci_board_init; > > - if (clksel) { > - host->clksel_val = clksel; > - } else { > - if (0 == index) > + if (!host->clksel_val) { > + if (index == 0) > host->clksel_val = DWMMC_MMC0_CLKSEL_VAL; > - if (2 == index) > + if (index == 2) else if? or you can use switch..case. > host->clksel_val = DWMMC_MMC2_CLKSEL_VAL; > } > > @@ -113,69 +109,134 @@ int exynos_dwmci_add_port(int index, u32 regbase, int > bus_width, u32 clksel) > return 0; > } > > +/* > + * This function adds the mmc channel to be registered with mmc core. > + * index - mmc channel number. > + * regbase - register base address of mmc channel specified in 'index'. > + * bus_width - operating bus width of mmc channel specified in 'index'. > + * clksel - value to be written into CLKSEL register in case of FDT. > + * NULL in case od non-FDT. > + */ > +int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel) > +{ > + struct dwmci_host *host = NULL; > + > + host = malloc(sizeof(struct dwmci_host)); > + if (!host) { > + error("dwmci_host malloc fail!\n"); > + return -ENOMEM; > + } > + > + host->ioaddr = (void *)regbase; > + host->buswidth = bus_width; > + > + if (clksel) > + host->clksel_val = clksel; > + > + return exynos_dwmci_core_init(host, index); > +} > + > #ifdef CONFIG_OF_CONTROL > -int exynos_dwmmc_init(const void *blob) > +struct dwmci_host dwmci_host[DWMMC_MAX_CH_NUM]; static struct? > + > +static int do_dwmci_init(struct dwmci_host *host) > { > - int index, bus_width; > - int node_list[DWMMC_MAX_CH_NUM]; > - int err = 0, dev_id, flag, count, i; > - u32 clksel_val, base, timing[3]; > + int index, flag = 0, err = 0; = 0; unnecessary. > > - count = fdtdec_find_aliases_for_id(blob, "mmc", > - COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list, > - DWMMC_MAX_CH_NUM); > + index = host->dev_index; > > - for (i = 0; i < count; i++) { > - int node = node_list[i]; > + flag = host->buswidth == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE; > + err = exynos_pinmux_config(host->dev_id, flag); > + if (err) { > + debug("DWMMC not configure\n"); > + return err; > + } > > - if (node <= 0) > - continue; > + return exynos_dwmci_core_init(host, index); > +} > > - /* Extract device id for each mmc channel */ > - dev_id = pinmux_decode_periph_id(blob, node); Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot