Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 420dd6b2 authored by Matt Wagantall's avatar Matt Wagantall
Browse files

Merge branch 'mmc_from_3.14' into branch 'msm-3.18'



When migrating from msm-3.14 to msm-3.18, a number of recently-
merged changes were left behind. Pick them up now.

* mmc_from_3.14 (31 commit):
  mmc: cmdq_hci: Add Inline Crypto Engine (ICE) support
  mmc: cmdq_hci: Fix timing and response type for busy commands
  mmc: host: Fix spinbug in performance sysfs nodes
  mmc: queue: issue requests when dcmd is in progress
  mmc: core: fix shutdown in cmdq mode
  mmc: sdhci-msm: increase number of testbuses to 60
  mmc: queue: add timeout capability to requests
  mmc: sdhci: propagate error to command queue engine
  mmc: block: Add error handling to command queue host
  mmc: block: add support for partition switch
  mmc: sdhci-msm: do not disable test-bus
  mmc: sdhci-msm: add support for command-queue
  mmc: sdhci: add command queue support to sdhci
  mmc: cmdq-host: add halt support to command queue host
  mmc: core: Add halt support
  mmc: cmdq: support for command queue enabled host
  mmc: core: add flush request support to command queue
  mmc: card: add read/write support in command queue mode
  mmc: core: Add command queue initialzation support
  mmc: queue: initialization of command queue
  mmc: sdhci: Add Inline Crypto Engine (ICE) support
  mmc: sdhci-msm: Add Inline Crypto Engine (ICE) support
  mmc: sdhci-msm-ice: Add Inline Crypto Engine (ICE) support
  qcom: crypto: Add support for eMMC based ICE
  mmc: core: Fix crash in mmc clk-scaling
  mmc: fix MMC clock scaling to meet upstream HS400 implementation
  mmc: core: devfreq: migrate to devfreq based clock scaling
  Revert "mmc: sdhci-msm: Disable pm functionalities"
  defconfig: Enable MMC_CLKGATE on msm-perf_defconfig
  Revert "defconfig: Disable MMC_CLKGATE on msm-3.14"
  mmc: add support for scheduling mmcqd on idle CPU

Change-Id: I8c36dddba6a416038210764f530a41f86e2181a8
Signed-off-by: default avatarMatt Wagantall <mattw@codeaurora.org>
parents 58d6bfbe 39259796
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@ Optional properties:
                          order as the clocks property.
  - qocm,op-freq-hz     : max clock speed sorted in the same order as the clocks
                          property.
  - qcom,instance-type  : describe the storage type for which ICE node is defined
			  currently, only "ufs" and "sdcc" are supported storage type

Example:
        ufs_ice: ufsice@630000 {
@@ -25,5 +27,6 @@ Example:
                clocks = <&clock_gcc clk_ufs_ice_core_clk_src>,
                         <&clock_gcc clk_gcc_ufs_ice_core_clk>;
                qcom,op-freq-hz = <300000000>, <0>;
		qcom,instance-type = "ufs";
                status = "disabled";
        };
+18 −0
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@ Required properties:
		      Required "interrupt-names" are "hc_irq" and "pwr_irq".
  - <supply-name>-supply: phandle to the regulator device tree node
			  Required "supply-name" are "vdd" and "vdd-io".
  - qcom,ice-clk-rates: this is an array that specifies supported Inline
		    Crypto Engine (ICE) clock frequencies, Units - Hz.
  - sdhc-msm-crypto: phandle to SDHC ICE node

Required alias:
- The slot number is specified via an alias with the following format
@@ -34,6 +37,14 @@ Optional Properties:
				"HS200_1p2v" - indicates that host can support HS200 at 1.2v.
				"DDR_1p8v" - indicates that host can support DDR mode at 1.8v.
				"DDR_1p2v" - indicates that host can support DDR mode at 1.2v.
	- qcom,devfreq,freq-table - specifies supported frequencies for clock scaling.
				    Clock scaling logic shall toggle between these frequencies based
				    on card load. In case the defined frequencies are over or below
				    the supported card frequencies, they will be overridden
				    during card init. In case this entry is not supplied,
				    the driver will construct one based on the card
				    supported max and min frequencies.
				    The frequencies must be ordered from lowest to highest.

In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltage).
	- qcom,<supply>-always-on - specifies whether supply should be kept "on" always.
@@ -75,6 +86,9 @@ In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltag
	- qcom,large-address-bus - specifies whether the soc is capable of
				 supporting larger than 32 bit address bus width.

	- qcom,wakeup-on-idle: if configured, the mmcqd thread will call
	  set_wake_up_idle(), thereby voting for it to be called on idle CPUs.

Example:

	aliases {
@@ -88,6 +102,7 @@ Example:
                reg-names = "hc_mem", "core_mem";
                interrupts = <0 123 0>, <0 138 0>;
                interrupt-names = "hc_irq", "pwr_irq";
		sdhc-msm-crypto = <&sdcc1_ice>;

		vdd-supply = <&pm8941_l21>;
		vdd-io-supply = <&pm8941_l13>;
@@ -99,6 +114,8 @@ Example:
		qcom,vdd-io-voltage-level = <1800000 2950000>;
		qcom,vdd-io-current-level = <6 22000>;

		qcom,devfreq,freq-table = <52000000 200000000>;

		pinctrl-names = "active", "sleep";
		pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
		pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_on &sdc1_data_on>;
@@ -108,6 +125,7 @@ Example:
		qcom,nonremovable;
		qcom,large-address-bus;
		qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
		qcom,ice-clk-rates = <300000000>;

		gpios = <&msmgpio 40 0>, /* CLK */
			<&msmgpio 39 0>, /* CMD */
+1 −0
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_G_ANDROID=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_CLKGATE=y
CONFIG_MMC_PARANOID_SD_INIT=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_TEST=m
+1 −0
Original line number Diff line number Diff line
@@ -382,6 +382,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y
CONFIG_USB_G_ANDROID=y
CONFIG_MMC=y
CONFIG_MMC_PERF_PROFILING=y
CONFIG_MMC_CLKGATE=y
CONFIG_MMC_PARANOID_SD_INIT=y
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_TEST=m
+107 −60
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/blk_types.h>
#include <linux/blkdev.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <crypto/ice.h>
#include <soc/qcom/scm.h>
#include "iceregs.h"
@@ -43,7 +44,8 @@
	TZ_SYSCALL_CREATE_PARAM_ID_0

#define ICE_REV(x, y) (((x) & ICE_CORE_##y##_REV_MASK) >> ICE_CORE_##y##_REV)
#define DEFAULT_ICE_CORE_CLK_FREQ 300000000
#define QCOM_ICE_DEV	"ice"
#define QCOM_ICE_TYPE_NAME_LEN 8

const struct qcom_ice_variant_ops qcom_ice_ops;

@@ -64,6 +66,9 @@ static LIST_HEAD(ice_devices);
struct ice_device {
	struct list_head	list;
	struct device		*pdev;
	struct cdev		cdev;
	dev_t			device_no;
	struct class		*driver_class;
	void __iomem		*mmio;
	int			irq;
	bool			is_irq_enabled;
@@ -77,15 +82,15 @@ struct ice_device {
	struct list_head	clk_list_head;
	u32			ice_hw_version;
	bool			is_ice_clk_available;
	char			ice_instance_type[QCOM_ICE_TYPE_NAME_LEN];
};

static int qcom_ice_enable_clocks(struct ice_device *, bool);

static void qcom_ice_config_proc_ignore(struct ice_device *ice_dev)
{
	u32 regval;
	if (ICE_REV(ice_dev->ice_hw_version, MAJOR) == 2 &&
	    ICE_REV(ice_dev->ice_hw_version, MINOR) == 0) {
	    ICE_REV(ice_dev->ice_hw_version, MINOR) == 0 &&
	    ICE_REV(ice_dev->ice_hw_version, STEP) == 0) {
		regval = qcom_ice_readl(ice_dev,
				QCOM_ICE_REGS_ADVANCED_CONTROL);
		regval |= 0x800;
@@ -316,6 +321,24 @@ static irqreturn_t qcom_ice_isr(int isr, void *data)
	return retval;
}

static void qcom_ice_parse_ice_instance_type(struct platform_device *pdev,
		struct ice_device *ice_dev)
{
	int ret = -1;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	const char *type;

	ret = of_property_read_string_index(np, "qcom,instance-type", 0, &type);
	if (ret) {
		pr_err("%s: Could not get ICE instance type\n", __func__);
		goto out;
	}
	strlcpy(ice_dev->ice_instance_type, type, QCOM_ICE_TYPE_NAME_LEN);
out:
	return;
}

static int qcom_ice_parse_clock_info(struct platform_device *pdev,
		struct ice_device *ice_dev)
{
@@ -422,6 +445,7 @@ static int qcom_ice_get_device_tree_data(struct platform_device *pdev,
			ice_dev->is_irq_enabled = true;
		}
		pr_info("ICE IRQ = %d\n", ice_dev->irq);
		qcom_ice_parse_ice_instance_type(pdev, ice_dev);
	}
	return 0;
err_dev:
@@ -431,6 +455,77 @@ out:
	return rc;
}

/*
 * ICE HW instance can exist in UFS or eMMC based storage HW
 * Userspace does not know what kind of ICE it is dealing with.
 * Though userspace can find which storage device it is booting
 * from but all kind of storage types dont support ICE from
 * beginning. So ICE device is created for user space to ping
 * if ICE exist for that kind of storage
 */
static const struct file_operations qcom_ice_fops = {
	.owner = THIS_MODULE,
};

static int register_ice_device(struct ice_device *ice_dev)
{
	int rc = 0;
	unsigned baseminor = 0;
	unsigned count = 1;
	struct device *class_dev;
	char tmp_dev_name[16];
	memset(tmp_dev_name, 0, 16);

	strlcpy(tmp_dev_name, QCOM_ICE_DEV, 8);
	strlcat(tmp_dev_name, ice_dev->ice_instance_type, 8);

	pr_debug("%s: instance type = %s device name = %s\n", __func__,
				ice_dev->ice_instance_type, tmp_dev_name);

	rc = alloc_chrdev_region(&ice_dev->device_no, baseminor, count,
							tmp_dev_name);
	if (rc < 0) {
		pr_err("alloc_chrdev_region failed %d for %s\n",
						rc, tmp_dev_name);
		return rc;
	}
	ice_dev->driver_class = class_create(THIS_MODULE, tmp_dev_name);
	if (IS_ERR(ice_dev->driver_class)) {
		rc = -ENOMEM;
		pr_err("class_create failed %d for %s\n", rc, tmp_dev_name);
		goto exit_unreg_chrdev_region;
	}
	class_dev = device_create(ice_dev->driver_class, NULL,
					ice_dev->device_no, NULL, tmp_dev_name);

	if (!class_dev) {
		pr_err("class_device_create failed %d for %s\n",
							rc, tmp_dev_name);
		rc = -ENOMEM;
		goto exit_destroy_class;
	}

	cdev_init(&ice_dev->cdev, &qcom_ice_fops);
	ice_dev->cdev.owner = THIS_MODULE;

	rc = cdev_add(&ice_dev->cdev, MKDEV(MAJOR(ice_dev->device_no), 0), 1);
	if (rc < 0) {
		pr_err("cdev_add failed %d for %s\n", rc, tmp_dev_name);
		goto exit_destroy_device;
	}
	return  0;

exit_destroy_device:
	device_destroy(ice_dev->driver_class, ice_dev->device_no);

exit_destroy_class:
	class_destroy(ice_dev->driver_class);

exit_unreg_chrdev_region:
	unregister_chrdev_region(ice_dev->device_no, 1);
	return rc;
}

static int qcom_ice_probe(struct platform_device *pdev)
{
	struct ice_device *ice_dev;
@@ -469,6 +564,13 @@ static int qcom_ice_probe(struct platform_device *pdev)
	if (rc)
		goto err_ice_dev;

	pr_debug("%s: Registering ICE device\n", __func__);
	rc = register_ice_device(ice_dev);
	if (rc) {
		pr_err("create character device failed.\n");
		goto err_ice_dev;
	}
	spin_lock_init(&ice_dev->lock);
	/*
	 * If ICE is enabled here, it would be waste of power.
	 * We would enable ICE when first request for crypto
@@ -510,18 +612,6 @@ static int qcom_ice_remove(struct platform_device *pdev)

static int  qcom_ice_suspend(struct platform_device *pdev)
{
	struct ice_device *ice_dev;

	ice_dev = (struct ice_device *)platform_get_drvdata(pdev);
	if (!ice_dev)
		return 0;

	/*
	 * Storage driver would take care of storage clocks. ICE Driver should
	 * disable its clock
	 */
	if (ice_dev->is_ice_clk_available)
		qcom_ice_enable_clocks(ice_dev, false);
	return 0;
}

@@ -591,45 +681,6 @@ out:
	return ret;
}

static int qcom_ice_enable_clocks(struct ice_device *ice, bool enable)
{
	int ret = 0;
	struct ice_clk_info *clki;
	struct device *dev = ice->pdev;
	struct list_head *head = &ice->clk_list_head;

	if (!head || list_empty(head)) {
		dev_err(dev, "%s:ICE Clock list null/empty\n", __func__);
		ret = -EINVAL;
		goto out;
	}

	if (!ice->is_ice_clk_available) {
		dev_err(dev, "%s:ICE Clock not available\n", __func__);
		ret = -EINVAL;
		goto out;
	}

	list_for_each_entry(clki, head, list) {
		if (!clki->name)
			continue;

		if (enable)
			ret = clk_prepare_enable(clki->clk);
		else
			clk_disable_unprepare(clki->clk);

		if (ret) {
			dev_err(dev, "Unable to %s ICE core clk\n",
				enable?"enable":"disable");
			goto out;
		}
	}
out:
	return ret;
}


static int qcom_ice_secure_ice_init(struct ice_device *ice_dev)
{
	/* We need to enable source for ICE secure interrupts */
@@ -706,9 +757,7 @@ static void qcom_ice_finish_init(void *data, async_cookie_t cookie)
	}

	if (ice_dev->is_ice_clk_available) {
		if (!qcom_ice_init_clocks(ice_dev)) {
			qcom_ice_enable_clocks(ice_dev, true);
		} else {
		if (qcom_ice_init_clocks(ice_dev)) {
			ice_dev->error_cb(ice_dev->host_controller_data,
					ICE_ERROR_IMPROPER_INITIALIZATION);
			return;
@@ -816,7 +865,6 @@ static void qcom_ice_finish_power_collapse(void *data, async_cookie_t cookie)
		 * ICE resets into global bypass mode with optimization and
		 * low power mode disabled. Hence we need to redo those seq's.
		 */
		qcom_ice_enable_clocks(ice_dev, true);
		qcom_ice_low_power_mode_enable(ice_dev);

		qcom_ice_enable_test_bus_config(ice_dev);
@@ -866,7 +914,6 @@ static int qcom_ice_resume(struct platform_device *pdev)
		return -EINVAL;

	if (ice_dev->is_ice_clk_available) {
		qcom_ice_enable_clocks(ice_dev, true);
		/*
		 * Storage is calling this function after power collapse which
		 * would put ICE into GLOBAL_BYPASS mode. Make sure to enable
Loading