From patchwork Wed May 29 17:43:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 17274 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f197.google.com (mail-ve0-f197.google.com [209.85.128.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 786D425D81 for ; Wed, 29 May 2013 17:43:46 +0000 (UTC) Received: by mail-ve0-f197.google.com with SMTP id d10sf4767696vea.0 for ; Wed, 29 May 2013 10:43:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-beenthere:x-forwarded-to:x-forwarded-for :delivered-to:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=r8vy9MYfNQwRou5omgB7fxZo36W9v6cOPWi5V5FrelU=; b=I9CTUagfKWnx94CthYgaMaVO9nXU8RHCd4/gmoknmFCvpXMcuec3+o5mmAB5i++F4f WuBg5h52EzCMGUfBjFs+MrMtih3dEt9Im6OqgJ6iKG/wmXuDWT6kIaijABAKse3OOEKL ATQJ4ei+RKAEPd4sDFdwPHuG+BJ2n34F0N7HZeTIp+Sz/YhNhix92ZU06JQj7EDTTgUs BuLtGmdxrESuZBFnTS/6g1dUvL21mrfQxv0jV+1TfcXDiQXeliWqh41XtB9sVrjdt2s9 yyZJjh4+iH0nTc/V4t6eKdDXU4Oo+GEVEBL69K1zzkIrpSjhKOcCbS80O9YwD1+WdwK1 lQdw== X-Received: by 10.236.134.132 with SMTP id s4mr1891867yhi.56.1369849426193; Wed, 29 May 2013 10:43:46 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.98.138 with SMTP id ei10ls3961405qeb.79.gmail; Wed, 29 May 2013 10:43:46 -0700 (PDT) X-Received: by 10.220.188.201 with SMTP id db9mr2300729vcb.30.1369849426021; Wed, 29 May 2013 10:43:46 -0700 (PDT) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by mx.google.com with ESMTPS id sa4si22253587vdc.23.2013.05.29.10.43.46 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 10:43:46 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.173; Received: by mail-vc0-f173.google.com with SMTP id ht10so6607417vcb.18 for ; Wed, 29 May 2013 10:43:45 -0700 (PDT) X-Received: by 10.58.225.228 with SMTP id rn4mr2314689vec.35.1369849425918; Wed, 29 May 2013 10:43:45 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.229.199 with SMTP id jj7csp22132vcb; Wed, 29 May 2013 10:43:45 -0700 (PDT) X-Received: by 10.15.109.142 with SMTP id cf14mr5157126eeb.77.1369849424829; Wed, 29 May 2013 10:43:44 -0700 (PDT) Received: from mail-we0-x22e.google.com (mail-we0-x22e.google.com [2a00:1450:400c:c03::22e]) by mx.google.com with ESMTPS id v46si21602452een.137.2013.05.29.10.43.44 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 10:43:44 -0700 (PDT) Received-SPF: neutral (google.com: 2a00:1450:400c:c03::22e is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) client-ip=2a00:1450:400c:c03::22e; Received: by mail-we0-f174.google.com with SMTP id x50so4776060wes.19 for ; Wed, 29 May 2013 10:43:44 -0700 (PDT) X-Received: by 10.194.179.2 with SMTP id dc2mr2035907wjc.53.1369849423929; Wed, 29 May 2013 10:43:43 -0700 (PDT) Received: from mai.home (AToulouse-654-1-324-164.w86-199.abo.wanadoo.fr. [86.199.211.164]) by mx.google.com with ESMTPSA id cw8sm32657116wib.7.2013.05.29.10.43.41 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 May 2013 10:43:42 -0700 (PDT) From: Daniel Lezcano To: rjw@sisk.pl Cc: linux-pm@lists.linux-foundation.org, patches@linaro.org, linaro-kernel@lists.linaro.org Subject: [PATCH 4/7] cpuidle: make sysfs code more modular Date: Wed, 29 May 2013 19:43:31 +0200 Message-Id: <1369849414-7761-4-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1369849414-7761-1-git-send-email-daniel.lezcano@linaro.org> References: <1369849414-7761-1-git-send-email-daniel.lezcano@linaro.org> X-Gm-Message-State: ALoCoQmI8mhrxl2+EO2HhFIP4Qmp0X4v7FmKLUL3Y5JPEsMhihqPCuHdbBDUladAWeCqV+TCbDOB X-Original-Sender: daniel.lezcano@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.173 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , The cpuidle sysfs code is designed to have a single instance of per cpu cpuidle directory. It is not possible to remove the sysfs entry and recreate it. This is not a problem with the current code but the next patches will add the cpu hotplug handling to enable/disable the device, thus removing the sysfs entry like does any other subsystems. Without this patch it is not possible because the kobj is a static object which can't be reused for kobj_init_and_add. Create a cpuidle_device_kobj to be allocated dynamically when adding/removing a sysfs entry. This approach is consistent with the other cpuidle's sysfs entries. Another benefit is the sysfs code is more encapsulated and the headers needed for sysfs are moved from cpuidle.h into the sysfs.c file, preventing useless header inclusions from cpuidle.h. Signed-off-by: Daniel Lezcano --- drivers/cpuidle/sysfs.c | 65 +++++++++++++++++++++++++++++++++++------------ include/linux/cpuidle.h | 11 ++++---- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 7d4448a..a8ea1a8 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include "cpuidle.h" @@ -167,14 +169,27 @@ struct cpuidle_attr { #define define_one_rw(_name, show, store) \ static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store) -#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj) #define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr) +struct cpuidle_device_kobj { + struct cpuidle_device *dev; + struct completion kobj_unregister; + struct kobject kobj; +}; + +static inline struct cpuidle_device *to_cpuidle_device(struct kobject *kobj) +{ + struct cpuidle_device_kobj *kdev = + container_of(kobj, struct cpuidle_device_kobj, kobj); + + return kdev->dev; +} + static ssize_t cpuidle_show(struct kobject *kobj, struct attribute *attr, char *buf) { int ret = -EIO; - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); + struct cpuidle_device *dev = to_cpuidle_device(kobj); struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr); if (cattr->show) { @@ -189,7 +204,7 @@ static ssize_t cpuidle_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { int ret = -EIO; - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); + struct cpuidle_device *dev = to_cpuidle_device(kobj); struct cpuidle_attr *cattr = attr_to_cpuidleattr(attr); if (cattr->store) { @@ -207,9 +222,10 @@ static const struct sysfs_ops cpuidle_sysfs_ops = { static void cpuidle_sysfs_release(struct kobject *kobj) { - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); + struct cpuidle_device_kobj *kdev = + container_of(kobj, struct cpuidle_device_kobj, kobj); - complete(&dev->kobj_unregister); + complete(&kdev->kobj_unregister); } static struct kobj_type ktype_cpuidle = { @@ -377,6 +393,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) { int i, ret = -ENOMEM; struct cpuidle_state_kobj *kobj; + struct cpuidle_device_kobj *kdev = device->kobj_dev; struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); /* state statistics */ @@ -389,7 +406,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) init_completion(&kobj->kobj_unregister); ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, - &device->kobj, "state%d", i); + &kdev->kobj, "state%d", i); if (ret) { kfree(kobj); goto error_state; @@ -506,6 +523,7 @@ static struct kobj_type ktype_driver_cpuidle = { static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) { struct cpuidle_driver_kobj *kdrv; + struct cpuidle_device_kobj *kdev = dev->kobj_dev; struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int ret; @@ -517,7 +535,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) init_completion(&kdrv->kobj_unregister); ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, - &dev->kobj, "driver"); + &kdev->kobj, "driver"); if (ret) { kfree(kdrv); return ret; @@ -586,16 +604,28 @@ void cpuidle_remove_device_sysfs(struct cpuidle_device *device) */ int cpuidle_add_sysfs(struct cpuidle_device *dev) { + struct cpuidle_device_kobj *kdev; struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); - int error; + int ret; - init_completion(&dev->kobj_unregister); + kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); + if (!kdev) + return -ENOMEM; + kdev->dev = dev; + dev->kobj_dev = kdev; + + init_completion(&kdev->kobj_unregister); - error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj, - "cpuidle"); - if (!error) - kobject_uevent(&dev->kobj, KOBJ_ADD); - return error; + ret = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj, + "cpuidle"); + if (ret) { + kfree(kdev); + return ret; + } + + kobject_uevent(&kdev->kobj, KOBJ_ADD); + + return 0; } /** @@ -604,6 +634,9 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) */ void cpuidle_remove_sysfs(struct cpuidle_device *dev) { - kobject_put(&dev->kobj); - wait_for_completion(&dev->kobj_unregister); + struct cpuidle_device_kobj *kdev = dev->kobj_dev; + + kobject_put(&kdev->kobj); + wait_for_completion(&kdev->kobj_unregister); + kfree(kdev); } diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 8f04062..a6b56b1 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -13,8 +13,6 @@ #include #include -#include -#include #include #define CPUIDLE_STATE_MAX 10 @@ -61,6 +59,10 @@ struct cpuidle_state { #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) +struct cpuidle_state_kobj; +struct cpuidle_driver_kobj; +struct cpuidle_device_kobj; + struct cpuidle_device { unsigned int registered:1; unsigned int enabled:1; @@ -69,11 +71,10 @@ struct cpuidle_device { int last_residency; int state_count; struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; - struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; + struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; struct cpuidle_driver_kobj *kobj_driver; + struct cpuidle_device_kobj *kobj_dev; struct list_head device_list; - struct kobject kobj; - struct completion kobj_unregister; #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED int safe_state_index;