build_wl18xx: add patch mechanism and bluetooth components
[wilink8-wlan/build-utilites.git] / patches / kernel_patches / imx-3.10.53 / 0007-ti-st-add-device-tree-support.patch
1 From 78403fb3232ba53c9f8d9499879edbba60a29cc8 Mon Sep 17 00:00:00 2001
2 From: Eyal Reizer <eyalr@ti.com>
3 Date: Thu, 23 May 2013 17:11:14 +0300
4 Subject: [PATCH 7/7] ti-st: add device tree support
6 When using device tree, driver configuration data need to be read from
7 device node.
8 Add support for getting the platform data information from the device
9 tree information stored in the .dtb file in case it exists.
11 Change-Id: I74f7f869fc257a057edb9f35c5fd8cbafb810164
12 Signed-off-by: Eyal Reizer <eyalr@ti.com>
13 Signed-off-by: bvijay <bvijay@ti.com>
14 ---
15  drivers/misc/ti-st/st_kim.c  |   96 ++++++++++++++++++++++++++++++++++++++----
16  drivers/misc/ti-st/st_ll.c   |   17 +++++++-
17  include/linux/ti_wilink_st.h |    1 +
18  3 files changed, 104 insertions(+), 10 deletions(-)
20 diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
21 index dbd22e3..8cb48b1 100644
22 --- a/drivers/misc/ti-st/st_kim.c
23 +++ b/drivers/misc/ti-st/st_kim.c
24 @@ -36,7 +36,8 @@
25  #include <linux/skbuff.h>
26  #include <linux/ti_wilink_st.h>
27  #include <linux/module.h>
28 -
29 +#include <linux/of.h>
30 +#include <linux/of_device.h>
31  
32  #define MAX_ST_DEVICES 3       /* Imagine 1 on each UART for now */
33  static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
34 @@ -44,6 +45,9 @@ static struct platform_device *st_kim_devices[MAX_ST_DEVICES];
35  /**********************************************************************/
36  /* internal functions */
37  
38 +struct ti_st_plat_data *dt_pdata;
39 +static struct ti_st_plat_data *get_platform_data(struct device *dev);
40 +
41  /**
42   * st_get_plat_device -
43   *     function which returns the reference to the platform device
44 @@ -461,7 +465,12 @@ long st_kim_start(void *kim_data)
45         struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
46  
47         pr_info(" %s", __func__);
48 -       pdata = kim_gdata->kim_pdev->dev.platform_data;
49 +       if (kim_gdata->kim_pdev->dev.of_node) {
50 +               pr_debug("use device tree data");
51 +               pdata = dt_pdata;
52 +       } else {
53 +               pdata = kim_gdata->kim_pdev->dev.platform_data;
54 +       }
55  
56         do {
57                 /* platform specific enabling code here */
58 @@ -521,12 +530,18 @@ long st_kim_stop(void *kim_data)
59  {
60         long err = 0;
61         struct kim_data_s       *kim_gdata = (struct kim_data_s *)kim_data;
62 -       struct ti_st_plat_data  *pdata =
63 -               kim_gdata->kim_pdev->dev.platform_data;
64 +       struct ti_st_plat_data  *pdata;
65         struct tty_struct       *tty = kim_gdata->core_data->tty;
66  
67         INIT_COMPLETION(kim_gdata->ldisc_installed);
68  
69 +       if (kim_gdata->kim_pdev->dev.of_node) {
70 +               pr_debug("use device tree data");
71 +               pdata = dt_pdata;
72 +       } else
73 +               pdata = kim_gdata->kim_pdev->dev.platform_data;
74 +
75 +
76         if (tty) {      /* can be called before ldisc is installed */
77                 /* Flush any pending characters in the driver and discipline. */
78                 tty_ldisc_flush(tty);
79 @@ -715,13 +730,53 @@ static const struct file_operations list_debugfs_fops = {
80   * board-*.c file
81   */
82  
83 +static const struct of_device_id kim_of_match[] = {
84 +{
85 +       .compatible = "kim",
86 +       },
87 +       {}
88 +};
89 +MODULE_DEVICE_TABLE(of, kim_of_match);
90 +
91 +static struct ti_st_plat_data *get_platform_data(struct device *dev)
92 +{
93 +       struct device_node *np = dev->of_node;
94 +       const u32 *dt_property;
95 +       int len;
96 +
97 +       dt_pdata = kzalloc(sizeof(*dt_pdata), GFP_KERNEL);
98 +
99 +       if (!dt_pdata)
100 +               pr_err("Can't allocate device_tree platform data\n");
102 +       dt_property = of_get_property(np, "dev_name", &len);
103 +       if (dt_property)
104 +               memcpy(&dt_pdata->dev_name, dt_property, len);
105 +       of_property_read_u32(np, "nshutdown_gpio",
106 +                            (u32 *)&dt_pdata->nshutdown_gpio);
107 +       of_property_read_u32(np, "flow_cntrl", (u32 *)&dt_pdata->flow_cntrl);
108 +       of_property_read_u32(np, "baud_rate", (u32 *)&dt_pdata->baud_rate);
110 +       return dt_pdata;
111 +}
113  static struct dentry *kim_debugfs_dir;
114  static int kim_probe(struct platform_device *pdev)
115  {
116         struct kim_data_s       *kim_gdata;
117 -       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
118 +       struct ti_st_plat_data  *pdata;
119         int err;
120  
121 +       if (pdev->dev.of_node)
122 +               pdata = get_platform_data(&pdev->dev);
123 +       else
124 +               pdata = pdev->dev.platform_data;
126 +       if (pdata == NULL) {
127 +               dev_err(&pdev->dev, "Platform Data is missing\n");
128 +               return -ENXIO;
129 +       }
131         if ((pdev->id != -1) && (pdev->id < MAX_ST_DEVICES)) {
132                 /* multiple devices could exist */
133                 st_kim_devices[pdev->id] = pdev;
134 @@ -809,9 +864,16 @@ err_core_init:
135  static int kim_remove(struct platform_device *pdev)
136  {
137         /* free the GPIOs requested */
138 -       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
139 +       struct ti_st_plat_data  *pdata;
140         struct kim_data_s       *kim_gdata;
141  
142 +       if (pdev->dev.of_node) {
143 +               pr_debug("use device tree data");
144 +               pdata = dt_pdata;
145 +       } else {
146 +               pdata = pdev->dev.platform_data;
147 +       }
149         kim_gdata = dev_get_drvdata(&pdev->dev);
150  
151         /* Free the Bluetooth/FM/GPIO
152 @@ -829,12 +891,22 @@ static int kim_remove(struct platform_device *pdev)
153  
154         kfree(kim_gdata);
155         kim_gdata = NULL;
156 +       kfree(dt_pdata);
157 +       dt_pdata = NULL;
159         return 0;
160  }
161  
162  static int kim_suspend(struct platform_device *pdev, pm_message_t state)
163  {
164 -       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
165 +       struct ti_st_plat_data  *pdata;
167 +       if (pdev->dev.of_node) {
168 +               pr_debug("use device tree data");
169 +               pdata = dt_pdata;
170 +       } else {
171 +               pdata = pdev->dev.platform_data;
172 +       }
173  
174         if (pdata->suspend)
175                 return pdata->suspend(pdev, state);
176 @@ -844,7 +916,14 @@ static int kim_suspend(struct platform_device *pdev, pm_message_t state)
177  
178  static int kim_resume(struct platform_device *pdev)
179  {
180 -       struct ti_st_plat_data  *pdata = pdev->dev.platform_data;
181 +       struct ti_st_plat_data  *pdata;
183 +       if (pdev->dev.of_node) {
184 +               pr_debug("use device tree data");
185 +               pdata = dt_pdata;
186 +       } else {
187 +               pdata = pdev->dev.platform_data;
188 +       }
189  
190         if (pdata->resume)
191                 return pdata->resume(pdev);
192 @@ -862,6 +941,7 @@ static struct platform_driver kim_platform_driver = {
193         .driver = {
194                 .name = "kim",
195                 .owner = THIS_MODULE,
196 +               .of_match_table = of_match_ptr(kim_of_match),
197         },
198  };
199  
200 diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c
201 index 93b4d67..518e1b7 100644
202 --- a/drivers/misc/ti-st/st_ll.c
203 +++ b/drivers/misc/ti-st/st_ll.c
204 @@ -26,6 +26,7 @@
205  #include <linux/ti_wilink_st.h>
206  
207  /**********************************************************************/
209  /* internal functions */
210  static void send_ll_cmd(struct st_data_s *st_data,
211         unsigned char cmd)
212 @@ -53,7 +54,13 @@ static void ll_device_want_to_sleep(struct st_data_s *st_data)
213  
214         /* communicate to platform about chip asleep */
215         kim_data = st_data->kim_data;
216 -       pdata = kim_data->kim_pdev->dev.platform_data;
217 +       if (kim_data->kim_pdev->dev.of_node) {
218 +               pr_debug("use device tree data");
219 +               pdata = dt_pdata;
220 +       } else {
221 +               pdata = kim_data->kim_pdev->dev.platform_data;
222 +       }
224         if (pdata->chip_asleep)
225                 pdata->chip_asleep(NULL);
226  }
227 @@ -86,7 +93,13 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data)
228  
229         /* communicate to platform about chip wakeup */
230         kim_data = st_data->kim_data;
231 -       pdata = kim_data->kim_pdev->dev.platform_data;
232 +       if (kim_data->kim_pdev->dev.of_node) {
233 +               pr_debug("use device tree data");
234 +               pdata = dt_pdata;
235 +       } else {
236 +               pdata = kim_data->kim_pdev->dev.platform_data;
237 +       }
239         if (pdata->chip_awake)
240                 pdata->chip_awake(NULL);
241  }
242 diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h
243 index 932b763..39e577c 100644
244 --- a/include/linux/ti_wilink_st.h
245 +++ b/include/linux/ti_wilink_st.h
246 @@ -86,6 +86,7 @@ struct st_proto_s {
247  extern long st_register(struct st_proto_s *);
248  extern long st_unregister(struct st_proto_s *);
249  
250 +extern struct ti_st_plat_data   *dt_pdata;
251  
252  /*
253   * header information used by st_core.c
254 -- 
255 1.7.9.5