Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Toshiba TC6387XB support
  3  * Copyright (c) 2005 Ian Molton
  4  *
  5  * This program is free software; you can redistribute it and/or modify
  6  * it under the terms of the GNU General Public License version 2 as
  7  * published by the Free Software Foundation.
  8  *
  9  * This file contains TC6387XB base support.
 10  *
 11  */
 12 
 13 #include <linux/module.h>
 14 #include <linux/platform_device.h>
 15 #include <linux/clk.h>
 16 #include <linux/err.h>
 17 #include <linux/mfd/core.h>
 18 #include <linux/mfd/tmio.h>
 19 #include <linux/mfd/tc6387xb.h>
 20 
 21 enum {
 22         TC6387XB_CELL_MMC,
 23 };
 24 
 25 #ifdef CONFIG_PM
 26 static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
 27 {
 28         struct clk *clk32k = platform_get_drvdata(dev);
 29         struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
 30 
 31         if (pdata && pdata->suspend)
 32                 pdata->suspend(dev);
 33         clk_disable(clk32k);
 34 
 35         return 0;
 36 }
 37 
 38 static int tc6387xb_resume(struct platform_device *dev)
 39 {
 40         struct clk *clk32k = platform_get_drvdata(dev);
 41         struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
 42 
 43         clk_enable(clk32k);
 44         if (pdata && pdata->resume)
 45                 pdata->resume(dev);
 46 
 47         return 0;
 48 }
 49 #else
 50 #define tc6387xb_suspend  NULL
 51 #define tc6387xb_resume   NULL
 52 #endif
 53 
 54 /*--------------------------------------------------------------------------*/
 55 
 56 static int tc6387xb_mmc_enable(struct platform_device *mmc)
 57 {
 58         struct platform_device *dev      = to_platform_device(mmc->dev.parent);
 59         struct clk *clk32k = platform_get_drvdata(dev);
 60 
 61         clk_enable(clk32k);
 62 
 63         return 0;
 64 }
 65 
 66 static int tc6387xb_mmc_disable(struct platform_device *mmc)
 67 {
 68         struct platform_device *dev      = to_platform_device(mmc->dev.parent);
 69         struct clk *clk32k = platform_get_drvdata(dev);
 70 
 71         clk_disable(clk32k);
 72 
 73         return 0;
 74 }
 75 
 76 /*--------------------------------------------------------------------------*/
 77 
 78 static struct tmio_mmc_data tc6387xb_mmc_data = {
 79         .hclk = 24000000,
 80 };
 81 
 82 static struct resource tc6387xb_mmc_resources[] = {
 83         {
 84                 .start = 0x800,
 85                 .end   = 0x9ff,
 86                 .flags = IORESOURCE_MEM,
 87         },
 88         {
 89                 .start = 0x200,
 90                 .end   = 0x2ff,
 91                 .flags = IORESOURCE_MEM,
 92         },
 93         {
 94                 .start = 0,
 95                 .end   = 0,
 96                 .flags = IORESOURCE_IRQ,
 97         },
 98 };
 99 
100 static struct mfd_cell tc6387xb_cells[] = {
101         [TC6387XB_CELL_MMC] = {
102                 .name = "tmio-mmc",
103                 .enable = tc6387xb_mmc_enable,
104                 .disable = tc6387xb_mmc_disable,
105                 .driver_data = &tc6387xb_mmc_data,
106                 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
107                 .resources = tc6387xb_mmc_resources,
108         },
109 };
110 
111 static int tc6387xb_probe(struct platform_device *dev)
112 {
113         struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
114         struct resource *iomem;
115         struct clk *clk32k;
116         int irq, ret;
117 
118         iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
119         if (!iomem) {
120                 return -EINVAL;
121         }
122 
123         ret  = platform_get_irq(dev, 0);
124         if (ret >= 0)
125                 irq = ret;
126         else
127                 goto err_resource;
128 
129         clk32k = clk_get(&dev->dev, "CLK_CK32K");
130         if (IS_ERR(clk32k)) {
131                 ret = PTR_ERR(clk32k);
132                 goto err_resource;
133         }
134         platform_set_drvdata(dev, clk32k);
135 
136         if (pdata && pdata->enable)
137                 pdata->enable(dev);
138 
139         printk(KERN_INFO "Toshiba tc6387xb initialised\n");
140 
141         tc6387xb_cells[TC6387XB_CELL_MMC].platform_data =
142                 &tc6387xb_cells[TC6387XB_CELL_MMC];
143         tc6387xb_cells[TC6387XB_CELL_MMC].data_size =
144                 sizeof(tc6387xb_cells[TC6387XB_CELL_MMC]);
145 
146         ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
147                               ARRAY_SIZE(tc6387xb_cells), iomem, irq);
148 
149         if (!ret)
150                 return 0;
151 
152         clk_put(clk32k);
153 err_resource:
154         return ret;
155 }
156 
157 static int tc6387xb_remove(struct platform_device *dev)
158 {
159         struct clk *clk32k = platform_get_drvdata(dev);
160 
161         mfd_remove_devices(&dev->dev);
162         clk_disable(clk32k);
163         clk_put(clk32k);
164         platform_set_drvdata(dev, NULL);
165 
166         return 0;
167 }
168 
169 
170 static struct platform_driver tc6387xb_platform_driver = {
171         .driver = {
172                 .name           = "tc6387xb",
173         },
174         .probe          = tc6387xb_probe,
175         .remove         = tc6387xb_remove,
176         .suspend        = tc6387xb_suspend,
177         .resume         = tc6387xb_resume,
178 };
179 
180 
181 static int __init tc6387xb_init(void)
182 {
183         return platform_driver_register(&tc6387xb_platform_driver);
184 }
185 
186 static void __exit tc6387xb_exit(void)
187 {
188         platform_driver_unregister(&tc6387xb_platform_driver);
189 }
190 
191 module_init(tc6387xb_init);
192 module_exit(tc6387xb_exit);
193 
194 MODULE_DESCRIPTION("Toshiba TC6387XB core driver");
195 MODULE_LICENSE("GPL v2");
196 MODULE_AUTHOR("Ian Molton");
197 MODULE_ALIAS("platform:tc6387xb");
198 
  This page was automatically generated by the LXR engine.