summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-22 19:09:46 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-22 19:09:46 +0300
commit5c73cc4b6c83e88863a5de869cc5df3b913aef4a (patch)
treeb7b573b58d31206c58bdee16c870d57d797ea1a6 /drivers
parente6c81cce5699ec6be3a7533b5ad7a062ab3357f2 (diff)
parent8b036556d68175caa9bea3fb98768f733fde33c6 (diff)
downloadlinux-5c73cc4b6c83e88863a5de869cc5df3b913aef4a.tar.xz
Merge tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM DT updates from Olof Johansson: "As always, this tends to be one of our bigger branches. There are lots of updates this release, but not that many jumps out as something that needs more detailed coverage. Some of the highlights are: - DTs for the new Annapurna Labs Alpine platform - more graphics DT pieces falling into place on Exynos, bridges, clocks. - plenty of DT updates for Qualcomm platforms for various IP blocks - some churn on Tegra due to switch-over to tool-generated pinctrl data - misc fixes and updates for Atmel at91 platforms - various DT updates to add IP block support on Broadcom's Cygnus platforms - more updates for Renesas platforms as DT support is added for various IP blocks (IPMMU, display, audio, etc)" * tag 'armsoc-dt' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (231 commits) ARM: dts: alpine: add internal pci Revert "ARM: dts: mt8135: Add pinctrl/GPIO/EINT node for mt8135." ARM: mvebu: use 0xf1000000 as internal registers on Armada 370 DB ARM: dts: qcom: Add idle state device nodes for 8064 ARM: dts: qcom: Add idle states device nodes for 8084 ARM: dts: qcom: Add idle states device nodes for 8974/8074 ARM: dts: qcom: Update power-controller device node for 8064 Krait CPUs ARM: dts: qcom: Add power-controller device node for 8084 Krait CPUs ARM: dts: qcom: Add power-controller device node for 8074 Krait CPUs devicetree: bindings: Document qcom,idle-states devicetree: bindings: Update qcom,saw2 node bindings dt-bindings: Add #defines for MSM8916 clocks and resets arm: dts: qcom: Add LPASS Audio HW to IPQ8064 device tree arm: dts: qcom: Add APQ8084 chipset SPMI PMIC's nodes arm: dts: qcom: Add 8x74 chipset SPMI PMIC's nodes arm: dts: qcom: Add SPMI PMIC Arbiter nodes for APQ8084 and MSM8974 arm: dts: qcom: Add LCC nodes arm: dts: qcom: Add TCSR support for MSM8960 arm: dts: qcom: Add TCSR support for MSM8660 arm: dts: qcom: Add TCSR support for IPQ8064 ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ti/wilink_platform_data.c25
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c63
-rw-r--r--drivers/net/wireless/ti/wl12xx/wl12xx.h28
-rw-r--r--drivers/net/wireless/ti/wlcore/boot.c1
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c31
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c63
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h5
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h6
10 files changed, 164 insertions, 66 deletions
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index a92bd3e89796..ea0e359bdb43 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,31 +23,6 @@
#include <linux/err.h>
#include <linux/wl12xx.h>
-static struct wl12xx_platform_data *wl12xx_platform_data;
-
-int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
-{
- if (wl12xx_platform_data)
- return -EBUSY;
- if (!data)
- return -EINVAL;
-
- wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
- if (!wl12xx_platform_data)
- return -ENOMEM;
-
- return 0;
-}
-
-struct wl12xx_platform_data *wl12xx_get_platform_data(void)
-{
- if (!wl12xx_platform_data)
- return ERR_PTR(-ENODEV);
-
- return wl12xx_platform_data;
-}
-EXPORT_SYMBOL(wl12xx_get_platform_data);
-
static struct wl1251_platform_data *wl1251_platform_data;
int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 144d1f8ba473..af0fe2e17151 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -24,8 +24,6 @@
#include <linux/err.h>
-#include <linux/wl12xx.h>
-
#include "../wlcore/wlcore.h"
#include "../wlcore/debug.h"
#include "../wlcore/io.h"
@@ -1770,11 +1768,44 @@ wl12xx_iface_combinations[] = {
},
};
+static const struct wl12xx_clock wl12xx_refclock_table[] = {
+ { 19200000, false, WL12XX_REFCLOCK_19 },
+ { 26000000, false, WL12XX_REFCLOCK_26 },
+ { 26000000, true, WL12XX_REFCLOCK_26_XTAL },
+ { 38400000, false, WL12XX_REFCLOCK_38 },
+ { 38400000, true, WL12XX_REFCLOCK_38_XTAL },
+ { 52000000, false, WL12XX_REFCLOCK_52 },
+ { 0, false, 0 }
+};
+
+static const struct wl12xx_clock wl12xx_tcxoclock_table[] = {
+ { 16368000, true, WL12XX_TCXOCLOCK_16_368 },
+ { 16800000, true, WL12XX_TCXOCLOCK_16_8 },
+ { 19200000, true, WL12XX_TCXOCLOCK_19_2 },
+ { 26000000, true, WL12XX_TCXOCLOCK_26 },
+ { 32736000, true, WL12XX_TCXOCLOCK_32_736 },
+ { 33600000, true, WL12XX_TCXOCLOCK_33_6 },
+ { 38400000, true, WL12XX_TCXOCLOCK_38_4 },
+ { 52000000, true, WL12XX_TCXOCLOCK_52 },
+ { 0, false, 0 }
+};
+
+static int wl12xx_get_clock_idx(const struct wl12xx_clock *table,
+ u32 freq, bool xtal)
+{
+ int i;
+
+ for (i = 0; table[i].freq != 0; i++)
+ if ((table[i].freq == freq) && (table[i].xtal == xtal))
+ return table[i].hw_idx;
+
+ return -EINVAL;
+}
+
static int wl12xx_setup(struct wl1271 *wl)
{
struct wl12xx_priv *priv = wl->priv;
struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev);
- struct wl12xx_platform_data *pdata = pdev_data->pdata;
BUILD_BUG_ON(WL12XX_MAX_LINKS > WLCORE_MAX_LINKS);
BUILD_BUG_ON(WL12XX_MAX_AP_STATIONS > WL12XX_MAX_LINKS);
@@ -1799,7 +1830,17 @@ static int wl12xx_setup(struct wl1271 *wl)
wl12xx_conf_init(wl);
if (!fref_param) {
- priv->ref_clock = pdata->board_ref_clock;
+ priv->ref_clock = wl12xx_get_clock_idx(wl12xx_refclock_table,
+ pdev_data->ref_clock_freq,
+ pdev_data->ref_clock_xtal);
+ if (priv->ref_clock < 0) {
+ wl1271_error("Invalid ref_clock frequency (%d Hz, %s)",
+ pdev_data->ref_clock_freq,
+ pdev_data->ref_clock_xtal ?
+ "XTAL" : "not XTAL");
+
+ return priv->ref_clock;
+ }
} else {
if (!strcmp(fref_param, "19.2"))
priv->ref_clock = WL12XX_REFCLOCK_19;
@@ -1817,9 +1858,17 @@ static int wl12xx_setup(struct wl1271 *wl)
wl1271_error("Invalid fref parameter %s", fref_param);
}
- if (!tcxo_param) {
- priv->tcxo_clock = pdata->board_tcxo_clock;
- } else {
+ if (!tcxo_param && pdev_data->tcxo_clock_freq) {
+ priv->tcxo_clock = wl12xx_get_clock_idx(wl12xx_tcxoclock_table,
+ pdev_data->tcxo_clock_freq,
+ true);
+ if (priv->tcxo_clock < 0) {
+ wl1271_error("Invalid tcxo_clock frequency (%d Hz)",
+ pdev_data->tcxo_clock_freq);
+
+ return priv->tcxo_clock;
+ }
+ } else if (tcxo_param) {
if (!strcmp(tcxo_param, "19.2"))
priv->tcxo_clock = WL12XX_TCXOCLOCK_19_2;
else if (!strcmp(tcxo_param, "26"))
diff --git a/drivers/net/wireless/ti/wl12xx/wl12xx.h b/drivers/net/wireless/ti/wl12xx/wl12xx.h
index 75c92658bfea..5952e99ace1b 100644
--- a/drivers/net/wireless/ti/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/ti/wl12xx/wl12xx.h
@@ -82,6 +82,34 @@ struct wl12xx_priv {
struct wl127x_rx_mem_pool_addr *rx_mem_addr;
};
+/* Reference clock values */
+enum {
+ WL12XX_REFCLOCK_19 = 0, /* 19.2 MHz */
+ WL12XX_REFCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_REFCLOCK_38 = 2, /* 38.4 MHz */
+ WL12XX_REFCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_REFCLOCK_38_XTAL = 4, /* 38.4 MHz, XTAL */
+ WL12XX_REFCLOCK_26_XTAL = 5, /* 26 MHz, XTAL */
+};
+
+/* TCXO clock values */
+enum {
+ WL12XX_TCXOCLOCK_19_2 = 0, /* 19.2MHz */
+ WL12XX_TCXOCLOCK_26 = 1, /* 26 MHz */
+ WL12XX_TCXOCLOCK_38_4 = 2, /* 38.4MHz */
+ WL12XX_TCXOCLOCK_52 = 3, /* 52 MHz */
+ WL12XX_TCXOCLOCK_16_368 = 4, /* 16.368 MHz */
+ WL12XX_TCXOCLOCK_32_736 = 5, /* 32.736 MHz */
+ WL12XX_TCXOCLOCK_16_8 = 6, /* 16.8 MHz */
+ WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
+};
+
+struct wl12xx_clock {
+ u32 freq;
+ bool xtal;
+ u8 hw_idx;
+};
+
struct wl12xx_fw_packet_counters {
/* Cumulative counter of released packets per AC */
u8 tx_released_pkts[NUM_TX_QUEUES];
diff --git a/drivers/net/wireless/ti/wlcore/boot.c b/drivers/net/wireless/ti/wlcore/boot.c
index 77752b03f189..19b7ec7b69c2 100644
--- a/drivers/net/wireless/ti/wlcore/boot.c
+++ b/drivers/net/wireless/ti/wlcore/boot.c
@@ -22,7 +22,6 @@
*/
#include <linux/slab.h>
-#include <linux/wl12xx.h>
#include <linux/export.h>
#include "debug.h"
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index 68f3bf229b5a..eb43f94a1597 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -502,7 +502,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
DRIVER_STATE_PRINT_HEX(irq);
/* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */
DRIVER_STATE_PRINT_HEX(hw_pg_ver);
- DRIVER_STATE_PRINT_HEX(platform_quirks);
+ DRIVER_STATE_PRINT_HEX(irq_flags);
DRIVER_STATE_PRINT_HEX(chip.id);
DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 1e136993580f..0be807951afe 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -25,8 +25,8 @@
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>
-#include <linux/wl12xx.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include "wlcore.h"
#include "debug.h"
@@ -538,7 +538,7 @@ static int wlcore_irq_locked(struct wl1271 *wl)
* In case edge triggered interrupt must be used, we cannot iterate
* more than once without introducing race conditions with the hardirq.
*/
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+ if (wl->irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
loopcount = 1;
wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -6249,7 +6249,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
wl->ap_ps_map = 0;
wl->ap_fw_ps_map = 0;
wl->quirks = 0;
- wl->platform_quirks = 0;
wl->system_hlid = WL12XX_SYSTEM_HLID;
wl->active_sta_count = 0;
wl->active_link_count = 0;
@@ -6390,8 +6389,8 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
struct wl1271 *wl = context;
struct platform_device *pdev = wl->pdev;
struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
- struct wl12xx_platform_data *pdata = pdev_data->pdata;
- unsigned long irqflags;
+ struct resource *res;
+
int ret;
irq_handler_t hardirq_fn = NULL;
@@ -6418,19 +6417,23 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
/* adjust some runtime configuration parameters */
wlcore_adjust_conf(wl);
- wl->irq = platform_get_irq(pdev, 0);
- wl->platform_quirks = pdata->platform_quirks;
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ wl1271_error("Could not get IRQ resource");
+ goto out_free_nvs;
+ }
+
+ wl->irq = res->start;
+ wl->irq_flags = res->flags & IRQF_TRIGGER_MASK;
wl->if_ops = pdev_data->if_ops;
- if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) {
- irqflags = IRQF_TRIGGER_RISING;
+ if (wl->irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
hardirq_fn = wlcore_hardirq;
- } else {
- irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
- }
+ else
+ wl->irq_flags |= IRQF_ONESHOT;
ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
- irqflags, pdev->name, wl);
+ wl->irq_flags, pdev->name, wl);
if (ret < 0) {
wl1271_error("request_irq() failed: %d", ret);
goto out_free_nvs;
@@ -6441,7 +6444,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
if (!ret) {
wl->irq_wake_enabled = true;
device_init_wakeup(wl->dev, 1);
- if (pdata->pwr_in_suspend)
+ if (pdev_data->pwr_in_suspend)
wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
}
#endif
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index d3dd7bfdf3f1..ea7e07abca4e 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -31,9 +31,10 @@
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/gpio.h>
-#include <linux/wl12xx.h>
#include <linux/pm_runtime.h>
#include <linux/printk.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include "wlcore.h"
#include "wl12xx_80211.h"
@@ -214,6 +215,52 @@ static struct wl1271_if_operations sdio_ops = {
.set_block_size = wl1271_sdio_set_block_size,
};
+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_sdio_of_match_table[] = {
+ { .compatible = "ti,wl1271" },
+ { .compatible = "ti,wl1273" },
+ { .compatible = "ti,wl1281" },
+ { .compatible = "ti,wl1283" },
+ { .compatible = "ti,wl1801" },
+ { .compatible = "ti,wl1805" },
+ { .compatible = "ti,wl1807" },
+ { .compatible = "ti,wl1831" },
+ { .compatible = "ti,wl1835" },
+ { .compatible = "ti,wl1837" },
+ { }
+};
+
+static int wlcore_probe_of(struct device *dev, int *irq,
+ struct wlcore_platdev_data *pdev_data)
+{
+ struct device_node *np = dev->of_node;
+
+ if (!np || !of_match_node(wlcore_sdio_of_match_table, np))
+ return -ENODATA;
+
+ *irq = irq_of_parse_and_map(np, 0);
+ if (!*irq) {
+ dev_err(dev, "No irq in platform data\n");
+ kfree(pdev_data);
+ return -EINVAL;
+ }
+
+ /* optional clock frequency params */
+ of_property_read_u32(np, "ref-clock-frequency",
+ &pdev_data->ref_clock_freq);
+ of_property_read_u32(np, "tcxo-clock-frequency",
+ &pdev_data->tcxo_clock_freq);
+
+ return 0;
+}
+#else
+static int wlcore_probe_of(struct device *dev, int *irq,
+ struct wlcore_platdev_data *pdev_data)
+{
+ return -ENODATA;
+}
+#endif
+
static int wl1271_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -222,6 +269,7 @@ static int wl1271_probe(struct sdio_func *func,
struct resource res[1];
mmc_pm_flag_t mmcflags;
int ret = -ENOMEM;
+ int irq;
const char *chip_family;
/* We are only able to handle the wlan function */
@@ -245,19 +293,15 @@ static int wl1271_probe(struct sdio_func *func,
/* Use block mode for transferring over one block size of data */
func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
- pdev_data.pdata = wl12xx_get_platform_data();
- if (IS_ERR(pdev_data.pdata)) {
- ret = PTR_ERR(pdev_data.pdata);
- dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
+ if (wlcore_probe_of(&func->dev, &irq, &pdev_data))
goto out_free_glue;
- }
/* if sdio can keep power while host is suspended, enable wow */
mmcflags = sdio_get_host_pm_caps(func);
dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
if (mmcflags & MMC_PM_KEEP_POWER)
- pdev_data.pdata->pwr_in_suspend = true;
+ pdev_data.pwr_in_suspend = true;
sdio_set_drvdata(func, glue);
@@ -286,8 +330,9 @@ static int wl1271_probe(struct sdio_func *func,
memset(res, 0x00, sizeof(res));
- res[0].start = pdev_data.pdata->irq;
- res[0].flags = IORESOURCE_IRQ;
+ res[0].start = irq;
+ res[0].flags = IORESOURCE_IRQ |
+ irqd_get_trigger_type(irq_get_irq_data(irq));
res[0].name = "irq";
ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index 69601f6741d9..f1ac2839d97c 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -331,11 +331,7 @@ static int wl1271_probe(struct spi_device *spi)
memset(&pdev_data, 0x00, sizeof(pdev_data));
- pdev_data.pdata = dev_get_platdata(&spi->dev);
- if (!pdev_data.pdata) {
- dev_err(&spi->dev, "no platform data\n");
- return -ENODEV;
- }
+ /* TODO: add DT parsing when needed */
pdev_data.if_ops = &spi_ops;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index d599c869e6e8..7f363fa566a3 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -197,6 +197,8 @@ struct wl1271 {
int irq;
+ int irq_flags;
+
spinlock_t wl_lock;
enum wlcore_state state;
@@ -404,9 +406,6 @@ struct wl1271 {
/* Quirks of specific hardware revisions */
unsigned int quirks;
- /* Platform limitations */
- unsigned int platform_quirks;
-
/* number of currently active RX BA sessions */
int ba_rx_session_count;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 3396ce5a934d..39efc6d78b10 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -201,8 +201,12 @@ struct wl1271_if_operations {
};
struct wlcore_platdev_data {
- struct wl12xx_platform_data *pdata;
struct wl1271_if_operations *if_ops;
+
+ bool ref_clock_xtal; /* specify whether the clock is XTAL or not */
+ u32 ref_clock_freq; /* in Hertz */
+ u32 tcxo_clock_freq; /* in Hertz, tcxo is always XTAL */
+ bool pwr_in_suspend;
};
#define MAX_NUM_KEYS 14