1b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman/* 2b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * linux/drivers/mmc/core/host.c 3b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 4b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * Copyright (C) 2003 Russell King, All Rights Reserved. 5ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman * Copyright (C) 2007-2008 Pierre Ossman 604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Copyright (C) 2010 Linus Walleij 7b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 8b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * This program is free software; you can redistribute it and/or modify 9b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * it under the terms of the GNU General Public License version 2 as 10b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * published by the Free Software Foundation. 11b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 12b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * MMC host class device management 13b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 14b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 15b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include <linux/device.h> 16b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include <linux/err.h> 17b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include <linux/idr.h> 186c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski#include <linux/of.h> 196c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski#include <linux/of_gpio.h> 20b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include <linux/pagemap.h> 213ef77af154b03776c6c662c68c6332719e9eecacPaul Gortmaker#include <linux/export.h> 22af8350c756cb48a738474738f7bf8c0e572fa057Pierre Ossman#include <linux/leds.h> 235a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 244c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky#include <linux/suspend.h> 25b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 26b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include <linux/mmc/host.h> 2704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#include <linux/mmc/card.h> 286c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski#include <linux/mmc/slot-gpio.h> 29b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 30b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include "core.h" 31b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#include "host.h" 32b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 33b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) 34b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 35b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanstatic void mmc_host_classdev_release(struct device *dev) 36b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 37b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman struct mmc_host *host = cls_dev_to_mmc_host(dev); 38a7d1a1ebd8f5858a812ac3d5fbbc178b4959a63bGuennadi Liakhovetski mutex_destroy(&host->slot.lock); 39b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman kfree(host); 40b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 41b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 42b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanstatic struct class mmc_host_class = { 43b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman .name = "mmc_host", 44b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman .dev_release = mmc_host_classdev_release, 45b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman}; 46b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 47b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanint mmc_register_host_class(void) 48b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 49b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman return class_register(&mmc_host_class); 50b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 51b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 52b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_unregister_host_class(void) 53b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 54b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman class_unregister(&mmc_host_class); 55b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 56b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 57b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanstatic DEFINE_IDR(mmc_host_idr); 58b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanstatic DEFINE_SPINLOCK(mmc_host_lock); 59b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 6004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#ifdef CONFIG_MMC_CLKGATE 61597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thummastatic ssize_t clkgate_delay_show(struct device *dev, 62597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma struct device_attribute *attr, char *buf) 63597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma{ 64597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma struct mmc_host *host = cls_dev_to_mmc_host(dev); 654137e50494cb3496fbb6ccd27aa7b6d7c9634c1eStephen Boyd return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay); 66597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma} 67597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma 68597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thummastatic ssize_t clkgate_delay_store(struct device *dev, 69597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma struct device_attribute *attr, const char *buf, size_t count) 70597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma{ 71597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma struct mmc_host *host = cls_dev_to_mmc_host(dev); 72597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma unsigned long flags, value; 73597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma 74597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma if (kstrtoul(buf, 0, &value)) 75597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma return -EINVAL; 76597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma 77597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma spin_lock_irqsave(&host->clk_lock, flags); 78597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma host->clkgate_delay = value; 79597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma spin_unlock_irqrestore(&host->clk_lock, flags); 80597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma return count; 81597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma} 8204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 8304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 8404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Enabling clock gating will make the core call out to the host 8504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * once up and once down when it performs a request or card operation 8604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * intermingled in any fashion. The driver will see this through 8704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * set_ios() operations with ios.clock field set to 0 to gate (disable) 8804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * the block clock, and to the old frequency to enable it again. 8904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 9004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic void mmc_host_clk_gate_delayed(struct mmc_host *host) 9104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 9204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long tick_ns; 9304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long freq = host->ios.clock; 9404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 9504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 9604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (!freq) { 9704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij pr_debug("%s: frequency set to 0 in disable function, " 9804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij "this means the clock is already disabled.\n", 9904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_hostname(host)); 10004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij return; 10104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 10204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 10304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * New requests may have appeared while we were scheduling, 10404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * then there is no reason to delay the check before 10504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * clk_disable(). 10604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 10704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 10804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 10904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 11004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Delay n bus cycles (at least 8 from MMC spec) before attempting 11104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * to disable the MCI block clock. The reference count may have 11204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * gone up again after this delay due to rescheduling! 11304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 11404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (!host->clk_requests) { 11504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 11604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij tick_ns = DIV_ROUND_UP(1000000000, freq); 11704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij ndelay(host->clk_delay * tick_ns); 11804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } else { 11904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* New users appeared while waiting for this work */ 12004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 12104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij return; 12204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 12386f315bbb2374f1f077500ad131dd9b71856e697Chris Ball mutex_lock(&host->clk_gate_mutex); 12404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 12504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (!host->clk_requests) { 12604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 12704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* This will set host->ios.clock to 0 */ 12804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_gate_clock(host); 12904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 13004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); 13104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 13204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 13386f315bbb2374f1f077500ad131dd9b71856e697Chris Ball mutex_unlock(&host->clk_gate_mutex); 13404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 13504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 13604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/* 13704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Internal work. Work to disable the clock at some later point. 13804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 13904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic void mmc_host_clk_gate_work(struct work_struct *work) 14004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 14104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij struct mmc_host *host = container_of(work, struct mmc_host, 142597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma clk_gate_work.work); 14304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 14404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_host_clk_gate_delayed(host); 14504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 14604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 14704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 14808c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg * mmc_host_clk_hold - ungate hardware MCI clocks 14904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @host: host to ungate. 15004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * 15104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Makes sure the host ios.clock is restored to a non-zero value 15204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * past this call. Increase clock reference count and ungate clock 15304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * if we're the first user. 15404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 15508c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerbergvoid mmc_host_clk_hold(struct mmc_host *host) 15604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 15704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 15804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 159597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma /* cancel any clock gating work scheduled by mmc_host_clk_release() */ 160597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma cancel_delayed_work_sync(&host->clk_gate_work); 16186f315bbb2374f1f077500ad131dd9b71856e697Chris Ball mutex_lock(&host->clk_gate_mutex); 16204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 16304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (host->clk_gated) { 16404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 16504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_ungate_clock(host); 16604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 16704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij pr_debug("%s: ungated MCI clock\n", mmc_hostname(host)); 16804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij } 16904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_requests++; 17004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 17186f315bbb2374f1f077500ad131dd9b71856e697Chris Ball mutex_unlock(&host->clk_gate_mutex); 17204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 17304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 17404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 17504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * mmc_host_may_gate_card - check if this card may be gated 17604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @card: card to check. 17704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 17804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic bool mmc_host_may_gate_card(struct mmc_card *card) 17904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 18004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* If there is no card we may gate it */ 18104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (!card) 18204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij return true; 18304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 18404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Don't gate SDIO cards! These need to be clocked at all times 18504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * since they may be independent systems generating interrupts 18604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * and other events. The clock requests counter from the core will 18704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * go down to zero since the core does not need it, but we will not 18804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * gate the clock, because there is somebody out there that may still 18904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * be using it. 19004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 191db9935000d95ae3f9702b7ff6ac0eef2319d8772Pierre Tardy return !(card->quirks & MMC_QUIRK_BROKEN_CLK_GATING); 19204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 19304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 19404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 19508c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg * mmc_host_clk_release - gate off hardware MCI clocks 19604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @host: host to gate. 19704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * 19804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Calls the host driver with ios.clock set to zero as often as possible 19904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * in order to gate off hardware MCI clocks. Decrease clock reference 20004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * count and schedule disabling of clock. 20104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 20208c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerbergvoid mmc_host_clk_release(struct mmc_host *host) 20304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 20404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 20504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 20604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 20704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_requests--; 20804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (mmc_host_may_gate_card(host->card) && 20904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij !host->clk_requests) 2103b07e9ca26866697616097044f25fbe53dbab693Tejun Heo schedule_delayed_work(&host->clk_gate_work, 2113b07e9ca26866697616097044f25fbe53dbab693Tejun Heo msecs_to_jiffies(host->clkgate_delay)); 21204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 21304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 21404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 21504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 21604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * mmc_host_clk_rate - get current clock frequency setting 21704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @host: host to get the clock frequency for. 21804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * 21904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Returns current clock frequency regardless of gating. 22004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 22104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijunsigned int mmc_host_clk_rate(struct mmc_host *host) 22204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 22304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long freq; 22404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij unsigned long flags; 22504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 22604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_irqsave(&host->clk_lock, flags); 22704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (host->clk_gated) 22804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij freq = host->clk_old; 22904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij else 23004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij freq = host->ios.clock; 23104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_unlock_irqrestore(&host->clk_lock, flags); 23204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij return freq; 23304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 23404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 23504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 23604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * mmc_host_clk_init - set up clock gating code 23704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @host: host with potential clock to control 23804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 23904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic inline void mmc_host_clk_init(struct mmc_host *host) 24004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 24104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_requests = 0; 24204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* Hold MCI clock for 8 cycles by default */ 24304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_delay = 8; 244597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma /* 245c84f15aed29d89995fd50ef37e19c7b88019d78fGuennadi Liakhovetski * Default clock gating delay is 0ms to avoid wasting power. 246597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma * This value can be tuned by writing into sysfs entry. 247597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma */ 248c84f15aed29d89995fd50ef37e19c7b88019d78fGuennadi Liakhovetski host->clkgate_delay = 0; 24904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij host->clk_gated = false; 250597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); 25104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij spin_lock_init(&host->clk_lock); 25286f315bbb2374f1f077500ad131dd9b71856e697Chris Ball mutex_init(&host->clk_gate_mutex); 25304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 25404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 25504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij/** 25604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * mmc_host_clk_exit - shut down clock gating code 25704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * @host: host with potential clock to control 25804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 25904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic inline void mmc_host_clk_exit(struct mmc_host *host) 26004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 26104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij /* 26204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * Wait for any outstanding gate and then make sure we're 26304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij * ungated before exiting. 26404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij */ 265597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma if (cancel_delayed_work_sync(&host->clk_gate_work)) 26604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_host_clk_gate_delayed(host); 26704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij if (host->clk_gated) 26808c14071fda4e69abb9d5b1566651cd092b158d3Mika Westerberg mmc_host_clk_hold(host); 269c288b85554097a3d1271f935c48b442280b2db9eLinus Walleij /* There should be only one user now */ 270c288b85554097a3d1271f935c48b442280b2db9eLinus Walleij WARN_ON(host->clk_requests > 1); 27104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 27204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 273597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thummastatic inline void mmc_host_clk_sysfs_init(struct mmc_host *host) 274597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma{ 275597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma host->clkgate_delay_attr.show = clkgate_delay_show; 276597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma host->clkgate_delay_attr.store = clkgate_delay_store; 277597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma sysfs_attr_init(&host->clkgate_delay_attr.attr); 278597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma host->clkgate_delay_attr.attr.name = "clkgate_delay"; 279597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR; 280597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma if (device_create_file(&host->class_dev, &host->clkgate_delay_attr)) 281597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma pr_err("%s: Failed to create clkgate_delay sysfs entry\n", 282597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma mmc_hostname(host)); 283597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma} 28404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#else 28504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 28604566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic inline void mmc_host_clk_init(struct mmc_host *host) 28704566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 28804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 28904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 29004566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleijstatic inline void mmc_host_clk_exit(struct mmc_host *host) 29104566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij{ 29204566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij} 29304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 294597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thummastatic inline void mmc_host_clk_sysfs_init(struct mmc_host *host) 295597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma{ 296597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma} 297597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma 29804566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij#endif 29904566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 300b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman/** 3016c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * mmc_of_parse() - parse host's device-tree node 3026c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * @host: host whose node should be parsed. 3036c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * 3046c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * To keep the rest of the MMC subsystem unaware of whether DT has been 3056c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * used to to instantiate and configure this host instance or not, we 3066c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * parse the properties and set respective generic mmc-host flags and 3076c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * parameters. 3086c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski */ 309ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatzint mmc_of_parse(struct mmc_host *host) 3106c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski{ 3116c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski struct device_node *np; 3126c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski u32 bus_width; 31398e90de99a0c43bd434da814c882c4332441871eLinus Walleij int len, ret; 314a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko bool cd_cap_invert, cd_gpio_invert = false; 315a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko bool ro_cap_invert, ro_gpio_invert = false; 3166c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3176c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski if (!host->parent || !host->parent->of_node) 318ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz return 0; 3196c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3206c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski np = host->parent->of_node; 3216c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3226c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */ 3236c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski if (of_property_read_u32(np, "bus-width", &bus_width) < 0) { 3246c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski dev_dbg(host->parent, 3256c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski "\"bus-width\" property is missing, assuming 1 bit.\n"); 3266c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski bus_width = 1; 3276c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski } 3286c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3296c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski switch (bus_width) { 3306c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski case 8: 3316c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski host->caps |= MMC_CAP_8_BIT_DATA; 3326c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* Hosts capable of 8-bit transfers can also do 4 bits */ 3336c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski case 4: 3346c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski host->caps |= MMC_CAP_4_BIT_DATA; 3356c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski break; 3366c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski case 1: 3376c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski break; 3386c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski default: 3396c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski dev_err(host->parent, 3401c279f4f971ba9d39e93c5f60452ade62c9ce0c5Alexander Shiyan "Invalid \"bus-width\" value %u!\n", bus_width); 341ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz return -EINVAL; 3426c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski } 3436c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3446c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* f_max is obtained from the optional "max-frequency" property */ 3456c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski of_property_read_u32(np, "max-frequency", &host->f_max); 3466c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3476c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* 3486c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * Configure CD and WP pins. They are both by default active low to 3496c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * match the SDHCI spec. If GPIOs are provided for CD and / or WP, the 3506c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * mmc-gpio helpers are used to attach, configure and use them. If 3516c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * polarity inversion is specified in DT, one of MMC_CAP2_CD_ACTIVE_HIGH 3526c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * and MMC_CAP2_RO_ACTIVE_HIGH capability-2 flags is set. If the 3536c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * "broken-cd" property is provided, the MMC_CAP_NEEDS_POLL capability 3546c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * is set. If the "non-removable" property is found, the 3556c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * MMC_CAP_NONREMOVABLE capability is set and no card-detection 3566c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski * configuration is performed. 3576c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski */ 3586c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3596c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* Parse Card Detection */ 3606c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski if (of_find_property(np, "non-removable", &len)) { 3616c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski host->caps |= MMC_CAP_NONREMOVABLE; 3626c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski } else { 363a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko cd_cap_invert = of_property_read_bool(np, "cd-inverted"); 3646c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3656c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski if (of_find_property(np, "broken-cd", &len)) 3666c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski host->caps |= MMC_CAP_NEEDS_POLL; 3676c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 36889168b48991537bec2573b3b6a8841df74465b12Linus Walleij ret = mmc_gpiod_request_cd(host, "cd", 0, true, 369a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko 0, &cd_gpio_invert); 37098e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret) { 37198e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret == -EPROBE_DEFER) 372ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz return ret; 37398e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret != -ENOENT) { 37498e90de99a0c43bd434da814c882c4332441871eLinus Walleij dev_err(host->parent, 37598e90de99a0c43bd434da814c882c4332441871eLinus Walleij "Failed to request CD GPIO: %d\n", 37698e90de99a0c43bd434da814c882c4332441871eLinus Walleij ret); 377ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz } 37898e90de99a0c43bd434da814c882c4332441871eLinus Walleij } else 37998e90de99a0c43bd434da814c882c4332441871eLinus Walleij dev_info(host->parent, "Got CD GPIO\n"); 38089168b48991537bec2573b3b6a8841df74465b12Linus Walleij 38189168b48991537bec2573b3b6a8841df74465b12Linus Walleij /* 38289168b48991537bec2573b3b6a8841df74465b12Linus Walleij * There are two ways to flag that the CD line is inverted: 38389168b48991537bec2573b3b6a8841df74465b12Linus Walleij * through the cd-inverted flag and by the GPIO line itself 38489168b48991537bec2573b3b6a8841df74465b12Linus Walleij * being inverted from the GPIO subsystem. This is a leftover 38589168b48991537bec2573b3b6a8841df74465b12Linus Walleij * from the times when the GPIO subsystem did not make it 38689168b48991537bec2573b3b6a8841df74465b12Linus Walleij * possible to flag a line as inverted. 38789168b48991537bec2573b3b6a8841df74465b12Linus Walleij * 38889168b48991537bec2573b3b6a8841df74465b12Linus Walleij * If the capability on the host AND the GPIO line are 38989168b48991537bec2573b3b6a8841df74465b12Linus Walleij * both inverted, the end result is that the CD line is 39089168b48991537bec2573b3b6a8841df74465b12Linus Walleij * not inverted. 39189168b48991537bec2573b3b6a8841df74465b12Linus Walleij */ 392a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko if (cd_cap_invert ^ cd_gpio_invert) 39389168b48991537bec2573b3b6a8841df74465b12Linus Walleij host->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; 3946c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski } 3956c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 3966c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski /* Parse Write Protection */ 397a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko ro_cap_invert = of_property_read_bool(np, "wp-inverted"); 3986c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 399a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); 40098e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret) { 40198e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret == -EPROBE_DEFER) 402ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz goto out; 40398e90de99a0c43bd434da814c882c4332441871eLinus Walleij if (ret != -ENOENT) { 40498e90de99a0c43bd434da814c882c4332441871eLinus Walleij dev_err(host->parent, 40598e90de99a0c43bd434da814c882c4332441871eLinus Walleij "Failed to request WP GPIO: %d\n", 40698e90de99a0c43bd434da814c882c4332441871eLinus Walleij ret); 407ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz } 40898e90de99a0c43bd434da814c882c4332441871eLinus Walleij } else 40998e90de99a0c43bd434da814c882c4332441871eLinus Walleij dev_info(host->parent, "Got WP GPIO\n"); 4102fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski 41189168b48991537bec2573b3b6a8841df74465b12Linus Walleij /* See the comment on CD inversion above */ 412a31b0c6c19bf28c54999c3cd8cc3a7c8ba565a45Kristina Martsenko if (ro_cap_invert ^ ro_gpio_invert) 41389168b48991537bec2573b3b6a8841df74465b12Linus Walleij host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; 41489168b48991537bec2573b3b6a8841df74465b12Linus Walleij 4152fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "cap-sd-highspeed", &len)) 4162fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->caps |= MMC_CAP_SD_HIGHSPEED; 4172fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "cap-mmc-highspeed", &len)) 4182fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->caps |= MMC_CAP_MMC_HIGHSPEED; 419b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson if (of_find_property(np, "sd-uhs-sdr12", &len)) 420b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson host->caps |= MMC_CAP_UHS_SDR12; 421b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson if (of_find_property(np, "sd-uhs-sdr25", &len)) 422b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson host->caps |= MMC_CAP_UHS_SDR25; 423b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson if (of_find_property(np, "sd-uhs-sdr50", &len)) 424b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson host->caps |= MMC_CAP_UHS_SDR50; 425b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson if (of_find_property(np, "sd-uhs-sdr104", &len)) 426b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson host->caps |= MMC_CAP_UHS_SDR104; 427b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson if (of_find_property(np, "sd-uhs-ddr50", &len)) 428b66bd0e4d00c89102851c1bc9a0f738a4ad9ca2dUlf Hansson host->caps |= MMC_CAP_UHS_DDR50; 4292fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "cap-power-off-card", &len)) 4302fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->caps |= MMC_CAP_POWER_OFF_CARD; 4312fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "cap-sdio-irq", &len)) 4322fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->caps |= MMC_CAP_SDIO_IRQ; 4335a36d6bcdf23e408da1d0cbb5d5ad2a26089e9caUlf Hansson if (of_find_property(np, "full-pwr-cycle", &len)) 4345a36d6bcdf23e408da1d0cbb5d5ad2a26089e9caUlf Hansson host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE; 4352fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "keep-power-in-suspend", &len)) 4362fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->pm_caps |= MMC_PM_KEEP_POWER; 4372fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski if (of_find_property(np, "enable-sdio-wakeup", &len)) 4382fdb6e2d9bf4b599d1cf8bc2b7874a06608fc7eeGuennadi Liakhovetski host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; 439c0baf8485928b2db8a9530672d522d758746a2b6Ulf Hansson if (of_find_property(np, "mmc-ddr-1_8v", &len)) 440c0baf8485928b2db8a9530672d522d758746a2b6Ulf Hansson host->caps |= MMC_CAP_1_8V_DDR; 441c0baf8485928b2db8a9530672d522d758746a2b6Ulf Hansson if (of_find_property(np, "mmc-ddr-1_2v", &len)) 442c0baf8485928b2db8a9530672d522d758746a2b6Ulf Hansson host->caps |= MMC_CAP_1_2V_DDR; 443321bd41de1580f953c637de0fd81e06fcba8b3e8Jaehoon Chung if (of_find_property(np, "mmc-hs200-1_8v", &len)) 444321bd41de1580f953c637de0fd81e06fcba8b3e8Jaehoon Chung host->caps2 |= MMC_CAP2_HS200_1_8V_SDR; 445321bd41de1580f953c637de0fd81e06fcba8b3e8Jaehoon Chung if (of_find_property(np, "mmc-hs200-1_2v", &len)) 446321bd41de1580f953c637de0fd81e06fcba8b3e8Jaehoon Chung host->caps2 |= MMC_CAP2_HS200_1_2V_SDR; 447c373eb489b27b268c9b8c267b212d10864bc8cddSeungwon Jeon if (of_find_property(np, "mmc-hs400-1_8v", &len)) 448c373eb489b27b268c9b8c267b212d10864bc8cddSeungwon Jeon host->caps2 |= MMC_CAP2_HS400_1_8V | MMC_CAP2_HS200_1_8V_SDR; 449c373eb489b27b268c9b8c267b212d10864bc8cddSeungwon Jeon if (of_find_property(np, "mmc-hs400-1_2v", &len)) 450c373eb489b27b268c9b8c267b212d10864bc8cddSeungwon Jeon host->caps2 |= MMC_CAP2_HS400_1_2V | MMC_CAP2_HS200_1_2V_SDR; 451ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz 4523d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer host->dsr_req = !of_property_read_u32(np, "dsr", &host->dsr); 4533d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer if (host->dsr_req && (host->dsr & ~0xffff)) { 4543d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer dev_err(host->parent, 4553d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer "device tree specified broken value for DSR: 0x%x, ignoring\n", 4563d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer host->dsr); 4573d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer host->dsr_req = 0; 4583d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer } 4593d705d14fe4c72be83bae1610680e209ee226b9dSascha Hauer 460ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz return 0; 461ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz 462ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatzout: 463ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz mmc_gpio_free_cd(host); 464ec0a7517dc25b4cca8a694fd61e09771bffba022Simon Baatz return ret; 4656c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski} 4666c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 4676c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi LiakhovetskiEXPORT_SYMBOL(mmc_of_parse); 4686c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski 4696c56e7a0fff166904ce2715f7ab1746460c1f11bGuennadi Liakhovetski/** 470b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * mmc_alloc_host - initialise the per-host structure. 471b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * @extra: sizeof private data structure 472b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * @dev: pointer to host device model structure 473b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 474b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * Initialise the per-host structure. 475b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 476b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanstruct mmc_host *mmc_alloc_host(int extra, struct device *dev) 477b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 478ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman int err; 479b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman struct mmc_host *host; 480b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 481be760a9de881d84994403bb93177bcb95319c4cbMariusz Kozlowski host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 482b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman if (!host) 483b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman return NULL; 484b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 485d9adcc12860d76cf3401c6ab7c0406b15b356b7aGuennadi Liakhovetski /* scanning will be enabled when we're ready */ 486d9adcc12860d76cf3401c6ab7c0406b15b356b7aGuennadi Liakhovetski host->rescan_disable = 1; 487803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo idr_preload(GFP_KERNEL); 488ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman spin_lock(&mmc_host_lock); 489803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo err = idr_alloc(&mmc_host_idr, host, 0, 0, GFP_NOWAIT); 490803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo if (err >= 0) 491803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo host->index = err; 492ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman spin_unlock(&mmc_host_lock); 493803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo idr_preload_end(); 494803d9e043dc31ea2d26442618f0eb020550f8e08Tejun Heo if (err < 0) 495ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman goto free; 496ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman 497d1b268630875a7713b5d468a0c03403c5b721c8eKay Sievers dev_set_name(&host->class_dev, "mmc%d", host->index); 498ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman 499b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->parent = dev; 500b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->class_dev.parent = dev; 501b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->class_dev.class = &mmc_host_class; 502b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman device_initialize(&host->class_dev); 503b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 50404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_host_clk_init(host); 50504566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 506a7d1a1ebd8f5858a812ac3d5fbbc178b4959a63bGuennadi Liakhovetski mutex_init(&host->slot.lock); 50727410ee7e391ce650d6d0242805f080599be7ad7Guennadi Liakhovetski host->slot.cd_irq = -EINVAL; 50827410ee7e391ce650d6d0242805f080599be7ad7Guennadi Liakhovetski 509b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman spin_lock_init(&host->lock); 510b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman init_waitqueue_head(&host->wq); 511b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman INIT_DELAYED_WORK(&host->detect, mmc_rescan); 51281ca03a0e2ea0207b2df80e0edcf4c775c07a505Uwe Kleine-König#ifdef CONFIG_PM 5134c2ef25fe0b847d2ae818f74758ddb0be1c27d8eMaxim Levitsky host->pm_notify.notifier_call = mmc_pm_notify; 51481ca03a0e2ea0207b2df80e0edcf4c775c07a505Uwe Kleine-König#endif 515b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 516b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman /* 517b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * By default, hosts do not support SGIO or large requests. 518b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * They have to set these according to their abilities. 519b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 520a36274e0184193e393fb82957925c3981a6b0477Martin K. Petersen host->max_segs = 1; 521b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->max_seg_size = PAGE_CACHE_SIZE; 522b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 523b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->max_req_size = PAGE_CACHE_SIZE; 524b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->max_blk_size = 512; 525b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman host->max_blk_count = PAGE_CACHE_SIZE / 512; 526b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 527b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman return host; 528ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman 529ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossmanfree: 530ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman kfree(host); 531ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman return NULL; 532b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 533b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 534b93931a61a119575f84c33af2438b9384fde9eb7Pierre OssmanEXPORT_SYMBOL(mmc_alloc_host); 535b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 536b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman/** 537b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * mmc_add_host - initialise host hardware 538b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * @host: mmc host 53967a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * 54067a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * Register the host with the driver model. The host must be 54167a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * prepared to start servicing requests before this function 54267a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * completes. 543b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 544b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanint mmc_add_host(struct mmc_host *host) 545b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 546b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman int err; 547b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 54817b759aff916b4d02721e75ce5ed82b1903e5bd6Nicolas Pitre WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && 54917b759aff916b4d02721e75ce5ed82b1903e5bd6Nicolas Pitre !host->ops->enable_sdio_irq); 55017b759aff916b4d02721e75ce5ed82b1903e5bd6Nicolas Pitre 551b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman err = device_add(&host->class_dev); 552b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman if (err) 553b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman return err; 554b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 555f317dfeb86c83d03304a74ce5426a69422b79547Wolfram Sang led_trigger_register_simple(dev_name(&host->class_dev), &host->led); 556f317dfeb86c83d03304a74ce5426a69422b79547Wolfram Sang 5576edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen#ifdef CONFIG_DEBUG_FS 5586edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen mmc_add_host_debugfs(host); 5596edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen#endif 560597dd9d79cfbbb1636d00a7fd0880355d9b20c41Sujit Reddy Thumma mmc_host_clk_sysfs_init(host); 5616edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen 562b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_start_host(host); 563cc84bb65565f525532958279c49fd9f31312e90cDmitry Shmidt if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) 564cc84bb65565f525532958279c49fd9f31312e90cDmitry Shmidt register_pm_notifier(&host->pm_notify); 565b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 566b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman return 0; 567b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 568b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 569b93931a61a119575f84c33af2438b9384fde9eb7Pierre OssmanEXPORT_SYMBOL(mmc_add_host); 570b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 571b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman/** 572b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * mmc_remove_host - remove host hardware 573b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * @host: mmc host 574b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 575b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * Unregister and remove all cards associated with this host, 57667a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * and power down the MMC bus. No new requests will be issued 57767a61c484735de9bf4f099830ecb4ef2eca95c38Pierre Ossman * after this function has returned. 578b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 579b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_remove_host(struct mmc_host *host) 580b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 581cc84bb65565f525532958279c49fd9f31312e90cDmitry Shmidt if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) 582cc84bb65565f525532958279c49fd9f31312e90cDmitry Shmidt unregister_pm_notifier(&host->pm_notify); 583cc84bb65565f525532958279c49fd9f31312e90cDmitry Shmidt 584b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman mmc_stop_host(host); 585b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 5866edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen#ifdef CONFIG_DEBUG_FS 5876edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen mmc_remove_host_debugfs(host); 5886edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen#endif 5896edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8cHaavard Skinnemoen 590b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman device_del(&host->class_dev); 591b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 59277f1fd6ecd04556cbac1ca72e7a284ae313ea538Pierre Ossman led_trigger_unregister_simple(host->led); 59304566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij 59404566831a703ae3ef4b49a2deae261c9ed26e020Linus Walleij mmc_host_clk_exit(host); 595b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 596b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 597b93931a61a119575f84c33af2438b9384fde9eb7Pierre OssmanEXPORT_SYMBOL(mmc_remove_host); 598b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 599b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman/** 600b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * mmc_free_host - free the host structure 601b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * @host: mmc host 602b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * 603b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman * Free the host once all references to it have been dropped. 604b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman */ 605b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossmanvoid mmc_free_host(struct mmc_host *host) 606b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman{ 607ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman spin_lock(&mmc_host_lock); 608ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman idr_remove(&mmc_host_idr, host->index); 609ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman spin_unlock(&mmc_host_lock); 610ff3112f5adcc9dc33c107c826f82017db8f889f5Pierre Ossman 611b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman put_device(&host->class_dev); 612b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman} 613b93931a61a119575f84c33af2438b9384fde9eb7Pierre Ossman 614b93931a61a119575f84c33af2438b9384fde9eb7Pierre OssmanEXPORT_SYMBOL(mmc_free_host); 615