From patchwork Wed Apr 18 13:45:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean Pihet X-Patchwork-Id: 153516 Return-Path: X-Original-To: incoming-imx@patchwork.ozlabs.org Delivered-To: patchwork-incoming-imx@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A3F4BB6F62 for ; Wed, 18 Apr 2012 23:50:56 +1000 (EST) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SKVFA-0008HF-VK; Wed, 18 Apr 2012 13:48:24 +0000 Received: from mail-we0-f177.google.com ([74.125.82.177]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1SKVCf-0006CM-VW for linux-arm-kernel@lists.infradead.org; Wed, 18 Apr 2012 13:45:56 +0000 Received: by werp11 with SMTP id p11so5743045wer.36 for ; Wed, 18 Apr 2012 06:45:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :mime-version:content-type:content-transfer-encoding :x-gm-message-state; bh=l0sEN4KhARf5znUTawELnZzly+076ZIe8uP7mKjAEZ0=; b=Jx9iuu6XdTY+BiaPq0fbTMrLpw6tqk/oZREly5he89HHrTWceX0fnI4813bxNFi2YA eo+EI7SkiRBJZh3AqAQohjiYQR/nC1Ez5oY7/ecOOc6T/y6RH7pcDOltMgH7w1+3zk9G HO7hxf3EL99/77xw3aPsEkGtjRqBTwcX2icuF2hZA+4ktTI3ujT0MVikmJyORaQoVo8T 30aCEeOufUIHK3v/XXo9rSyQ7P3K4J9tmvMjBXGQ7KAmTVLjpis9sUBHgMqozVheI0eD jK3ZSn2Cpf9JGkSzUOd7qYprDOKlw/sPfI/FnjmzRwbsn77FQaBTkx9X0TLE8vJZjSYJ ifTA== Received: by 10.216.143.209 with SMTP id l59mr1486467wej.87.1334756748323; Wed, 18 Apr 2012 06:45:48 -0700 (PDT) Received: from localhost.localdomain (216.84-66-87.adsl-dyn.isp.belgacom.be. [87.66.84.216]) by mx.google.com with ESMTPS id ea6sm34675432wib.5.2012.04.18.06.45.46 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Apr 2012 06:45:47 -0700 (PDT) From: jean.pihet@newoldbits.com To: linux-omap@vger.kernel.org, paul@pwsan.com, b-cousson@ti.com, khilman@ti.com, linux-arm-kernel@lists.infradead.org Subject: =?UTF-8?q?=5BPATCH=203/6=5D=20ARM=3A=20OMAP=3A=20omap=5Fdevice=3A=20register=20to=20the=20per-device=20PM=20QoS=20framework?= Date: Wed, 18 Apr 2012 15:45:17 +0200 Message-Id: <1334756720-29166-4-git-send-email-j-pihet@ti.com> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1334756720-29166-1-git-send-email-j-pihet@ti.com> References: <1334756720-29166-1-git-send-email-j-pihet@ti.com> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkc5ziqPJb2+PI3O42uL4H7RATvfi+0WwBueFkxjE7DKVuC/PT80pZZMoUjIrRiCwLGaPre X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.177 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Jean Pihet X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org List-Id: linux-imx-kernel.lists.patchwork.ozlabs.org From: Jean Pihet Implement the devices wake-up latency constraints using the global device PM QoS notification handler which applies the constraints to the underlying layer by calling the corresponding function at hwmod level. Tested on OMAP3 Beagleboard and OMAP4 Pandaboard in RET/OFF using wake-up latency constraints on MPU, CORE and PER. Signed-off-by: Jean Pihet Reviewed-by: Kevin Hilman [paul@pwsan.com: modified to work with omap_devices with large numbers of hwmods; moved code to mach-omap2/omap_device.c; added documentation; use notifier return codes] Signed-off-by: Paul Walmsley --- arch/arm/plat-omap/omap_device.c | 81 +++++++++++++++++++++++++++++++++++++- 1 files changed, 80 insertions(+), 1 deletions(-) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index d50cbc6..fb66879 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -3,6 +3,7 @@ * omap_device implementation * * Copyright (C) 2009-2010 Nokia Corporation + * Copyright (C) 2011 Texas Instruments, Inc. * Paul Walmsley, Kevin Hilman * * Developed in collaboration with (alphabetical order): Benoit @@ -89,6 +90,7 @@ #include #include #include +#include #include #include @@ -401,6 +403,72 @@ static int _omap_device_notifier_call(struct notifier_block *nb, return NOTIFY_DONE; } +/** + * _omap_device_pm_qos_handler - interface to the per-device PM QoS framework + * @nb: pointer to omap_device_pm_qos_nb (not used) + * @new_value: new maximum wakeup latency constraint for @req->dev (in µs) + * @req: struct dev_pm_qos_request * passed by the Linux PM QoS code + * + * Called by the Linux core device PM QoS code to alter the maximum + * wakeup latency constraint on a device. If the underlying device is + * an omap_device, then this code will pass the constraint on to the + * underlying hwmods. Returns -EINVAL if this code can't handle the + * constraint for some reason, or passes along the return code from the + * hwmod wakeup latency constraint functions. + */ +static int _omap_device_pm_qos_handler(struct notifier_block *nb, + unsigned long new_value, + void *req) +{ + struct omap_device *od; + struct omap_hwmod *oh; + struct platform_device *pdev; + struct dev_pm_qos_request *dev_pm_qos_req = req; + int ret = NOTIFY_OK; + int r, i; + + pr_debug("OMAP PM constraints: req@0x%p, new_value=%lu\n", + req, new_value); + + /* Look for the platform device for the constraint target device */ + pdev = to_platform_device(dev_pm_qos_req->dev); + + /* Try to catch non platform devices */ + if (pdev->name == NULL) { + pr_err("%s: Error: platform device for device %s not valid\n", + __func__, dev_name(dev_pm_qos_req->dev)); + return NOTIFY_DONE; + } + + /* Find the associated omap_device for dev */ + od = to_omap_device(pdev); + if (od == NULL) { + pr_err("%s: Error: no omap_device for device %s\n", + __func__, dev_name(dev_pm_qos_req->dev)); + return NOTIFY_DONE; + } + + pr_debug("OMAP PM constraints: req@0x%p, dev=0x%p, new_value=%lu\n", + req, dev_pm_qos_req->dev, new_value); + + for (i = 0; i < od->hwmods_cnt; i++) { + oh = od->hwmods[i]; + if (new_value == PM_QOS_DEV_LAT_DEFAULT_VALUE) + r = omap_hwmod_remove_wakeuplat_constraint( + oh, + dev_pm_qos_req); + else + r = omap_hwmod_set_wakeuplat_constraint( + oh, + dev_pm_qos_req, + new_value); + + if (!r) + ret = NOTIFY_BAD; + } + + return ret; +} /* Public functions for use by core code */ @@ -1117,13 +1185,24 @@ int omap_device_enable_clocks(struct omap_device *od) return 0; } +static struct notifier_block omap_device_pm_qos_nb = { + .notifier_call = _omap_device_pm_qos_handler, +}; + static struct notifier_block platform_nb = { .notifier_call = _omap_device_notifier_call, }; static int __init omap_device_init(void) { + int ret; + bus_register_notifier(&platform_bus_type, &platform_nb); - return 0; + + ret = dev_pm_qos_add_global_notifier(&omap_device_pm_qos_nb); + if (!ret) + pr_err("omap_device: cannot add global notifier for dev PM QoS\n"); + + return ret; } core_initcall(omap_device_init);