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

Commit 06d5054c authored by Can Guo's avatar Can Guo
Browse files

scsi: ufs: Remove UFS card support



UFS card support is removed from Kona, thus remove the changes specifically
introduced for UFS card.

Change-Id: I7a8e6907c3f323005d513bd3b2b370e6e44ba6de
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
parent 1ef2523a
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -92,8 +92,6 @@ config SCSI_UFS_QCOM
	tristate "QCOM specific hooks to UFS controller platform driver"
	depends on SCSI_UFSHCD_PLATFORM && ARCH_QCOM
	select PHY_QCOM_UFS
	select EXTCON
	select EXTCON_STORAGE_CD_GPIO
	help
	  This selects the QCOM specific additions to UFSHCD platform driver.
	  UFS host on QCOM needs some vendor specific configuration before
+0 −17
Original line number Diff line number Diff line
@@ -304,20 +304,6 @@ static int ufshcd_parse_pinctrl_info(struct ufs_hba *hba)
	return ret;
}

static int ufshcd_parse_extcon_info(struct ufs_hba *hba)
{
	struct extcon_dev *extcon;

	extcon = extcon_get_edev_by_phandle(hba->dev, 0);
	if (IS_ERR(extcon) && PTR_ERR(extcon) != -ENODEV)
		return PTR_ERR(extcon);

	if (!IS_ERR(extcon))
		hba->extcon = extcon;

	return 0;
}

static void ufshcd_parse_gear_limits(struct ufs_hba *hba)
{
	struct device *dev = hba->dev;
@@ -527,9 +513,6 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
	ufshcd_parse_gear_limits(hba);
	ufshcd_parse_cmd_timeout(hba);
	ufshcd_parse_force_g4_flag(hba);
	err = ufshcd_parse_extcon_info(hba);
	if (err)
		goto dealloc_host;

	if (!dev->dma_mask)
		dev->dma_mask = &dev->coherent_dma_mask;
+18 −411
Original line number Diff line number Diff line
@@ -364,26 +364,6 @@ ufs_get_pm_lvl_to_link_pwr_state(enum ufs_pm_level lvl)
	return ufs_pm_lvl_states[lvl].link_state;
}

static inline void ufshcd_set_card_online(struct ufs_hba *hba)
{
	atomic_set(&hba->card_state, UFS_CARD_STATE_ONLINE);
}

static inline void ufshcd_set_card_offline(struct ufs_hba *hba)
{
	atomic_set(&hba->card_state, UFS_CARD_STATE_OFFLINE);
}

static inline bool ufshcd_is_card_online(struct ufs_hba *hba)
{
	return (atomic_read(&hba->card_state) == UFS_CARD_STATE_ONLINE);
}

static inline bool ufshcd_is_card_offline(struct ufs_hba *hba)
{
	return (atomic_read(&hba->card_state) == UFS_CARD_STATE_OFFLINE);
}

static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba)
{
	/*
@@ -416,28 +396,6 @@ static inline void ufshcd_wb_config(struct ufs_hba *hba)
			__func__, ret);
}

static inline bool ufshcd_is_device_offline(struct ufs_hba *hba)
{
	if (hba->extcon && ufshcd_is_card_offline(hba))
		return true;
	else
		return false;
}

static int ufshcd_card_get_extcon_state(struct ufs_hba *hba)
{
	int ret;

	if (!hba->extcon)
		return -EINVAL;

	ret = extcon_get_state(hba->extcon, EXTCON_MECHANICAL);
	if (ret < 0)
		dev_err(hba->dev, "%s: Failed to check card Extcon state, ret=%d\n",
				 __func__, ret);
	return ret;
}

static inline enum ufs_pm_level
ufs_get_desired_pm_lvl_for_dev_link_state(enum ufs_dev_pwr_mode dev_state,
					enum uic_link_state link_state)
@@ -543,11 +501,6 @@ static int ufshcd_config_vreg(struct device *dev,
				struct ufs_vreg *vreg, bool on);
static int ufshcd_enable_vreg(struct device *dev, struct ufs_vreg *vreg);
static int ufshcd_disable_vreg(struct device *dev, struct ufs_vreg *vreg);
static void ufshcd_register_pm_notifier(struct ufs_hba *hba);
static void ufshcd_unregister_pm_notifier(struct ufs_hba *hba);
static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on);
static void ufshcd_remove_scsi_devices(struct ufs_hba *hba);
static void ufshcd_detect_card(struct ufs_hba *hba, unsigned long delay);

#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
static struct devfreq_simple_ondemand_data ufshcd_ondemand_data = {
@@ -1812,9 +1765,6 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up)
{
	int ret = 0;

	if (ufshcd_is_device_offline(hba))
		return 0;

	/* let's not get into low power until clock scaling is completed */
	hba->ufs_stats.clk_hold.ctx = CLK_SCALE_WORK;
	ufshcd_hold_all(hba);
@@ -2196,9 +2146,6 @@ static void ufshcd_ungate_work(struct work_struct *work)
	ufshcd_hba_vreg_set_hpm(hba);
	ufshcd_enable_clocks(hba);

	if (ufshcd_is_device_offline(hba))
		goto unblock_reqs;

	/* Exit from hibern8 */
	if (ufshcd_can_hibern8_during_gating(hba)) {
		/* Prevent gating in this path */
@@ -2241,8 +2188,6 @@ int ufshcd_hold(struct ufs_hba *hba, bool async)
start:
	switch (hba->clk_gating.state) {
	case CLKS_ON:
		if (ufshcd_is_device_offline(hba))
			break;
		/*
		 * Wait for the ungate work to complete if in progress.
		 * Though the clocks may be in ON state, the link could
@@ -2346,9 +2291,6 @@ static void ufshcd_gate_work(struct work_struct *work)

	spin_unlock_irqrestore(hba->host->host_lock, flags);

	if (ufshcd_is_device_offline(hba))
		goto disable_clocks;

	if (ufshcd_is_hibern8_on_idle_allowed(hba) &&
	    hba->hibern8_on_idle.is_enabled)
		/*
@@ -2368,7 +2310,6 @@ static void ufshcd_gate_work(struct work_struct *work)
		ufshcd_set_link_hibern8(hba);
	}

disable_clocks:
	/*
	 * If auto hibern8 is enabled then the link will already
	 * be in hibern8 state and the ref clock can be gated.
@@ -3072,8 +3013,6 @@ int ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
{
	hba->lrb[task_tag].issue_time_stamp = ktime_get();
	hba->lrb[task_tag].compl_time_stamp = ktime_set(0, 0);
	if (ufshcd_is_device_offline(hba))
		return -ENOLINK;
	ufshcd_clk_scaling_start_busy(hba);
	__set_bit(task_tag, &hba->outstanding_reqs);
	ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
@@ -3263,9 +3202,6 @@ __ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd,
		return -EIO;
	}

	if (ufshcd_is_device_offline(hba))
		return -ENOLINK;

	if (completion)
		init_completion(&uic_cmd->done);

@@ -3756,12 +3692,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
		goto out_unlock;
	}

	if (ufshcd_is_device_offline(hba)) {
		set_host_byte(cmd, DID_BAD_TARGET);
		cmd->scsi_done(cmd);
		goto out_unlock;
	}

	switch (hba->ufshcd_state) {
	case UFSHCD_STATE_OPERATIONAL:
		break;
@@ -4092,9 +4022,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
	unsigned long flags;
	bool has_read_lock = false;

	if (ufshcd_is_device_offline(hba))
		return -ENOLINK;

	/*
	 * May get invoked from shutdown and IOCTL contexts.
	 * In shutdown context, it comes in with lock acquired.
@@ -5250,7 +5177,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
	ufshcd_dme_cmd_log(hba, "dme_cmpl_2", hba->active_uic_cmd->command);

out:
	if (ret && !ufshcd_is_device_offline(hba)) {
	if (ret) {
		ufsdbg_set_err_state(hba);
		ufshcd_print_host_state(hba);
		ufshcd_print_pwr_info(hba);
@@ -5310,9 +5237,6 @@ static int ufshcd_link_recovery(struct ufs_hba *hba)
	int ret = 0;
	unsigned long flags;

	if (ufshcd_is_device_offline(hba))
		return -ENOLINK;

	/*
	 * Check if there is any race with fatal error handling.
	 * If so, wait for it to complete. Even though fatal error
@@ -5416,7 +5340,7 @@ int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)

	for (retries = UIC_HIBERN8_ENTER_RETRIES; retries > 0; retries--) {
		ret = __ufshcd_uic_hibern8_enter(hba);
		if (!ret || ufshcd_is_device_offline(hba))
		if (!ret)
			goto out;
		else if (ret != -EAGAIN)
			/* Unable to recover the link, so no point proceeding */
@@ -5448,7 +5372,7 @@ int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
			__func__, ret);
		ret = ufshcd_link_recovery(hba);
		/* Unable to recover the link, so no point proceeding */
		if (ret && !ufshcd_is_device_offline(hba))
		if (ret)
			BUG_ON(1);
	} else {
		ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_EXIT,
@@ -6021,14 +5945,6 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
out:
	if (ret)
		dev_err(hba->dev, "link startup failed %d\n", ret);
	/*
	 * For some external cards, link startup succeeds only after few link
	 * startup attempts and err_state may get set in this case.
	 * But as the link startup has finally succeded, we are clearing the
	 * error state.
	 */
	else if (hba->extcon)
		ufsdbg_clr_err_state(hba);

	return ret;
}
@@ -7241,17 +7157,6 @@ static void ufshcd_err_handler(struct work_struct *work)

	hba = container_of(work, struct ufs_hba, eh_work);

	if (ufshcd_is_device_offline(hba)) {
		spin_lock_irqsave(hba->host->host_lock, flags);
		hba->saved_err = 0;
		hba->saved_uic_err = 0;
		hba->saved_ce_err = 0;
		hba->auto_h8_err = false;
		hba->force_host_reset = false;
		hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
		goto out;
	}

	spin_lock_irqsave(hba->host->host_lock, flags);
	ufsdbg_set_err_state(hba);

@@ -7441,9 +7346,6 @@ static void ufshcd_rls_handler(struct work_struct *work)

	hba = container_of(work, struct ufs_hba, rls_work);

	if (ufshcd_is_device_offline(hba))
		return;

	pm_runtime_get_sync(hba->dev);
	ufshcd_scsi_block_requests(hba);
	down_write(&hba->lock);
@@ -7613,10 +7515,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
			queue_eh_work = true;
	}

	if (ufshcd_is_device_offline(hba)) {
		/* ignore UIC errors if card is offline */
		retval |= IRQ_HANDLED;
	} else if (queue_eh_work) {
	if (queue_eh_work) {
		/*
		 * update the transfer error masks to sticky bits, let's do this
		 * irrespective of current ufshcd_state.
@@ -7743,7 +7642,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
		intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
	} while (intr_status && --retries);

	if (retval == IRQ_NONE && !ufshcd_is_device_offline(hba)) {
	if (retval == IRQ_NONE) {
		dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n",
					__func__, intr_status);
		ufshcd_hex_dump(hba, "host regs: ", hba->mmio_base,
@@ -8222,7 +8121,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba)
	 * There is no point proceeding even after failing
	 * to recover after multiple retries.
	 */
	BUG_ON(err && ufshcd_is_embedded_dev(hba) && !hba->extcon);
	BUG_ON(err && ufshcd_is_embedded_dev(hba));

	/*
	 * After reset the door-bell might be cleared, complete
@@ -9178,8 +9077,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)

		scsi_scan_host(hba->host);
		pm_runtime_put_sync(hba->dev);
		if (hba->extcon)
			hba->card_rpm_paired = true;
	}

	/*
@@ -9198,11 +9095,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
	 * If we failed to initialize the device or the device is not
	 * present, turn off the power/clocks etc.
	 */
	if (ret && !ufshcd_eh_in_progress(hba) && !hba->pm_op_in_progress) {
	if (ret && !ufshcd_eh_in_progress(hba) && !hba->pm_op_in_progress)
		pm_runtime_put_sync(hba->dev);
		if (hba->extcon)
			hba->card_rpm_paired = true;
	}

	trace_ufshcd_init(dev_name(hba->dev), ret,
		ktime_to_us(ktime_sub(ktime_get(), start)),
@@ -9210,197 +9104,6 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
	return ret;
}

static void ufshcd_remove_scsi_devices(struct ufs_hba *hba)
{
	struct Scsi_Host *shost = hba->host;
	struct scsi_device *sdev;
	unsigned long flags;

	spin_lock_irqsave(shost->host_lock, flags);
restart:
	list_for_each_entry(sdev, &shost->__devices, siblings) {
		if (sdev->sdev_state == SDEV_DEL ||
		    sdev->sdev_state == SDEV_CANCEL ||
		    !get_device(&sdev->sdev_gendev))
			continue;
		spin_unlock_irqrestore(shost->host_lock, flags);
		scsi_remove_device(sdev);
		put_device(&sdev->sdev_gendev);
		spin_lock_irqsave(shost->host_lock, flags);
		goto restart;
	}
	spin_unlock_irqrestore(shost->host_lock, flags);
}

static void ufshcd_remove_card(struct ufs_hba *hba)
{
	unsigned long flags;

	spin_lock_irqsave(hba->host->host_lock, flags);
	ufshcd_set_card_removal_ongoing(hba);
	ufshcd_set_card_offline(hba);
	spin_unlock_irqrestore(hba->host->host_lock, flags);
	/* Turn on host vreg and clocks */
	ufshcd_setup_hba_vreg(hba, true);
	ufshcd_enable_clocks(hba);
	/* Make sure clocks are stable */
	usleep_range(50, 60);
	spin_lock_irqsave(hba->host->host_lock, flags);
	ufshcd_hba_stop(hba, false);
	/* Clear interrupt status and disable interrupts */
	ufshcd_writel(hba, ufshcd_readl(hba, REG_INTERRUPT_STATUS),
		      REG_INTERRUPT_STATUS);
	ufshcd_writel(hba, 0, REG_INTERRUPT_ENABLE);
	/*
	 * Make sure that UFS interrupts are disabled and
	 * any pending interrupt status is cleared.
	 */
	mb();
	hba->silence_err_logs = true;
	/* Complete requests that have door-bell cleared by h/w */
	ufshcd_complete_requests(hba);
	/* Complete the sync/async UIC command if there is one */
	if (hba->uic_async_done)
		complete(hba->uic_async_done);
	else if (hba->active_uic_cmd)
		complete(&hba->active_uic_cmd->done);
	spin_unlock_irqrestore(hba->host->host_lock, flags);
	cancel_delayed_work_sync(&hba->card_detect_work);
	/* Flush runtime PM events */
	pm_runtime_get_sync(hba->dev);
	/* Clear runtime PM errors if any */
	pm_runtime_set_active(hba->dev);
	cancel_work_sync(&hba->rls_work);
	cancel_work_sync(&hba->eh_work);
	cancel_work_sync(&hba->eeh_work);
	hba->auto_bkops_enabled = false;
	__ufshcd_shutdown_clkscaling(hba);
	spin_lock_irqsave(hba->host->host_lock, flags);
	ufshcd_clear_eh_in_progress(hba);
	hba->saved_err = 0;
	hba->saved_uic_err = 0;
	hba->saved_ce_err = 0;
	hba->auto_h8_err = false;
	hba->force_host_reset = false;
	hba->ufshcd_state = UFSHCD_STATE_RESET;
	hba->silence_err_logs = false;
	ufsdbg_clr_err_state(hba);
	ufshcd_set_ufs_dev_poweroff(hba);
	ufshcd_set_link_off(hba);
	spin_unlock_irqrestore(hba->host->host_lock, flags);
	/*
	 * Remove scsi devices only when we are not in middle
	 * of system resume events.
	 */
	if (!down_trylock(&hba->sdev_sema)) {
		ufshcd_remove_scsi_devices(hba);
		up(&hba->sdev_sema);
	}
	ufshcd_clear_card_removal_ongoing(hba);
	pm_runtime_put_sync(hba->dev);
}

static void ufshcd_card_detect_handler(struct work_struct *work)
{
	struct ufs_hba *hba;
	unsigned long flags;
	int ret;

	hba = container_of(to_delayed_work(work), struct ufs_hba,
			   card_detect_work);

	spin_lock_irqsave(hba->host->host_lock, flags);
	if (!ufshcd_is_card_removal_ongoing(hba))
		ufshcd_set_card_online(hba);
	spin_unlock_irqrestore(hba->host->host_lock, flags);

	if (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device) {
		pm_runtime_get_sync(hba->dev);
		if (ufshcd_is_clkgating_allowed(hba)) {
			spin_lock_irqsave(hba->host->host_lock, flags);
			hba->clk_gating.active_reqs = 0;
			spin_unlock_irqrestore(hba->host->host_lock, flags);
		}
		hba->card_rpm_paired = false;
		ret = ufshcd_detect_device(hba);
		if (ret) {
			ufshcd_set_card_offline(hba);
			ufsdbg_clr_err_state(hba);
			dev_err(hba->dev, "%s: device detect failed: %d\n",
				__func__, ret);
		}

		/*
		 * pm_runtime_put_sync() may not be called if
		 * failure happens before or inside ufshcd_probe_hba()
		 */
		if (!hba->card_rpm_paired) {
			cancel_work_sync(&hba->eh_work);
			pm_runtime_put_sync(hba->dev);
		}
	}
}

static void ufshcd_detect_card(struct ufs_hba *hba, unsigned long delay)
{
	if (hba->extcon && !hba->card_detect_disabled)
		schedule_delayed_work(&hba->card_detect_work, delay);
}

static int ufshcd_card_detect_notifier(struct notifier_block *nb,
				       unsigned long event, void *ptr)
{
	struct ufs_hba *hba = container_of(nb, struct ufs_hba, card_detect_nb);

	/*
	 * card insertion/removal are not frequent events and having this
	 * message helps if there is some issue with card detection/removal.
	 */
	dev_info(hba->dev, "%s: card %s notification rcvd\n",
		__func__, event ? "inserted" : "removed");

	if (event)
		ufshcd_detect_card(hba, msecs_to_jiffies(200));
	else
		ufshcd_remove_card(hba);

	return NOTIFY_DONE;
}

static int ufshcd_extcon_register(struct ufs_hba *hba)
{
	int ret;

	if (!hba->extcon)
		return 0;

	hba->card_detect_nb.notifier_call = ufshcd_card_detect_notifier;
	ret = extcon_register_notifier(hba->extcon,
				       EXTCON_MECHANICAL,
				       &hba->card_detect_nb);
	if (ret)
		dev_err(hba->dev, "%s: extcon_register_notifier() failed, ret %d\n",
			__func__, ret);

	return ret;
}

static int ufshcd_extcon_unregister(struct ufs_hba *hba)
{
	int ret;

	if (!hba->extcon)
		return 0;

	ret = extcon_unregister_notifier(hba->extcon, EXTCON_MECHANICAL,
					 &hba->card_detect_nb);
	if (ret)
		dev_err(hba->dev, "%s: extcon_unregister_notifier() failed, ret %d\n",
			__func__, ret);

	return ret;
}

/**
 * ufshcd_async_scan - asynchronous execution for probing hba
 * @data: data pointer to pass to this function
@@ -9410,16 +9113,6 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
{
	struct ufs_hba *hba = (struct ufs_hba *)data;

	if (hba->extcon) {
		ufshcd_hba_stop(hba, true);
		ufshcd_set_ufs_dev_poweroff(hba);
		ufshcd_set_link_off(hba);
		ufshcd_set_card_offline(hba);
		pm_runtime_put_sync(hba->dev);
		ufshcd_extcon_register(hba);
		if (ufshcd_card_get_extcon_state(hba) > 0)
			ufshcd_detect_card(hba, 0);
	} else {
	/*
	 * Don't allow clock gating and hibern8 enter for faster device
	 * detection.
@@ -9428,7 +9121,6 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
	ufshcd_probe_hba(hba);
	ufshcd_release_all(hba);
}
}

static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
{
@@ -9909,12 +9601,6 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on)
	struct ufs_vreg_info *info = &hba->vreg_info;
	int ret = 0;

	if (hba->extcon)
		mutex_lock(&hba->card_mutex);

	if (!on && ufshcd_is_card_removal_ongoing(hba))
		goto out;

	if (info->vdd_hba) {
		ret = ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on);

@@ -9922,9 +9608,6 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on)
			ufshcd_vops_update_sec_cfg(hba, on);
	}

out:
	if (hba->extcon)
		mutex_unlock(&hba->card_mutex);
	return ret;
}

@@ -10018,19 +9701,13 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	bool clk_state_changed = false;

	if (list_empty(head))
		return ret;

	if (hba->extcon)
		mutex_lock(&hba->card_mutex);

	if (!on && ufshcd_is_card_removal_ongoing(hba))
		goto out_unlock;
		goto out;

	/* call vendor specific bus vote before enabling the clocks */
	if (on) {
		ret = ufshcd_vops_set_bus_vote(hba, on);
		if (ret)
			goto out_unlock;
			return ret;
	}

	/*
@@ -10041,7 +9718,7 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	if (!on) {
		ret = ufshcd_vops_setup_clocks(hba, on, PRE_CHANGE);
		if (ret)
			goto out_unlock;
			return ret;
	}

	list_for_each_entry(clki, head, list) {
@@ -10080,7 +9757,7 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
	if (on) {
		ret = ufshcd_vops_setup_clocks(hba, on, POST_CHANGE);
		if (ret)
			goto out;
			return ret;
	}

	/*
@@ -10113,9 +9790,6 @@ static int ufshcd_setup_clocks(struct ufs_hba *hba, bool on,
		trace_ufshcd_profile_clk_gating(dev_name(hba->dev),
			(on ? "on" : "off"),
			ktime_to_us(ktime_sub(ktime_get(), start)), ret);
out_unlock:
	if (hba->extcon)
		mutex_unlock(&hba->card_mutex);
	return ret;
}

@@ -10253,7 +9927,6 @@ static int ufshcd_hba_init(struct ufs_hba *hba)
static void ufshcd_hba_exit(struct ufs_hba *hba)
{
	if (hba->is_powered) {
		ufshcd_extcon_unregister(hba);
		ufshcd_variant_hba_exit(hba);
		ufshcd_setup_vreg(hba, false);
		if (ufshcd_is_clkscaling_supported(hba)) {
@@ -10536,55 +10209,6 @@ static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba)
		ufshcd_setup_hba_vreg(hba, true);
}

#ifdef CONFIG_PM_SLEEP
static int ufshcd_pm_notify(struct notifier_block *notify_block,
			 unsigned long mode, void *unused)
{
	struct ufs_hba *hba = container_of(
		notify_block, struct ufs_hba, pm_notify);

	if (!hba->extcon)
		return 0;

	switch (mode) {
	case PM_SUSPEND_PREPARE:
		hba->card_detect_disabled = true;
		cancel_delayed_work_sync(&hba->card_detect_work);
		down(&hba->sdev_sema);
		break;
	case PM_POST_SUSPEND:
		if (ufshcd_is_card_offline(hba) && hba->sdev_ufs_device)
			ufshcd_remove_scsi_devices(hba);
		up(&hba->sdev_sema);
		hba->card_detect_disabled = false;
		if (ufshcd_card_get_extcon_state(hba) > 0 &&
		    !hba->sdev_ufs_device)
			ufshcd_detect_card(hba, 0);
	}

	return 0;
}

static void ufshcd_register_pm_notifier(struct ufs_hba *hba)
{
	hba->pm_notify.notifier_call = ufshcd_pm_notify;
	register_pm_notifier(&hba->pm_notify);
}

static void ufshcd_unregister_pm_notifier(struct ufs_hba *hba)
{
	unregister_pm_notifier(&hba->pm_notify);
}
#else
static void ufshcd_register_pm_notifier(struct ufs_hba *hba)
{
}

static void ufshcd_unregister_pm_notifier(struct ufs_hba *hba)
{
}
#endif /* CONFIG_PM_SLEEP */

/**
 * ufshcd_suspend - helper function for suspend operations
 * @hba: per adapter instance
@@ -10796,11 +10420,6 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
	if (ret)
		goto disable_vreg;

	if (hba->extcon &&
	    (ufshcd_is_card_offline(hba) ||
	     (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device)))
		goto skip_dev_ops;

	if (ufshcd_is_link_hibern8(hba)) {
		ret = ufshcd_uic_hibern8_exit(hba);
		if (!ret) {
@@ -10849,7 +10468,6 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
	if (hba->clk_scaling.is_allowed)
		ufshcd_resume_clkscaling(hba);

skip_dev_ops:
	/* Set Auto-Hibernate timer if supported */
	ufshcd_set_auto_hibern8_timer(hba);

@@ -11091,11 +10709,6 @@ int ufshcd_shutdown(struct ufs_hba *hba)
	if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
		goto out;

	if (hba->extcon) {
		hba->card_detect_disabled = true;
		cancel_delayed_work_sync(&hba->card_detect_work);
	}

	pm_runtime_get_sync(hba->dev);
	ufshcd_hold_all(hba);
	ufshcd_mark_shutdown_ongoing(hba);
@@ -11146,7 +10759,6 @@ void ufshcd_remove(struct ufs_hba *hba)
	}
	ufshcd_hba_exit(hba);
	ufsdbg_remove_debugfs(hba);
	ufshcd_unregister_pm_notifier(hba);
}
EXPORT_SYMBOL_GPL(ufshcd_remove);

@@ -11306,12 +10918,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
	/* Initialize work queues */
	INIT_WORK(&hba->eh_work, ufshcd_err_handler);
	INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler);
	INIT_DELAYED_WORK(&hba->card_detect_work, ufshcd_card_detect_handler);
	INIT_WORK(&hba->rls_work, ufshcd_rls_handler);

	sema_init(&hba->sdev_sema, 1);
	mutex_init(&hba->card_mutex);

	/* Initialize UIC command mutex */
	mutex_init(&hba->uic_cmd_mutex);

@@ -11427,7 +11035,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)

	ufs_sysfs_add_nodes(hba->dev);

	ufshcd_register_pm_notifier(hba);
	return 0;

out_remove_scsi_host:
+0 −43
Original line number Diff line number Diff line
@@ -711,13 +711,6 @@ struct ufshcd_cmd_log {
	u32 seq_num;
};

/* UFS card state - hotplug state */
enum ufshcd_card_state {
	UFS_CARD_STATE_UNKNOWN	= 0,
	UFS_CARD_STATE_ONLINE	= 1,
	UFS_CARD_STATE_OFFLINE	= 2,
};

/**
 * struct ufs_hba - per adapter private structure
 * @mmio_base: UFSHCI base register address
@@ -765,16 +758,6 @@ enum ufshcd_card_state {
 * @debugfs_files: debugfs files associated with the ufs stats
 * @ufshcd_dbg_print: Bitmask for enabling debug prints
 * @extcon: pointer to external connector device
 * @card_detect_nb: card detector notifier registered with @extcon
 * @card_detect_work: work to exectute the card detect function
 * @card_state: card state event, enum ufshcd_card_state defines possible states
 * @card_removal_in_prog: flag to track card removal progress
 * @pm_notify: used to register for PM events
 * @sdev_sema: semaphore to protect scsi devices from being removed
 * @card_mutex: mutex to serialize ON/OFF sequences of hba vregs and clocks
 * @card_rpm_paired: indicates whether runtime PM events are paired after card
 *  detection is finished
 * @card_detect_disabled: to enable/disable card detect
 * @vreg_info: UFS device voltage regulator information
 * @clk_list_head: UFS host controller clocks list node head
 * @pwr_info: holds current power mode
@@ -1009,17 +992,6 @@ struct ufs_hba {
	/* Bitmask for enabling debug prints */
	u32 ufshcd_dbg_print;

	struct extcon_dev *extcon;
	struct notifier_block card_detect_nb;
	struct delayed_work card_detect_work;
	atomic_t card_state;
	unsigned long card_removal_in_prog;
	struct notifier_block pm_notify;
	struct semaphore sdev_sema;
	struct mutex card_mutex;
	bool card_rpm_paired;
	bool card_detect_disabled;

	struct ufs_pa_layer_attr pwr_info;
	struct ufs_pwr_mode_info max_pwr_info;

@@ -1088,21 +1060,6 @@ struct ufs_hba {
	bool wb_enabled;
};

static inline void ufshcd_set_card_removal_ongoing(struct ufs_hba *hba)
{
	set_bit(0, &hba->card_removal_in_prog);
}

static inline void ufshcd_clear_card_removal_ongoing(struct ufs_hba *hba)
{
	clear_bit(0, &hba->card_removal_in_prog);
}

static inline bool ufshcd_is_card_removal_ongoing(struct ufs_hba *hba)
{
	return !!(test_bit(0, &hba->card_removal_in_prog));
}

static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
{
	set_bit(0, &hba->shutdown_in_prog);