@@ -3302,6 +3302,28 @@ static irq_handler_t fatal_interrupts[HISI_SAS_FATAL_INT_NR] = {
3302
3302
fatal_axi_int_v2_hw
3303
3303
};
3304
3304
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
+
3305
3327
/*
3306
3328
* There is a limitation in the hip06 chipset that we need
3307
3329
* 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)
3310
3332
{
3311
3333
struct platform_device * pdev = hisi_hba -> platform_dev ;
3312
3334
struct device * dev = & pdev -> dev ;
3313
- int irq , rc = 0 , irq_map [ 128 ] ;
3335
+ int irq , rc = 0 ;
3314
3336
int i , phy_no , fatal_no , queue_no ;
3315
3337
3316
- for (i = 0 ; i < 128 ; i ++ )
3317
- irq_map [i ] = platform_get_irq (pdev , i );
3318
-
3319
3338
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 */
3321
3340
rc = devm_request_irq (dev , irq , phy_interrupts [i ], 0 ,
3322
3341
DRV_NAME " phy" , hisi_hba );
3323
3342
if (rc ) {
@@ -3331,7 +3350,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
3331
3350
for (phy_no = 0 ; phy_no < hisi_hba -> n_phy ; phy_no ++ ) {
3332
3351
struct hisi_sas_phy * phy = & hisi_hba -> phy [phy_no ];
3333
3352
3334
- irq = irq_map [phy_no + 72 ];
3353
+ irq = hisi_hba -> irq_map [phy_no + 72 ];
3335
3354
rc = devm_request_irq (dev , irq , sata_int_v2_hw , 0 ,
3336
3355
DRV_NAME " sata" , phy );
3337
3356
if (rc ) {
@@ -3343,7 +3362,7 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
3343
3362
}
3344
3363
3345
3364
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 ];
3347
3366
rc = devm_request_irq (dev , irq , fatal_interrupts [fatal_no ], 0 ,
3348
3367
DRV_NAME " fatal" , hisi_hba );
3349
3368
if (rc ) {
@@ -3354,24 +3373,22 @@ static int interrupt_init_v2_hw(struct hisi_hba *hisi_hba)
3354
3373
}
3355
3374
}
3356
3375
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 ++ ) {
3358
3377
struct hisi_sas_cq * cq = & hisi_hba -> cq [queue_no ];
3359
3378
3360
- cq -> irq_no = irq_map [queue_no + 96 ];
3379
+ cq -> irq_no = hisi_hba -> irq_map [queue_no + 96 ];
3361
3380
rc = devm_request_threaded_irq (dev , cq -> irq_no ,
3362
3381
cq_interrupt_v2_hw ,
3363
3382
cq_thread_v2_hw , IRQF_ONESHOT ,
3364
3383
DRV_NAME " cq" , cq );
3365
3384
if (rc ) {
3366
3385
dev_err (dev , "irq init: could not request cq interrupt %d, rc=%d\n" ,
3367
- irq , rc );
3386
+ cq -> irq_no , rc );
3368
3387
rc = - ENOENT ;
3369
3388
goto err_out ;
3370
3389
}
3390
+ cq -> irq_mask = irq_get_affinity_mask (cq -> irq_no );
3371
3391
}
3372
-
3373
- hisi_hba -> cq_nvecs = hisi_hba -> queue_count ;
3374
-
3375
3392
err_out :
3376
3393
return rc ;
3377
3394
}
@@ -3529,6 +3546,26 @@ static struct device_attribute *host_attrs_v2_hw[] = {
3529
3546
NULL
3530
3547
};
3531
3548
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
+
3532
3569
static struct scsi_host_template sht_v2_hw = {
3533
3570
.name = DRV_NAME ,
3534
3571
.proc_name = DRV_NAME ,
@@ -3553,10 +3590,13 @@ static struct scsi_host_template sht_v2_hw = {
3553
3590
#endif
3554
3591
.shost_attrs = host_attrs_v2_hw ,
3555
3592
.host_reset = hisi_sas_host_reset ,
3593
+ .map_queues = map_queues_v2_hw ,
3594
+ .host_tagset = 1 ,
3556
3595
};
3557
3596
3558
3597
static const struct hisi_sas_hw hisi_sas_v2_hw = {
3559
3598
.hw_init = hisi_sas_v2_init ,
3599
+ .interrupt_preinit = hisi_sas_v2_interrupt_preinit ,
3560
3600
.setup_itct = setup_itct_v2_hw ,
3561
3601
.slot_index_alloc = slot_index_alloc_quirk_v2_hw ,
3562
3602
.alloc_dev = alloc_dev_quirk_v2_hw ,
0 commit comments