Contributors: 17
| Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
| Dinh Nguyen |
163 |
28.10% |
2 |
7.14% |
| Will Newton |
107 |
18.45% |
1 |
3.57% |
| Shashidhar Hiremath |
90 |
15.52% |
1 |
3.57% |
| Thomas Abraham |
76 |
13.10% |
4 |
14.29% |
| Shawn Lin |
54 |
9.31% |
5 |
17.86% |
| Heiko Stübner |
40 |
6.90% |
1 |
3.57% |
| Thierry Reding |
11 |
1.90% |
1 |
3.57% |
| Andy Shevchenko |
8 |
1.38% |
2 |
7.14% |
| Andrew Bresticker |
6 |
1.03% |
1 |
3.57% |
| Doug Anderson |
5 |
0.86% |
1 |
3.57% |
| Jaehoon Chung |
4 |
0.69% |
2 |
7.14% |
| Li Yang |
4 |
0.69% |
1 |
3.57% |
| Shawn Guo |
3 |
0.52% |
1 |
3.57% |
| Jingoo Han |
3 |
0.52% |
1 |
3.57% |
| Arnd Bergmann |
2 |
0.34% |
1 |
3.57% |
| Uwe Kleine-König |
2 |
0.34% |
2 |
7.14% |
| Thomas Gleixner |
2 |
0.34% |
1 |
3.57% |
| Total |
580 |
|
28 |
|
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Synopsys DesignWare Multimedia Card Interface driver
*
* Copyright (C) 2009 NXP Semiconductors
* Copyright (C) 2009, 2010 Imagination Technologies Ltd.
*/
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/of.h>
#include <linux/mfd/altera-sysmgr.h>
#include <linux/regmap.h>
#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"
#define SOCFPGA_DW_MMC_CLK_PHASE_STEP 45
#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel, reg_shift) \
((((smplsel) & 0x7) << reg_shift) | (((drvsel) & 0x7) << 0))
int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
host = dw_mci_alloc_host(&pdev->dev);
if (IS_ERR(host))
return PTR_ERR(host);
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0)
return host->irq;
host->drv_data = drv_data;
host->irq_flags = 0;
host->regs = devm_platform_get_and_ioremap_resource(pdev, 0, ®s);
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
/* Get registers' physical base address */
host->phy_regs = regs->start;
platform_set_drvdata(pdev, host);
return dw_mci_probe(host);
}
EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
static int dw_mci_socfpga_priv_init(struct dw_mci *host)
{
struct device_node *np = host->dev->of_node;
struct mmc_clk_phase phase;
struct regmap *sys_mgr_base_addr;
u32 reg_offset, reg_shift;
int hs_timing;
phase = host->phase_map.phase[MMC_TIMING_SD_HS];
if (!phase.valid)
return 0;
sys_mgr_base_addr = altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
if (IS_ERR(sys_mgr_base_addr)) {
dev_warn(host->dev, "clk-phase-sd-hs was specified, but failed to find altr,sys-mgr regmap!\n");
return 0;
}
of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset);
of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift);
phase.in_deg /= SOCFPGA_DW_MMC_CLK_PHASE_STEP;
phase.out_deg /= SOCFPGA_DW_MMC_CLK_PHASE_STEP;
hs_timing = SYSMGR_SDMMC_CTRL_SET(phase.in_deg, phase.out_deg, reg_shift);
regmap_write(sys_mgr_base_addr, reg_offset, hs_timing);
return 0;
}
static const struct dw_mci_drv_data socfpga_drv_data = {
.init = dw_mci_socfpga_priv_init,
};
static const struct of_device_id dw_mci_pltfm_match[] = {
{ .compatible = "snps,dw-mshc", },
{ .compatible = "altr,socfpga-dw-mshc", .data = &socfpga_drv_data, },
{ .compatible = "img,pistachio-dw-mshc", },
{},
};
MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
static int dw_mci_pltfm_probe(struct platform_device *pdev)
{
const struct dw_mci_drv_data *drv_data = NULL;
const struct of_device_id *match;
if (pdev->dev.of_node) {
match = of_match_node(dw_mci_pltfm_match, pdev->dev.of_node);
drv_data = match->data;
}
return dw_mci_pltfm_register(pdev, drv_data);
}
void dw_mci_pltfm_remove(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
dw_mci_remove(host);
}
EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
static struct platform_driver dw_mci_pltfm_driver = {
.probe = dw_mci_pltfm_probe,
.remove = dw_mci_pltfm_remove,
.driver = {
.name = "dw_mmc",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = dw_mci_pltfm_match,
.pm = pm_ptr(&dw_mci_pmops),
},
};
module_platform_driver(dw_mci_pltfm_driver);
MODULE_DESCRIPTION("DW Multimedia Card Interface driver");
MODULE_AUTHOR("NXP Semiconductor VietNam");
MODULE_AUTHOR("Imagination Technologies Ltd");
MODULE_LICENSE("GPL v2");