diff options
| -rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_main.c | 20 | ||||
| -rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 39 |
3 files changed, 62 insertions, 0 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 4000de429430..e7fd2877c19c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h | |||
| @@ -244,6 +244,8 @@ struct hisi_sas_hw { | |||
| 244 | struct domain_device *device); | 244 | struct domain_device *device); |
| 245 | int (*soft_reset)(struct hisi_hba *hisi_hba); | 245 | int (*soft_reset)(struct hisi_hba *hisi_hba); |
| 246 | u32 (*get_phys_state)(struct hisi_hba *hisi_hba); | 246 | u32 (*get_phys_state)(struct hisi_hba *hisi_hba); |
| 247 | int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type, | ||
| 248 | u8 reg_index, u8 reg_count, u8 *write_data); | ||
| 247 | int max_command_entries; | 249 | int max_command_entries; |
| 248 | int complete_hdr_size; | 250 | int complete_hdr_size; |
| 249 | }; | 251 | }; |
| @@ -257,6 +259,7 @@ struct hisi_hba { | |||
| 257 | struct device *dev; | 259 | struct device *dev; |
| 258 | 260 | ||
| 259 | void __iomem *regs; | 261 | void __iomem *regs; |
| 262 | void __iomem *sgpio_regs; | ||
| 260 | struct regmap *ctrl; | 263 | struct regmap *ctrl; |
| 261 | u32 ctrl_reset_reg; | 264 | u32 ctrl_reset_reg; |
| 262 | u32 ctrl_reset_sts_reg; | 265 | u32 ctrl_reset_sts_reg; |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index e3e7285f5eb1..791462d7fbfc 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c | |||
| @@ -1634,6 +1634,18 @@ static void hisi_sas_port_deformed(struct asd_sas_phy *sas_phy) | |||
| 1634 | { | 1634 | { |
| 1635 | } | 1635 | } |
| 1636 | 1636 | ||
| 1637 | static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type, | ||
| 1638 | u8 reg_index, u8 reg_count, u8 *write_data) | ||
| 1639 | { | ||
| 1640 | struct hisi_hba *hisi_hba = sha->lldd_ha; | ||
| 1641 | |||
| 1642 | if (!hisi_hba->hw->write_gpio) | ||
| 1643 | return -EOPNOTSUPP; | ||
| 1644 | |||
| 1645 | return hisi_hba->hw->write_gpio(hisi_hba, reg_type, | ||
| 1646 | reg_index, reg_count, write_data); | ||
| 1647 | } | ||
| 1648 | |||
| 1637 | static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) | 1649 | static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy) |
| 1638 | { | 1650 | { |
| 1639 | phy->phy_attached = 0; | 1651 | phy->phy_attached = 0; |
| @@ -1731,6 +1743,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { | |||
| 1731 | .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha, | 1743 | .lldd_clear_nexus_ha = hisi_sas_clear_nexus_ha, |
| 1732 | .lldd_port_formed = hisi_sas_port_formed, | 1744 | .lldd_port_formed = hisi_sas_port_formed, |
| 1733 | .lldd_port_deformed = hisi_sas_port_deformed, | 1745 | .lldd_port_deformed = hisi_sas_port_deformed, |
| 1746 | .lldd_write_gpio = hisi_sas_write_gpio, | ||
| 1734 | }; | 1747 | }; |
| 1735 | 1748 | ||
| 1736 | void hisi_sas_init_mem(struct hisi_hba *hisi_hba) | 1749 | void hisi_sas_init_mem(struct hisi_hba *hisi_hba) |
| @@ -2055,6 +2068,13 @@ static struct Scsi_Host *hisi_sas_shost_alloc(struct platform_device *pdev, | |||
| 2055 | if (IS_ERR(hisi_hba->regs)) | 2068 | if (IS_ERR(hisi_hba->regs)) |
| 2056 | goto err_out; | 2069 | goto err_out; |
| 2057 | 2070 | ||
| 2071 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 2072 | if (res) { | ||
| 2073 | hisi_hba->sgpio_regs = devm_ioremap_resource(dev, res); | ||
| 2074 | if (IS_ERR(hisi_hba->sgpio_regs)) | ||
| 2075 | goto err_out; | ||
| 2076 | } | ||
| 2077 | |||
| 2058 | if (hisi_sas_alloc(hisi_hba, shost)) { | 2078 | if (hisi_sas_alloc(hisi_hba, shost)) { |
| 2059 | hisi_sas_free(hisi_hba); | 2079 | hisi_sas_free(hisi_hba); |
| 2060 | goto err_out; | 2080 | goto err_out; |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index ebee2e463245..4ccb61e2ae5c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | |||
| @@ -3474,6 +3474,44 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba) | |||
| 3474 | return 0; | 3474 | return 0; |
| 3475 | } | 3475 | } |
| 3476 | 3476 | ||
| 3477 | static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type, | ||
| 3478 | u8 reg_index, u8 reg_count, u8 *write_data) | ||
| 3479 | { | ||
| 3480 | struct device *dev = hisi_hba->dev; | ||
| 3481 | int phy_no, count; | ||
| 3482 | |||
| 3483 | if (!hisi_hba->sgpio_regs) | ||
| 3484 | return -EOPNOTSUPP; | ||
| 3485 | |||
| 3486 | switch (reg_type) { | ||
| 3487 | case SAS_GPIO_REG_TX: | ||
| 3488 | count = reg_count * 4; | ||
| 3489 | count = min(count, hisi_hba->n_phy); | ||
| 3490 | |||
| 3491 | for (phy_no = 0; phy_no < count; phy_no++) { | ||
| 3492 | /* | ||
| 3493 | * GPIO_TX[n] register has the highest numbered drive | ||
| 3494 | * of the four in the first byte and the lowest | ||
| 3495 | * numbered drive in the fourth byte. | ||
| 3496 | * See SFF-8485 Rev. 0.7 Table 24. | ||
| 3497 | */ | ||
| 3498 | void __iomem *reg_addr = hisi_hba->sgpio_regs + | ||
| 3499 | reg_index * 4 + phy_no; | ||
| 3500 | int data_idx = phy_no + 3 - (phy_no % 4) * 2; | ||
| 3501 | |||
| 3502 | writeb(write_data[data_idx], reg_addr); | ||
| 3503 | } | ||
| 3504 | |||
| 3505 | break; | ||
| 3506 | default: | ||
| 3507 | dev_err(dev, "write gpio: unsupported or bad reg type %d\n", | ||
| 3508 | reg_type); | ||
| 3509 | return -EINVAL; | ||
| 3510 | } | ||
| 3511 | |||
| 3512 | return 0; | ||
| 3513 | } | ||
| 3514 | |||
| 3477 | static const struct hisi_sas_hw hisi_sas_v2_hw = { | 3515 | static const struct hisi_sas_hw hisi_sas_v2_hw = { |
| 3478 | .hw_init = hisi_sas_v2_init, | 3516 | .hw_init = hisi_sas_v2_init, |
| 3479 | .setup_itct = setup_itct_v2_hw, | 3517 | .setup_itct = setup_itct_v2_hw, |
| @@ -3501,6 +3539,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = { | |||
| 3501 | .complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr), | 3539 | .complete_hdr_size = sizeof(struct hisi_sas_complete_v2_hdr), |
| 3502 | .soft_reset = soft_reset_v2_hw, | 3540 | .soft_reset = soft_reset_v2_hw, |
| 3503 | .get_phys_state = get_phys_state_v2_hw, | 3541 | .get_phys_state = get_phys_state_v2_hw, |
| 3542 | .write_gpio = write_gpio_v2_hw, | ||
| 3504 | }; | 3543 | }; |
| 3505 | 3544 | ||
| 3506 | static int hisi_sas_v2_probe(struct platform_device *pdev) | 3545 | static int hisi_sas_v2_probe(struct platform_device *pdev) |
