From patchwork Fri Aug 22 09:49:32 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: 35792 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f70.google.com (mail-yh0-f70.google.com [209.85.213.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id DA8AA2057E for ; Fri, 22 Aug 2014 09:49:53 +0000 (UTC) Received: by mail-yh0-f70.google.com with SMTP id b6sf34453702yha.9 for ; Fri, 22 Aug 2014 02:49:53 -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=KFfeZ3QQCDQW4mjatHIdSE1ctidOl2WT3fzCX6LArBo=; b=WC4QpNrA4SzvP4b5yftyY/IyavOwaJ0ODXrbIZIvGUgbHJ0zkCbPOA9LKD+1Z9G9lC TCKjzlzICiulEdtWeB5NS19M7rutqiDd0Y2jmAZxoF+rJF/7hRfTKgf0FuoAmAEBD+mk R8XVYKaJTUS3GQavKg9oDeJweCb3NcgX7MOvevdl2fiDQmAlP2kHTVftwTpFWuP58VTa mi7tU/EJEyhxRBYla7fxInPK7I4SGBL/tndOqeUo9tf1bp5ZRNl/g2pyq5/fmT168Oiv JJVtxtJ+hQM+coYLrKztzj/Qlobxabd73zq+KAkSoYh/uCo0MrtaGkEm2e5DioHXHxsE 7ILQ== X-Gm-Message-State: ALoCoQnTpJErOFUyx7LeRNQp7PklNw9EvVNAt8uCefWNK+4tmRHYiA/Uw/bl9Tle+aRg2Nuzv8Zy X-Received: by 10.236.180.202 with SMTP id j50mr8485505yhm.51.1408700993730; Fri, 22 Aug 2014 02:49:53 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.25.148 with SMTP id 20ls1122472qgt.86.gmail; Fri, 22 Aug 2014 02:49:53 -0700 (PDT) X-Received: by 10.220.251.200 with SMTP id mt8mr3322562vcb.24.1408700993649; Fri, 22 Aug 2014 02:49:53 -0700 (PDT) Received: from mail-vc0-f179.google.com (mail-vc0-f179.google.com [209.85.220.179]) by mx.google.com with ESMTPS id v6si7247912vcs.2.2014.08.22.02.49.53 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 22 Aug 2014 02:49:53 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.179 as permitted sender) client-ip=209.85.220.179; Received: by mail-vc0-f179.google.com with SMTP id hq11so12165087vcb.10 for ; Fri, 22 Aug 2014 02:49:53 -0700 (PDT) X-Received: by 10.220.105.142 with SMTP id t14mr1573072vco.14.1408700993500; Fri, 22 Aug 2014 02:49:53 -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 uj3csp3395vcb; Fri, 22 Aug 2014 02:49:52 -0700 (PDT) X-Received: by 10.70.5.33 with SMTP id p1mr5115050pdp.134.1408700992535; Fri, 22 Aug 2014 02:49:52 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id io3si39975353pbc.246.2014.08.22.02.49.51 for ; Fri, 22 Aug 2014 02:49:52 -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 S1753829AbaHVJtu (ORCPT + 2 others); Fri, 22 Aug 2014 05:49:50 -0400 Received: from mail-pd0-f169.google.com ([209.85.192.169]:45673 "EHLO mail-pd0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750729AbaHVJtt (ORCPT ); Fri, 22 Aug 2014 05:49:49 -0400 Received: by mail-pd0-f169.google.com with SMTP id y10so15494737pdj.0 for ; Fri, 22 Aug 2014 02:49:48 -0700 (PDT) X-Received: by 10.70.93.8 with SMTP id cq8mr3606814pdb.160.1408700988655; Fri, 22 Aug 2014 02:49:48 -0700 (PDT) Received: from c-krapar-linux.qualcomm.com ([202.46.23.54]) by mx.google.com with ESMTPSA id eb11sm100488407pad.33.2014.08.22.02.49.43 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 22 Aug 2014 02:49:47 -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 , =?UTF-8?q?Arve=20Hj=F8nnev=E5g?= , Benoit Goby , Kiran Raparthy Subject: [RFC 1/2] USB: OTG: Hold wakeupsource when VBUS present Date: Fri, 22 Aug 2014 15:19:32 +0530 Message-Id: <1408700972-8518-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.179 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: OTG: Hold wakeupsource when VBUS present Enabled by default, can disable with: echo N > /sys/module/otg_wakeupsource/parameters/enabled This is one of the number of patches from the Android AOSP common.git tree, which is used on almost all Android devices. so I wanted to submit it for review to see if it should go upstream. 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: Arve Hjřnnevĺg Cc: Benoit Goby Signed-off-by: Todd Poynor Signed-off-by: Kiran Raparthy [kiran: Added context to commit message Included build fix from Benoit Goby and Arve Arve Hjřnnevĺg Removed lock->held field in driver as this mechanism is provided in wakeup.c wakelock(wl) terminology replaced with wakeup_source(ws) sys entry(module param) field modified to otg_wakeupsource __pm_stay_awake and __pm_relax called directly from the main code instead of calling them via otgws_grab,otgws_drop] --- drivers/usb/phy/Kconfig | 8 ++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/otg-wakeupsource.c | 171 +++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 drivers/usb/phy/otg-wakeupsource.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index e253fa0..9c747b2 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 a wakeupsource when USB connected" + depends on PM_SLEEP + select USB_PHY + help + Select this to automatically hold a wakeupsource when USB is + connected, preventing suspend. + # # 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..fa44e11 --- /dev/null +++ b/drivers/usb/phy/otg-wakeupsource.c @@ -0,0 +1,171 @@ +/* + * 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 + +static bool enabled = true; +static struct usb_phy *otgws_xceiv; +static struct notifier_block otgws_nb; + + +static DEFINE_SPINLOCK(otgws_spinlock); + +/* + * Only one lock, but since these 2 fields are associated with each other... + */ + +struct otgws_lock { + char name[40]; + struct wakeup_source wsource; +}; + +/* + * VBUS present lock. + */ + +static struct otgws_lock vbus_lock; + +static int otgws_otg_notifications(struct notifier_block *nb, + unsigned long event, void *unused) +{ + unsigned long irqflags; + + if (!enabled) + return NOTIFY_OK; + + spin_lock_irqsave(&otgws_spinlock, irqflags); + + switch (event) { + case USB_EVENT_VBUS: + case USB_EVENT_ENUMERATED: + __pm_stay_awake(&vbus_lock.wsource); + break; + + case USB_EVENT_NONE: + case USB_EVENT_ID: + case USB_EVENT_CHARGER: + __pm_relax(&vbus_lock.wsource); + break; + + default: + break; + } + + spin_unlock_irqrestore(&otgws_spinlock, irqflags); + return NOTIFY_OK; +} + +static void sync_with_xceiv_state(void) +{ + if ((otgws_xceiv->last_event == USB_EVENT_VBUS) || + (otgws_xceiv->last_event == USB_EVENT_ENUMERATED)) + __pm_stay_awake(&vbus_lock.wsource); + else + __pm_relax(&vbus_lock.wsource); +} + +static int init_for_xceiv(void) +{ + int rv; + struct usb_phy *phy; + + if (!otgws_xceiv) { + phy = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(phy)) { + pr_err("%s: No USB transceiver found\n", __func__); + return PTR_ERR(phy); + } + otgws_xceiv = phy; + + snprintf(vbus_lock.name, sizeof(vbus_lock.name), "vbus-%s", + dev_name(otgws_xceiv->dev)); + wakeup_source_init(&vbus_lock.wsource, vbus_lock.name); + + rv = usb_register_notifier(otgws_xceiv, &otgws_nb); + + if (rv) { + pr_err("%s: usb_register_notifier on transceiver %s + failed\n", __func__, + dev_name(otgws_xceiv->dev)); + otgws_xceiv = NULL; + wakeup_source_trash(&vbus_lock.wsource); + return rv; + } + } + + return 0; +} + +static int set_enabled(const char *val, const struct kernel_param *kp) +{ + unsigned long irqflags; + int rv = param_set_bool(val, kp); + + if (rv) + return rv; + + rv = init_for_xceiv(); + + if (rv) + return rv; + + spin_lock_irqsave(&otgws_spinlock, irqflags); + + if (enabled) + sync_with_xceiv_state(); + else + __pm_relax(&vbus_lock.wsource); + + spin_unlock_irqrestore(&otgws_spinlock, irqflags); + 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) +{ + unsigned long irqflags; + + otgws_nb.notifier_call = otgws_otg_notifications; + + if (!init_for_xceiv()) { + spin_lock_irqsave(&otgws_spinlock, irqflags); + + if (enabled) + sync_with_xceiv_state(); + + spin_unlock_irqrestore(&otgws_spinlock, irqflags); + } else { + enabled = false; + } + + return 0; +} + +late_initcall(otg_wakeupsource_init);