Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mtd: rawnand: tegra: Add runtime PM and OPP support

The NAND on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now NAND must be resumed using
runtime PM API in order to initialize the NAND power state. Add runtime PM
and OPP support to the NAND driver.

Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Dmitry Osipenko and committed by
Thierry Reding
6902dc2f d618978d

+50 -8
+50 -8
drivers/mtd/nand/raw/tegra_nand.c
··· 17 17 #include <linux/mtd/rawnand.h> 18 18 #include <linux/of.h> 19 19 #include <linux/platform_device.h> 20 + #include <linux/pm_runtime.h> 20 21 #include <linux/reset.h> 22 + 23 + #include <soc/tegra/common.h> 21 24 22 25 #define COMMAND 0x00 23 26 #define COMMAND_GO BIT(31) ··· 1154 1151 return -ENOMEM; 1155 1152 1156 1153 ctrl->dev = &pdev->dev; 1154 + platform_set_drvdata(pdev, ctrl); 1157 1155 nand_controller_init(&ctrl->controller); 1158 1156 ctrl->controller.ops = &tegra_nand_controller_ops; 1159 1157 ··· 1170 1166 if (IS_ERR(ctrl->clk)) 1171 1167 return PTR_ERR(ctrl->clk); 1172 1168 1173 - err = clk_prepare_enable(ctrl->clk); 1169 + err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev); 1170 + if (err) 1171 + return err; 1172 + 1173 + /* 1174 + * This driver doesn't support active power management yet, 1175 + * so we will simply keep device resumed. 1176 + */ 1177 + pm_runtime_enable(&pdev->dev); 1178 + err = pm_runtime_resume_and_get(&pdev->dev); 1174 1179 if (err) 1175 1180 return err; 1176 1181 1177 1182 err = reset_control_reset(rst); 1178 1183 if (err) { 1179 1184 dev_err(ctrl->dev, "Failed to reset HW: %d\n", err); 1180 - goto err_disable_clk; 1185 + goto err_put_pm; 1181 1186 } 1182 1187 1183 1188 writel_relaxed(HWSTATUS_CMD_DEFAULT, ctrl->regs + HWSTATUS_CMD); ··· 1201 1188 dev_name(&pdev->dev), ctrl); 1202 1189 if (err) { 1203 1190 dev_err(ctrl->dev, "Failed to get IRQ: %d\n", err); 1204 - goto err_disable_clk; 1191 + goto err_put_pm; 1205 1192 } 1206 1193 1207 1194 writel_relaxed(DMA_MST_CTRL_IS_DONE, ctrl->regs + DMA_MST_CTRL); 1208 1195 1209 1196 err = tegra_nand_chips_init(ctrl->dev, ctrl); 1210 1197 if (err) 1211 - goto err_disable_clk; 1212 - 1213 - platform_set_drvdata(pdev, ctrl); 1198 + goto err_put_pm; 1214 1199 1215 1200 return 0; 1216 1201 1217 - err_disable_clk: 1218 - clk_disable_unprepare(ctrl->clk); 1202 + err_put_pm: 1203 + pm_runtime_put_sync_suspend(ctrl->dev); 1204 + pm_runtime_force_suspend(ctrl->dev); 1219 1205 return err; 1220 1206 } 1221 1207 ··· 1231 1219 1232 1220 nand_cleanup(chip); 1233 1221 1222 + pm_runtime_put_sync_suspend(ctrl->dev); 1223 + pm_runtime_force_suspend(ctrl->dev); 1224 + 1225 + return 0; 1226 + } 1227 + 1228 + static int __maybe_unused tegra_nand_runtime_resume(struct device *dev) 1229 + { 1230 + struct tegra_nand_controller *ctrl = dev_get_drvdata(dev); 1231 + int err; 1232 + 1233 + err = clk_prepare_enable(ctrl->clk); 1234 + if (err) { 1235 + dev_err(dev, "Failed to enable clock: %d\n", err); 1236 + return err; 1237 + } 1238 + 1239 + return 0; 1240 + } 1241 + 1242 + static int __maybe_unused tegra_nand_runtime_suspend(struct device *dev) 1243 + { 1244 + struct tegra_nand_controller *ctrl = dev_get_drvdata(dev); 1245 + 1234 1246 clk_disable_unprepare(ctrl->clk); 1235 1247 1236 1248 return 0; 1237 1249 } 1250 + 1251 + static const struct dev_pm_ops tegra_nand_pm = { 1252 + SET_RUNTIME_PM_OPS(tegra_nand_runtime_suspend, tegra_nand_runtime_resume, 1253 + NULL) 1254 + }; 1238 1255 1239 1256 static const struct of_device_id tegra_nand_of_match[] = { 1240 1257 { .compatible = "nvidia,tegra20-nand" }, ··· 1275 1234 .driver = { 1276 1235 .name = "tegra-nand", 1277 1236 .of_match_table = tegra_nand_of_match, 1237 + .pm = &tegra_nand_pm, 1278 1238 }, 1279 1239 .probe = tegra_nand_probe, 1280 1240 .remove = tegra_nand_remove,