Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wlcore: add device-tree support

When running with device-tree, we no longer have a board file
that can set up the platform data for wlcore.
Allow this data to be passed from DT.

Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Tested-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
Tested-by: Nikita Kiryanov <nikita@compulab.co.il>
Acked-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by

Eliad Peller and committed by
Tony Lindgren
5ea5c518 d96c8b77

+87 -6
+87 -6
drivers/net/wireless/ti/wlcore/sdio.c
··· 34 34 #include <linux/wl12xx.h> 35 35 #include <linux/pm_runtime.h> 36 36 #include <linux/printk.h> 37 + #include <linux/of.h> 38 + #include <linux/of_irq.h> 37 39 38 40 #include "wlcore.h" 39 41 #include "wl12xx_80211.h" ··· 216 214 .set_block_size = wl1271_sdio_set_block_size, 217 215 }; 218 216 217 + #ifdef CONFIG_OF 218 + static const struct of_device_id wlcore_sdio_of_match_table[] = { 219 + { .compatible = "ti,wl1271" }, 220 + { .compatible = "ti,wl1273" }, 221 + { .compatible = "ti,wl1281" }, 222 + { .compatible = "ti,wl1283" }, 223 + { .compatible = "ti,wl1801" }, 224 + { .compatible = "ti,wl1805" }, 225 + { .compatible = "ti,wl1807" }, 226 + { .compatible = "ti,wl1831" }, 227 + { .compatible = "ti,wl1835" }, 228 + { .compatible = "ti,wl1837" }, 229 + { } 230 + }; 231 + 232 + static struct wl12xx_platform_data *wlcore_probe_of(struct device *dev) 233 + { 234 + struct device_node *np = dev->of_node; 235 + struct wl12xx_platform_data *pdata; 236 + 237 + if (!np || !of_match_node(wlcore_sdio_of_match_table, np)) 238 + return NULL; 239 + 240 + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); 241 + if (!pdata) 242 + return NULL; 243 + 244 + pdata->irq = irq_of_parse_and_map(np, 0); 245 + if (!pdata->irq) { 246 + dev_err(dev, "No irq in platform data\n"); 247 + kfree(pdata); 248 + return NULL; 249 + } 250 + 251 + pdata->irq_trigger = 252 + irqd_get_trigger_type(irq_get_irq_data(pdata->irq)); 253 + 254 + /* optional clock frequency params */ 255 + of_property_read_u32(np, "ref-clock-frequency", 256 + &pdata->ref_clock_freq); 257 + of_property_read_u32(np, "tcxo-clock-frequency", 258 + &pdata->tcxo_clock_freq); 259 + 260 + return pdata; 261 + } 262 + #else 263 + static struct wl12xx_platform_data *wlcore_probe_of(struct device *dev) 264 + { 265 + return NULL; 266 + } 267 + #endif 268 + 269 + static struct wl12xx_platform_data * 270 + wlcore_get_platform_data(struct device *dev) 271 + { 272 + struct wl12xx_platform_data *pdata; 273 + 274 + /* first, look for DT data */ 275 + pdata = wlcore_probe_of(dev); 276 + if (pdata) 277 + return pdata; 278 + 279 + /* if not found - fallback to static platform data */ 280 + pdata = wl12xx_get_platform_data(); 281 + if (!IS_ERR(pdata)) 282 + return kmemdup(pdata, sizeof(*pdata), GFP_KERNEL); 283 + 284 + dev_err(dev, "No platform data set\n"); 285 + return NULL; 286 + } 287 + 288 + static void wlcore_del_platform_data(struct wl12xx_platform_data *pdata) 289 + { 290 + kfree(pdata); 291 + } 292 + 219 293 static int wl1271_probe(struct sdio_func *func, 220 294 const struct sdio_device_id *id) 221 295 { ··· 323 245 /* Use block mode for transferring over one block size of data */ 324 246 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 325 247 326 - pdev_data.pdata = wl12xx_get_platform_data(); 327 - if (IS_ERR(pdev_data.pdata)) { 328 - ret = PTR_ERR(pdev_data.pdata); 329 - dev_err(glue->dev, "missing wlan platform data: %d\n", ret); 248 + pdev_data.pdata = wlcore_get_platform_data(&func->dev); 249 + if (!pdev_data.pdata) 330 250 goto out_free_glue; 331 - } 332 251 333 252 /* if sdio can keep power while host is suspended, enable wow */ 334 253 mmcflags = sdio_get_host_pm_caps(func); ··· 354 279 if (!glue->core) { 355 280 dev_err(glue->dev, "can't allocate platform_device"); 356 281 ret = -ENOMEM; 357 - goto out_free_glue; 282 + goto out_free_pdata; 358 283 } 359 284 360 285 glue->core->dev.parent = &func->dev; ··· 388 313 out_dev_put: 389 314 platform_device_put(glue->core); 390 315 316 + out_free_pdata: 317 + wlcore_del_platform_data(pdev_data.pdata); 318 + 391 319 out_free_glue: 392 320 kfree(glue); 393 321 ··· 401 323 static void wl1271_remove(struct sdio_func *func) 402 324 { 403 325 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); 326 + struct wlcore_platdev_data *pdev_data = glue->core->dev.platform_data; 327 + struct wl12xx_platform_data *pdata = pdev_data->pdata; 404 328 405 329 /* Undo decrement done above in wl1271_probe */ 406 330 pm_runtime_get_noresume(&func->dev); 407 331 408 332 platform_device_unregister(glue->core); 333 + wlcore_del_platform_data(pdata); 409 334 kfree(glue); 410 335 } 411 336