1 /* 2 * Generic GPIO card-detect helper 3 * 4 * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/err.h> 12 #include <linux/gpio.h> 13 #include <linux/interrupt.h> 14 #include <linux/jiffies.h> 15 #include <linux/mmc/host.h> 16 #include <linux/mmc/slot-gpio.h> 17 #include <linux/module.h> 18 #include <linux/slab.h> 19 20 struct mmc_gpio { 21 int ro_gpio; 22 int cd_gpio; 23 char *ro_label; 24 char cd_label[0]; 25 }; 26 27 static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) 28 { 29 /* Schedule a card detection after a debounce timeout */ 30 mmc_detect_change(dev_id, msecs_to_jiffies(100)); 31 return IRQ_HANDLED; 32 } 33 34 static int mmc_gpio_alloc(struct mmc_host *host) 35 { 36 size_t len = strlen(dev_name(host->parent)) + 4; 37 struct mmc_gpio *ctx; 38 39 mutex_lock(&host->slot.lock); 40 41 ctx = host->slot.handler_priv; 42 if (!ctx) { 43 /* 44 * devm_kzalloc() can be called after device_initialize(), even 45 * before device_add(), i.e., between mmc_alloc_host() and 46 * mmc_add_host() 47 */ 48 ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len, 49 GFP_KERNEL); 50 if (ctx) { 51 ctx->ro_label = ctx->cd_label + len; 52 snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); 53 snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); 54 ctx->cd_gpio = -EINVAL; 55 ctx->ro_gpio = -EINVAL; 56 host->slot.handler_priv = ctx; 57 } 58 } 59 60 mutex_unlock(&host->slot.lock); 61 62 return ctx ? 0 : -ENOMEM; 63 } 64 65 int mmc_gpio_get_ro(struct mmc_host *host) 66 { 67 struct mmc_gpio *ctx = host->slot.handler_priv; 68 69 if (!ctx || !gpio_is_valid(ctx->ro_gpio)) 70 return -ENOSYS; 71 72 return !gpio_get_value_cansleep(ctx->ro_gpio) ^ 73 !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); 74 } 75 EXPORT_SYMBOL(mmc_gpio_get_ro); 76 77 int mmc_gpio_get_cd(struct mmc_host *host) 78 { 79 struct mmc_gpio *ctx = host->slot.handler_priv; 80 81 if (!ctx || !gpio_is_valid(ctx->cd_gpio)) 82 return -ENOSYS; 83 84 return !gpio_get_value_cansleep(ctx->cd_gpio) ^ 85 !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); 86 } 87 EXPORT_SYMBOL(mmc_gpio_get_cd); 88 89 int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) 90 { 91 struct mmc_gpio *ctx; 92 int ret; 93 94 if (!gpio_is_valid(gpio)) 95 return -EINVAL; 96 97 ret = mmc_gpio_alloc(host); 98 if (ret < 0) 99 return ret; 100 101 ctx = host->slot.handler_priv; 102 103 return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label); 104 } 105 EXPORT_SYMBOL(mmc_gpio_request_ro); 106 107 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio) 108 { 109 struct mmc_gpio *ctx; 110 int irq = gpio_to_irq(gpio); 111 int ret; 112 113 ret = mmc_gpio_alloc(host); 114 if (ret < 0) 115 return ret; 116 117 ctx = host->slot.handler_priv; 118 119 ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->cd_label); 120 if (ret < 0) 121 /* 122 * don't bother freeing memory. It might still get used by other 123 * slot functions, in any case it will be freed, when the device 124 * is destroyed. 125 */ 126 return ret; 127 128 /* 129 * Even if gpio_to_irq() returns a valid IRQ number, the platform might 130 * still prefer to poll, e.g., because that IRQ number is already used 131 * by another unit and cannot be shared. 132 */ 133 if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) 134 irq = -EINVAL; 135 136 if (irq >= 0) { 137 ret = request_threaded_irq(irq, NULL, mmc_gpio_cd_irqt, 138 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 139 ctx->cd_label, host); 140 if (ret < 0) 141 irq = ret; 142 } 143 144 host->slot.cd_irq = irq; 145 146 if (irq < 0) 147 host->caps |= MMC_CAP_NEEDS_POLL; 148 149 ctx->cd_gpio = gpio; 150 151 return 0; 152 } 153 EXPORT_SYMBOL(mmc_gpio_request_cd); 154 155 void mmc_gpio_free_ro(struct mmc_host *host) 156 { 157 struct mmc_gpio *ctx = host->slot.handler_priv; 158 int gpio; 159 160 if (!ctx || !gpio_is_valid(ctx->ro_gpio)) 161 return; 162 163 gpio = ctx->ro_gpio; 164 ctx->ro_gpio = -EINVAL; 165 166 gpio_free(gpio); 167 } 168 EXPORT_SYMBOL(mmc_gpio_free_ro); 169 170 void mmc_gpio_free_cd(struct mmc_host *host) 171 { 172 struct mmc_gpio *ctx = host->slot.handler_priv; 173 int gpio; 174 175 if (!ctx || !gpio_is_valid(ctx->cd_gpio)) 176 return; 177 178 if (host->slot.cd_irq >= 0) { 179 free_irq(host->slot.cd_irq, host); 180 host->slot.cd_irq = -EINVAL; 181 } 182 183 gpio = ctx->cd_gpio; 184 ctx->cd_gpio = -EINVAL; 185 186 gpio_free(gpio); 187 } 188 EXPORT_SYMBOL(mmc_gpio_free_cd); 189