From patchwork Mon Oct 12 15:20:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 54775 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f197.google.com (mail-wi0-f197.google.com [209.85.212.197]) by patches.linaro.org (Postfix) with ESMTPS id 6897F23001 for ; Mon, 12 Oct 2015 15:05:38 +0000 (UTC) Received: by wicid10 with SMTP id id10sf11090963wic.2 for ; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=937RrODzHnAcsx3EmyZ5NMRxruVpQBhWqleJmIiwk4Q=; b=LArojymubAjoRBi2kKAJPOoMQpJvvsvVJ87LtTtfiy0TTECmsmGTTWdP8/nqOR24Ik ddWDXWAm14oBdKa5hmd9348pM7Cxglx9Y1mXzimwNU/liK8IJVu203Tjbiq7lHEs56Rx cEFY9lWM+K+II0Kj84uIujpIAdlTA1/PqIfLWkXurEp0H6X3usOnLvJ/lUDwgF8l6crQ aHWvorNd+02WHRbMlp/yCN0JvDk/NIKFJ8jt+LYeVf1FjDogL6Iq80/cIcc7n0OZ57Kf wXk6XnbcOm+Zt1dszXcj8l9fTsKJ6mJ2++tcd3ewQ3mqn/1dm9hArF2RVlJgY+kzesb7 zLUg== X-Gm-Message-State: ALoCoQkNhbIJkNSfAvCiFoUebCZ2xP5BDd+VeDOKv1Rw9CEkV44qlX9ksJN6OJwFeuPJbjDmqz8O X-Received: by 10.194.83.169 with SMTP id r9mr5786371wjy.6.1444662337670; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.151.79 with SMTP id z76ls490205lfd.104.gmail; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) X-Received: by 10.25.154.5 with SMTP id c5mr8484382lfe.103.1444662337447; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com. [209.85.217.174]) by mx.google.com with ESMTPS id q201si11511224lfd.144.2015.10.12.08.05.37 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Oct 2015 08:05:37 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) client-ip=209.85.217.174; Received: by lbbck17 with SMTP id ck17so25743931lbb.1 for ; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) X-Received: by 10.25.82.10 with SMTP id g10mr8526590lfb.56.1444662337329; Mon, 12 Oct 2015 08:05:37 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp1599238lbq; Mon, 12 Oct 2015 08:05:36 -0700 (PDT) X-Received: by 10.50.117.97 with SMTP id kd1mr12413405igb.42.1444662332032; Mon, 12 Oct 2015 08:05:32 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l8si803654igx.37.2015.10.12.08.05.31 for ; Mon, 12 Oct 2015 08:05:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-scsi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752054AbbJLPFa (ORCPT ); Mon, 12 Oct 2015 11:05:30 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:11743 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751616AbbJLPF2 (ORCPT ); Mon, 12 Oct 2015 11:05:28 -0400 Received: from 172.24.1.49 (EHLO szxeml432-hub.china.huawei.com) ([172.24.1.49]) by szxrg02-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id CUB61540; Mon, 12 Oct 2015 23:05:19 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by szxeml432-hub.china.huawei.com (10.82.67.209) with Microsoft SMTP Server id 14.3.235.1; Mon, 12 Oct 2015 23:05:05 +0800 From: John Garry To: CC: , , , , , , , , , John Garry Subject: [PATCH 23/25] scsi: hisi_sas: add control phy handler Date: Mon, 12 Oct 2015 23:20:35 +0800 Message-ID: <1444663237-238302-24-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1444663237-238302-1-git-send-email-john.garry@huawei.com> References: <1444663237-238302-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: linux-scsi-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.garry@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.174 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add method for lldd_control_phy. Currently link rate control and spinup hold is unsupported. Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 7 ++++ drivers/scsi/hisi_sas/hisi_sas_init.c | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 64 ++++++++++++++++++++++++++++++++++ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 22 ++++++++++++ 4 files changed, 94 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index b488fe3..be91b8c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -133,6 +133,7 @@ struct hisi_sas_tei { }; enum hisi_sas_wq_event { + CONTROL_PHY, PHYUP, }; @@ -360,6 +361,9 @@ void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int i); int hisi_sas_dev_found(struct domain_device *dev); void hisi_sas_dev_gone(struct domain_device *dev); int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags); +int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, + enum phy_func func, + void *funcdata); int hisi_sas_abort_task(struct sas_task *task); int hisi_sas_abort_task_set(struct domain_device *dev, u8 *lun); int hisi_sas_clear_aca(struct domain_device *dev, u8 *lun); @@ -375,6 +379,7 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot); /* hw specific functions */ +extern void hard_phy_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no); extern int slot_complete_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot, int abort); @@ -392,8 +397,10 @@ extern int interrupt_openall_v1_hw(struct hisi_hba *hisi_hba); extern int hw_init_v1_hw(struct hisi_hba *hisi_hba); extern int free_device_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_device *dev); +extern void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no); extern int phys_init_v1_hw(struct hisi_hba *hisi_hba); extern void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int phy_no); extern void setup_itct_v1_hw(struct hisi_hba *hisi_hba, struct hisi_sas_device *device); +extern void disable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_init.c b/drivers/scsi/hisi_sas/hisi_sas_init.c index b6272d8..af4d613e1 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_init.c +++ b/drivers/scsi/hisi_sas/hisi_sas_init.c @@ -38,6 +38,7 @@ static struct sas_domain_function_template hisi_sas_transport_ops = { .lldd_dev_found = hisi_sas_dev_found, .lldd_dev_gone = hisi_sas_dev_gone, .lldd_execute_task = hisi_sas_queue_command, + .lldd_control_phy = hisi_sas_control_phy, .lldd_abort_task = hisi_sas_abort_task, .lldd_abort_task_set = hisi_sas_abort_task_set, .lldd_clear_aca = hisi_sas_clear_aca, diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 12af29c..1e42611 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -472,6 +472,32 @@ int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time) return 1; } +static void hisi_sas_control_phy_work(struct hisi_hba *hisi_hba, + int func, + int phy_no) +{ + struct device *dev = &hisi_hba->pdev->dev; + + switch (func) { + case PHY_FUNC_HARD_RESET: + hard_phy_reset_v1_hw(hisi_hba, phy_no); + break; + + case PHY_FUNC_LINK_RESET: + enable_phy_v1_hw(hisi_hba, phy_no); + hard_phy_reset_v1_hw(hisi_hba, phy_no); + break; + + case PHY_FUNC_DISABLE: + disable_phy_v1_hw(hisi_hba, phy_no); + break; + + case PHY_FUNC_SET_LINK_RATE: + case PHY_FUNC_RELEASE_SPINUP_HOLD: + default: + dev_err(dev, "Control phy func %d unsupported\n", func); + } +} static void hisi_sas_phyup_work(struct hisi_hba *hisi_hba, int phy_no) @@ -487,8 +513,12 @@ void hisi_sas_wq_process(struct work_struct *work) struct hisi_hba *hisi_hba = wq->hisi_hba; int event = wq->event; int phy_no = wq->phy_no; + int func = wq->data; switch (event) { + case CONTROL_PHY: + hisi_sas_control_phy_work(hisi_hba, func, phy_no); + break; case PHYUP: hisi_sas_phyup_work(hisi_hba, phy_no); break; @@ -681,6 +711,40 @@ int hisi_sas_queue_command(struct sas_task *task, gfp_t gfp_flags) return hisi_sas_task_exec(task, gfp_flags, NULL, 0, NULL); } +int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, + enum phy_func func, + void *funcdata) +{ + struct sas_ha_struct *sas_ha = sas_phy->ha; + struct hisi_hba *hisi_hba = NULL; + struct hisi_sas_phy *phy = NULL; + int phy_no = 0; + struct hisi_sas_wq *wq = kmalloc(sizeof(*wq), GFP_ATOMIC); + + if (!wq) + return -ENOMEM; + + while (sas_ha->sas_phy[phy_no]) { + if (sas_ha->sas_phy[phy_no] == sas_phy) { + hisi_hba = (struct hisi_hba *)sas_ha->lldd_ha; + break; + } + phy_no++; + } + + phy = &hisi_hba->phy[phy_no]; + + wq->event = CONTROL_PHY; + wq->data = func; + wq->hisi_hba = hisi_hba; + wq->phy_no = phy_no; + + INIT_WORK(&wq->work_struct, hisi_sas_wq_process); + + queue_work(hisi_hba->wq, &wq->work_struct); + + return 0; +} static void hisi_sas_task_done(struct sas_task *task) { diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index b470c72..b5ba46a 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -766,6 +766,13 @@ void enable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); } +void disable_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); + + cfg &= ~PHY_CFG_ENA_MSK; + hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); +} static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) { @@ -775,6 +782,21 @@ static void start_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) enable_phy_v1_hw(hisi_hba, phy_no); } +static void stop_phy_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + disable_phy_v1_hw(hisi_hba, phy_no); +} + +void hard_phy_reset_v1_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + struct sas_ha_struct *sha = &hisi_hba->sha; + + stop_phy_v1_hw(hisi_hba, phy_no); + sas_drain_work(sha); + msleep(100); + start_phy_v1_hw(hisi_hba, phy_no); +} + static void start_phys_v1_hw(unsigned long data) { struct hisi_hba *hisi_hba = (struct hisi_hba *)data;