lkml.org 
[lkml]   [2012]   [May]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC][PATCH 1/2] PM / cpuidle: Add driver reference counter
    Date
    From: Rafael J. Wysocki <rjw@sisk.pl>

    Add a reference counter for the cpuidle driver, so that it can't
    be unregistered when it is in use.

    Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
    ---
    drivers/cpuidle/driver.c | 29 ++++++++++++++++++++++++++++-
    include/linux/cpuidle.h | 6 +++++-
    2 files changed, 33 insertions(+), 2 deletions(-)

    Index: linux/drivers/cpuidle/driver.c
    ===================================================================
    --- linux.orig/drivers/cpuidle/driver.c
    +++ linux/drivers/cpuidle/driver.c
    @@ -16,6 +16,7 @@

    static struct cpuidle_driver *cpuidle_curr_driver;
    DEFINE_SPINLOCK(cpuidle_driver_lock);
    +int cpuidle_driver_refcount;

    static void __cpuidle_register_driver(struct cpuidle_driver *drv)
    {
    @@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cp
    }

    spin_lock(&cpuidle_driver_lock);
    - cpuidle_curr_driver = NULL;
    +
    + if (!WARN_ON(cpuidle_driver_refcount > 0))
    + cpuidle_curr_driver = NULL;
    +
    spin_unlock(&cpuidle_driver_lock);
    }

    EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
    +
    +struct cpuidle_driver *cpuidle_driver_ref(void)
    +{
    + struct cpuidle_driver *drv;
    +
    + spin_lock(&cpuidle_driver_lock);
    +
    + drv = cpuidle_curr_driver;
    + cpuidle_driver_refcount++;
    +
    + spin_unlock(&cpuidle_driver_lock);
    + return drv;
    +}
    +
    +void cpuidle_driver_unref(void)
    +{
    + spin_lock(&cpuidle_driver_lock);
    +
    + if (!WARN_ON(cpuidle_driver_refcount <= 0))
    + cpuidle_driver_refcount--;
    +
    + spin_unlock(&cpuidle_driver_lock);
    +}
    Index: linux/include/linux/cpuidle.h
    ===================================================================
    --- linux.orig/include/linux/cpuidle.h
    +++ linux/include/linux/cpuidle.h
    @@ -136,7 +136,9 @@ struct cpuidle_driver {
    extern void disable_cpuidle(void);
    extern int cpuidle_idle_call(void);
    extern int cpuidle_register_driver(struct cpuidle_driver *drv);
    -struct cpuidle_driver *cpuidle_get_driver(void);
    +extern struct cpuidle_driver *cpuidle_get_driver(void);
    +extern struct cpuidle_driver *cpuidle_driver_ref(void);
    +extern void cpuidle_driver_unref(void);
    extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
    extern int cpuidle_register_device(struct cpuidle_device *dev);
    extern void cpuidle_unregister_device(struct cpuidle_device *dev);
    @@ -157,6 +159,8 @@ static inline int cpuidle_idle_call(void
    static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
    {return -ENODEV; }
    static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }
    +static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; }
    +static inline void cpuidle_driver_unref(void) {}
    static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
    static inline int cpuidle_register_device(struct cpuidle_device *dev)
    {return -ENODEV; }


    \
     
     \ /
      Last update: 2012-05-09 23:41    [W:0.025 / U:32.828 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site