/* * Copyright (C) ST-Ericsson SA 2011 * * Author: Hemant Gupta * Author: Tomasz Hliwiak * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, as * published by the Free Software Foundation. * */ #include #include #include #include #include #include #include #include #include "clock.h" #include "cg2900.h" static DEFINE_MUTEX(cg2900_clk_mutex); static struct cg2900_user_data *pf_data; static struct clk_lookup *cg2900_clk_lookup; /** * cg2900_clk_enable() - Enables CG2900 Clock * * Enables CG2900 Clock by starting CG2900. * * Returns: * 0 if success. * -EINVAL if stored pf_data is NULL. * Error codes generated by open. */ static int cg2900_clk_enable(struct clk *clk) { int err = -EINVAL; if (pf_data) err = pf_data->open(pf_data); return err; } /** * cg2900_clk_disable() - Disables CG2900 Clock * * Disables CG2900 Clock by switching off CG2900. */ static void cg2900_clk_disable(struct clk *clk) { if (pf_data) pf_data->close(pf_data); } static struct clkops cg2900_clk_ops = { .enable = cg2900_clk_enable, .disable = cg2900_clk_disable, }; static struct clk cg2900_clk = { .name = "cg2900_clk", .ops = &cg2900_clk_ops, .mutex = &cg2900_clk_mutex, }; /** * cg2900_read_cb() - Dummy callback for cg2900 core read. * * Function is required by cg2900_core->open(). */ static void cg2900_read_cb(struct cg2900_user_data *user, struct sk_buff *skb) { kfree_skb(skb); } /** * cg2900_core_probe() - Initialize resources. * * Function initializes pf_data structure and also adds the cg2900 * clock source. */ static int __devinit cg2900_core_probe(struct platform_device *pdev) { cg2900_clk_lookup = clkdev_alloc(&cg2900_clk, "sys_clk_out", "cw1200_wlan"); if (!cg2900_clk_lookup) return -ENOMEM; clkdev_add(cg2900_clk_lookup); pf_data = dev_get_platdata(&pdev->dev); pf_data->dev = &pdev->dev; pf_data->read_cb = cg2900_read_cb; return 0; } /** * cg2900_core_remove() - Clean resources. * * Function cleans pf_data structure and removes the clock source. */ static int __devexit cg2900_core_remove(struct platform_device *pdev) { clkdev_drop(cg2900_clk_lookup); pf_data = NULL; return 0; } static struct platform_driver cg2900_core_ctrl_driver = { .driver = { .name = "cg2900-core", .owner = THIS_MODULE, }, .probe = cg2900_core_probe, .remove = __devexit_p(cg2900_core_remove), }; /** * clock_cg2900_init() - Register Platform Data * * Registers the platform data. */ static int __init clock_cg2900_init(void) { return platform_driver_register(&cg2900_core_ctrl_driver); } /** * clock_cg2900_exit() - Unregister Platform Data * * Unregister Platform Data */ static void __exit clock_cg2900_exit(void) { platform_driver_unregister(&cg2900_core_ctrl_driver); } module_init(clock_cg2900_init); module_exit(clock_cg2900_exit);