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

mmc: pwrseq: simplify alloc/free hooks

The alloc() and free() hooks required each pwrseq implementation to set
host->pwrseq themselves. This is error-prone and could be done at a
higher level if alloc() was changed to return a pointer to a struct
mmc_pwrseq instead of an error code.

This patch performs this change and moves the burden of maintaining
host->pwrseq from the power sequence hooks to the pwrseq code.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Alexandre Courbot and committed by
Ulf Hansson
0f12a0ce d34712d2

+26 -18
+12 -4
drivers/mmc/core/pwrseq.c
··· 19 19 20 20 struct mmc_pwrseq_match { 21 21 const char *compatible; 22 - int (*alloc)(struct mmc_host *host, struct device *dev); 22 + struct mmc_pwrseq *(*alloc)(struct mmc_host *host, struct device *dev); 23 23 }; 24 24 25 25 static struct mmc_pwrseq_match pwrseq_match[] = { ··· 52 52 struct platform_device *pdev; 53 53 struct device_node *np; 54 54 struct mmc_pwrseq_match *match; 55 + struct mmc_pwrseq *pwrseq; 55 56 int ret = 0; 56 57 57 58 np = of_parse_phandle(host->parent->of_node, "mmc-pwrseq", 0); ··· 71 70 goto err; 72 71 } 73 72 74 - ret = match->alloc(host, &pdev->dev); 75 - if (!ret) 76 - dev_info(host->parent, "allocated mmc-pwrseq\n"); 73 + pwrseq = match->alloc(host, &pdev->dev); 74 + if (IS_ERR(pwrseq)) { 75 + ret = PTR_ERR(host->pwrseq); 76 + goto err; 77 + } 78 + 79 + host->pwrseq = pwrseq; 80 + dev_info(host->parent, "allocated mmc-pwrseq\n"); 77 81 78 82 err: 79 83 of_node_put(np); ··· 115 109 116 110 if (pwrseq && pwrseq->ops && pwrseq->ops->free) 117 111 pwrseq->ops->free(host); 112 + 113 + host->pwrseq = NULL; 118 114 }
+4 -2
drivers/mmc/core/pwrseq.h
··· 27 27 void mmc_pwrseq_power_off(struct mmc_host *host); 28 28 void mmc_pwrseq_free(struct mmc_host *host); 29 29 30 - int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev); 31 - int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev); 30 + struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, 31 + struct device *dev); 32 + struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, 33 + struct device *dev); 32 34 33 35 #else 34 36
+5 -6
drivers/mmc/core/pwrseq_emmc.c
··· 49 49 unregister_restart_handler(&pwrseq->reset_nb); 50 50 gpiod_put(pwrseq->reset_gpio); 51 51 kfree(pwrseq); 52 - host->pwrseq = NULL; 53 52 } 54 53 55 54 static struct mmc_pwrseq_ops mmc_pwrseq_emmc_ops = { ··· 66 67 return NOTIFY_DONE; 67 68 } 68 69 69 - int mmc_pwrseq_emmc_alloc(struct mmc_host *host, struct device *dev) 70 + struct mmc_pwrseq *mmc_pwrseq_emmc_alloc(struct mmc_host *host, 71 + struct device *dev) 70 72 { 71 73 struct mmc_pwrseq_emmc *pwrseq; 72 74 int ret = 0; 73 75 74 76 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_emmc), GFP_KERNEL); 75 77 if (!pwrseq) 76 - return -ENOMEM; 78 + return ERR_PTR(-ENOMEM); 77 79 78 80 pwrseq->reset_gpio = gpiod_get_index(dev, "reset", 0, GPIOD_OUT_LOW); 79 81 if (IS_ERR(pwrseq->reset_gpio)) { ··· 92 92 register_restart_handler(&pwrseq->reset_nb); 93 93 94 94 pwrseq->pwrseq.ops = &mmc_pwrseq_emmc_ops; 95 - host->pwrseq = &pwrseq->pwrseq; 96 95 97 - return 0; 96 + return &pwrseq->pwrseq; 98 97 free: 99 98 kfree(pwrseq); 100 - return ret; 99 + return ERR_PTR(ret); 101 100 }
+5 -6
drivers/mmc/core/pwrseq_simple.c
··· 85 85 clk_put(pwrseq->ext_clk); 86 86 87 87 kfree(pwrseq); 88 - host->pwrseq = NULL; 89 88 } 90 89 91 90 static struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = { ··· 94 95 .free = mmc_pwrseq_simple_free, 95 96 }; 96 97 97 - int mmc_pwrseq_simple_alloc(struct mmc_host *host, struct device *dev) 98 + struct mmc_pwrseq *mmc_pwrseq_simple_alloc(struct mmc_host *host, 99 + struct device *dev) 98 100 { 99 101 struct mmc_pwrseq_simple *pwrseq; 100 102 int i, nr_gpios, ret = 0; ··· 107 107 pwrseq = kzalloc(sizeof(struct mmc_pwrseq_simple) + nr_gpios * 108 108 sizeof(struct gpio_desc *), GFP_KERNEL); 109 109 if (!pwrseq) 110 - return -ENOMEM; 110 + return ERR_PTR(-ENOMEM); 111 111 112 112 pwrseq->ext_clk = clk_get(dev, "ext_clock"); 113 113 if (IS_ERR(pwrseq->ext_clk) && ··· 133 133 134 134 pwrseq->nr_gpios = nr_gpios; 135 135 pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops; 136 - host->pwrseq = &pwrseq->pwrseq; 137 136 138 - return 0; 137 + return &pwrseq->pwrseq; 139 138 clk_put: 140 139 if (!IS_ERR(pwrseq->ext_clk)) 141 140 clk_put(pwrseq->ext_clk); 142 141 free: 143 142 kfree(pwrseq); 144 - return ret; 143 + return ERR_PTR(ret); 145 144 }