ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / tegra_bbc_proxy.c
1 /*
2  * arch/arm/mach-tegra/tegra_bbc_proxy.c
3  *
4  * Copyright (C) 2013 NVIDIA Corporation. All rights reserved.
5  *
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 #include <linux/err.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/slab.h>
24 #include <linux/edp.h>
25
26 #include <mach/isomgr.h>
27 #include <mach/latency_allowance.h>
28 #include <mach/tegra_bbc_proxy.h>
29 #include <mach/tegra_bbc_thermal.h>
30
31 #define MAX_MODEM_EDP_STATES 10
32
33 #define MAX_ISO_BW_REQ  1200000
34
35 struct tegra_bbc_proxy {
36         struct edp_client *modem_boot_edp_client;
37         struct edp_client modem_edp_client;
38         unsigned int modem_edp_states[MAX_MODEM_EDP_STATES];
39         int edp_client_registered;
40         int edp_boot_client_registered;
41         int edp_initialized;
42         char *edp_manager_name;
43         char *ap_name;
44         unsigned int i_breach_ppm; /* percent time current exceeds i_thresh */
45         unsigned int i_thresh_3g_adjperiod; /* 3g i_thresh adj period */
46         unsigned int i_thresh_lte_adjperiod; /* lte i_thresh adj period */
47         unsigned int threshold; /* current edp threshold value */
48         unsigned int state; /* current edp state value */
49         struct mutex edp_lock; /* lock for edp operations */
50
51         tegra_isomgr_handle isomgr_handle;
52         /* last iso settings with proxy driver */
53         unsigned int last_bw;
54         unsigned int last_ult;
55         unsigned int margin; /* current iso margin bw request */
56         unsigned int bw; /* current iso bandwidth request */
57         unsigned int lt; /* current iso latency tolerance for emc frequency
58                             switches */
59         struct mutex iso_lock; /* lock for iso operations */
60
61         struct regulator *sim0;
62         struct regulator *sim1;
63         struct regulator *rf1v7;
64         struct regulator *rf2v65;
65 };
66
67
68 #define EDP_INT_ATTR(field)                                             \
69 static ssize_t                                                          \
70 field ## _show(struct device *pdev, struct device_attribute *attr,      \
71                char *buf)                                               \
72 {                                                                       \
73         struct tegra_bbc_proxy *bbc = dev_get_drvdata(pdev);            \
74                                                                         \
75         if (!bbc)                                                       \
76                 return -EAGAIN;                                         \
77                                                                         \
78         return sprintf(buf, "%d\n", bbc->field);                        \
79 }                                                                       \
80 static DEVICE_ATTR(field, S_IRUSR, field ## _show, NULL);
81
82 EDP_INT_ATTR(i_breach_ppm);
83 EDP_INT_ATTR(i_thresh_3g_adjperiod);
84 EDP_INT_ATTR(i_thresh_lte_adjperiod);
85
86 static ssize_t i_max_store(struct device *pdev, struct device_attribute *attr,
87                            const char *buff, size_t size)
88 {
89         char *s, *state_i_max, buf[50];
90         unsigned int states[MAX_MODEM_EDP_STATES];
91         unsigned int num_states = 0;
92         int ret;
93
94         /* retrieve max current for supported states */
95         strlcpy(buf, buff, sizeof(buf));
96         s = strim(buf);
97         while (s && (num_states < MAX_MODEM_EDP_STATES)) {
98                 state_i_max = strsep(&s, ",");
99                 ret = kstrtoul(state_i_max, 10,
100                         (unsigned long *)&states[num_states]);
101                 if (ret) {
102                         dev_err(pdev, "invalid bbc state-current setting\n");
103                         goto done;
104                 }
105                 num_states++;
106         }
107
108         if (s && (num_states >= MAX_MODEM_EDP_STATES)) {
109                 dev_err(pdev, "number of bbc EDP states exceeded max\n");
110                 ret = -EINVAL;
111                 goto done;
112         }
113
114         ret = tegra_bbc_proxy_edp_register(pdev, num_states, states);
115         if (ret)
116                 goto done;
117
118         ret = size;
119 done:
120         return ret;
121 }
122 static DEVICE_ATTR(i_max, S_IWUSR, NULL, i_max_store);
123
124 int tegra_bbc_proxy_edp_register(struct device *dev, u32 num_states,
125                                 u32 *states)
126 {
127         struct edp_manager *mgr;
128         struct edp_client *ap;
129         int ret;
130         int i;
131         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
132
133         mutex_lock(&bbc->edp_lock);
134
135         /* client should only be registered once per modem boot */
136         if (bbc->edp_client_registered) {
137                 dev_err(dev, "bbc edp client already registered\n");
138                 ret = -EBUSY;
139                 goto done;
140         }
141
142         memset(bbc->modem_edp_states, 0, sizeof(bbc->modem_edp_states));
143         memset(&bbc->modem_edp_client, 0, sizeof(bbc->modem_edp_client));
144
145         /* retrieve max current for supported states */
146         for (i = 0; i < num_states; i++) {
147                 bbc->modem_edp_states[i] = *states;
148                 states++;
149         }
150
151         strncpy(bbc->modem_edp_client.name, "bbc", EDP_NAME_LEN);
152         bbc->modem_edp_client.name[EDP_NAME_LEN - 1] = '\0';
153         bbc->modem_edp_client.states = bbc->modem_edp_states;
154         bbc->modem_edp_client.num_states = num_states;
155         bbc->modem_edp_client.e0_index = 0;
156         bbc->modem_edp_client.max_borrowers = 1;
157         bbc->modem_edp_client.priority = EDP_MAX_PRIO;
158
159         mgr = edp_get_manager(bbc->edp_manager_name);
160         if (!mgr) {
161                 dev_err(dev, "can't get edp manager\n");
162                 ret = -EINVAL;
163                 goto done;
164         }
165
166         /* unregister modem_boot_client */
167         ret = edp_unregister_client(bbc->modem_boot_edp_client);
168         if (ret) {
169                 dev_err(dev, "unable to register bbc boot edp client\n");
170                 goto done;
171         }
172
173         bbc->edp_boot_client_registered = 0;
174
175         /* register modem client */
176         ret = edp_register_client(mgr, &bbc->modem_edp_client);
177         if (ret) {
178                 dev_err(dev, "unable to register bbc edp client\n");
179                 goto done;
180         }
181
182         bbc->edp_client_registered = 1;
183
184         ap = edp_get_client(bbc->ap_name);
185         if (!ap) {
186                 dev_err(dev, "can't get ap client\n");
187                 goto done;
188         }
189
190         ret = edp_register_loan(&bbc->modem_edp_client, ap);
191         if (ret && ret != -EEXIST) {
192                 dev_err(dev, "unable to register bbc loan to ap\n");
193                 goto done;
194         }
195
196 done:
197         mutex_unlock(&bbc->edp_lock);
198         return ret;
199 }
200 EXPORT_SYMBOL(tegra_bbc_proxy_edp_register);
201
202 static int bbc_edp_request_unlocked(struct device *dev, u32 mode, u32 state,
203                                 u32 threshold)
204 {
205         int ret;
206         struct edp_client *c;
207         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
208
209         if (!bbc->edp_client_registered)
210                 return -EINVAL;
211
212         if (state != bbc->state) {
213                 c = &bbc->modem_edp_client;
214                 if (state >= c->num_states)
215                         return -EINVAL;
216
217                 ret = edp_update_client_request(c, state, NULL);
218                 if (ret) {
219                         dev_err(dev, "state update to %u failed\n", state);
220                         return ret;
221                 }
222                 bbc->state = state;
223         }
224
225         if (threshold != bbc->threshold) {
226                 ret = edp_update_loan_threshold(&bbc->modem_edp_client,
227                                                 threshold);
228                 if (ret) {
229                         dev_err(dev, "threshold update to %u failed\n",
230                                 threshold);
231                         return ret;
232                 }
233                 bbc->threshold = threshold;
234         }
235
236         return 0;
237 }
238
239 int tegra_bbc_proxy_edp_request(struct device *dev, u32 mode, u32 state,
240                                 u32 threshold)
241 {
242         int ret;
243         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
244
245         mutex_lock(&bbc->edp_lock);
246         ret = bbc_edp_request_unlocked(dev, mode, state, threshold);
247         mutex_unlock(&bbc->edp_lock);
248
249         return ret;
250 }
251 EXPORT_SYMBOL(tegra_bbc_proxy_edp_request);
252
253 static ssize_t request_store(struct device *pdev, struct device_attribute *attr,
254                              const char *buff, size_t size)
255 {
256         struct tegra_bbc_proxy *bbc = dev_get_drvdata(pdev);
257         unsigned int id;
258         int ret;
259
260         if (sscanf(buff, "%u", &id) != 1)
261                 return -EINVAL;
262
263         if (!bbc->edp_client_registered)
264                 return -EINVAL;
265
266         mutex_lock(&bbc->edp_lock);
267         ret = bbc_edp_request_unlocked(pdev, 0, id, bbc->threshold);
268         mutex_unlock(&bbc->edp_lock);
269
270         return ret ? ret : size;
271 }
272 static DEVICE_ATTR(request, S_IWUSR, NULL, request_store);
273
274 static ssize_t threshold_store(struct device *pdev,
275                                struct device_attribute *attr,
276                                const char *buff, size_t size)
277 {
278         struct tegra_bbc_proxy *bbc = dev_get_drvdata(pdev);
279         unsigned int tv;
280         int ret;
281
282         if (sscanf(buff, "%u", &tv) != 1)
283                 return -EINVAL;
284
285         mutex_lock(&bbc->edp_lock);
286         ret = bbc_edp_request_unlocked(pdev, 0, bbc->state, tv);
287         mutex_unlock(&bbc->edp_lock);
288
289         return ret ? ret : size;
290 }
291 static DEVICE_ATTR(threshold, S_IWUSR, NULL, threshold_store);
292
293 static struct device_attribute *edp_attributes[] = {
294         &dev_attr_i_breach_ppm,
295         &dev_attr_i_thresh_3g_adjperiod,
296         &dev_attr_i_thresh_lte_adjperiod,
297         &dev_attr_i_max,
298         &dev_attr_request,
299         &dev_attr_threshold,
300         NULL
301 };
302
303 static ssize_t la_bbcr_store(struct device *dev,
304                 struct device_attribute *attr, const char *buf, size_t size)
305 {
306         unsigned int la_val;
307
308         if (sscanf(buf, "%u", &la_val) != 1)
309                 return -EINVAL;
310         if (la_val > (MAX_ISO_BW_REQ / 1000))
311                 return -EINVAL;
312
313         tegra_set_latency_allowance(TEGRA_LA_BBCR, la_val);
314
315         return size;
316 }
317
318 static ssize_t la_bbcw_store(struct device *dev,
319                 struct device_attribute *attr, const char *buf, size_t size)
320 {
321         unsigned int la_val;
322
323         if (sscanf(buf, "%u", &la_val) != 1)
324                 return -EINVAL;
325         if (la_val > (MAX_ISO_BW_REQ / 1000))
326                 return -EINVAL;
327
328         tegra_set_latency_allowance(TEGRA_LA_BBCW, la_val);
329
330         return size;
331 }
332
333 static int bbc_bw_request_unlocked(struct device *dev, u32 mode, u32 bw,
334                                 u32 lt, u32 margin)
335 {
336         int ret;
337         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
338
339         if (bw > MAX_ISO_BW_REQ)
340                 return -EINVAL;
341
342         if (margin > MAX_ISO_BW_REQ)
343                 return -EINVAL;
344
345         if (margin != bbc->margin) {
346                 ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
347                         margin, true);
348                 if (ret) {
349                         dev_err(dev, "can't margin for bbc bw\n");
350                         return ret;
351                 }
352
353                 bbc->margin = margin;
354         }
355
356         if ((bw != bbc->bw) || (lt != bbc->lt)) {
357                 ret = tegra_isomgr_reserve(bbc->isomgr_handle, bw, lt);
358                 if (!ret) {
359                         dev_err(dev, "can't reserve iso bw\n");
360                         return ret;
361                 }
362                 bbc->bw = bw;
363
364                 ret = tegra_isomgr_realize(bbc->isomgr_handle);
365                 if (!ret) {
366                         dev_err(dev, "can't realize iso bw\n");
367                         return ret;
368                 }
369                 bbc->lt = lt;
370
371                 tegra_set_latency_allowance(TEGRA_LA_BBCR, bw / 1000);
372                 tegra_set_latency_allowance(TEGRA_LA_BBCW, bw / 1000);
373         }
374
375         return 0;
376 }
377
378 int tegra_bbc_proxy_bw_request(struct device *dev, u32 mode, u32 bw, u32 lt,
379                         u32 margin)
380 {
381         int ret;
382         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
383
384         mutex_lock(&bbc->iso_lock);
385         bbc->last_bw = bw;
386         bbc->last_ult = lt;
387
388         ret = bbc_bw_request_unlocked(dev, mode, bw, lt, margin);
389         mutex_unlock(&bbc->iso_lock);
390
391         return ret;
392 }
393 EXPORT_SYMBOL(tegra_bbc_proxy_bw_request);
394
395 int tegra_bbc_proxy_restore_iso(struct device *dev)
396 {
397         int ret;
398         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
399
400         if (!bbc)
401                 return -EINVAL;
402
403         mutex_lock(&bbc->iso_lock);
404         ret = bbc_bw_request_unlocked(dev, 0, bbc->last_bw,
405                                         bbc->last_ult, bbc->margin);
406         mutex_unlock(&bbc->iso_lock);
407
408         return 0;
409 }
410 EXPORT_SYMBOL(tegra_bbc_proxy_restore_iso);
411
412 int tegra_bbc_proxy_clear_iso(struct device *dev)
413 {
414         int ret;
415         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
416
417         if (!bbc)
418                 return -EINVAL;
419
420         mutex_lock(&bbc->iso_lock);
421         ret = bbc_bw_request_unlocked(dev, 0, 0,
422                                         1000, bbc->margin);
423         mutex_unlock(&bbc->iso_lock);
424
425         return 0;
426 }
427 EXPORT_SYMBOL(tegra_bbc_proxy_clear_iso);
428
429 static ssize_t iso_res_realize_store(struct device *dev,
430                 struct device_attribute *attr, const char *buf, size_t size)
431 {
432
433         unsigned int bw;
434         unsigned int ult = 4;
435         char buff[50];
436         char *val, *s;
437         int ret;
438         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
439
440         strlcpy(buff, buf, sizeof(buff));
441         s = strim(buff);
442
443         /* first param is bw */
444         val = strsep(&s, ",");
445         ret = kstrtouint(val, 10, &bw);
446         if (ret) {
447                 pr_err("invalid bw setting\n");
448                 return -EINVAL;
449         }
450
451         /* second param is latency */
452         if (s) {
453                 ret = kstrtouint(s, 10, &ult);
454                 if (ret) {
455                         pr_err("invalid latency setting\n");
456                         return -EINVAL;
457                 }
458         }
459
460         mutex_lock(&bbc->iso_lock);
461         bbc->last_bw = bw;
462         bbc->last_ult = ult;
463
464         ret = bbc_bw_request_unlocked(dev, 0, bw, ult, bbc->margin);
465         mutex_unlock(&bbc->iso_lock);
466
467         return ret ? ret : size;
468 }
469
470 static ssize_t iso_register_store(struct device *dev,
471                 struct device_attribute *attr, const char *buf, size_t size)
472 {
473
474         unsigned int bw;
475         int ret;
476
477         if (sscanf(buf, "%u", &bw) != 1)
478                 return -EINVAL;
479
480         ret = tegra_bbc_proxy_bw_register(dev, bw);
481
482         return ret ? ret : size;
483 }
484
485 int tegra_bbc_proxy_bw_register(struct device *dev, u32 bw)
486 {
487         int ret;
488         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
489
490         mutex_lock(&bbc->iso_lock);
491
492         if (bbc->isomgr_handle)
493                 tegra_isomgr_unregister(bbc->isomgr_handle);
494
495         bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
496                 bw, NULL, NULL);
497         ret = PTR_RET(bbc->isomgr_handle);
498         if (ret)
499                 dev_err(dev, "error registering bbc with isomgr\n");
500
501         ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
502                 bw, true);
503         if (ret)
504                 dev_err(dev, "can't margin for bbc bw\n");
505         else
506                 bbc->margin = bw;
507
508         mutex_unlock(&bbc->iso_lock);
509
510         return ret;
511 }
512 EXPORT_SYMBOL(tegra_bbc_proxy_bw_register);
513
514 static ssize_t iso_margin_store(struct device *dev,
515                 struct device_attribute *attr, const char *buf, size_t size)
516 {
517
518         unsigned int margin;
519         int ret;
520         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);
521
522         if (sscanf(buf, "%u", &margin) != 1)
523                 return -EINVAL;
524
525         mutex_lock(&bbc->iso_lock);
526         ret = bbc_bw_request_unlocked(dev, 0, bbc->bw, bbc->lt, margin);
527         mutex_unlock(&bbc->iso_lock);
528
529         return ret ? ret : size;
530 }
531
532
533 static DEVICE_ATTR(la_bbcr, S_IWUSR, NULL, la_bbcr_store);
534 static DEVICE_ATTR(la_bbcw, S_IWUSR, NULL, la_bbcw_store);
535 static DEVICE_ATTR(iso_reserve_realize, S_IWUSR, NULL, iso_res_realize_store);
536 static DEVICE_ATTR(iso_register, S_IWUSR, NULL, iso_register_store);
537 static DEVICE_ATTR(iso_margin, S_IWUSR, NULL, iso_margin_store);
538
539
540 static struct device_attribute *mc_attributes[] = {
541         &dev_attr_la_bbcr,
542         &dev_attr_la_bbcw,
543         &dev_attr_iso_reserve_realize,
544         &dev_attr_iso_register,
545         &dev_attr_iso_margin,
546         NULL
547 };
548
549
550 #define REG_ATTR(field)                                                 \
551 static ssize_t                                                          \
552 field ## _show_state(struct device *dev, struct device_attribute *attr, \
553                      char *buf)                                         \
554 {                                                                       \
555         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
556                                                                         \
557         if (!bbc)                                                       \
558                 return -EAGAIN;                                         \
559                                                                         \
560         if (regulator_is_enabled(bbc->field))                           \
561                 return sprintf(buf, "enabled\n");                       \
562         else                                                            \
563                 return sprintf(buf, "disabled\n");                      \
564 }                                                                       \
565                                                                         \
566 static ssize_t                                                          \
567 field ## _store_state(struct device *dev, struct device_attribute *attr,\
568                       const char *buf, size_t count)                    \
569 {                                                                       \
570         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
571                                                                         \
572         if (!bbc)                                                       \
573                 return -EAGAIN;                                         \
574                                                                         \
575         if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))     \
576                 regulator_enable(bbc->field);                           \
577         else if (sysfs_streq(buf, "disabled\n") ||                      \
578                  sysfs_streq(buf, "0"))                                 \
579                 regulator_disable(bbc->field);                          \
580                                                                         \
581         return count;                                                   \
582 }                                                                       \
583 static DEVICE_ATTR(field ## _state, 0644,                               \
584                    field ## _show_state, field ## _store_state);        \
585                                                                         \
586 static ssize_t                                                          \
587 field ## _show_microvolts(struct device *dev,                           \
588                           struct device_attribute *attr, char *buf)     \
589 {                                                                       \
590         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
591                                                                         \
592         if (!bbc)                                                       \
593                 return -EAGAIN;                                         \
594                                                                         \
595         return sprintf(buf, "%d\n", regulator_get_voltage(bbc->field)); \
596 }                                                                       \
597                                                                         \
598 static ssize_t                                                          \
599 field ## _store_microvolts(struct device *dev,                          \
600         struct device_attribute *attr, const char *buf, size_t count)   \
601 {                                                                       \
602         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
603         int value;                                                      \
604                                                                         \
605         if (!bbc)                                                       \
606                 return -EAGAIN;                                         \
607                                                                         \
608         if (sscanf(buf, "%d", &value) != 1)                             \
609                 return -EINVAL;                                         \
610                                                                         \
611         if (value)                                                      \
612                 regulator_set_voltage(bbc->field, value, value);        \
613                                                                         \
614         return count;                                                   \
615 }                                                                       \
616 static DEVICE_ATTR(field ## _microvolts, 0644,                          \
617                    field ## _show_microvolts,                           \
618                    field ## _store_microvolts);                         \
619                                                                         \
620 static ssize_t                                                          \
621 field ## _show_mode(struct device *dev, struct device_attribute *attr,  \
622                      char *buf)                                         \
623 {                                                                       \
624         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
625                                                                         \
626         if (!bbc)                                                       \
627                 return -EAGAIN;                                         \
628                                                                         \
629         switch (regulator_get_mode(bbc->field)) {                       \
630         case REGULATOR_MODE_FAST:                                       \
631                 return sprintf(buf, "fast\n");                          \
632         case REGULATOR_MODE_NORMAL:                                     \
633                 return sprintf(buf, "normal\n");                        \
634         case REGULATOR_MODE_IDLE:                                       \
635                 return sprintf(buf, "idle\n");                          \
636         case REGULATOR_MODE_STANDBY:                                    \
637                 return sprintf(buf, "standby\n");                       \
638         }                                                               \
639         return sprintf(buf, "unknown\n");                               \
640 }                                                                       \
641                                                                         \
642 static ssize_t                                                          \
643 field ## _store_mode(struct device *dev, struct device_attribute *attr, \
644                       const char *buf, size_t count)                    \
645 {                                                                       \
646         struct tegra_bbc_proxy *bbc = dev_get_drvdata(dev);             \
647         int mode = 0;                                                   \
648                                                                         \
649         if (!bbc)                                                       \
650                 return -EAGAIN;                                         \
651                                                                         \
652         if (sysfs_streq(buf, "fast\n"))                                 \
653                 mode = REGULATOR_MODE_FAST;                             \
654         else if (sysfs_streq(buf, "normal\n"))                          \
655                 mode = REGULATOR_MODE_NORMAL;                           \
656         else if (sysfs_streq(buf, "idle\n"))                            \
657                 mode = REGULATOR_MODE_IDLE;                             \
658         else if (sysfs_streq(buf, "standby\n"))                         \
659                 mode = REGULATOR_MODE_STANDBY;                          \
660         else                                                            \
661                 return -EINVAL;                                         \
662                                                                         \
663         if (regulator_set_mode(bbc->field, mode))                       \
664                 return -EINVAL;                                         \
665                                                                         \
666         return count;                                                   \
667 }                                                                       \
668 static DEVICE_ATTR(field ## _mode, 0644,                                \
669                    field ## _show_mode, field ## _store_mode);
670
671 REG_ATTR(sim0);
672 REG_ATTR(sim1);
673 REG_ATTR(rf1v7);
674 REG_ATTR(rf2v65);
675
676 static struct device_attribute *sim_attributes[] = {
677         &dev_attr_sim0_state,
678         &dev_attr_sim0_microvolts,
679         &dev_attr_sim0_mode,
680         &dev_attr_sim1_state,
681         &dev_attr_sim1_microvolts,
682         &dev_attr_sim1_mode,
683         NULL
684 };
685
686 static struct device_attribute *rf_attributes[] = {
687         &dev_attr_rf1v7_state,
688         &dev_attr_rf1v7_microvolts,
689         &dev_attr_rf1v7_mode,
690         &dev_attr_rf2v65_state,
691         &dev_attr_rf2v65_microvolts,
692         &dev_attr_rf2v65_mode,
693         NULL
694 };
695
696 static int tegra_bbc_proxy_probe(struct platform_device *pdev)
697 {
698         struct tegra_bbc_proxy_platform_data *pdata = pdev->dev.platform_data;
699         struct tegra_bbc_proxy *bbc;
700         struct edp_manager *mgr;
701         struct device_attribute **attrs;
702         struct device_attribute *attr;
703         int ret = 0;
704
705         /* check for platform data */
706         if (!pdata) {
707                 dev_err(&pdev->dev, "platform data not available\n");
708                 return -ENODEV;
709         }
710
711         bbc = kzalloc(sizeof(struct tegra_bbc_proxy), GFP_KERNEL);
712         if (!bbc) {
713                 dev_err(&pdev->dev, "failed to allocate memory\n");
714                 return -ENOMEM;
715         }
716
717         if (pdata->modem_boot_edp_client && pdata->edp_manager_name) {
718                 mutex_init(&bbc->edp_lock);
719
720                 /* register bbc boot client */
721                 bbc->edp_manager_name = pdata->edp_manager_name;
722                 mgr = edp_get_manager(pdata->edp_manager_name);
723                 if (!mgr) {
724                         dev_err(&pdev->dev, "can't get edp manager\n");
725                         goto error;
726                 }
727
728                 bbc->modem_boot_edp_client = pdata->modem_boot_edp_client;
729                 ret = edp_register_client(mgr, bbc->modem_boot_edp_client);
730                 if (ret) {
731                         dev_err(&pdev->dev,
732                                 "unable to register bbc boot edp client\n");
733                         goto error;
734                 }
735
736                 /* request E0 */
737                 ret = edp_update_client_request(bbc->modem_boot_edp_client,
738                                                 0, NULL);
739                 if (ret) {
740                         dev_err(&pdev->dev,
741                                 "unable to set e0 state\n");
742                         goto edp_req_error;
743                 }
744
745                 bbc->edp_boot_client_registered = 1;
746
747                 bbc->i_breach_ppm = pdata->i_breach_ppm;
748                 bbc->i_thresh_3g_adjperiod = pdata->i_thresh_3g_adjperiod;
749                 bbc->i_thresh_lte_adjperiod = pdata->i_thresh_lte_adjperiod;
750
751                 attrs = edp_attributes;
752                 while ((attr = *attrs++)) {
753                         ret = device_create_file(&pdev->dev, attr);
754                         if (ret) {
755                                 dev_err(&pdev->dev,
756                                         "can't create sysfs file\n");
757                                 goto edp_req_error;
758                         }
759                 }
760
761                 bbc->edp_initialized = 1;
762                 bbc->ap_name = pdata->ap_name;
763         }
764
765         mutex_init(&bbc->iso_lock);
766
767         bbc->isomgr_handle = tegra_isomgr_register(TEGRA_ISO_CLIENT_BBC_0,
768                 MAX_ISO_BW_REQ, NULL, NULL);
769         if (!bbc->isomgr_handle)
770                 goto iso_error;
771
772         tegra_set_latency_allowance(TEGRA_LA_BBCLLR, 640);
773
774         /* statically margin for bbc bw */
775         ret = tegra_isomgr_set_margin(TEGRA_ISO_CLIENT_BBC_0,
776                 MAX_ISO_BW_REQ, true);
777         if (ret)
778                 dev_err(&pdev->dev, "can't margin for bbc bw\n");
779         else
780                 bbc->margin = MAX_ISO_BW_REQ;
781
782         /* thermal zones from bbc */
783         tegra_bbc_thermal_init();
784
785         attrs = mc_attributes;
786         while ((attr = *attrs++)) {
787                 ret = device_create_file(&pdev->dev, attr);
788                 if (ret) {
789                         dev_err(&pdev->dev, "can't create sysfs file\n");
790                         goto mc_error;
791                 }
792         }
793
794         bbc->sim0 = regulator_get(&pdev->dev, "vddio_sim0");
795         if (IS_ERR(bbc->sim0)) {
796                 dev_err(&pdev->dev, "vddio_sim0 regulator get failed\n");
797                 bbc->sim0 = NULL;
798                 goto sim_error;
799         }
800
801         bbc->sim1 = regulator_get(&pdev->dev, "vddio_sim1");
802         if (IS_ERR(bbc->sim1)) {
803                 dev_err(&pdev->dev, "vddio_sim1 regulator get failed\n");
804                 bbc->sim1 = NULL;
805                 goto sim_error;
806         }
807
808         attrs = sim_attributes;
809         while ((attr = *attrs++)) {
810                 ret = device_create_file(&pdev->dev, attr);
811                 if (ret) {
812                         dev_err(&pdev->dev, "can't create sysfs file\n");
813                         goto sim_error;
814                 }
815         }
816
817         bbc->rf1v7 = regulator_get(&pdev->dev, "vdd_1v7_rf");
818         if (IS_ERR(bbc->rf1v7)) {
819                 dev_info(&pdev->dev,
820                          "vdd_1v7_rf regulator not available\n");
821                 bbc->rf1v7 = NULL;
822         }
823
824         bbc->rf2v65 = regulator_get(&pdev->dev, "vdd_2v65_rf");
825         if (IS_ERR(bbc->rf2v65)) {
826                 dev_info(&pdev->dev,
827                          "vdd_2v65_rf regulator not available\n");
828                 bbc->rf2v65 = NULL;
829         }
830
831         if (bbc->rf1v7 && bbc->rf2v65) {
832                 attrs = rf_attributes;
833                 while ((attr = *attrs++)) {
834                         ret = device_create_file(&pdev->dev, attr);
835                         if (ret) {
836                                 dev_err(&pdev->dev,
837                                         "can't create sysfs file\n");
838                                 goto rf_error;
839                         }
840                 }
841         }
842
843         dev_set_drvdata(&pdev->dev, bbc);
844
845         return 0;
846
847 rf_error:
848         regulator_put(bbc->rf1v7);
849         regulator_put(bbc->rf2v65);
850 sim_error:
851         regulator_put(bbc->sim0);
852         regulator_put(bbc->sim1);
853
854         attrs = mc_attributes;
855         while ((attr = *attrs++))
856                 device_remove_file(&pdev->dev, attr);
857
858 mc_error:
859         tegra_isomgr_unregister(bbc->isomgr_handle);
860
861 iso_error:
862         if (bbc->edp_initialized) {
863                 attrs = edp_attributes;
864                 while ((attr = *attrs++))
865                         device_remove_file(&pdev->dev, attr);
866         }
867
868 edp_req_error:
869         if (bbc->edp_boot_client_registered)
870                 edp_unregister_client(bbc->modem_boot_edp_client);
871
872 error:
873         kfree(bbc);
874
875         return ret;
876 }
877
878 static int __exit tegra_bbc_proxy_remove(struct platform_device *pdev)
879 {
880         struct tegra_bbc_proxy *bbc = platform_get_drvdata(pdev);
881         struct device_attribute **attrs;
882         struct device_attribute *attr;
883
884
885         if (bbc->rf1v7 && bbc->rf2v65) {
886                 attrs = rf_attributes;
887                 while ((attr = *attrs++))
888                         device_remove_file(&pdev->dev, attr);
889                 regulator_put(bbc->rf1v7);
890                 regulator_put(bbc->rf2v65);
891         }
892
893         attrs = sim_attributes;
894         while ((attr = *attrs++))
895                 device_remove_file(&pdev->dev, attr);
896
897         regulator_put(bbc->sim0);
898         regulator_put(bbc->sim1);
899
900         attrs = mc_attributes;
901         while ((attr = *attrs++))
902                 device_remove_file(&pdev->dev, attr);
903
904         tegra_isomgr_unregister(bbc->isomgr_handle);
905
906         if (bbc->edp_initialized) {
907                 attrs = edp_attributes;
908                 while ((attr = *attrs++))
909                         device_remove_file(&pdev->dev, attr);
910         }
911
912         if (bbc->edp_boot_client_registered)
913                 edp_unregister_client(bbc->modem_boot_edp_client);
914
915         if (bbc->edp_client_registered)
916                 edp_unregister_client(&bbc->modem_edp_client);
917
918         kfree(bbc);
919
920         return 0;
921 }
922
923 #ifdef CONFIG_PM
924 static int tegra_bbc_proxy_suspend(struct platform_device *pdev,
925                                         pm_message_t state)
926 {
927         return 0;
928 }
929
930 static int tegra_bbc_proxy_resume(struct platform_device *pdev)
931 {
932         return 0;
933 }
934 #endif
935
936 static struct platform_driver tegra_bbc_proxy_driver = {
937         .driver = {
938                 .name = "tegra_bbc_proxy",
939                 .owner = THIS_MODULE,
940         },
941         .probe = tegra_bbc_proxy_probe,
942         .remove = tegra_bbc_proxy_remove,
943 #ifdef CONFIG_PM
944         .suspend = tegra_bbc_proxy_suspend,
945         .resume = tegra_bbc_proxy_resume,
946 #endif
947 };
948
949 static int __init tegra_bbc_proxy_init(void)
950 {
951         return platform_driver_register(&tegra_bbc_proxy_driver);
952 }
953
954 static void __exit tegra_bbc_proxy_exit(void)
955 {
956         platform_driver_unregister(&tegra_bbc_proxy_driver);
957 }
958
959 module_init(tegra_bbc_proxy_init);
960 module_exit(tegra_bbc_proxy_exit);
961
962 MODULE_DESCRIPTION("Tegra T148 BBC Proxy Module");
963 MODULE_LICENSE("GPL");