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

Commit d9d51e0c authored by Xiaofei Tan's avatar Xiaofei Tan Committed by Martin K. Petersen
Browse files

scsi: hisi_sas: tidy channel interrupt handler for v3 hw



The ISR of channel interrupt of v3 hw is a little long and messy. This
patch tidies it by relocating CHL_INT1 and CHL_INT2 handling to new
function separately.

Signed-off-by: default avatarXiaofei Tan <tanxiaofei@huawei.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4e32b2f4
Loading
Loading
Loading
Loading
+78 −78
Original line number Diff line number Diff line
@@ -1333,78 +1333,61 @@ static const struct hisi_sas_hw_error port_axi_error[] = {
	},
};

static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
{
	struct hisi_hba *hisi_hba = p;
	u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT1);
	u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT1_MSK);
	struct device *dev = hisi_hba->dev;
	struct pci_dev *pci_dev = hisi_hba->pci_dev;
	u32 irq_msk;
	int phy_no = 0;

	irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS)
				& 0xeeeeeeee;

	while (irq_msk) {
		u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
						     CHL_INT0);
		u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,
						     CHL_INT1);
		u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
						     CHL_INT2);
		u32 irq_msk1 = hisi_sas_phy_read32(hisi_hba, phy_no,
							CHL_INT1_MSK);
		u32 irq_msk2 = hisi_sas_phy_read32(hisi_hba, phy_no,
							CHL_INT2_MSK);

		irq_value1 &= ~irq_msk1;
		irq_value2 &= ~irq_msk2;

		if ((irq_msk & (4 << (phy_no * 4))) &&
						irq_value1) {
	int i;

	irq_value &= ~irq_msk;
	if (!irq_value)
		return;

	for (i = 0; i < ARRAY_SIZE(port_axi_error); i++) {
				const struct hisi_sas_hw_error *error =
						&port_axi_error[i];
		const struct hisi_sas_hw_error *error = &port_axi_error[i];

				if (!(irq_value1 & error->irq_msk))
		if (!(irq_value & error->irq_msk))
			continue;

		dev_err(dev, "%s error (phy%d 0x%x) found!\n",
					error->msg, phy_no, irq_value1);
			error->msg, phy_no, irq_value);
		queue_work(hisi_hba->wq, &hisi_hba->rst_work);
	}

			hisi_sas_phy_write32(hisi_hba, phy_no,
					     CHL_INT1, irq_value1);
	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value);
}

		if (irq_msk & (8 << (phy_no * 4)) && irq_value2) {
static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
{
	u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK);
	u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2);
	struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
	struct pci_dev *pci_dev = hisi_hba->pci_dev;
	struct device *dev = hisi_hba->dev;

			if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
				dev_warn(dev, "phy%d identify timeout\n",
							phy_no);
				hisi_sas_notify_phy_event(phy,
					HISI_PHYE_LINK_RESET);
	irq_value &= ~irq_msk;
	if (!irq_value)
		return;

	if (irq_value & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
		dev_warn(dev, "phy%d identify timeout\n", phy_no);
		hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
	}

			if (irq_value2 & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
				u32 reg_value = hisi_sas_phy_read32(hisi_hba,
						phy_no, STP_LINK_TIMEOUT_STATE);
	if (irq_value & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
		u32 reg_value = hisi_sas_phy_read32(hisi_hba, phy_no,
				STP_LINK_TIMEOUT_STATE);

		dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
			 phy_no, reg_value);
		if (reg_value & BIT(4))
					hisi_sas_notify_phy_event(phy,
						HISI_PHYE_LINK_RESET);
			hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
	}

			hisi_sas_phy_write32(hisi_hba, phy_no,
					     CHL_INT2, irq_value2);
	hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value);

			if ((irq_value2 & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
	if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
	    (pci_dev->revision == 0x20)) {
		u32 reg_value;
		int rc;
@@ -1415,17 +1398,34 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
				1000, 10000);
		if (rc) {
			disable_phy_v3_hw(hisi_hba, phy_no);
					hisi_sas_phy_write32(hisi_hba, phy_no,
						CHL_INT2,
			hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
					     BIT(CHL_INT2_RX_INVLD_DW_OFF));
					hisi_sas_phy_read32(hisi_hba, phy_no,
						ERR_CNT_INVLD_DW);
			hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW);
			mdelay(1);
			enable_phy_v3_hw(hisi_hba, phy_no);
		}
	}
}

static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
{
	struct hisi_hba *hisi_hba = p;
	u32 irq_msk;
	int phy_no = 0;

	irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS)
				& 0xeeeeeeee;

	while (irq_msk) {
		u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
						     CHL_INT0);

		if (irq_msk & (4 << (phy_no * 4)))
			handle_chl_int1_v3_hw(hisi_hba, phy_no);

		if (irq_msk & (8 << (phy_no * 4)))
			handle_chl_int2_v3_hw(hisi_hba, phy_no);

		if (irq_msk & (2 << (phy_no * 4)) && irq_value0) {
			hisi_sas_phy_write32(hisi_hba, phy_no,
					CHL_INT0, irq_value0