diff options
| -rw-r--r-- | drivers/mmc/host/sdhci-tegra.c | 119 | ||||
| -rw-r--r-- | include/linux/platform_data/mmc-sdhci-tegra.h | 28 |
2 files changed, 45 insertions, 102 deletions
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 5a600a53b876..08b06e9a3a21 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
| @@ -27,8 +27,6 @@ | |||
| 27 | 27 | ||
| 28 | #include <asm/gpio.h> | 28 | #include <asm/gpio.h> |
| 29 | 29 | ||
| 30 | #include <linux/platform_data/mmc-sdhci-tegra.h> | ||
| 31 | |||
| 32 | #include "sdhci-pltfm.h" | 30 | #include "sdhci-pltfm.h" |
| 33 | 31 | ||
| 34 | /* Tegra SDHOST controller vendor register definitions */ | 32 | /* Tegra SDHOST controller vendor register definitions */ |
| @@ -45,8 +43,11 @@ struct sdhci_tegra_soc_data { | |||
| 45 | }; | 43 | }; |
| 46 | 44 | ||
| 47 | struct sdhci_tegra { | 45 | struct sdhci_tegra { |
| 48 | const struct tegra_sdhci_platform_data *plat; | ||
| 49 | const struct sdhci_tegra_soc_data *soc_data; | 46 | const struct sdhci_tegra_soc_data *soc_data; |
| 47 | int cd_gpio; | ||
| 48 | int wp_gpio; | ||
| 49 | int power_gpio; | ||
| 50 | int is_8bit; | ||
| 50 | }; | 51 | }; |
| 51 | 52 | ||
| 52 | static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) | 53 | static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg) |
| @@ -108,12 +109,11 @@ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host) | |||
| 108 | { | 109 | { |
| 109 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 110 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 110 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | 111 | struct sdhci_tegra *tegra_host = pltfm_host->priv; |
| 111 | const struct tegra_sdhci_platform_data *plat = tegra_host->plat; | ||
| 112 | 112 | ||
| 113 | if (!gpio_is_valid(plat->wp_gpio)) | 113 | if (!gpio_is_valid(tegra_host->wp_gpio)) |
| 114 | return -1; | 114 | return -1; |
| 115 | 115 | ||
| 116 | return gpio_get_value(plat->wp_gpio); | 116 | return gpio_get_value(tegra_host->wp_gpio); |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | static irqreturn_t carddetect_irq(int irq, void *data) | 119 | static irqreturn_t carddetect_irq(int irq, void *data) |
| @@ -147,11 +147,10 @@ static int tegra_sdhci_buswidth(struct sdhci_host *host, int bus_width) | |||
| 147 | { | 147 | { |
| 148 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); | 148 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 149 | struct sdhci_tegra *tegra_host = pltfm_host->priv; | 149 | struct sdhci_tegra *tegra_host = pltfm_host->priv; |
| 150 | const struct tegra_sdhci_platform_data *plat = tegra_host->plat; | ||
| 151 | u32 ctrl; | 150 | u32 ctrl; |
| 152 | 151 | ||
| 153 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); | 152 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
| 154 | if (plat->is_8bit && bus_width == MMC_BUS_WIDTH_8) { | 153 | if (tegra_host->is_8bit && bus_width == MMC_BUS_WIDTH_8) { |
| 155 | ctrl &= ~SDHCI_CTRL_4BITBUS; | 154 | ctrl &= ~SDHCI_CTRL_4BITBUS; |
| 156 | ctrl |= SDHCI_CTRL_8BITBUS; | 155 | ctrl |= SDHCI_CTRL_8BITBUS; |
| 157 | } else { | 156 | } else { |
| @@ -217,31 +216,19 @@ static const struct of_device_id sdhci_tegra_dt_match[] = { | |||
| 217 | }; | 216 | }; |
| 218 | MODULE_DEVICE_TABLE(of, sdhci_dt_ids); | 217 | MODULE_DEVICE_TABLE(of, sdhci_dt_ids); |
| 219 | 218 | ||
| 220 | static struct tegra_sdhci_platform_data *sdhci_tegra_dt_parse_pdata( | 219 | static void sdhci_tegra_parse_dt(struct device *dev, |
| 221 | struct platform_device *pdev) | 220 | struct sdhci_tegra *tegra_host) |
| 222 | { | 221 | { |
| 223 | struct tegra_sdhci_platform_data *plat; | 222 | struct device_node *np = dev->of_node; |
| 224 | struct device_node *np = pdev->dev.of_node; | ||
| 225 | u32 bus_width; | 223 | u32 bus_width; |
| 226 | 224 | ||
| 227 | if (!np) | 225 | tegra_host->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); |
| 228 | return NULL; | 226 | tegra_host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); |
| 229 | 227 | tegra_host->power_gpio = of_get_named_gpio(np, "power-gpios", 0); | |
| 230 | plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); | ||
| 231 | if (!plat) { | ||
| 232 | dev_err(&pdev->dev, "Can't allocate platform data\n"); | ||
| 233 | return NULL; | ||
| 234 | } | ||
| 235 | |||
| 236 | plat->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0); | ||
| 237 | plat->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0); | ||
| 238 | plat->power_gpio = of_get_named_gpio(np, "power-gpios", 0); | ||
| 239 | 228 | ||
| 240 | if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && | 229 | if (of_property_read_u32(np, "bus-width", &bus_width) == 0 && |
| 241 | bus_width == 8) | 230 | bus_width == 8) |
| 242 | plat->is_8bit = 1; | 231 | tegra_host->is_8bit = 1; |
| 243 | |||
| 244 | return plat; | ||
| 245 | } | 232 | } |
| 246 | 233 | ||
| 247 | static int sdhci_tegra_probe(struct platform_device *pdev) | 234 | static int sdhci_tegra_probe(struct platform_device *pdev) |
| @@ -250,7 +237,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
| 250 | const struct sdhci_tegra_soc_data *soc_data; | 237 | const struct sdhci_tegra_soc_data *soc_data; |
| 251 | struct sdhci_host *host; | 238 | struct sdhci_host *host; |
| 252 | struct sdhci_pltfm_host *pltfm_host; | 239 | struct sdhci_pltfm_host *pltfm_host; |
| 253 | struct tegra_sdhci_platform_data *plat; | ||
| 254 | struct sdhci_tegra *tegra_host; | 240 | struct sdhci_tegra *tegra_host; |
| 255 | struct clk *clk; | 241 | struct clk *clk; |
| 256 | int rc; | 242 | int rc; |
| @@ -263,52 +249,40 @@ static int sdhci_tegra_probe(struct platform_device *pdev) | |||
| 263 | host = sdhci_pltfm_init(pdev, soc_data->pdata); | 249 | host = sdhci_pltfm_init(pdev, soc_data->pdata); |
| 264 | if (IS_ERR(host)) | 250 | if (IS_ERR(host)) |
| 265 | return PTR_ERR(host); | 251 | return PTR_ERR(host); |
| 266 | |||
| 267 | pltfm_host = sdhci_priv(host); | 252 | pltfm_host = sdhci_priv(host); |
| 268 | 253 | ||
| 269 | plat = pdev->dev.platform_data; | ||
| 270 | |||
| 271 | if (plat == NULL) | ||
| 272 | plat = sdhci_tegra_dt_parse_pdata(pdev); | ||
| 273 | |||
| 274 | if (plat == NULL) { | ||
| 275 | dev_err(mmc_dev(host->mmc), "missing platform data\n"); | ||
| 276 | rc = -ENXIO; | ||
| 277 | goto err_no_plat; | ||
| 278 | } | ||
| 279 | |||
| 280 | tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL); | 254 | tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL); |
| 281 | if (!tegra_host) { | 255 | if (!tegra_host) { |
| 282 | dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n"); | 256 | dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n"); |
| 283 | rc = -ENOMEM; | 257 | rc = -ENOMEM; |
| 284 | goto err_no_plat; | 258 | goto err_alloc_tegra_host; |
| 285 | } | 259 | } |
| 286 | |||
| 287 | tegra_host->plat = plat; | ||
| 288 | tegra_host->soc_data = soc_data; | 260 | tegra_host->soc_data = soc_data; |
| 289 | |||
| 290 | pltfm_host->priv = tegra_host; | 261 | pltfm_host->priv = tegra_host; |
| 291 | 262 | ||
| 292 | if (gpio_is_valid(plat->power_gpio)) { | 263 | sdhci_tegra_parse_dt(&pdev->dev, tegra_host); |
| 293 | rc = gpio_request(plat->power_gpio, "sdhci_power"); | 264 | |
| 265 | if (gpio_is_valid(tegra_host->power_gpio)) { | ||
| 266 | rc = gpio_request(tegra_host->power_gpio, "sdhci_power"); | ||
| 294 | if (rc) { | 267 | if (rc) { |
| 295 | dev_err(mmc_dev(host->mmc), | 268 | dev_err(mmc_dev(host->mmc), |
| 296 | "failed to allocate power gpio\n"); | 269 | "failed to allocate power gpio\n"); |
| 297 | goto err_power_req; | 270 | goto err_power_req; |
| 298 | } | 271 | } |
| 299 | gpio_direction_output(plat->power_gpio, 1); | 272 | gpio_direction_output(tegra_host->power_gpio, 1); |
| 300 | } | 273 | } |
| 301 | 274 | ||
| 302 | if (gpio_is_valid(plat->cd_gpio)) { | 275 | if (gpio_is_valid(tegra_host->cd_gpio)) { |
| 303 | rc = gpio_request(plat->cd_gpio, "sdhci_cd"); | 276 | rc = gpio_request(tegra_host->cd_gpio, "sdhci_cd"); |
| 304 | if (rc) { | 277 | if (rc) { |
| 305 | dev_err(mmc_dev(host->mmc), | 278 | dev_err(mmc_dev(host->mmc), |
| 306 | "failed to allocate cd gpio\n"); | 279 | "failed to allocate cd gpio\n"); |
| 307 | goto err_cd_req; | 280 | goto err_cd_req; |
| 308 | } | 281 | } |
| 309 | gpio_direction_input(plat->cd_gpio); | 282 | gpio_direction_input(tegra_host->cd_gpio); |
| 310 | 283 | ||
| 311 | rc = request_irq(gpio_to_irq(plat->cd_gpio), carddetect_irq, | 284 | rc = request_irq(gpio_to_irq(tegra_host->cd_gpio), |
| 285 | carddetect_irq, | ||
| 312 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 286 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, |
