From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 13 May 2024 10:30:14 +0000 Subject: [PATCH] modify sin led gpio --- kernel/drivers/mmc/host/sunxi-mmc.c | 69 ++++++++++++++++++++++------------ 1 files changed, 45 insertions(+), 24 deletions(-) diff --git a/kernel/drivers/mmc/host/sunxi-mmc.c b/kernel/drivers/mmc/host/sunxi-mmc.c index c458418..b834fde 100644 --- a/kernel/drivers/mmc/host/sunxi-mmc.c +++ b/kernel/drivers/mmc/host/sunxi-mmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Driver for sunxi SD/MMC host controllers * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. @@ -6,11 +7,6 @@ * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch> * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> * (C) Copyright 2017 Sootech SA - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. */ #include <linux/clk.h> @@ -19,7 +15,6 @@ #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/err.h> -#include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/kernel.h> @@ -32,7 +27,6 @@ #include <linux/mmc/slot-gpio.h> #include <linux/module.h> #include <linux/of_address.h> -#include <linux/of_gpio.h> #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -258,11 +252,16 @@ /* Does DATA0 needs to be masked while the clock is updated */ bool mask_data0; - /* hardware only supports new timing mode */ + /* + * hardware only supports new timing mode, either due to lack of + * a mode switch in the clock controller, or the mmc controller + * is permanently configured in the new timing mode, without the + * NTSR mode switch. + */ bool needs_new_timings; - /* hardware can switch between old and new timing modes */ - bool has_timings_switch; + /* clock hardware can switch between old and new timing modes */ + bool ccu_has_timings_switch; }; struct sunxi_mmc_host { @@ -787,7 +786,7 @@ clock <<= 1; } - if (host->use_new_timings && host->cfg->has_timings_switch) { + if (host->use_new_timings && host->cfg->ccu_has_timings_switch) { ret = sunxi_ccu_set_mmc_timing_mode(host->clk_mmc, true); if (ret) { dev_err(mmc_dev(mmc), @@ -822,6 +821,12 @@ /* update card clock rate to account for internal divider */ rate /= div; + /* + * Configure the controller to use the new timing mode if needed. + * On controllers that only support the new timing mode, such as + * the eMMC controller on the A64, this register does not exist, + * and any writes to it are ignored. + */ if (host->use_new_timings) { /* Don't touch the delay bits */ rval = mmc_readl(host, REG_SD_NTSR); @@ -946,9 +951,13 @@ static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios) { + int ret; + /* vqmmc regulator is available */ - if (!IS_ERR(mmc->supply.vqmmc)) - return mmc_regulator_set_vqmmc(mmc, ios); + if (!IS_ERR(mmc->supply.vqmmc)) { + ret = mmc_regulator_set_vqmmc(mmc, ios); + return ret < 0 ? ret : 0; + } /* no vqmmc regulator, assume fixed regulator at 3/3.3V */ if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) @@ -1145,7 +1154,7 @@ .idma_des_size_bits = 16, .clk_delays = sunxi_mmc_clk_delays, .can_calibrate = false, - .has_timings_switch = true, + .ccu_has_timings_switch = true, }; static const struct sunxi_mmc_cfg sun9i_a80_cfg = { @@ -1166,6 +1175,7 @@ .idma_des_size_bits = 13, .clk_delays = NULL, .can_calibrate = true, + .needs_new_timings = true, }; static const struct of_device_id sunxi_mmc_of_match[] = { @@ -1267,8 +1277,7 @@ if (ret) return ret; - host->reg_base = devm_ioremap_resource(&pdev->dev, - platform_get_resource(pdev, IORESOURCE_MEM, 0)); + host->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(host->reg_base)) return PTR_ERR(host->reg_base); @@ -1308,8 +1317,8 @@ return ret; host->irq = platform_get_irq(pdev, 0); - if (host->irq <= 0) { - ret = -EINVAL; + if (host->irq < 0) { + ret = host->irq; goto error_disable_mmc; } @@ -1351,7 +1360,7 @@ goto error_free_host; } - if (host->cfg->has_timings_switch) { + if (host->cfg->ccu_has_timings_switch) { /* * Supports both old and new timing modes. * Try setting the clk to new timing mode. @@ -1385,9 +1394,18 @@ mmc->f_min = 400000; mmc->f_max = 52000000; mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | - MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ; + MMC_CAP_SDIO_IRQ; - if (host->cfg->clk_delays || host->use_new_timings) + /* + * Some H5 devices do not have signal traces precise enough to + * use HS DDR mode for their eMMC chips. + * + * We still enable HS DDR modes for all the other controller + * variants that support them. + */ + if ((host->cfg->clk_delays || host->use_new_timings) && + !of_device_is_compatible(pdev->dev.of_node, + "allwinner,sun50i-h5-emmc")) mmc->caps |= MMC_CAP_1_8V_DDR | MMC_CAP_3_3V_DDR; ret = mmc_of_parse(mmc); @@ -1441,9 +1459,11 @@ struct sunxi_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); - pm_runtime_force_suspend(&pdev->dev); - disable_irq(host->irq); - sunxi_mmc_disable(host); + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) { + disable_irq(host->irq); + sunxi_mmc_disable(host); + } dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); mmc_free_host(mmc); @@ -1496,6 +1516,7 @@ static struct platform_driver sunxi_mmc_driver = { .driver = { .name = "sunxi-mmc", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, .of_match_table = of_match_ptr(sunxi_mmc_of_match), .pm = &sunxi_mmc_pm_ops, }, -- Gitblit v1.6.2