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