From patchwork Thu Jul 9 15:19:44 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 34828 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n69FNT0F028496 for ; Thu, 9 Jul 2009 15:23:39 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752189AbZGIPXi (ORCPT ); Thu, 9 Jul 2009 11:23:38 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759503AbZGIPXi (ORCPT ); Thu, 9 Jul 2009 11:23:38 -0400 Received: from mail-pz0-f175.google.com ([209.85.222.175]:49517 "EHLO mail-pz0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752189AbZGIPXi (ORCPT ); Thu, 9 Jul 2009 11:23:38 -0400 Received: by pzk5 with SMTP id 5so164114pzk.33 for ; Thu, 09 Jul 2009 08:23:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :in-reply-to:references:subject; bh=TGfciQKi6e9+utVxV2oHQc1hh1/RXaLRZw6bMMWjn3s=; b=TT21Vn3PMB/09sKlsjH+OaIvesU46wg+vE7xgkX63uomxHapORQ8bzjtd2GD1rWFov vxZ9RexuALuk6UDOYro9KDrM2gXWu/opmBG6EFDYj9OFgY6n57zNFiYMBH12D6OcLXK8 SrwFo5NzHdj+UNZC7G759o3CTMJOPp9CIjKH0= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:in-reply-to:references:subject; b=f0NRoNEYYdFW6y2KI5ayDV4R+DWYH/55bYpwwHQOo+XEtJsZXDJ523O5D+i+ljEUTB v9cFy4mwVY9zIFQ5thQuvvqJfAVQfzu2W2pKnSWqRK1NTIeyc7YKbjsj8sQVokAVh+xF 99q0JTycZDqzLogtyD0vp7khW3Jz36gk+G6f8= Received: by 10.142.73.19 with SMTP id v19mr378112wfa.73.1247153017314; Thu, 09 Jul 2009 08:23:37 -0700 (PDT) Received: from rx1.opensource.se (58x80x213x53.ap58.ftth.ucom.ne.jp [58.80.213.53]) by mx.google.com with ESMTPS id 24sm8941042wff.26.2009.07.09.08.23.35 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 09 Jul 2009 08:23:36 -0700 (PDT) From: Magnus Damm To: linux-pm@lists.linux-foundation.org Cc: linux-sh@vger.kernel.org, gregkh@suse.de, rjw@sisk.pl, lethal@linux-sh.org, stern@rowland.harvard.edu, pavel@ucw.cz, Magnus Damm Date: Fri, 10 Jul 2009 00:19:44 +0900 Message-Id: <20090709151944.8385.62628.sendpatchset@rx1.opensource.se> In-Reply-To: <20090709151926.8385.92800.sendpatchset@rx1.opensource.se> References: <20090709151926.8385.92800.sendpatchset@rx1.opensource.se> Subject: [PATCH 02/06] sh: Add support for multiple hwblk counters Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org From: Magnus Damm Extend the SuperH hwblk code to support more than one counter. This is needed by the Runtime PM prototype implementation. Signed-off-by: Magnus Damm --- arch/sh/include/asm/hwblk.h | 13 +++++- arch/sh/kernel/cpu/hwblk.c | 69 +++++++++++++++++++++----------- arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c | 4 - 3 files changed, 60 insertions(+), 26 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- 0001/arch/sh/include/asm/hwblk.h +++ work/arch/sh/include/asm/hwblk.h 2009-07-09 18:38:04.000000000 +0900 @@ -4,6 +4,9 @@ #include #include +#define HWBLK_CNT_USAGE 0 +#define HWBLK_CNT_NR 1 + #define HWBLK_AREA_FLAG_PARENT (1 << 0) /* valid parent */ #define HWBLK_AREA(_flags, _parent) \ @@ -13,7 +16,7 @@ } struct hwblk_area { - unsigned long cnt; + int cnt[HWBLK_CNT_NR]; unsigned char parent; unsigned char flags; }; @@ -29,7 +32,7 @@ struct hwblk { void __iomem *mstp; unsigned char bit; unsigned char area; - unsigned long cnt; + int cnt[HWBLK_CNT_NR]; }; struct hwblk_info { @@ -46,6 +49,12 @@ int arch_hwblk_sleep_mode(void); int hwblk_register(struct hwblk_info *info); int hwblk_init(void); +void hwblk_enable(struct hwblk_info *info, int hwblk); +void hwblk_disable(struct hwblk_info *info, int hwblk); + +void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int cnt); +void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int cnt); + /* allow clocks to enable and disable hardware blocks */ #define SH_HWBLK_CLK(_name, _id, _parent, _hwblk, _flags) \ { \ --- 0001/arch/sh/kernel/cpu/hwblk.c +++ work/arch/sh/kernel/cpu/hwblk.c 2009-07-09 18:34:46.000000000 +0900 @@ -9,38 +9,64 @@ static DEFINE_SPINLOCK(hwblk_lock); -static void hwblk_area_inc(struct hwblk_info *info, int area) +static void hwblk_area_mod_cnt(struct hwblk_info *info, + int area, int counter, int value, int goal) { struct hwblk_area *hap = info->areas + area; - hap->cnt++; - if (hap->cnt == 1) - if (hap->flags & HWBLK_AREA_FLAG_PARENT) - hwblk_area_inc(info, hap->parent); + hap->cnt[counter] += value; + + if (hap->cnt[counter] != goal) + return; + + if (hap->flags & HWBLK_AREA_FLAG_PARENT) + hwblk_area_mod_cnt(info, hap->parent, counter, value, goal); } -static void hwblk_area_dec(struct hwblk_info *info, int area) + +static int __hwblk_mod_cnt(struct hwblk_info *info, int hwblk, + int counter, int value, int goal) { - struct hwblk_area *hap = info->areas + area; + struct hwblk *hp = info->hwblks + hwblk; + + hp->cnt[counter] += value; + if (hp->cnt[counter] == goal) + hwblk_area_mod_cnt(info, hp->area, counter, value, goal); - if (hap->cnt == 1) - if (hap->flags & HWBLK_AREA_FLAG_PARENT) - hwblk_area_dec(info, hap->parent); - hap->cnt--; + return hp->cnt[counter]; } -static void hwblk_enable(struct hwblk_info *info, int hwblk) +static void hwblk_mod_cnt(struct hwblk_info *info, int hwblk, + int counter, int value, int goal) +{ + unsigned long flags; + + spin_lock_irqsave(&hwblk_lock, flags); + __hwblk_mod_cnt(info, hwblk, counter, value, goal); + spin_unlock_irqrestore(&hwblk_lock, flags); +} + +void hwblk_cnt_inc(struct hwblk_info *info, int hwblk, int counter) +{ + hwblk_mod_cnt(info, hwblk, counter, 1, 1); +} + +void hwblk_cnt_dec(struct hwblk_info *info, int hwblk, int counter) +{ + hwblk_mod_cnt(info, hwblk, counter, -1, 0); +} + +void hwblk_enable(struct hwblk_info *info, int hwblk) { struct hwblk *hp = info->hwblks + hwblk; unsigned long tmp; unsigned long flags; + int ret; spin_lock_irqsave(&hwblk_lock, flags); - hp->cnt++; - if (hp->cnt == 1) { - hwblk_area_inc(info, hp->area); - + ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, 1, 1); + if (ret == 1) { tmp = __raw_readl(hp->mstp); tmp &= ~(1 << hp->bit); __raw_writel(tmp, hp->mstp); @@ -49,27 +75,26 @@ static void hwblk_enable(struct hwblk_in spin_unlock_irqrestore(&hwblk_lock, flags); } -static void hwblk_disable(struct hwblk_info *info, int hwblk) +void hwblk_disable(struct hwblk_info *info, int hwblk) { struct hwblk *hp = info->hwblks + hwblk; unsigned long tmp; unsigned long flags; + int ret; spin_lock_irqsave(&hwblk_lock, flags); - if (hp->cnt == 1) { - hwblk_area_dec(info, hp->area); - + ret = __hwblk_mod_cnt(info, hwblk, HWBLK_CNT_USAGE, -1, 0); + if (ret == 0) { tmp = __raw_readl(hp->mstp); tmp |= 1 << hp->bit; __raw_writel(tmp, hp->mstp); } - hp->cnt--; spin_unlock_irqrestore(&hwblk_lock, flags); } -static struct hwblk_info *hwblk_info; +struct hwblk_info *hwblk_info; int __init hwblk_register(struct hwblk_info *info) { --- 0001/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c +++ work/arch/sh/kernel/cpu/sh4a/hwblk-sh7722.c 2009-07-09 18:38:48.000000000 +0900 @@ -91,10 +91,10 @@ static struct hwblk_info sh7722_hwblk_in int arch_hwblk_sleep_mode(void) { - if (!sh7722_hwblk_area[CORE_AREA].cnt) + if (!sh7722_hwblk_area[CORE_AREA].cnt[HWBLK_CNT_USAGE]) return SUSP_SH_STANDBY | SUSP_SH_SF; - if (!sh7722_hwblk_area[CORE_AREA_BM].cnt) + if (!sh7722_hwblk_area[CORE_AREA_BM].cnt[HWBLK_CNT_USAGE]) return SUSP_SH_SLEEP | SUSP_SH_SF; return SUSP_SH_SLEEP;