@@ -3302,6 +3302,28 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = {
33023302 fatal_axi_int_v2_hw
33033303};
33043304
3305+ #define CQ0_IRQ_INDEX (96)
3306+
3307+ static int hisi_sas_v2_interrupt_preinit (struct hisi_hba * hisi_hba )
3308+ {
3309+ struct platform_device * pdev = hisi_hba -> platform_dev ;
3310+ struct Scsi_Host * shost = hisi_hba -> shost ;
3311+ struct irq_affinity desc = {
3312+ .pre_vectors = CQ0_IRQ_INDEX ,
3313+ .post_vectors = 16 ,
3314+ };
3315+ int resv = desc .pre_vectors + desc .post_vectors , minvec = resv + 1 , nvec ;
3316+
3317+ nvec = devm_platform_get_irqs_affinity (pdev , & desc , minvec , 128 ,
3318+ & hisi_hba -> irq_map );
3319+ if (nvec < 0 )
3320+ return nvec ;
3321+
3322+ shost -> nr_hw_queues = hisi_hba -> cq_nvecs = nvec - resv ;
3323+
3324+ return 0 ;
3325+ }
3326+
33053327/*
33063328 * There is a limitation in the hip06 chipset that we need
33073329 * to map in all mbigen interrupts, even if they are not used.
@@ -3310,14 +3332,11 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33103332{
33113333 struct platform_device * pdev = hisi_hba -> platform_dev ;
33123334 struct device * dev = & pdev -> dev ;
3313- int irq , rc = 0 , irq_map [ 128 ] ;
3335+ int irq , rc = 0 ;
33143336 int i , phy_no , fatal_no , queue_no ;
33153337
3316- for (i = 0 ; i < 128 ; i ++ )
3317- irq_map [i ] = platform_get_irq (pdev , i );
3318-
33193338 for (i = 0 ; i < HISI_SAS_PHY_INT_NR ; i ++ ) {
3320- irq = irq_map [i + 1 ]; /* Phy up/down is irq1 */
3339+ irq = hisi_hba -> irq_map [i + 1 ]; /* Phy up/down is irq1 */
33213340 rc = devm_request_irq (dev , irq , phy_interrupts [i ], 0 ,
33223341 DRV_NAME " phy" , hisi_hba );
33233342 if (rc ) {
@@ -3331,7 +3350,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33313350 for (phy_no = 0 ; phy_no < hisi_hba -> n_phy ; phy_no ++ ) {
33323351 struct hisi_sas_phy * phy = & hisi_hba -> phy [phy_no ];
33333352
3334- irq = irq_map [phy_no + 72 ];
3353+ irq = hisi_hba -> irq_map [phy_no + 72 ];
33353354 rc = devm_request_irq (dev , irq , sata_int_v2_hw , 0 ,
33363355 DRV_NAME " sata" , phy );
33373356 if (rc ) {
@@ -3343,7 +3362,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33433362 }
33443363
33453364 for (fatal_no = 0 ; fatal_no < HISI_SAS_FATAL_INT_NR ; fatal_no ++ ) {
3346- irq = irq_map [fatal_no + 81 ];
3365+ irq = hisi_hba -> irq_map [fatal_no + 81 ];
33473366 rc = devm_request_irq (dev , irq , fatal_interrupts [fatal_no ], 0 ,
33483367 DRV_NAME " fatal" , hisi_hba );
33493368 if (rc ) {
@@ -3354,24 +3373,22 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
33543373 }
33553374 }
33563375
3357- for (queue_no = 0 ; queue_no < hisi_hba -> queue_count ; queue_no ++ ) {
3376+ for (queue_no = 0 ; queue_no < hisi_hba -> cq_nvecs ; queue_no ++ ) {
33583377 struct hisi_sas_cq * cq = & hisi_hba -> cq [queue_no ];
33593378
3360- cq -> irq_no = irq_map [queue_no + 96 ];
3379+ cq -> irq_no = hisi_hba -> irq_map [queue_no + 96 ];
33613380 rc = devm_request_threaded_irq (dev , cq -> irq_no ,
33623381 cq_interrupt_v2_hw ,
33633382 cq_thread_v2_hw , IRQF_ONESHOT ,
33643383 DRV_NAME " cq" , cq );
33653384 if (rc ) {
33663385 dev_err (dev , "irq init: could not request cq interrupt %d, rc=%d\n" ,
3367- irq , rc );
3386+ cq -> irq_no , rc );
33683387 rc = - ENOENT ;
33693388 goto err_out ;
33703389 }
3390+ cq -> irq_mask = irq_get_affinity_mask (cq -> irq_no );
33713391 }
3372-
3373- hisi_hba -> cq_nvecs = hisi_hba -> queue_count ;
3374-
33753392err_out :
33763393 return rc ;
33773394}
@@ -3529,6 +3546,26 @@ static struct device_attribute *host_attrs_v2_hw[] = {
35293546 NULL
35303547};
35313548
3549+ static int map_queues_v2_hw (struct Scsi_Host * shost )
3550+ {
3551+ struct hisi_hba * hisi_hba = shost_priv (shost );
3552+ struct blk_mq_queue_map * qmap = & shost -> tag_set .map [HCTX_TYPE_DEFAULT ];
3553+ const struct cpumask * mask ;
3554+ unsigned int queue , cpu ;
3555+
3556+ for (queue = 0 ; queue < qmap -> nr_queues ; queue ++ ) {
3557+ mask = irq_get_affinity_mask (hisi_hba -> irq_map [96 + queue ]);
3558+ if (!mask )
3559+ continue ;
3560+
3561+ for_each_cpu (cpu , mask )
3562+ qmap -> mq_map [cpu ] = qmap -> queue_offset + queue ;
3563+ }
3564+
3565+ return 0 ;
3566+
3567+ }
3568+
35323569static struct scsi_host_template sht_v2_hw = {
35333570 .name = DRV_NAME ,
35343571 .proc_name = DRV_NAME ,
@@ -3553,10 +3590,13 @@ static struct scsi_host_template sht_v2_hw = {
35533590#endif
35543591 .shost_attrs = host_attrs_v2_hw ,
35553592 .host_reset = hisi_sas_host_reset ,
3593+ .map_queues = map_queues_v2_hw ,
3594+ .host_tagset = 1 ,
35563595};
35573596
35583597static const struct hisi_sas_hw hisi_sas_v2_hw = {
35593598 .hw_init = hisi_sas_v2_init ,
3599+ .interrupt_preinit = hisi_sas_v2_interrupt_preinit ,
35603600 .setup_itct = setup_itct_v2_hw ,
35613601 .slot_index_alloc = slot_index_alloc_quirk_v2_hw ,
35623602 .alloc_dev = alloc_dev_quirk_v2_hw ,
0 commit comments