generic clock framework
Subsystems (3)
PATCH 1/1 generic clock framework
Hi all
I'm Francesco and I work in STMicroelectronics
In the last ELC-E_2009 I spoke on a generic clock framework I'm working on
(see
http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&do=view&target=ELC_E_2009_Generic_Clock_Framework.pdf).
I wrote the gcf to manage both clocks the platform_devices during a clock operation.
The main features are:
- it's integrated in the LDM
- it tracks the clock-to-clock relationship
- it tracks the clock-to-device relationship
- it has sysfs interface
- - the user can navigate the clock tree under /sys/clocks/...
- it uses the linux API (<linux/clk.h>) with some extra functions (to
register/unregister a clock
and other utility functions as clk_for_each())
- it involves the platform_device and the platform_driver in the clock
propagation.
- - basically each clock operation is managed as a transaction which
evolves step by step.
- - all the clock rates are evaluated (before the clk operation is
actually done)
- - each platform_device can check (before the clk operation is
actually done) the clk environment
it will have at the end of clock operation and if required it can
reject the operation.
- - each clock operation is actually executed only if all theplatform_devices accept the operation it-self
Moreover a common clock framework could be used to avoid a lot of duplicated and/or similar code
just a grep of 'EXPORT_SYMBOL\(clk_enable' under arch/arm finds 22
entries.
The patch is based on a 2.6.30 kernel also if it has a preliminary integration with the PM_RUNTIME
support.
It works on our st40 (an sh4 cpu based system) no test/porting was done on any ARM platform.
It would be mainly a starting point for a discussion and I'm available to extend/fix/share it.
Regards
Francesco
From 4e065fb9247ec511bfdc88001f0713977d3f4e89 Mon Sep 17 00:00:00 2001
From: Francesco Virlinzi <[email protected]>
Date: Fri, 23 Oct 2009 15:26:42 +0200
Subject: [PATCH] generic clock framework
version: 0.6.2
--- drivers/base/Makefile | 4 + drivers/base/base.h | 5 + drivers/base/clk.c | 1606 +++++++++++++++++++++++++++++++++++++++ drivers/base/clk.h | 319 ++++++++ drivers/base/clk_pm.c | 197 +++++ drivers/base/clk_utils.c | 456 +++++++++++ drivers/base/init.c | 1 + drivers/base/platform.c | 27 + include/linux/clk.h | 251 ++++++ include/linux/platform_device.h | 9 + init/Kconfig | 23 + 11 files changed, 2898 insertions(+), 0 deletions(-) create mode 100644 drivers/base/clk.c create mode 100644 drivers/base/clk.h create mode 100644 drivers/base/clk_pm.c create mode 100644 drivers/base/clk_utils.c
drivers/base/Makefile +4 -0
@@ -16,6 +16,10 @@ ifeq ($(CONFIG_SYSFS),y) obj-$(CONFIG_MODULES) += module.o endif obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o +ifdef CONFIG_GENERIC_CLK_FM +obj-y += clk.o clk_utils.o +obj-$(CONFIG_PM) += clk_pm.o +endif ifeq ($(CONFIG_DEBUG_DRIVER),y) EXTRA_CFLAGS += -DDEBUG
drivers/base/base.h +5 -0
@@ -94,6 +94,11 @@ extern int devices_init(void);extern int buses_init (void );extern int classes_init (void );extern int firmware_init (void ); +#ifdef CONFIG_GENERIC_CLK_FM +extern int clock_init (void ); +#else +static inline int clock_init (void ){return 0 ; } +#endif #ifdef CONFIG_SYS_HYPERVISOR extern int hypervisor_init (void );#else
drivers/base/clk.c new file +1606 -0
1,606 lines not on this page · raw message
drivers/base/clk.h new file +319 -0
319 lines not on this page · raw message
drivers/base/clk_pm.c new file +197 -0
197 lines not on this page · raw message
drivers/base/clk_utils.c new file +456 -0
456 lines not on this page · raw message
drivers/base/init.c +1 -0
@@ -24,6 +24,7 @@ void __init driver_init(void)buses_init ();classes_init ();firmware_init (); +clock_init ();hypervisor_init ();/* These are also core pieces, but must come after the
drivers/base/platform.c +27 -0
@@ -17,6 +17,8 @@#include <linux/bootmem.h> #include <linux/err.h> #include <linux/slab.h> +#include <linux/clk.h> +#include "clk.h" #include "base.h"
@@ -272,9 +274,20 @@ int platform_device_add(struct platform_device *pdev)pr_debug ("Registering platform device '%s'. Parent at %s\n" ,dev_name (&pdev->dev),dev_name (pdev->dev.parent)); +#ifdef CONFIG_GENERIC_CLK_FM +clk_add_device (pdev,PDEV_ADDING ); + + ret =device_add (&pdev->dev); + +clk_add_device (pdev, (ret ?PDEV_ADD_FAILED :PDEV_ADDED )); + +if (ret ==0 ) +return ret; +#else ret =device_add (&pdev->dev);if (ret ==0 )return ret; +#endif failed:while (--i >=0 ) {
@@ -311,6 +324,9 @@ void platform_device_del(struct platform_device *pdev)if (type ==IORESOURCE_MEM || type ==IORESOURCE_IO )release_resource (r); } +#ifdef CONFIG_GENERIC_CLK_FM +clk_del_device (pdev); +#endif } }EXPORT_SYMBOL_GPL (platform_device_del);
@@ -445,7 +461,18 @@ static int platform_drv_probe(struct device *_dev)struct platform_driver *drv =to_platform_driver (_dev->driver);struct platform_device *dev =to_platform_device (_dev); +#ifdef CONFIG_GENERIC_CLK_FM +int ret; + ret =clk_probe_device (dev,PDEV_PROBEING ); +if (ret) +return ret; + ret = drv->probe (dev); + +clk_probe_device (dev, (ret ?PDEV_PROBE_FAILED :PDEV_PROBED )); +return ret; +#else return drv->probe (dev); +#endif }static int platform_drv_probe_fail (struct device *_dev)
include/linux/clk.h +251 -0
261 lines not on this page · raw message
include/linux/platform_device.h +9 -0
@@ -12,6 +12,7 @@#define _PLATFORM_DEVICE_H_#include <linux/device.h> +#include <linux/clk.h> #include <linux/mod_devicetable.h> struct platform_device {
@@ -22,6 +23,11 @@ struct platform_device {struct resource * resource;struct platform_device_id *id_entry; +#ifdef CONFIG_GENERIC_CLK_FM +unsigned long clk_state;/* used by the core */ +unsigned long nr_clks; +struct pdev_clk_info *clks; +#endif };#define platform_get_device_id (pdev) ((pdev)->id_entry)
@@ -61,6 +67,9 @@ struct platform_driver {int (*resume_early)(struct platform_device *);int (*resume)(struct platform_device *);struct device_driver driver; +#ifdef CONFIG_GENERIC_CLK_FM +int (*notify)(unsigned long code,struct platform_device *,void *); +#endif struct platform_device_id *id_table; };
init/Kconfig +23 -0
@@ -1042,6 +1042,29 @@ config SLOW_WORK See Documentation/slow-work.txt. +config GENERIC_CLK_FM + default n + depends on EXPERIMENTAL + bool "Generic Clock Framework" + help + Add the clock framework in the Linux driver model + to track the clocks used by each devices and drivers + +config CLK_FORCE_GENERIC_EVALUATE + depends on GENERIC_CLK_FM + default n + bool "Force the clk_generic_evaluate_rate" + help + Say the if you want use the clk_generic_evaluate_rate on every clock + without evaluate_rate + +config CLK_DEBUG + depends on GENERIC_CLK_FM + default n + bool "Debug the Generic Clk Framework" + help + Prints some message to debug the clock framework + endmenu # General setup config HAVE_GENERIC_DMA_COHERENT
Signature · 1 line
1.6.2.5
Quoted 11 lines · Francesco VIRLINZI
Hi all
I'm Francesco and I work in STMicroelectronics
In the last ELC-E_2009 I spoke on a generic clock framework I'm working on
(see
http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&do=view&target=ELC_E_2009_Generic_Clock_Framework.pdf).I wrote the gcf to manage both clocks the
platform_devicesduring a clock operation.
This looks good to me, in principle, but I'm not a clock or PM expert. I would recommend sending this to the linux-kernel and linux-pm lists as well. I think you'll get a wider audience for feedback.
-- Tim
=============================
Tim Bird
Architecture Group Chair, CE Linux Forum Senior Staff Engineer, Sony Corporation of America
=============================
PATCH 1/1 generic clock framework
Hi Tim
Thanks for your feedback.
ARM mail list was already involved.
Regards
Francesco
Quoted 28 lines · Tim Bird
Quoted 4 lines · Francesco VIRLINZI
Hi all
I'm Francesco and I work in STMicroelectronics
Quoted 8 lines
In the last ELC-E_2009 I spoke on a generic clock framework I'm working on
(see
http://tree.celinuxforum.org/CelfPubWiki/ELCEurope2009Presentations?action=AttachFile&do=view&target=ELC_E_2009_Generic_Clock_Framework.pdf).I wrote the gcf to manage both clocks the
platform_devicesduring a clock operation.This looks good to me, in principle, but I'm not a clock or PM expert. I would recommend sending this to the linux-kernel and linux-pm lists as well. I think you'll get a wider audience for feedback.
-- Tim=============================
Tim Bird
Architecture Group Chair, CE Linux Forum Senior Staff Engineer, Sony Corporation of America
=============================