From patchwork Mon Sep 8 10:09:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kiran Kumar Raparthy X-Patchwork-Id: 36953 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f72.google.com (mail-yh0-f72.google.com [209.85.213.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1E7552054D for ; Mon, 8 Sep 2014 10:10:23 +0000 (UTC) Received: by mail-yh0-f72.google.com with SMTP id f73sf1218792yha.11 for ; Mon, 08 Sep 2014 03:10:22 -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 :mime-version:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=3s9K+EmiV83Z3Js3cgAfkg6/6uEHqJZOxrjrBjUcSsM=; b=lzgwbHXKNvZO55nk1TAqnIHrzX3kCmP90+hl5s/S6hIihpDrVbc6HOFAJ3jgOTOebT GeXGCHoVqNhGH0UV4HDUk1r9EbnCxM7l4NHTHIwnlPMBan+Ky8rWjFuasD2Y6H9rCvFD 1xEoCXD9ZsbTX8zrDSyzSBiW+d1VNkTkuCtN0g5lXT0gv4VEPWf5X8bhSdWfifqNEHYP RTdBm9BlBds4jr6BL9nQlNPG6aM8U1YRlOEB3fGtSnPqzbot2xwkAHakFiUL5gs/O5e0 J1ZefllgljKT441IgYjCniH2Jl4BJn45cI8QsLChGMSdkke7H42dA198ysvtA2v8Jani wdZA== X-Gm-Message-State: ALoCoQma2+hVSHPV8TOO7ZDTtyS6Yw+Jg0vTbint+Cdx8B1JhlJoSvHSUqr4Oexhk53AWo1d1R/S X-Received: by 10.236.148.2 with SMTP id u2mr155313yhj.55.1410171022935; Mon, 08 Sep 2014 03:10:22 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.34.99 with SMTP id k90ls1662656qgk.78.gmail; Mon, 08 Sep 2014 03:10:22 -0700 (PDT) X-Received: by 10.52.255.232 with SMTP id at8mr20679555vdd.4.1410171022831; Mon, 08 Sep 2014 03:10:22 -0700 (PDT) Received: from mail-vc0-f180.google.com (mail-vc0-f180.google.com [209.85.220.180]) by mx.google.com with ESMTPS id dp8si3726555vcb.12.2014.09.08.03.10.22 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 08 Sep 2014 03:10:22 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.180 as permitted sender) client-ip=209.85.220.180; Received: by mail-vc0-f180.google.com with SMTP id lf12so14644316vcb.25 for ; Mon, 08 Sep 2014 03:10:22 -0700 (PDT) X-Received: by 10.52.185.193 with SMTP id fe1mr8310816vdc.31.1410171022673; Mon, 08 Sep 2014 03:10:22 -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.221.45.67 with SMTP id uj3csp109191vcb; Mon, 8 Sep 2014 03:10:22 -0700 (PDT) X-Received: by 10.70.9.129 with SMTP id z1mr44915707pda.37.1410171021654; Mon, 08 Sep 2014 03:10:21 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id py9si16723830pac.208.2014.09.08.03.10.21 for ; Mon, 08 Sep 2014 03:10:21 -0700 (PDT) Received-SPF: none (google.com: linux-usb-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753051AbaIHKKT (ORCPT + 2 others); Mon, 8 Sep 2014 06:10:19 -0400 Received: from mail-pa0-f42.google.com ([209.85.220.42]:37383 "EHLO mail-pa0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752421AbaIHKKR (ORCPT ); Mon, 8 Sep 2014 06:10:17 -0400 Received: by mail-pa0-f42.google.com with SMTP id lj1so1485911pab.15 for ; Mon, 08 Sep 2014 03:10:17 -0700 (PDT) X-Received: by 10.68.215.67 with SMTP id og3mr18677349pbc.30.1410171017153; Mon, 08 Sep 2014 03:10:17 -0700 (PDT) Received: from c-krapar-linux.qualcomm.com ([202.46.23.54]) by mx.google.com with ESMTPSA id y9sm9066711pas.23.2014.09.08.03.10.13 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 08 Sep 2014 03:10:16 -0700 (PDT) From: Kiran Kumar Raparthy To: linux-kernel@vger.kernel.org Cc: Todd Poynor , Felipe Balbi , Greg Kroah-Hartman , linux-usb@vger.kernel.org, Android Kernel Team , John Stultz , Sumit Semwal , =?UTF-8?q?Arve=20Hj=F8nnev=E5g?= , Benoit Goby , Kiran Raparthy Subject: [RFC v3 1/2] usb: phy: Hold wakeupsource when USB is enumerated in peripheral mode Date: Mon, 8 Sep 2014 15:39:23 +0530 Message-Id: <1410170963-14182-1-git-send-email-kiran.kumar@linaro.org> X-Mailer: git-send-email 1.8.2.1 MIME-Version: 1.0 Sender: linux-usb-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: kiran.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.180 as permitted sender) smtp.mail=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: , From: Todd Poynor usb: phy: Hold wakeupsource when USB is enumerated in peripheral mode Purpose of this is to prevent the system to enter into suspend state from USB peripheral traffic by hodling a wakeupsource when USB is connected and enumerated in peripheral mode(say adb). Disabled by default, can enable with: echo Y > /sys/module/otg_wakeupsource/parameters/enabled Cc: Felipe Balbi Cc: Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org Cc: linux-usb@vger.kernel.org Cc: Android Kernel Team Cc: John Stultz Cc: Sumit Semwal Cc: Arve Hjřnnevĺg Cc: Benoit Goby Signed-off-by: Todd Poynor [kiran: Added context to commit message, squished build fixes from Benoit Goby and Arve Hjřnnevĺg, changed wakelocks usage to wakeupsource, merged Todd's refactoring logic and simplified the structures and code and addressed community feedback] Signed-off-by: Kiran Raparthy --- v3: * As per the feedback,no global phy pointer used. * called the one-liner wakeupsource handling calls directly instead of indirect functions implemented in v2. * Removed indirect function get_phy_hook and used usb_get_phy to get the phy handle.. v2: * wakeupsource handling implemeted per-PHY * Implemented wakeupsource handling calls in phy * included Todd's refactoring logic. v1: * changed to "disabled by default" from "enable by default". * Kconfig help text modified * Included better commit text * otgws_nb moved to otg_wakeupsource_init function * Introduced get_phy_hook to handle otgws_xceiv per-PHY RFC: * Included build fix from Benoit Goby and Arve Hjřnnevĺg * Removed lock->held field in driver as this mechanism is provided in wakeupsource driver. * wakelock(wl) terminology replaced with wakeup_source(ws). drivers/usb/phy/Kconfig | 8 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/otg-wakeupsource.c | 136 +++++++++++++++++++++++++++++++++++++ include/linux/usb/phy.h | 4 ++ 4 files changed, 149 insertions(+) create mode 100644 drivers/usb/phy/otg-wakeupsource.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index e253fa0..d9ddd85 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -6,6 +6,14 @@ menu "USB Physical Layer drivers" config USB_PHY def_bool n +config USB_OTG_WAKEUPSOURCE + bool "Hold wakeupsource when USB is enumerated in peripheral mode" + depends on PM_SLEEP + select USB_PHY + help + Prevent the system going into automatic suspend while + it is attached as a USB peripheral by holding a wakeupsource. + # # USB Transceiver Drivers # diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 24a9133..ca2fbaf 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_USB_PHY) += phy.o obj-$(CONFIG_OF) += of.o +obj-$(CONFIG_USB_OTG_WAKEUPSOURCE) += otg-wakeupsource.o # transceiver drivers, keep the list sorted diff --git a/drivers/usb/phy/otg-wakeupsource.c b/drivers/usb/phy/otg-wakeupsource.c new file mode 100644 index 0000000..d9a1720 --- /dev/null +++ b/drivers/usb/phy/otg-wakeupsource.c @@ -0,0 +1,136 @@ +/* + * otg-wakeupsource.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +bool enabled = false; + +static DEFINE_SPINLOCK(otgws_spinlock); + +static void otgws_handle_event(struct usb_phy *otgws_xceiv, unsigned long event) +{ + unsigned long irqflags; + + spin_lock_irqsave(&otgws_spinlock, irqflags); + + if (!enabled) { + __pm_relax(&otgws_xceiv->wsource); + spin_unlock_irqrestore(&otgws_spinlock, irqflags); + return; + } + + switch (event) { + case USB_EVENT_VBUS: + case USB_EVENT_ENUMERATED: + __pm_stay_awake(&otgws_xceiv->wsource); + break; + + case USB_EVENT_NONE: + case USB_EVENT_ID: + case USB_EVENT_CHARGER: + __pm_relax(&otgws_xceiv->wsource); + break; + + default: + break; + } + + spin_unlock_irqrestore(&otgws_spinlock, irqflags); +} + +static int otgws_otg_notifications(struct notifier_block *nb, + unsigned long event, void *unused) +{ + static struct usb_phy *otgws_xceiv; + + otgws_xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(otgws_xceiv)) { + pr_err("%s: No OTG transceiver found\n", __func__); + return PTR_ERR(otgws_xceiv); + } + + otgws_handle_event(otgws_xceiv, event); + + return NOTIFY_OK; +} + +static int set_enabled(const char *val, const struct kernel_param *kp) +{ + int rv = param_set_bool(val, kp); + static struct usb_phy *otgws_xceiv; + + if (rv) + return rv; + + otgws_xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(otgws_xceiv)) { + pr_err("%s: No OTG transceiver found\n", __func__); + return PTR_ERR(otgws_xceiv); + } + + otgws_handle_event(otgws_xceiv, otgws_xceiv->last_event); + + return 0; +} + +static struct kernel_param_ops enabled_param_ops = { + .set = set_enabled, + .get = param_get_bool, +}; + +module_param_cb(enabled, &enabled_param_ops, &enabled, 0644); +MODULE_PARM_DESC(enabled, "Hold wakeupsource when VBUS present"); + +static int __init otg_wakeupsource_init(void) +{ + int ret; + char wsource_name[40]; + static struct usb_phy *otgws_xceiv; + + otgws_xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(otgws_xceiv)) { + pr_err("%s: No OTG transceiver found\n", __func__); + return PTR_ERR(otgws_xceiv); + } + + snprintf(wsource_name, sizeof(wsource_name), "vbus-%s", + dev_name(otgws_xceiv->dev)); + wakeup_source_init(&otgws_xceiv->wsource, wsource_name); + + otgws_xceiv->otgws_nb.notifier_call = otgws_otg_notifications; + ret = usb_register_notifier(otgws_xceiv, &otgws_xceiv->otgws_nb); + + if (ret) { + pr_err("%s: usb_register_notifier on transceiver %s failed\n", + __func__, dev_name(otgws_xceiv->dev)); + wakeup_source_trash(&otgws_xceiv->wsource); + otgws_xceiv = NULL; + return ret; + } + + return 0; +} + +late_initcall(otg_wakeupsource_init); diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 353053a..c71cf15 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -88,6 +88,10 @@ struct usb_phy { /* for notification of usb_phy_events */ struct atomic_notifier_head notifier; + struct notifier_block otgws_nb; + + /* wakeup source */ + struct wakeup_source wsource; /* to pass extra port status to the root hub */ u16 port_status;