Input: sprd_eic_keys: remove event log
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / sipc / stty.c
1 /*
2  * Copyright (C) 2012 Spreadtrum Communications Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
18
19 #include <linux/sipc.h>
20 #include <linux/stty.h>
21 #include <linux/types.h>
22 #include <linux/kdev_t.h>
23 #include <linux/tty.h>
24 #include <linux/vt_kern.h>
25 #include <linux/init.h>
26 #include <linux/console.h>
27 #include <linux/delay.h>
28 #ifdef CONFIG_OF
29 #include <linux/of_device.h>
30 #endif
31
32 #include <linux/compat.h>
33 #include <linux/tty_flip.h>
34 #include <linux/kthread.h>
35
36 #ifdef CONFIG_SPRD_2351
37 #include <linux/sprd_2351.h>
38 #endif
39
40
41 #define STTY_DEV_MAX_NR         1
42 #define STTY_MAX_DATA_LEN               4096
43
44 #define STTY_STATE_OPEN         1
45 #define STTY_STATE_CLOSE        0
46
47 struct stty_device {
48         struct stty_init_data   *pdata;
49         struct tty_port                 *port;
50         struct tty_struct               *tty;
51         struct tty_driver               *driver;
52
53         /* stty state */
54         uint32_t                state;
55         struct mutex            stat_lock;
56 };
57
58 static void stty_handler (int event, void* data)
59 {
60         struct stty_device *stty = data;
61         int i, cnt = 0;
62         unsigned char buf[STTY_MAX_DATA_LEN] = {0};
63
64         pr_debug("stty handler event=%d \n", event);
65
66         switch(event) {
67                 case SBUF_NOTIFY_WRITE:
68                         break;
69                 case SBUF_NOTIFY_READ:
70                         cnt = sbuf_read(stty->pdata->dst, stty->pdata->channel,
71                                         stty->pdata->bufid,(void *)buf, STTY_MAX_DATA_LEN, 0);
72                         pr_debug("stty handler read data len =%d \n", cnt);
73                         mutex_lock(&(stty->stat_lock));
74                         if ((stty->state == STTY_STATE_OPEN) && (cnt > 0)) {
75                                 for(i = 0; i < cnt; i++) {
76                                         tty_insert_flip_char(stty->port, buf[i], TTY_NORMAL);
77                                 }
78                                 tty_schedule_flip(stty->port);
79                         }
80                         mutex_unlock(&(stty->stat_lock));
81                         break;
82                 default:
83                         printk(KERN_ERR "Received event is invalid(event=%d)\n", event);
84         }
85
86         return;
87 }
88
89 static int stty_open(struct tty_struct *tty, struct file * filp)
90 {
91         struct stty_device *stty = NULL;
92         struct tty_driver *driver = NULL;
93
94         if (tty == NULL) {
95                 printk(KERN_ERR "stty open input tty is NULL!\n");
96                 return -ENOMEM;
97         }
98         driver = tty->driver;
99         stty = (struct stty_device *)driver->driver_state;
100
101         if(stty == NULL) {
102                 printk(KERN_ERR "stty open input stty NULL!\n");
103                 return -ENOMEM;
104         }
105
106         if (sbuf_status(stty->pdata->dst, stty->pdata->channel) != 0) {
107                 printk(KERN_ERR "stty_open sbuf not ready to open!dst=%d,channel=%d\n"
108                         ,stty->pdata->dst,stty->pdata->channel);
109                 return -ENODEV;
110         }
111         stty->tty = tty;
112         tty->driver_data = (void *)stty;
113
114         mutex_lock(&(stty->stat_lock));
115         stty->state = STTY_STATE_OPEN;
116         mutex_unlock(&(stty->stat_lock));
117
118 #ifdef CONFIG_SPRD_2351
119     rf2351_gpio_ctrl_power_enable(1);
120 #endif
121 #ifdef CONFIG_ARCH_SCX20
122     rf2351_vddwpa_ctrl_power_enable(1);
123 #endif
124
125         pr_debug("stty_open device success! \n");
126
127         return 0;
128 }
129
130 static void stty_close(struct tty_struct *tty, struct file * filp)
131 {
132         struct stty_device *stty = NULL;
133
134         if (tty == NULL) {
135                 printk(KERN_ERR "stty close input tty is NULL!\n");
136                 return;
137         }
138         stty = (struct stty_device *) tty->driver_data;
139         if (stty == NULL) {
140                 printk(KERN_ERR "stty close s tty is NULL!\n");
141                 return;
142         }
143
144         mutex_lock(&(stty->stat_lock));
145         stty->state = STTY_STATE_CLOSE;
146         mutex_unlock(&(stty->stat_lock));
147
148         pr_debug("stty_close device success !\n");
149
150 #ifdef CONFIG_SPRD_2351
151     rf2351_gpio_ctrl_power_enable(0);
152 #endif
153 #ifdef CONFIG_ARCH_SCX20
154     rf2351_vddwpa_ctrl_power_enable(0);
155 #endif
156
157         return;
158 }
159
160 static int stty_write(struct tty_struct * tty,
161               const unsigned char *buf, int count)
162 {
163         struct stty_device *stty = tty->driver_data;
164         int cnt;
165         pr_debug("stty write count=%d \n", count);
166
167         cnt = sbuf_write(stty->pdata->dst, stty->pdata->channel,
168                                         stty->pdata->bufid, (void *)buf, count, -1);
169         return cnt;
170 }
171
172
173 static void stty_flush_chars(struct tty_struct *tty)
174 {
175         return;
176 }
177
178 static int stty_write_room(struct tty_struct *tty)
179 {
180         return INT_MAX;
181 }
182
183 static const struct tty_operations stty_ops = {
184         .open  = stty_open,
185         .close = stty_close,
186         .write = stty_write,
187         .flush_chars = stty_flush_chars,
188         .write_room  = stty_write_room,
189 };
190
191 static struct tty_port *stty_port_init()
192 {
193         struct tty_port *port = NULL;
194
195         port = kzalloc(sizeof(struct tty_port),GFP_KERNEL);
196         if (port == NULL) {
197                 printk(KERN_ERR "stty_port_init Failed to allocate device!\n");
198                 return NULL;
199         }
200         tty_port_init(port);
201         return port;
202 }
203
204 static int stty_driver_init(struct stty_device *device)
205 {
206         struct tty_driver *driver;
207         int ret = 0;
208
209         mutex_init(&(device->stat_lock));
210
211         device->port = stty_port_init();
212         if (!device->port) {
213                 return -ENOMEM;
214         }
215
216         driver = alloc_tty_driver(STTY_DEV_MAX_NR);
217         if (!driver)
218                 return -ENOMEM;
219         /*
220          * Initialize the tty_driver structure
221          * Entries in stty_driver that are NOT initialized:
222          * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
223          */
224         driver->owner = THIS_MODULE;
225         driver->driver_name = device->pdata->name;
226         driver->name = device->pdata->name;
227         driver->major = 0;
228         driver->type = TTY_DRIVER_TYPE_SYSTEM;
229         driver->subtype = SYSTEM_TYPE_TTY;
230         driver->init_termios = tty_std_termios;
231         driver->driver_state = (void*)device;
232         device->driver = driver;
233          /* initialize the tty driver */
234         tty_set_operations(driver, &stty_ops);
235         tty_port_link_device(device->port, driver, 0);
236         ret = tty_register_driver(driver);
237         if (ret) {
238                 put_tty_driver(driver);
239                 tty_port_destroy(device->port);
240                 return ret;
241         }
242         return ret;
243 }
244
245 static void stty_driver_exit(struct stty_device *device)
246 {
247         struct tty_driver *driver = device->driver;
248         tty_unregister_driver(driver);
249         tty_port_destroy(device->port);
250 }
251
252 static int stty_parse_dt(struct stty_init_data **init, struct device *dev)
253 {
254 #ifdef CONFIG_OF
255         struct of_device_node *np = dev->of_node;
256         struct stty_init_data *pdata = NULL;
257         int ret;
258         uint32_t data;
259
260         pdata = kzalloc(sizeof(struct stty_init_data), GFP_KERNEL);
261         if (!pdata) {
262                 return -ENOMEM;
263         }
264
265         ret = of_property_read_string(np, "sprd,name", (const char **)&pdata->name);
266         if (ret) {
267                 goto error;
268         }
269
270         ret = of_property_read_u32(np, "sprd,dst", (uint32_t *)&data);
271         if (ret) {
272                 goto error;
273         }
274         pdata->dst = (uint8_t)data;
275
276         ret = of_property_read_u32(np, "sprd,channel", (uint32_t *)&data);
277         if (ret) {
278                 goto error;
279         }
280         pdata->channel = (uint8_t)data;
281
282         ret = of_property_read_u32(np, "sprd,bufid", (uint32_t *)&pdata->bufid);
283         if (ret) {
284                 goto error;
285         }
286
287         *init = pdata;
288         return 0;
289 error:
290         kfree(pdata);
291         *init = NULL;
292         return ret;
293 #else
294         return -ENODEV;
295 #endif
296 }
297
298 static inline void stty_destroy_pdata(struct stty_init_data **init)
299 {
300 #ifdef CONFIG_OF
301         struct stty_init_data *pdata = *init;
302
303         if (pdata) {
304                 kfree(pdata);
305         }
306
307         *init = NULL;
308 #else
309         return;
310 #endif
311 }
312
313
314 static int  stty_probe(struct platform_device *pdev)
315 {
316         struct stty_init_data *pdata = (struct stty_init_data*)pdev->dev.platform_data;
317         struct stty_device *stty;
318         int rval= 0;
319
320         if (pdev->dev.of_node && !pdata) {
321                 rval = stty_parse_dt(&pdata, &pdev->dev);
322                 if (rval) {
323                         printk(KERN_ERR "failed to parse styy device tree, ret=%d\n", rval);
324                         return rval;
325                 }
326         }
327         pr_info("stty: after parse device tree, name=%s, dst=%u, channel=%u, bufid=%u\n",
328                 pdata->name, pdata->dst, pdata->channel, pdata->bufid);
329
330         stty = kzalloc(sizeof(struct stty_device),GFP_KERNEL);
331         if (stty == NULL) {
332                 stty_destroy_pdata(&pdata);
333                 printk(KERN_ERR "stty Failed to allocate device!\n");
334                 return -ENOMEM;
335         }
336
337         stty->pdata = pdata;
338         rval = stty_driver_init(stty);
339         if (rval) {
340                 kfree(stty);
341                 stty_destroy_pdata(&pdata);
342                 printk(KERN_ERR "stty driver init error!\n");
343                 return -EINVAL;
344         }
345
346         rval = sbuf_register_notifier(pdata->dst, pdata->channel,
347                                         pdata->bufid, stty_handler, stty);
348         if (rval) {
349                 stty_driver_exit(stty);
350                 kfree(stty->port);
351                 kfree(stty);
352                 printk(KERN_ERR "regitster notifier failed (%d)\n", rval);
353                 return rval;
354         }
355
356         printk( "stty_probe init device addr: 0x%0x\n", (void *)stty);
357         platform_set_drvdata(pdev, stty);
358
359         return 0;
360 }
361
362 static int  stty_remove(struct platform_device *pdev)
363 {
364         struct stty_device *stty = platform_get_drvdata(pdev);
365         int rval;
366
367         rval = sbuf_register_notifier(stty->pdata->dst, stty->pdata->channel,
368                                         stty->pdata->bufid, NULL, NULL);
369         if (rval) {
370                 printk(KERN_ERR " unregitster notifier failed (%d)\n", rval);
371                 return rval;
372         }
373
374         stty_driver_exit(stty);
375         kfree(stty->port);
376         stty_destroy_pdata(&stty->pdata);
377         kfree(stty);
378         platform_set_drvdata(pdev, NULL);
379         return 0;
380 }
381
382 static const struct of_device_id stty_match_table[] = {
383         { .compatible = "sprd,stty4bt", },
384         { },
385 };
386
387 static struct platform_driver stty_driver = {
388         .driver = {
389                 .owner = THIS_MODULE,
390                 .name = "sttybt",
391                 .of_match_table = stty_match_table,
392         },
393         .probe = stty_probe,
394         .remove = stty_remove,
395 };
396
397 static int __init stty_init(void)
398 {
399         return platform_driver_register(&stty_driver);
400 }
401
402 static void __exit stty_exit(void)
403 {
404         platform_driver_unregister(&stty_driver);
405 }
406
407 late_initcall(stty_init);
408 module_exit(stty_exit);
409
410 MODULE_AUTHOR("Dewu Jiang");
411 MODULE_DESCRIPTION("SIPC/stty driver");
412 MODULE_LICENSE("GPL");