From patchwork Wed Jun 12 13:08:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 17829 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f199.google.com (mail-qc0-f199.google.com [209.85.216.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BFB6623903 for ; Wed, 12 Jun 2013 13:09:01 +0000 (UTC) Received: by mail-qc0-f199.google.com with SMTP id a1sf5953433qcx.2 for ; Wed, 12 Jun 2013 06:09:01 -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=v3rX1VObWJ9WgM4UcFd9BxQhGbfDoXA1xRe4L6L2uXM=; b=Cvz4czP6K1IEag8GOLs13gnTEKQV46HWwHQjGw1YUmo1fonkCOjnOqog368OHMany0 nm82RpSa86zSAanbSCs+qUpLwZl55ueiTnO6Jqp9J3P6SaIusXo5D8Uch4rL6qVsyNRJ uDisNuxFUj3O5JZKG431JK526q84NcOLQwPvE6PYlHmFIajNFMluhwpS/9hx4XKOHINz UlFZq1I4JXFnn9k5B0wKWNeytXfY0wB4BrkSee897KBi44qWVduhbF1L2PlvIwSFt1fT 2IUb+B4Vt+E6shUrgXF1cZdFLycgtMRWG6XsLG7s8zH72fUt5vpiggaLdKbvLoEm24+M ibKQ== X-Received: by 10.236.194.33 with SMTP id l21mr7464731yhn.42.1371042541456; Wed, 12 Jun 2013 06:09:01 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.64.74 with SMTP id m10ls889627qes.44.gmail; Wed, 12 Jun 2013 06:09:01 -0700 (PDT) X-Received: by 10.52.36.115 with SMTP id p19mr8280707vdj.8.1371042541273; Wed, 12 Jun 2013 06:09:01 -0700 (PDT) Received: from mail-ve0-x231.google.com (mail-ve0-x231.google.com [2607:f8b0:400c:c01::231]) by mx.google.com with ESMTPS id tn5si8570999vdc.65.2013.06.12.06.09.00 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 12 Jun 2013 06:09:01 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::231 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::231; Received: by mail-ve0-f177.google.com with SMTP id cz10so6716947veb.36 for ; Wed, 12 Jun 2013 06:09:00 -0700 (PDT) X-Received: by 10.220.53.7 with SMTP id k7mr4372862vcg.52.1371042540876; Wed, 12 Jun 2013 06:09:00 -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.58.191.99 with SMTP id gx3csp143387vec; Wed, 12 Jun 2013 06:09:00 -0700 (PDT) X-Received: by 10.194.103.226 with SMTP id fz2mr11816881wjb.75.1371042539685; Wed, 12 Jun 2013 06:08:59 -0700 (PDT) Received: from mail-we0-x22d.google.com (mail-we0-x22d.google.com [2a00:1450:400c:c03::22d]) by mx.google.com with ESMTPS id t12si5628487wib.3.2013.06.12.06.08.59 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 12 Jun 2013 06:08:59 -0700 (PDT) Received-SPF: neutral (google.com: 2a00:1450:400c:c03::22d is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) client-ip=2a00:1450:400c:c03::22d; Received: by mail-we0-f173.google.com with SMTP id x54so6105005wes.32 for ; Wed, 12 Jun 2013 06:08:59 -0700 (PDT) X-Received: by 10.194.84.74 with SMTP id w10mr12149861wjy.52.1371042539264; Wed, 12 Jun 2013 06:08:59 -0700 (PDT) Received: from mai.home (AToulouse-654-1-404-219.w82-125.abo.wanadoo.fr. [82.125.3.219]) by mx.google.com with ESMTPSA id x13sm24555864wib.3.2013.06.12.06.08.57 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 12 Jun 2013 06:08:58 -0700 (PDT) From: Daniel Lezcano To: rjw@sisk.pl Cc: linux-pm@vger.kernel.org, linaro-kernel@lists.linaro.org, patches@linaro.org Subject: [PATCH 4/8] cpuidle: Make cpuidle's sysfs directory dynamically allocated Date: Wed, 12 Jun 2013 15:08:51 +0200 Message-Id: <1371042535-22630-4-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1371042535-22630-1-git-send-email-daniel.lezcano@linaro.org> References: <1371042535-22630-1-git-send-email-daniel.lezcano@linaro.org> X-Gm-Message-State: ALoCoQlkbxyhg/7/8X48V7YU7D4OSLuzezSxMCckY33T2gwOrCuNQXhGRtqQWqyhj6++2kOpZZjX X-Original-Sender: daniel.lezcano@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::231 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 | 63 ++++++++++++++++++++++++++++++++++++----------- include/linux/cpuidle.h | 7 +++--- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 7d4448a..8739cc0 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; - 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(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj, + "cpuidle"); + if (error) { + kfree(kdev); + return error; + } - error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj, - "cpuidle"); - if (!error) - kobject_uevent(&dev->kobj, KOBJ_ADD); - return error; + 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 0bc4b74..b922db5 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,8 @@ struct cpuidle_state { #define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) +struct cpuidle_device_kobj; + struct cpuidle_device { unsigned int registered:1; unsigned int enabled:1; @@ -71,9 +71,8 @@ struct cpuidle_device { struct cpuidle_state_usage states_usage[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;