Commit 8f633369 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull misc driver fix from Greg KH:
 "Here is a single, much requested, fix for a set of misc drivers to
  resolve a much reported regression in the -rc series that has also
  propagated back to the stable releases. Sorry for the delay, lots of
  conference travel for a few weeks put me very far behind in patch
  wrangling.

  It has been reported by many to resolve the reported problem, and has
  been in linux-next with no reported issues"

* tag 'char-misc-6.6-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  misc: rtsx: Fix some platforms can not boot and move the l1ss judgment to probe
parents 3abd15e2 0e4cac55
Loading
Loading
Loading
Loading
+6 −49
Original line number Diff line number Diff line
@@ -83,65 +83,22 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)

static void rts5227_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	u32 lval;
	struct rtsx_cr_option *option = &pcr->option;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (CHK_PCI_PID(pcr, 0x522A)) {
		if (0 == (lval & 0x0F))
			rtsx_pci_enable_oobs_polling(pcr);
		else
		if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
			rtsx_pci_disable_oobs_polling(pcr);
	}

	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);
		else
		rtsx_clear_dev_flag(pcr, PM_L1_2_EN);
			rtsx_pci_enable_oobs_polling(pcr);
	}

	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
	}
}

	if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
		option->force_clkreq_0 = false;
	else
		option->force_clkreq_0 = true;

}

static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
{
	u16 cap;
@@ -195,7 +152,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
		}
	}

	if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG)
	if (option->force_clkreq_0)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
				FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
+17 −40
Original line number Diff line number Diff line
@@ -386,59 +386,25 @@ static void rts5228_process_ocp(struct rtsx_pcr *pcr)

static void rts5228_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	u32 lval;
	struct rtsx_cr_option *option = &pcr->option;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (0 == (lval & 0x0F))
		rtsx_pci_enable_oobs_polling(pcr);
	else
	if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
		rtsx_pci_disable_oobs_polling(pcr);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_2_EN);
		rtsx_pci_enable_oobs_polling(pcr);

	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
	if (option->ltr_en) {
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
		}
	}
}

static int rts5228_extra_init_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;

	rtsx_pci_write_register(pcr, RTS5228_AUTOLOAD_CFG1,
			CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);
@@ -469,6 +435,17 @@ static int rts5228_extra_init_hw(struct rtsx_pcr *pcr)
	else
		rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);

	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

	rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);

	if (pcr->rtd3_en) {
+7 −49
Original line number Diff line number Diff line
@@ -86,62 +86,20 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)

static void rts5249_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	struct rtsx_cr_option *option = &(pcr->option);
	u32 lval;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) {
		if (0 == (lval & 0x0F))
			rtsx_pci_enable_oobs_polling(pcr);
		else
		if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
			rtsx_pci_disable_oobs_polling(pcr);
		else
			rtsx_pci_enable_oobs_polling(pcr);
	}


	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);

	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
		}
	}
	}

static int rts5249_init_from_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &(pcr->option);

	if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
				| PM_L1_1_EN | PM_L1_2_EN))
		option->force_clkreq_0 = false;
	else
		option->force_clkreq_0 = true;

	return 0;
}

static void rts52xa_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
@@ -276,7 +234,6 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
	struct rtsx_cr_option *option = &(pcr->option);

	rts5249_init_from_cfg(pcr);
	rts5249_init_from_hw(pcr);

	rtsx_pci_init_cmd(pcr);

@@ -327,11 +284,12 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
		}
	}


	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0 && pcr->aspm_mode == ASPM_MODE_CFG)
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
			FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
+13 −30
Original line number Diff line number Diff line
@@ -480,47 +480,19 @@ static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)

static void rts5260_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	struct rtsx_cr_option *option = &pcr->option;
	u32 lval;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);

	rts5260_pwr_saving_setting(pcr);

	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
		}
	}
}

static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;

	/* Set mcu_cnt to 7 to ensure data can be sampled properly */
	rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07);
@@ -539,6 +511,17 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)

	rts5260_init_hw(pcr);

	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

	rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00);

	return 0;
+13 −39
Original line number Diff line number Diff line
@@ -454,54 +454,17 @@ static void rts5261_init_from_hw(struct rtsx_pcr *pcr)

static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	int l1ss;
	u32 lval;
	struct rtsx_cr_option *option = &pcr->option;

	l1ss = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
	if (!l1ss)
		return;

	pci_read_config_dword(pdev, l1ss + PCI_L1SS_CTL1, &lval);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_1)
		rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_ASPM_L1_2)
		rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, ASPM_L1_2_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_1)
		rtsx_set_dev_flag(pcr, PM_L1_1_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_1_EN);

	if (lval & PCI_L1SS_CTL1_PCIPM_L1_2)
		rtsx_set_dev_flag(pcr, PM_L1_2_EN);
	else
		rtsx_clear_dev_flag(pcr, PM_L1_2_EN);

	rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0);
	if (option->ltr_en) {
		u16 val;

		pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &val);
		if (val & PCI_EXP_DEVCTL2_LTR_EN) {
			option->ltr_enabled = true;
			option->ltr_active = true;
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
		} else {
			option->ltr_enabled = false;
		}
	}
}

static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;
	u32 val;

	rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
@@ -547,6 +510,17 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
	else
		rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00);

	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
	else
		rtsx_pci_write_register(pcr, PETXCFG,
				 FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);

	rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB);

	if (pcr->rtd3_en) {
Loading