Re: [PATCH v4 3/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2016-01-07 Thread Uri Mashiach

Hi Kalle Valo,

On 01/07/2016 11:02 AM, Kalle Valo wrote:

Uri Mashiach <uri.mashi...@compulab.co.il> writes:


Device tree modifications:
- Pinmux for SPI0 and WiFi GPIOs.
- SPI0 node with wlcore as a child node.

Cc: Tony Lindgren <t...@atomide.com>
Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: Replace interrupts and interrupt-parent with interrupts-extended.
v2 -> v3: Move the pinctrl-0 = <_pins> to the wlcore node.
v3 -> v4: replace interrupts-extended with interrupts and interrupt-parent. 
(revert v2 modification).
   According to Rob Herring and 
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt,
  interrupts-extended should only be used when a device has multiple 
interrupt parents.

  arch/arm/boot/dts/am335x-cm-t335.dts | 55 
  1 file changed, 55 insertions(+)


To what tree should this patch go? My wireless-drivers-next tree doesn't
even have this file.


Should be applied into omap-for-v4.x/dt



https://patchwork.kernel.org/patch/7933441/



--
Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)

2015-12-30 Thread Uri Mashiach

Hello Kalle Valo,

On 12/30/2015 05:15 PM, Kalle Valo wrote:

Uri Mashiach <uri.mashi...@compulab.co.il> writes:


Fix the below Oops when trying to modprobe wlcore_spi.
The oops occurs because the wl1271_power_{off,on}()
function doesn't check the power() function pointer.

[   23.401447] Unable to handle kernel NULL pointer dereference at
virtual address 
[   23.409954] pgd = c0004000
[   23.412922] [] *pgd=
[   23.416693] Internal error: Oops: 8007 [#1] SMP ARM
[   23.422168] Modules linked in: wl12xx wlcore mac80211 cfg80211
musb_dsps musb_hdrc usbcore usb_common snd_soc_simple_card evdev joydev
omap_rng wlcore_spi snd_soc_tlv320aic23_i2c rng_core snd_soc_tlv320aic23
c_can_platform c_can can_dev snd_soc_davinci_mcasp snd_soc_edma
snd_soc_omap omap_wdt musb_am335x cpufreq_dt thermal_sys hwmon
[   23.453253] CPU: 0 PID: 36 Comm: kworker/0:2 Not tainted
4.2.0-2-g951efee-dirty #233
[   23.461720] Hardware name: Generic AM33XX (Flattened Device Tree)
[   23.468123] Workqueue: events request_firmware_work_func
[   23.473690] task: de32efc0 ti: de4ee000 task.ti: de4ee000
[   23.479341] PC is at 0x0
[   23.482112] LR is at wl12xx_set_power_on+0x28/0x124 [wlcore]
[   23.488074] pc : [<>]lr : []psr: 6013
[   23.488074] sp : de4efe50  ip : 0002  fp : 
[   23.500162] r10: de7cdd00  r9 : dc848800  r8 : bf27af00
[   23.505663] r7 : bf27a1a8  r6 : dcbd8a80  r5 : dce0e2e0  r4 :
dce0d2e0
[   23.512536] r3 :   r2 :   r1 : 0001  r0 :
dc848810
[   23.519412] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[   23.527109] Control: 10c5387d  Table: 9cb78019  DAC: 0015
[   23.533160] Process kworker/0:2 (pid: 36, stack limit = 0xde4ee218)
[   23.539760] Stack: (0xde4efe50 to 0xde4f)

[...]

[   23.665030] [] (wl12xx_set_power_on [wlcore]) from
[] (wlcore_nvs_cb+0x118/0xa4c [wlcore])
[   23.675604] [] (wlcore_nvs_cb [wlcore]) from []
(request_firmware_work_func+0x30/0x58)
[   23.685784] [] (request_firmware_work_func) from
[] (process_one_work+0x1b4/0x4b4)
[   23.695591] [] (process_one_work) from []
(worker_thread+0x3c/0x4a4)
[   23.704124] [] (worker_thread) from []
(kthread+0xd4/0xf0)
[   23.711747] [] (kthread) from []
(ret_from_fork+0x14/0x3c)
[   23.719357] Code: bad PC value
[   23.722760] ---[ end trace 981be8510db9b3a9 ]---

Prevent oops by validationg power() pointer value before
calling the function.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Cc: sta...@vger.kernel.org
Acked-by: Igor Grinberg <grinb...@compulab.co.il>


Please always provide a changelog when you resend patches, I lost track
what I'm supposed to do with this. Should I apply or drop?


Sorry for not providing a changelog.
The patch should be applied.

--
Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 3/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-30 Thread Uri Mashiach
Device tree modifications:
- Pinmux for SPI0 and WiFi GPIOs.
- SPI0 node with wlcore as a child node.

Cc: Tony Lindgren <t...@atomide.com>
Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: Replace interrupts and interrupt-parent with interrupts-extended.
v2 -> v3: Move the pinctrl-0 = <_pins> to the wlcore node.
v3 -> v4: replace interrupts-extended with interrupts and interrupt-parent. 
(revert v2 modification).
  According to Rob Herring and 
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt,
  interrupts-extended should only be used when a device has multiple 
interrupt parents.

 arch/arm/boot/dts/am335x-cm-t335.dts | 55 
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts 
b/arch/arm/boot/dts/am335x-cm-t335.dts
index 42e9b66..65f1099 100644
--- a/arch/arm/boot/dts/am335x-cm-t335.dts
+++ b/arch/arm/boot/dts/am335x-cm-t335.dts
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include 
 
 / {
model = "CompuLab CM-T335";
@@ -40,6 +41,15 @@
regulator-max-microvolt = <330>;
};
 
+   /* Regulator for WiFi */
+   vwlan_fixed: fixedregulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "vwlan_fixed";
+   gpio = < 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */
+   enable-active-high;
+   regulator-boot-off;
+   };
+
backlight {
compatible = "pwm-backlight";
pwms = < 0 5 0>;
@@ -223,6 +233,21 @@
>;
};
 
+   spi0_pins: pinmux_spi0_pins {
+   pinctrl-single,pins = <
+   /* spi0_sclk.spi0_sclk */
+   AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0)
+   /* spi0_d0.spi0_d0 */
+   AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+   /* spi0_d1.spi0_d1 */
+   AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0)
+   /* spi0_cs0.spi0_cs0 */
+   AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0)
+   /* spi0_cs1.spi0_cs1 */
+   AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0)
+   >;
+   };
+
/* wl1271 bluetooth */
bluetooth_pins: pinmux_bluetooth_pins {
pinctrl-single,pins = <
@@ -230,6 +255,16 @@
AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
>;
};
+
+   /* wl1271 WiFi */
+   wifi_pins: pinmux_wifi_pins {
+   pinctrl-single,pins = <
+   /* EMU1.gpio3_8 - WiFi IRQ */
+   AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7)
+   /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */
+   AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7)
+   >;
+   };
 };
 
  {
@@ -394,3 +429,23 @@ status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   ti,pindir-d0-out-d1-in = <1>;
+   /* WLS1271 WiFi */
+   wlcore: wlcore@1 {
+   compatible = "ti,wl1271";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 1/3] wlcore/wl12xx: spi: add power operation function

2015-12-30 Thread Uri Mashiach
The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: oops fix was removed to a separate fix.
v2 -> v3: no changes
v3 -> v4: update devm_regulator_get() error handling.

 drivers/net/wireless/ti/wlcore/spi.c | 39 
 1 file changed, 39 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index 44f059f..dec1512 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "wlcore.h"
 #include "wl12xx_80211.h"
@@ -81,6 +82,7 @@
 struct wl12xx_spi_glue {
struct device *dev;
struct platform_device *core;
+   struct regulator *reg; /* Power regulator */
 };
 
 static void wl12xx_spi_reset(struct device *child)
@@ -318,11 +320,40 @@ static int __must_check wl12xx_spi_raw_write(struct 
device *child, int addr,
return 0;
 }
 
+/**
+ * wl12xx_spi_set_power - power on/off the wl12xx unit
+ * @child: wl12xx device handle.
+ * @enable: true/false to power on/off the unit.
+ *
+ * use the WiFi enable regulator to enable/disable the WiFi unit.
+ */
+static int wl12xx_spi_set_power(struct device *child, bool enable)
+{
+   int ret = 0;
+   struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+
+   WARN_ON(!glue->reg);
+
+   /* Update regulator state */
+   if (enable) {
+   ret = regulator_enable(glue->reg);
+   if (ret)
+   dev_err(child, "Power enable failure\n");
+   } else {
+   ret =  regulator_disable(glue->reg);
+   if (ret)
+   dev_err(child, "Power disable failure\n");
+   }
+
+   return ret;
+}
+
 static struct wl1271_if_operations spi_ops = {
.read   = wl12xx_spi_raw_read,
.write  = wl12xx_spi_raw_write,
.reset  = wl12xx_spi_reset,
.init   = wl12xx_spi_init,
+   .power  = wl12xx_spi_set_power,
.set_block_size = NULL,
 };
 
@@ -353,6 +384,14 @@ static int wl1271_probe(struct spi_device *spi)
 * comes from the board-peripherals file */
spi->bits_per_word = 32;
 
+   glue->reg = devm_regulator_get(>dev, "vwlan");
+   if (PTR_ERR(glue->reg) == -EPROBE_DEFER)
+   return -EPROBE_DEFER;
+   if (IS_ERR(glue->reg)) {
+   dev_err(glue->dev, "can't get regulator\n");
+   return PTR_ERR(glue->reg);
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "spi_setup failed\n");
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-30 Thread Uri Mashiach
Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Rob Herring <r...@kernel.org>
---
v1 -> v2: update interrupt documentation.
  replace interrupts and interrupt-parent with interrupts-extended.
  IRQ parameters retrieved from spi_device instead of DT.
  remove redundant #ifdef CONFIG_OF
v2 -> v3: Add MODULE_DEVICE_TABLE.
  Remove #ifdef CONFIG_OF.
  Make the Kconfig symbol to depend on OF.
  Replace irqd_get_trigger_type() with irq_get_trigger_type().
v3 -> v4: replace interrupts-extended with interrupts and interrupt-parent. 
(revert v2 modification).
  According to Rob Herring and 
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt,
  interrupts-extended should only be used when a device has multiple 
interrupt parents.

 .../bindings/net/wireless/ti,wlcore,spi.txt| 36 +
 drivers/net/wireless/ti/wlcore/Kconfig |  2 +-
 drivers/net/wireless/ti/wlcore/spi.c   | 47 --
 3 files changed, 80 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..9180724
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,36 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupt-parent, interrupts :
+Should contain parameters for 1 interrupt line.
+Interrupt parameters: parent, line number, type.
+- vwlan-supply :Point the node of the regulator that powers/enable the 
wl1271 chip
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig 
b/drivers/net/wireless/ti/wlcore/Kconfig
index 7c09954..5918080 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -13,7 +13,7 @@ config WLCORE
 
 config WLCORE_SPI
tristate "TI wlcore SPI support"
-   depends on WLCORE && SPI_MASTER
+   depends on WLCORE && SPI_MASTER && OF
select CRC7
---help---
  This module adds support for the SPI interface of adapters using
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index dec1512..020ac1a 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "wlcore.h"
@@ -357,6 +358,39 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
 };
 
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table);
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+ 

[PATCH v4 0/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-30 Thread Uri Mashiach
Add DT support for WLS1271 SPI driver.
Add power operation function to the WLS1271 SPI driver.

Uri Mashiach (3):
  wlcore/wl12xx: spi: add power operation function
  wlcore/wl12xx: spi: add device tree support
  wlcore/wl12xx: spi: add wifi support to cm-t335

 .../bindings/net/wireless/ti,wlcore,spi.txt| 36 +
 arch/arm/boot/dts/am335x-cm-t335.dts   | 55 ++
 drivers/net/wireless/ti/wlcore/Kconfig |  2 +-
 drivers/net/wireless/ti/wlcore/spi.c   | 86 +-
 4 files changed, 174 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 3/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-28 Thread Uri Mashiach
Device tree modifications:
- Pinmux for SPI0 and WiFi GPIOs.
- SPI0 node with wlcore as a child node.

Cc: Tony Lindgren <t...@atomide.com>
Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@complab.co.il>
---
v1 -> v2: Replace interrupts and interrupt-parent with interrupts-extended.
v2 -> v3: Move the pinctrl-0 = <_pins> to the wlcore node.

arch/arm/boot/dts/am335x-cm-t335.dts | 54 
 1 file changed, 54 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts 
b/arch/arm/boot/dts/am335x-cm-t335.dts
index 42e9b66..b700940 100644
--- a/arch/arm/boot/dts/am335x-cm-t335.dts
+++ b/arch/arm/boot/dts/am335x-cm-t335.dts
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include 
 
 / {
model = "CompuLab CM-T335";
@@ -40,6 +41,15 @@
regulator-max-microvolt = <330>;
};
 
+   /* Regulator for WiFi */
+   vwlan_fixed: fixedregulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "vwlan_fixed";
+   gpio = < 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */
+   enable-active-high;
+   regulator-boot-off;
+   };
+
backlight {
compatible = "pwm-backlight";
pwms = < 0 5 0>;
@@ -223,6 +233,21 @@
>;
};
 
+   spi0_pins: pinmux_spi0_pins {
+   pinctrl-single,pins = <
+   /* spi0_sclk.spi0_sclk */
+   AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0)
+   /* spi0_d0.spi0_d0 */
+   AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+   /* spi0_d1.spi0_d1 */
+   AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0)
+   /* spi0_cs0.spi0_cs0 */
+   AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0)
+   /* spi0_cs1.spi0_cs1 */
+   AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0)
+   >;
+   };
+
/* wl1271 bluetooth */
bluetooth_pins: pinmux_bluetooth_pins {
pinctrl-single,pins = <
@@ -230,6 +255,16 @@
AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
>;
};
+
+   /* wl1271 WiFi */
+   wifi_pins: pinmux_wifi_pins {
+   pinctrl-single,pins = <
+   /* EMU1.gpio3_8 - WiFi IRQ */
+   AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7)
+   /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */
+   AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7)
+   >;
+   };
 };
 
  {
@@ -394,3 +429,22 @@ status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   ti,pindir-d0-out-d1-in = <1>;
+   /* WLS1271 WiFi */
+   wlcore: wlcore@1 {
+   compatible = "ti,wl1271";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-28 Thread Uri Mashiach
Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
v1 -> v2: update interrupt documentation.
  replace interrupts and interrupt-parent with interrupts-extended.
  IRQ parameters retrieved from spi_device instead of DT.
  remove redundant #ifdef CONFIG_OF
v2 -> v3: Add MODULE_DEVICE_TABLE.
  Remove #ifdef CONFIG_OF.
  Make the Kconfig symbol to depend on OF.
  Replace irqd_get_trigger_type() with irq_get_trigger_type().

 .../bindings/net/wireless/ti,wlcore,spi.txt| 34 
 drivers/net/wireless/ti/wlcore/Kconfig |  2 +-
 drivers/net/wireless/ti/wlcore/spi.c   | 47 --
 3 files changed, 78 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..502c27e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,34 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts-extended : Should contain parameters for 1 interrupt line.
+Interrupt parameters: parent, line number, type.
+- vwlan-supply :Point the node of the regulator that powers/enable the 
wl1271 chip
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/Kconfig 
b/drivers/net/wireless/ti/wlcore/Kconfig
index 7c09954..5918080 100644
--- a/drivers/net/wireless/ti/wlcore/Kconfig
+++ b/drivers/net/wireless/ti/wlcore/Kconfig
@@ -13,7 +13,7 @@ config WLCORE
 
 config WLCORE_SPI
tristate "TI wlcore SPI support"
-   depends on WLCORE && SPI_MASTER
+   depends on WLCORE && SPI_MASTER && OF
select CRC7
---help---
  This module adds support for the SPI interface of adapters using
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..0f2fb50 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "wlcore.h"
@@ -357,6 +358,39 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
 };
 
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table);
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int wl1271_probe(struct spi_device *spi)
 {
struct wl12xx_spi_glue *glue;
@@ -366,8 +400,6 @@ static int wl1271_probe(struct spi_device *spi)
 
memset(_data, 0x00, sizeof(pdev_data));
 
-   /* TODO: add DT parsing when needed */
-
pdev_data.if_ops = _ops;
 
glue = devm_kzalloc(>dev, sizeof(*glue), GFP_KERNEL);
@@ 

[PATCH v3 0/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-28 Thread Uri Mashiach
Add DT support for WLS1271 SPI driver.
Add power operation function to the WLS1271 SPI driver.

Uri Mashiach (3):
  wlcore/wl12xx: spi: add power operation function
  wlcore/wl12xx: spi: add device tree support
  wlcore/wl12xx: spi: add wifi support to cm-t335

 .../bindings/net/wireless/ti,wlcore,spi.txt| 34 +
 arch/arm/boot/dts/am335x-cm-t335.dts   | 54 ++
 drivers/net/wireless/ti/wlcore/Kconfig |  2 +-
 drivers/net/wireless/ti/wlcore/spi.c   | 84 --
 4 files changed, 169 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/3] wlcore/wl12xx: spi: add power operation function

2015-12-28 Thread Uri Mashiach
The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: oops fix was removed to a separate fix.
v2 -> v3: no changes

 drivers/net/wireless/ti/wlcore/spi.c | 37 
 1 file changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index 44f059f..d3a4bcb 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "wlcore.h"
 #include "wl12xx_80211.h"
@@ -81,6 +82,7 @@
 struct wl12xx_spi_glue {
struct device *dev;
struct platform_device *core;
+   struct regulator *reg; /* Power regulator */
 };
 
 static void wl12xx_spi_reset(struct device *child)
@@ -318,11 +320,40 @@ static int __must_check wl12xx_spi_raw_write(struct 
device *child, int addr,
return 0;
 }
 
+/**
+ * wl12xx_spi_set_power - power on/off the wl12xx unit
+ * @child: wl12xx device handle.
+ * @enable: true/false to power on/off the unit.
+ *
+ * use the WiFi enable regulator to enable/disable the WiFi unit.
+ */
+static int wl12xx_spi_set_power(struct device *child, bool enable)
+{
+   int ret = 0;
+   struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+
+   WARN_ON(!glue->reg);
+
+   /* Update regulator state */
+   if (enable) {
+   ret = regulator_enable(glue->reg);
+   if (ret)
+   dev_err(child, "Power enable failure\n");
+   } else {
+   ret =  regulator_disable(glue->reg);
+   if (ret)
+   dev_err(child, "Power disable failure\n");
+   }
+
+   return ret;
+}
+
 static struct wl1271_if_operations spi_ops = {
.read   = wl12xx_spi_raw_read,
.write  = wl12xx_spi_raw_write,
.reset  = wl12xx_spi_reset,
.init   = wl12xx_spi_init,
+   .power  = wl12xx_spi_set_power,
.set_block_size = NULL,
 };
 
@@ -353,6 +384,12 @@ static int wl1271_probe(struct spi_device *spi)
 * comes from the board-peripherals file */
spi->bits_per_word = 32;
 
+   glue->reg = devm_regulator_get(>dev, "vwlan");
+   if (IS_ERR(glue->reg)) {
+   dev_err(glue->dev, "can't get regulator\n");
+   return PTR_ERR(glue->reg);
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "spi_setup failed\n");
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] wlcore/wl12xx: spi: add power operation function

2015-12-28 Thread Uri Mashiach

Hi Grygorii,

On 12/28/2015 01:59 PM, Grygorii Strashko wrote:

On 12/27/2015 07:14 PM, Uri Mashiach wrote:

Hello Grygorii,

On 12/24/2015 06:32 PM, Grygorii Strashko wrote:

On 12/24/2015 05:35 PM, Uri Mashiach wrote:

The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: oops fix was removed to a separate fix.

   drivers/net/wireless/ti/wlcore/spi.c | 37

   1 file changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c
b/drivers/net/wireless/ti/wlcore/spi.c



[...]


+
   static struct wl1271_if_operations spi_ops = {
   .read= wl12xx_spi_raw_read,
   .write= wl12xx_spi_raw_write,
   .reset= wl12xx_spi_reset,
   .init= wl12xx_spi_init,
+.power= wl12xx_spi_set_power,
   .set_block_size = NULL,
   };

@@ -353,6 +384,12 @@ static int wl1271_probe(struct spi_device *spi)
* comes from the board-peripherals file */
   spi->bits_per_word = 32;

+glue->reg = devm_regulator_get(>dev, "vwlan");
+if (IS_ERR(glue->reg)) {


It will be more correct to handle -EPROBE_DEFER here also. Like:
   if (PTR_ERR(glue->reg) == -EPROBE_DEFER)
  return PTR_ERR(glue->reg);



It seems that the IS_ERR(glue->reg) condition covers the EPROBE_DEFER case.


True. But this is not an error and it's common practice do not print
any log messages in this case from driver :)



Sorry, already posted v3.
Will be in v4.




+dev_err(glue->dev, "can't get regulator\n");
+return PTR_ERR(glue->reg);
+}
+
   ret = spi_setup(spi);
   if (ret < 0) {
   dev_err(glue->dev, "spi_setup failed\n");











--
Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/3] wlcore/wl12xx: spi: add power operation function

2015-12-27 Thread Uri Mashiach

Hello Grygorii,

On 12/24/2015 06:32 PM, Grygorii Strashko wrote:

On 12/24/2015 05:35 PM, Uri Mashiach wrote:

The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: oops fix was removed to a separate fix.

  drivers/net/wireless/ti/wlcore/spi.c | 37

  1 file changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c
b/drivers/net/wireless/ti/wlcore/spi.c



[...]


+
  static struct wl1271_if_operations spi_ops = {
  .read= wl12xx_spi_raw_read,
  .write= wl12xx_spi_raw_write,
  .reset= wl12xx_spi_reset,
  .init= wl12xx_spi_init,
+.power= wl12xx_spi_set_power,
  .set_block_size = NULL,
  };

@@ -353,6 +384,12 @@ static int wl1271_probe(struct spi_device *spi)
   * comes from the board-peripherals file */
  spi->bits_per_word = 32;

+glue->reg = devm_regulator_get(>dev, "vwlan");
+if (IS_ERR(glue->reg)) {


It will be more correct to handle -EPROBE_DEFER here also. Like:
  if (PTR_ERR(glue->reg) == -EPROBE_DEFER)
 return PTR_ERR(glue->reg);



It seems that the IS_ERR(glue->reg) condition covers the EPROBE_DEFER case.


+dev_err(glue->dev, "can't get regulator\n");
+return PTR_ERR(glue->reg);
+}
+
  ret = spi_setup(spi);
  if (ret < 0) {
  dev_err(glue->dev, "spi_setup failed\n");






--
Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-24 Thread Uri Mashiach

Hi Grygorii,

On 12/24/2015 06:32 PM, Grygorii Strashko wrote:

On 12/24/2015 05:35 PM, Uri Mashiach wrote:

Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
v1 -> v2: update interrupt documentation.
replace interrupts and interrupt-parent with interrupts-extended.
  IRQ parameters retrieved from spi_device instead of DT.
  remove redundant #ifdef CONFIG_OF

   .../bindings/net/wireless/ti,wlcore,spi.txt| 34 +
   drivers/net/wireless/ti/wlcore/spi.c   | 55 
--
   2 files changed, 85 insertions(+), 4 deletions(-)
   create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..502c27e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,34 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts-extended : Should contain parameters for 1 interrupt line.
+Interrupt parameters: parent, line number, type.
+- vwlan-supply :Point the node of the regulator that powers/enable the 
wl1271 chip
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..e9e8d54 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 

   #include "wlcore.h"
@@ -357,6 +358,46 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
   };

+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */


My question for your v1 was related to all above ifdefs.
If CONFIG_OF=n is not going to be supported then all this ifdefs
can be dropped and proper dependency can be added to Kconfig instead.



Will be done in v3.


+
   static int wl1271_probe(struct spi_device *spi)
   {
struct wl12xx_spi_glue *glue;
@@ -366,8 +407,6 @@ static int wl1271_probe(struct spi_device *spi)

memset(_data, 0x00, sizeof(pdev_data));

-   /* TODO: add DT parsing when needed */
-
pdev_data.if_ops = _ops;

glue = devm_kzalloc(>dev, sizeof(*glue), GFP_KERNEL);
@@ -390,6 +429,13 @@ static int wl1271_probe(struct spi_device *spi)
return PTR_ERR(glue->reg);
}

+   ret = wlcore_probe_of(spi, glue, _data);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   

Re: [PATCH v2 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-24 Thread Uri Mashiach

Hello Javier,

On 12/24/2015 06:25 PM, Javier Martinez Canillas wrote:

Hello Uri,

On Thu, Dec 24, 2015 at 12:35 PM, Uri Mashiach
<uri.mashi...@compulab.co.il> wrote:

Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
v1 -> v2: update interrupt documentation.
   replace interrupts and interrupt-parent with interrupts-extended.
   IRQ parameters retrieved from spi_device instead of DT.
   remove redundant #ifdef CONFIG_OF

  .../bindings/net/wireless/ti,wlcore,spi.txt| 34 +
  drivers/net/wireless/ti/wlcore/spi.c   | 55 --
  2 files changed, 85 insertions(+), 4 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..502c27e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,34 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts-extended : Should contain parameters for 1 interrupt line.
+Interrupt parameters: parent, line number, type.
+- vwlan-supply :Point the node of the regulator that powers/enable the 
wl1271 chip
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..e9e8d54 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 

  #include "wlcore.h"
@@ -357,6 +358,46 @@ static struct wl1271_if_operations spi_ops = {
 .set_block_size = NULL,
  };

+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};


Could you please add a MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table) here?



Will be added in v3.


+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */
+


I don't understand what's the point of making the driver to be built
with !CONFIG_OF if the probe function is going to fail anyways. If
this driver really need then is better to remove the ifdefery and make
the Kconfig symbol to depend on OF.



Will be done in v3.


Best regards,
Javier



Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)

2015-12-24 Thread Uri Mashiach
Fix the below Oops when trying to modprobe wlcore_spi.
The oops occurs because the wl1271_power_{off,on}()
function doesn't check the power() function pointer.

[   23.401447] Unable to handle kernel NULL pointer dereference at
virtual address 
[   23.409954] pgd = c0004000
[   23.412922] [] *pgd=
[   23.416693] Internal error: Oops: 8007 [#1] SMP ARM
[   23.422168] Modules linked in: wl12xx wlcore mac80211 cfg80211
musb_dsps musb_hdrc usbcore usb_common snd_soc_simple_card evdev joydev
omap_rng wlcore_spi snd_soc_tlv320aic23_i2c rng_core snd_soc_tlv320aic23
c_can_platform c_can can_dev snd_soc_davinci_mcasp snd_soc_edma
snd_soc_omap omap_wdt musb_am335x cpufreq_dt thermal_sys hwmon
[   23.453253] CPU: 0 PID: 36 Comm: kworker/0:2 Not tainted
4.2.0-2-g951efee-dirty #233
[   23.461720] Hardware name: Generic AM33XX (Flattened Device Tree)
[   23.468123] Workqueue: events request_firmware_work_func
[   23.473690] task: de32efc0 ti: de4ee000 task.ti: de4ee000
[   23.479341] PC is at 0x0
[   23.482112] LR is at wl12xx_set_power_on+0x28/0x124 [wlcore]
[   23.488074] pc : [<>]lr : []psr: 6013
[   23.488074] sp : de4efe50  ip : 0002  fp : 
[   23.500162] r10: de7cdd00  r9 : dc848800  r8 : bf27af00
[   23.505663] r7 : bf27a1a8  r6 : dcbd8a80  r5 : dce0e2e0  r4 :
dce0d2e0
[   23.512536] r3 :   r2 :   r1 : 0001  r0 :
dc848810
[   23.519412] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[   23.527109] Control: 10c5387d  Table: 9cb78019  DAC: 0015
[   23.533160] Process kworker/0:2 (pid: 36, stack limit = 0xde4ee218)
[   23.539760] Stack: (0xde4efe50 to 0xde4f)

[...]

[   23.665030] [] (wl12xx_set_power_on [wlcore]) from
[] (wlcore_nvs_cb+0x118/0xa4c [wlcore])
[   23.675604] [] (wlcore_nvs_cb [wlcore]) from []
(request_firmware_work_func+0x30/0x58)
[   23.685784] [] (request_firmware_work_func) from
[] (process_one_work+0x1b4/0x4b4)
[   23.695591] [] (process_one_work) from []
(worker_thread+0x3c/0x4a4)
[   23.704124] [] (worker_thread) from []
(kthread+0xd4/0xf0)
[   23.711747] [] (kthread) from []
(ret_from_fork+0x14/0x3c)
[   23.719357] Code: bad PC value
[   23.722760] ---[ end trace 981be8510db9b3a9 ]---

Prevent oops by validationg power() pointer value before
calling the function.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Cc: sta...@vger.kernel.org
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
 drivers/net/wireless/ti/wlcore/io.h | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/io.h 
b/drivers/net/wireless/ti/wlcore/io.h
index 0305729..10cf374 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -207,19 +207,23 @@ static inline int __must_check wlcore_write_reg(struct 
wl1271 *wl, int reg,
 
 static inline void wl1271_power_off(struct wl1271 *wl)
 {
-   int ret;
+   int ret = 0;
 
if (!test_bit(WL1271_FLAG_GPIO_POWER, >flags))
return;
 
-   ret = wl->if_ops->power(wl->dev, false);
+   if (wl->if_ops->power)
+   ret = wl->if_ops->power(wl->dev, false);
if (!ret)
clear_bit(WL1271_FLAG_GPIO_POWER, >flags);
 }
 
 static inline int wl1271_power_on(struct wl1271 *wl)
 {
-   int ret = wl->if_ops->power(wl->dev, true);
+   int ret = 0;
+
+   if (wl->if_ops->power)
+   ret = wl->if_ops->power(wl->dev, true);
if (ret == 0)
set_bit(WL1271_FLAG_GPIO_POWER, >flags);
 
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 3/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-24 Thread Uri Mashiach
Device tree modifications:
- Pinmux for SPI0 and WiFi GPIOs.
- SPI0 node with wlcore as a child node.

Cc: Tony Lindgren <t...@atomide.com>
Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@complab.co.il>
---
v1 -> v2: replace interrupts and interrupt-parent with interrupts-extended.

 arch/arm/boot/dts/am335x-cm-t335.dts | 57 +++-
 1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts 
b/arch/arm/boot/dts/am335x-cm-t335.dts
index 42e9b66..31f8371 100644
--- a/arch/arm/boot/dts/am335x-cm-t335.dts
+++ b/arch/arm/boot/dts/am335x-cm-t335.dts
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include 
 
 / {
model = "CompuLab CM-T335";
@@ -40,6 +41,15 @@
regulator-max-microvolt = <330>;
};
 
+   /* Regulator for WiFi */
+   vwlan_fixed: fixedregulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "vwlan_fixed";
+   gpio = < 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */
+   enable-active-high;
+   regulator-boot-off;
+   };
+
backlight {
compatible = "pwm-backlight";
pwms = < 0 5 0>;
@@ -50,7 +60,10 @@
 
 _pinmux {
pinctrl-names = "default";
-   pinctrl-0 = <_pins>;
+   pinctrl-0 = <
+ _pins
+ _pins
+   >;
 
i2c0_pins: pinmux_i2c0_pins {
pinctrl-single,pins = <
@@ -223,6 +236,21 @@
>;
};
 
+   spi0_pins: pinmux_spi0_pins {
+   pinctrl-single,pins = <
+   /* spi0_sclk.spi0_sclk */
+   AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0)
+   /* spi0_d0.spi0_d0 */
+   AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+   /* spi0_d1.spi0_d1 */
+   AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0)
+   /* spi0_cs0.spi0_cs0 */
+   AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0)
+   /* spi0_cs1.spi0_cs1 */
+   AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0)
+   >;
+   };
+
/* wl1271 bluetooth */
bluetooth_pins: pinmux_bluetooth_pins {
pinctrl-single,pins = <
@@ -230,6 +258,16 @@
AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
>;
};
+
+   /* wl1271 WiFi */
+   wifi_pins: pinmux_wifi_pins {
+   pinctrl-single,pins = <
+   /* EMU1.gpio3_8 - WiFi IRQ */
+   AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7)
+   /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */
+   AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7)
+   >;
+   };
 };
 
  {
@@ -394,3 +432,20 @@ status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   ti,pindir-d0-out-d1-in = <1>;
+   /* WLS1271 WiFi */
+   wlcore: wlcore@1 {
+   compatible = "ti,wl1271";
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/3] wlcore/wl12xx: spi: add power operation function

2015-12-24 Thread Uri Mashiach
The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
v1 -> v2: oops fix was removed to a separate fix.

 drivers/net/wireless/ti/wlcore/spi.c | 37 
 1 file changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index 44f059f..d3a4bcb 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "wlcore.h"
 #include "wl12xx_80211.h"
@@ -81,6 +82,7 @@
 struct wl12xx_spi_glue {
struct device *dev;
struct platform_device *core;
+   struct regulator *reg; /* Power regulator */
 };
 
 static void wl12xx_spi_reset(struct device *child)
@@ -318,11 +320,40 @@ static int __must_check wl12xx_spi_raw_write(struct 
device *child, int addr,
return 0;
 }
 
+/**
+ * wl12xx_spi_set_power - power on/off the wl12xx unit
+ * @child: wl12xx device handle.
+ * @enable: true/false to power on/off the unit.
+ *
+ * use the WiFi enable regulator to enable/disable the WiFi unit.
+ */
+static int wl12xx_spi_set_power(struct device *child, bool enable)
+{
+   int ret = 0;
+   struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+
+   WARN_ON(!glue->reg);
+
+   /* Update regulator state */
+   if (enable) {
+   ret = regulator_enable(glue->reg);
+   if (ret)
+   dev_err(child, "Power enable failure\n");
+   } else {
+   ret =  regulator_disable(glue->reg);
+   if (ret)
+   dev_err(child, "Power disable failure\n");
+   }
+
+   return ret;
+}
+
 static struct wl1271_if_operations spi_ops = {
.read   = wl12xx_spi_raw_read,
.write  = wl12xx_spi_raw_write,
.reset  = wl12xx_spi_reset,
.init   = wl12xx_spi_init,
+   .power  = wl12xx_spi_set_power,
.set_block_size = NULL,
 };
 
@@ -353,6 +384,12 @@ static int wl1271_probe(struct spi_device *spi)
 * comes from the board-peripherals file */
spi->bits_per_word = 32;
 
+   glue->reg = devm_regulator_get(>dev, "vwlan");
+   if (IS_ERR(glue->reg)) {
+   dev_err(glue->dev, "can't get regulator\n");
+   return PTR_ERR(glue->reg);
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "spi_setup failed\n");
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-24 Thread Uri Mashiach
Add DT support for WLS1271 SPI driver.
Add power operation function to the WLS1271 SPI driver.

Uri Mashiach (3):
  wlcore/wl12xx: spi: add power operation function
  wlcore/wl12xx: spi: add device tree support
  wlcore/wl12xx: spi: add wifi support to cm-t335

 .../bindings/net/wireless/ti,wlcore,spi.txt| 34 
 arch/arm/boot/dts/am335x-cm-t335.dts   | 57 +-
 drivers/net/wireless/ti/wlcore/spi.c   | 92 +-
 3 files changed, 178 insertions(+), 5 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-24 Thread Uri Mashiach
Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
v1 -> v2: update interrupt documentation.
  replace interrupts and interrupt-parent with interrupts-extended.
  IRQ parameters retrieved from spi_device instead of DT.
  remove redundant #ifdef CONFIG_OF

 .../bindings/net/wireless/ti,wlcore,spi.txt| 34 +
 drivers/net/wireless/ti/wlcore/spi.c   | 55 --
 2 files changed, 85 insertions(+), 4 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..502c27e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,34 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts-extended : Should contain parameters for 1 interrupt line.
+Interrupt parameters: parent, line number, type.
+- vwlan-supply :Point the node of the regulator that powers/enable the 
wl1271 chip
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupts-extended = < 8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..e9e8d54 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "wlcore.h"
@@ -357,6 +358,46 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue 
*glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */
+
 static int wl1271_probe(struct spi_device *spi)
 {
struct wl12xx_spi_glue *glue;
@@ -366,8 +407,6 @@ static int wl1271_probe(struct spi_device *spi)
 
memset(_data, 0x00, sizeof(pdev_data));
 
-   /* TODO: add DT parsing when needed */
-
pdev_data.if_ops = _ops;
 
glue = devm_kzalloc(>dev, sizeof(*glue), GFP_KERNEL);
@@ -390,6 +429,13 @@ static int wl1271_probe(struct spi_device *spi)
return PTR_ERR(glue->reg);
}
 
+   ret = wlcore_probe_of(spi, glue, _data);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get device tree parameters (%d)\n", ret);
+   return ret;
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "spi_setup failed\n");
@@ -407,7 +453,8 @@ static int wl1271_probe(struct spi_device *spi)
memset(res, 0x00, sizeof(res)

Re: [PATCH 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-23 Thread Uri Mashiach

Hi Grygorii,

On 12/23/2015 12:25 PM, Grygorii Strashko wrote:

On 12/23/2015 10:35 AM, Uri Mashiach wrote:

Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
   .../bindings/net/wireless/ti,wlcore,spi.txt| 35 +++
   drivers/net/wireless/ti/wlcore/spi.c   | 67 
+++---
   2 files changed, 95 insertions(+), 7 deletions(-)
   create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..a3e7eb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,35 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts :  Should contain interrupt line and trigger type


It's good to describe here number of IRQ lines your device have and IRQ types 
(edge/level)



Maybe IRQ type should be provided by dts file 
(IRQ_TYPE_LEVEL_HIGH/IRQ_TYPE_EDGE_RISING...)

to enable support for additional controllers?


+- interrupt-parent :Should be the phandle for the interrupt controller

interrupt-parent is not required (also interrupts-extended can be used)



Will be done in v2.


+that services interrupts for this device
+- vwlan-supply :Point the node of the regulator that controls the 
wl1271 chip WLAN_EN pin


Pls, use gpio if this is required just to toggle WLAN_EN pin.

[ti,] power-gpio or en-gpio




The controller's power might need toggling in some board implementation.
Maybe GPIO and regulator should be implemented?


+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,just
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   wifi-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..7281f5a 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 

   #include "wlcore.h"
@@ -357,6 +358,54 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
   };

+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   ret = of_irq_to_resource(dt_node, 0, [0]);
+   if (spi->irq != ret) {
+   dev_err(glue->dev, "can't get interrupt resource\n");
+   return -EINVAL;
+   }


SPI core will parse IRQ for you (see below)


+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */
+
   static int wl1271_probe(struct spi_device *spi)
   {
struct wl12xx_spi_glue *glue;
@@ -365,8 +

Re: [PATCH 1/3] wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)

2015-12-23 Thread Uri Mashiach

Hi Grygorii,

On 12/23/2015 12:08 PM, Grygorii Strashko wrote:

On 12/23/2015 10:35 AM, Uri Mashiach wrote:

The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Fix the below Oops when trying to modprobe wlcore_spi.
The oops occurs because the wl1271_power_{off,on}()
function doesn't check the power() function pointer.

[   23.401447] Unable to handle kernel NULL pointer dereference at
virtual address 
[   23.409954] pgd = c0004000
[   23.412922] [] *pgd=
[   23.416693] Internal error: Oops: 8007 [#1] SMP ARM
[   23.422168] Modules linked in: wl12xx wlcore mac80211 cfg80211
musb_dsps musb_hdrc usbcore usb_common snd_soc_simple_card evdev joydev
omap_rng wlcore_spi snd_soc_tlv320aic23_i2c rng_core snd_soc_tlv320aic23
c_can_platform c_can can_dev snd_soc_davinci_mcasp snd_soc_edma
snd_soc_omap omap_wdt musb_am335x cpufreq_dt thermal_sys hwmon
[   23.453253] CPU: 0 PID: 36 Comm: kworker/0:2 Not tainted
4.2.0-2-g951efee-dirty #233
[   23.461720] Hardware name: Generic AM33XX (Flattened Device Tree)
[   23.468123] Workqueue: events request_firmware_work_func
[   23.473690] task: de32efc0 ti: de4ee000 task.ti: de4ee000
[   23.479341] PC is at 0x0
[   23.482112] LR is at wl12xx_set_power_on+0x28/0x124 [wlcore]


Why can't you just add proper check in wl1271_power_on/wl1271_power_off() 
instead?



Will be done in v2.

Thanks,
Uri
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-23 Thread Uri Mashiach

Hi Grygorii,

On 12/23/2015 12:25 PM, Grygorii Strashko wrote:

On 12/23/2015 10:35 AM, Uri Mashiach wrote:

Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
   .../bindings/net/wireless/ti,wlcore,spi.txt| 35 +++
   drivers/net/wireless/ti/wlcore/spi.c   | 67 
+++---
   2 files changed, 95 insertions(+), 7 deletions(-)
   create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..a3e7eb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,35 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts :  Should contain interrupt line and trigger type


It's good to describe here number of IRQ lines your device have and IRQ types 
(edge/level)


+- interrupt-parent :Should be the phandle for the interrupt controller

interrupt-parent is not required (also interrupts-extended can be used)


+that services interrupts for this device
+- vwlan-supply :Point the node of the regulator that controls the 
wl1271 chip WLAN_EN pin


Pls, use gpio if this is required just to toggle WLAN_EN pin.

[ti,] power-gpio or en-gpio



+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,just
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   wifi-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..7281f5a 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 

   #include "wlcore.h"
@@ -357,6 +358,54 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
   };

+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   ret = of_irq_to_resource(dt_node, 0, [0]);
+   if (spi->irq != ret) {
+   dev_err(glue->dev, "can't get interrupt resource\n");
+   return -EINVAL;
+   }


SPI core will parse IRQ for you (see below)



The IRQ type should be stored in res[0].flags.
Is there an alternative to of_irq_to_resource() for getting the IRQ type?


+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */
+
   static int wl1271_probe(struct spi_device *spi)
   {
struct wl12xx_spi_glue *glue;
@@ -365,8 +414,7 @@ static int wl1271_probe(struct spi_device *spi)
int ret;

memset(_data, 0x00, sizeof(pdev_data));
-
-   /* TODO: add DT parsing w

[PATCH 1/3] wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)

2015-12-23 Thread Uri Mashiach
The power function uses a consumer regulator access to update the WiFi
enable GPIO value.

Fix the below Oops when trying to modprobe wlcore_spi.
The oops occurs because the wl1271_power_{off,on}()
function doesn't check the power() function pointer.

[   23.401447] Unable to handle kernel NULL pointer dereference at
virtual address 
[   23.409954] pgd = c0004000
[   23.412922] [] *pgd=
[   23.416693] Internal error: Oops: 8007 [#1] SMP ARM
[   23.422168] Modules linked in: wl12xx wlcore mac80211 cfg80211
musb_dsps musb_hdrc usbcore usb_common snd_soc_simple_card evdev joydev
omap_rng wlcore_spi snd_soc_tlv320aic23_i2c rng_core snd_soc_tlv320aic23
c_can_platform c_can can_dev snd_soc_davinci_mcasp snd_soc_edma
snd_soc_omap omap_wdt musb_am335x cpufreq_dt thermal_sys hwmon
[   23.453253] CPU: 0 PID: 36 Comm: kworker/0:2 Not tainted
4.2.0-2-g951efee-dirty #233
[   23.461720] Hardware name: Generic AM33XX (Flattened Device Tree)
[   23.468123] Workqueue: events request_firmware_work_func
[   23.473690] task: de32efc0 ti: de4ee000 task.ti: de4ee000
[   23.479341] PC is at 0x0
[   23.482112] LR is at wl12xx_set_power_on+0x28/0x124 [wlcore]
[   23.488074] pc : [<>]lr : []psr: 6013
[   23.488074] sp : de4efe50  ip : 0002  fp : 
[   23.500162] r10: de7cdd00  r9 : dc848800  r8 : bf27af00
[   23.505663] r7 : bf27a1a8  r6 : dcbd8a80  r5 : dce0e2e0  r4 :
dce0d2e0
[   23.512536] r3 :   r2 :   r1 : 0001  r0 :
dc848810
[   23.519412] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment kernel
[   23.527109] Control: 10c5387d  Table: 9cb78019  DAC: 0015
[   23.533160] Process kworker/0:2 (pid: 36, stack limit = 0xde4ee218)
[   23.539760] Stack: (0xde4efe50 to 0xde4f)

[...]

[   23.665030] [] (wl12xx_set_power_on [wlcore]) from
[] (wlcore_nvs_cb+0x118/0xa4c [wlcore])
[   23.675604] [] (wlcore_nvs_cb [wlcore]) from []
(request_firmware_work_func+0x30/0x58)
[   23.685784] [] (request_firmware_work_func) from
[] (process_one_work+0x1b4/0x4b4)
[   23.695591] [] (process_one_work) from []
(worker_thread+0x3c/0x4a4)
[   23.704124] [] (worker_thread) from []
(kthread+0xd4/0xf0)
[   23.711747] [] (kthread) from []
(ret_from_fork+0x14/0x3c)
[   23.719357] Code: bad PC value
[   23.722760] ---[ end trace 981be8510db9b3a9 ]---

Fix this by adding a power() function implementation.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
 drivers/net/wireless/ti/wlcore/spi.c | 37 
 1 file changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index 44f059f..d3a4bcb 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "wlcore.h"
 #include "wl12xx_80211.h"
@@ -81,6 +82,7 @@
 struct wl12xx_spi_glue {
struct device *dev;
struct platform_device *core;
+   struct regulator *reg; /* Power regulator */
 };
 
 static void wl12xx_spi_reset(struct device *child)
@@ -318,11 +320,40 @@ static int __must_check wl12xx_spi_raw_write(struct 
device *child, int addr,
return 0;
 }
 
+/**
+ * wl12xx_spi_set_power - power on/off the wl12xx unit
+ * @child: wl12xx device handle.
+ * @enable: true/false to power on/off the unit.
+ *
+ * use the WiFi enable regulator to enable/disable the WiFi unit.
+ */
+static int wl12xx_spi_set_power(struct device *child, bool enable)
+{
+   int ret = 0;
+   struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
+
+   WARN_ON(!glue->reg);
+
+   /* Update regulator state */
+   if (enable) {
+   ret = regulator_enable(glue->reg);
+   if (ret)
+   dev_err(child, "Power enable failure\n");
+   } else {
+   ret =  regulator_disable(glue->reg);
+   if (ret)
+   dev_err(child, "Power disable failure\n");
+   }
+
+   return ret;
+}
+
 static struct wl1271_if_operations spi_ops = {
.read   = wl12xx_spi_raw_read,
.write  = wl12xx_spi_raw_write,
.reset  = wl12xx_spi_reset,
.init   = wl12xx_spi_init,
+   .power  = wl12xx_spi_set_power,
.set_block_size = NULL,
 };
 
@@ -353,6 +384,12 @@ static int wl1271_probe(struct spi_device *spi)
 * comes from the board-peripherals file */
spi->bits_per_word = 32;
 
+   glue->reg = devm_regulator_get(>dev, "vwlan");
+   if (IS_ERR(glue->reg)) {
+   dev_err(glue->dev, "can't get regulator\n");
+   return PTR_ERR(glue->reg);
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "sp

[PATCH 2/3] wlcore/wl12xx: spi: add device tree support

2015-12-23 Thread Uri Mashiach
Add DT support for the wl1271 SPI WiFi.

Add documentation file for the wl1271 SPI WiFi.

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
---
 .../bindings/net/wireless/ti,wlcore,spi.txt| 35 +++
 drivers/net/wireless/ti/wlcore/spi.c   | 67 +++---
 2 files changed, 95 insertions(+), 7 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt 
b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
new file mode 100644
index 000..a3e7eb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -0,0 +1,35 @@
+* Texas Instruments wl1271 wireless lan controller
+
+The wl1271 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible :  Should be "ti,wl1271"
+- reg : Chip select address of device
+- spi-max-frequency :   Maximum SPI clocking speed of device in Hz
+- ref-clock-frequency : Reference clock frequency
+- interrupts :  Should contain interrupt line and trigger type
+- interrupt-parent :Should be the phandle for the interrupt controller
+that services interrupts for this device
+- vwlan-supply :Point the node of the regulator that controls the 
wl1271 chip WLAN_EN pin
+
+Optional properties:
+- clock-xtal :  boolean, clock is generated from XTAL
+
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+  for optional SPI connection related properties,
+
+Examples:
+
+ {
+   wl1271@1 {
+   compatible = "ti,wl1271";
+
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   wifi-supply = <_fixed>;
+   };
+};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index d3a4bcb..7281f5a 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "wlcore.h"
@@ -357,6 +358,54 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id wlcore_spi_of_match_table[] = {
+   { .compatible = "ti,wl1271" },
+   { }
+};
+
+/**
+ * wlcore_probe_of - DT node parsing.
+ * @spi: SPI slave device parameters.
+ * @res: resource parameters.
+ * @glue: wl12xx SPI bus to slave device glue parameters.
+ * @pdev_data: wlcore device parameters
+ */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   struct device_node *dt_node = spi->dev.of_node;
+   int ret;
+
+   ret = of_irq_to_resource(dt_node, 0, [0]);
+   if (spi->irq != ret) {
+   dev_err(glue->dev, "can't get interrupt resource\n");
+   return -EINVAL;
+   }
+
+   if (of_find_property(dt_node, "clock-xtal", NULL))
+   pdev_data->ref_clock_xtal = true;
+
+   ret = of_property_read_u32(dt_node, "ref-clock-frequency",
+  _data->ref_clock_freq);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get reference clock frequency (%d)\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+#else /* CONFIG_OF */
+static int wlcore_probe_of(struct spi_device *spi, struct resource *res,
+  struct wl12xx_spi_glue *glue,
+  struct wlcore_platdev_data *pdev_data)
+{
+   return -ENODATA;
+}
+#endif /* CONFIG_OF */
+
 static int wl1271_probe(struct spi_device *spi)
 {
struct wl12xx_spi_glue *glue;
@@ -365,8 +414,7 @@ static int wl1271_probe(struct spi_device *spi)
int ret;
 
memset(_data, 0x00, sizeof(pdev_data));
-
-   /* TODO: add DT parsing when needed */
+   memset(res, 0x00, sizeof(res));
 
pdev_data.if_ops = _ops;
 
@@ -390,6 +438,13 @@ static int wl1271_probe(struct spi_device *spi)
return PTR_ERR(glue->reg);
}
 
+   ret = wlcore_probe_of(spi, [0], glue, _data);
+   if (IS_ERR_VALUE(ret)) {
+   dev_err(glue->dev,
+   "can't get device tree parameters (%d)\n", ret);
+   return ret;
+   }
+
ret = spi_setup(spi);
if (ret < 0) {
dev_err(glue->dev, "spi

[PATCH 3/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-23 Thread Uri Mashiach
Device tree modifications:
- Pinmux for SPI0 and WiFi GPIOs.
- SPI0 node with wlcore as a child node.

Cc: Tony Lindgren <t...@atomide.com>
Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@complab.co.il>
---
Prerequisites:
This patch applies on Tony's omap-for-v4.5/dt branch.

 arch/arm/boot/dts/am335x-cm-t335.dts | 58 +++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts 
b/arch/arm/boot/dts/am335x-cm-t335.dts
index 42e9b66..41242a5 100644
--- a/arch/arm/boot/dts/am335x-cm-t335.dts
+++ b/arch/arm/boot/dts/am335x-cm-t335.dts
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include 
 
 / {
model = "CompuLab CM-T335";
@@ -40,6 +41,15 @@
regulator-max-microvolt = <330>;
};
 
+   /* Regulator for WiFi */
+   vwlan_fixed: fixedregulator@2 {
+   compatible = "regulator-fixed";
+   regulator-name = "vwlan_fixed";
+   gpio = < 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */
+   enable-active-high;
+   regulator-boot-off;
+   };
+
backlight {
compatible = "pwm-backlight";
pwms = < 0 5 0>;
@@ -50,7 +60,10 @@
 
 _pinmux {
pinctrl-names = "default";
-   pinctrl-0 = <_pins>;
+   pinctrl-0 = <
+ _pins
+ _pins
+   >;
 
i2c0_pins: pinmux_i2c0_pins {
pinctrl-single,pins = <
@@ -223,6 +236,21 @@
>;
};
 
+   spi0_pins: pinmux_spi0_pins {
+   pinctrl-single,pins = <
+   /* spi0_sclk.spi0_sclk */
+   AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0)
+   /* spi0_d0.spi0_d0 */
+   AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+   /* spi0_d1.spi0_d1 */
+   AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0)
+   /* spi0_cs0.spi0_cs0 */
+   AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0)
+   /* spi0_cs1.spi0_cs1 */
+   AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0)
+   >;
+   };
+
/* wl1271 bluetooth */
bluetooth_pins: pinmux_bluetooth_pins {
pinctrl-single,pins = <
@@ -230,6 +258,16 @@
AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7)
>;
};
+
+   /* wl1271 WiFi */
+   wifi_pins: pinmux_wifi_pins {
+   pinctrl-single,pins = <
+   /* EMU1.gpio3_8 - WiFi IRQ */
+   AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7)
+   /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */
+   AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7)
+   >;
+   };
 };
 
  {
@@ -394,3 +432,21 @@ status = "okay";
pinctrl-names = "default";
pinctrl-0 = <_pins>;
 };
+
+ {
+   status = "okay";
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins>;
+   ti,pindir-d0-out-d1-in = <1>;
+   /* WLS1271 WiFi */
+   wlcore: wlcore@1 {
+   compatible = "ti,wl1271";
+   reg = <1>;
+   spi-max-frequency = <4800>;
+   clock-xtal;
+   ref-clock-frequency = <3840>;
+   interrupt-parent = <>;
+   interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+   vwlan-supply = <_fixed>;
+   };
+};
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] wlcore/wl12xx: spi: add wifi support to cm-t335

2015-12-23 Thread Uri Mashiach
Add DT support for WLS1271 SPI driver.
Fix oops by adding a power callback.

Uri Mashiach (3):
  wlcore/wl12xx: spi: fix NULL pointer dereference (Oops)
  wlcore/wl12xx: spi: add device tree support
  wlcore/wl12xx: spi: add wifi support to cm-t335

 .../bindings/net/wireless/ti,wlcore,spi.txt|  35 +++
 arch/arm/boot/dts/am335x-cm-t335.dts   |  58 +++-
 drivers/net/wireless/ti/wlcore/spi.c   | 104 +++--
 3 files changed, 189 insertions(+), 8 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt

-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] wlcore/wl12xx: spi: fix oops on firmware load

2015-12-10 Thread Uri Mashiach
The maximum chunks used by the function is
(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE + 1).
The original commands array had space for
(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) commands.
When the last chunk is used (len > 4 * WSPI_MAX_CHUNK_SIZE), the last
command is stored outside the bounds of the commands array.

Oops 5 (page fault) is generated during current wl1271 firmware load
attempt:

root@debian-armhf:~# ifconfig wlan0 up
[  294.312399] Unable to handle kernel paging request at virtual address
00203fc4
[  294.320173] pgd = de528000
[  294.323028] [00203fc4] *pgd=
[  294.326916] Internal error: Oops: 5 [#1] SMP ARM
[  294.331789] Modules linked in: bnep rfcomm bluetooth ipv6 arc4 wl12xx
wlcore mac80211 musb_dsps cfg80211 musb_hdrc usbcore usb_common
wlcore_spi omap_rng rng_core musb_am335x omap_wdt cpufreq_dt thermal_sys
hwmon
[  294.351838] CPU: 0 PID: 1827 Comm: ifconfig Not tainted
4.2.0-2-g3e9ad27-dirty #78
[  294.360154] Hardware name: Generic AM33XX (Flattened Device Tree)
[  294.366557] task: dc9d6d40 ti: de55 task.ti: de55
[  294.372236] PC is at __spi_validate+0xa8/0x2ac
[  294.376902] LR is at __spi_sync+0x78/0x210
[  294.381200] pc : []lr : []psr: 6013
[  294.381200] sp : de551998  ip : de5519d8  fp : 0020
[  294.393242] r10: de551c8c  r9 : de5519d8  r8 : de3a9000
[  294.398730] r7 : de3a9258  r6 : de3a9400  r5 : de551a48  r4 :
00203fbc
[  294.405577] r3 :   r2 :   r1 :   r0 :
de3a9000
[  294.412420] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment user
[  294.419918] Control: 10c5387d  Table: 9e528019  DAC: 0015
[  294.425954] Process ifconfig (pid: 1827, stack limit = 0xde550218)
[  294.432437] Stack: (0xde551998 to 0xde552000)

...

[  294.883613] [] (__spi_validate) from []
(__spi_sync+0x78/0x210)
[  294.891670] [] (__spi_sync) from []
(wl12xx_spi_raw_write+0xfc/0x148 [wlcore_spi])
[  294.901661] [] (wl12xx_spi_raw_write [wlcore_spi]) from
[] (wlcore_boot_upload_firmware+0x1ec/0x458 [wlcore])
[  294.914038] [] (wlcore_boot_upload_firmware [wlcore]) from
[] (wl12xx_boot+0xc10/0xfac [wl12xx])
[  294.925161] [] (wl12xx_boot [wl12xx]) from []
(wl1271_op_add_interface+0x5b0/0x910 [wlcore])
[  294.936364] [] (wl1271_op_add_interface [wlcore]) from
[] (ieee80211_do_open+0x44c/0xf7c [mac80211])
[  294.947963] [] (ieee80211_do_open [mac80211]) from
[] (__dev_open+0xa8/0x110)
[  294.957307] [] (__dev_open) from []
(__dev_change_flags+0x88/0x148)
[  294.965713] [] (__dev_change_flags) from []
(dev_change_flags+0x18/0x48)
[  294.974576] [] (dev_change_flags) from []
(devinet_ioctl+0x6b4/0x7d0)
[  294.983191] [] (devinet_ioctl) from []
(sock_ioctl+0x1e4/0x2bc)
[  294.991244] [] (sock_ioctl) from []
(do_vfs_ioctl+0x420/0x6b0)
[  294.999208] [] (do_vfs_ioctl) from []
(SyS_ioctl+0x6c/0x7c)
[  295.006880] [] (SyS_ioctl) from []
(ret_fast_syscall+0x0/0x54)
[  295.014835] Code: e1550004 e2444034 0a7d e5953018 (e5942008)
[  295.021544] ---[ end trace 66ed188198f4e24e ]---

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
Acked-by: Igor Grinberg <grinb...@compulab.co.il>
Cc: sta...@vger.kernel.org
---
v1 -> v2: Stable tag v3.9+

 drivers/net/wireless/ti/wlcore/spi.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index f1ac283..720e4e4 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -73,7 +73,10 @@
  */
 #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
 
-#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
+/* Maximum number of SPI write chunks */
+#define WSPI_MAX_NUM_OF_CHUNKS \
+   ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
+
 
 struct wl12xx_spi_glue {
struct device *dev;
@@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_write(struct device 
*child, int addr,
 void *buf, size_t len, bool fixed)
 {
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
-   struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
+   /* SPI write buffers - 2 for each chunk */
+   struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
struct spi_message m;
-   u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
+   u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
u32 *cmd;
u32 chunk_len;
int i;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] wlcore/wl12xx: spi: fix oops on firmware load

2015-12-07 Thread Uri Mashiach
The maximum chunks used by the function is
(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE + 1).
The original commands array had space for
(SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) commands.
When the last chunk is used (len > 4 * WSPI_MAX_CHUNK_SIZE), the last
command is stored outside the bounds of the commands array.

Oops 5 (page fault) is generated during current wl1271 firmware load
attempt:

root@debian-armhf:~# ifconfig wlan0 up
[  294.312399] Unable to handle kernel paging request at virtual address
00203fc4
[  294.320173] pgd = de528000
[  294.323028] [00203fc4] *pgd=
[  294.326916] Internal error: Oops: 5 [#1] SMP ARM
[  294.331789] Modules linked in: bnep rfcomm bluetooth ipv6 arc4 wl12xx
wlcore mac80211 musb_dsps cfg80211 musb_hdrc usbcore usb_common
wlcore_spi omap_rng rng_core musb_am335x omap_wdt cpufreq_dt thermal_sys
hwmon
[  294.351838] CPU: 0 PID: 1827 Comm: ifconfig Not tainted
4.2.0-2-g3e9ad27-dirty #78
[  294.360154] Hardware name: Generic AM33XX (Flattened Device Tree)
[  294.366557] task: dc9d6d40 ti: de55 task.ti: de55
[  294.372236] PC is at __spi_validate+0xa8/0x2ac
[  294.376902] LR is at __spi_sync+0x78/0x210
[  294.381200] pc : []lr : []psr: 6013
[  294.381200] sp : de551998  ip : de5519d8  fp : 0020
[  294.393242] r10: de551c8c  r9 : de5519d8  r8 : de3a9000
[  294.398730] r7 : de3a9258  r6 : de3a9400  r5 : de551a48  r4 :
00203fbc
[  294.405577] r3 :   r2 :   r1 :   r0 :
de3a9000
[  294.412420] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM
Segment user
[  294.419918] Control: 10c5387d  Table: 9e528019  DAC: 0015
[  294.425954] Process ifconfig (pid: 1827, stack limit = 0xde550218)
[  294.432437] Stack: (0xde551998 to 0xde552000)

...

[  294.883613] [] (__spi_validate) from []
(__spi_sync+0x78/0x210)
[  294.891670] [] (__spi_sync) from []
(wl12xx_spi_raw_write+0xfc/0x148 [wlcore_spi])
[  294.901661] [] (wl12xx_spi_raw_write [wlcore_spi]) from
[] (wlcore_boot_upload_firmware+0x1ec/0x458 [wlcore])
[  294.914038] [] (wlcore_boot_upload_firmware [wlcore]) from
[] (wl12xx_boot+0xc10/0xfac [wl12xx])
[  294.925161] [] (wl12xx_boot [wl12xx]) from []
(wl1271_op_add_interface+0x5b0/0x910 [wlcore])
[  294.936364] [] (wl1271_op_add_interface [wlcore]) from
[] (ieee80211_do_open+0x44c/0xf7c [mac80211])
[  294.947963] [] (ieee80211_do_open [mac80211]) from
[] (__dev_open+0xa8/0x110)
[  294.957307] [] (__dev_open) from []
(__dev_change_flags+0x88/0x148)
[  294.965713] [] (__dev_change_flags) from []
(dev_change_flags+0x18/0x48)
[  294.974576] [] (dev_change_flags) from []
(devinet_ioctl+0x6b4/0x7d0)
[  294.983191] [] (devinet_ioctl) from []
(sock_ioctl+0x1e4/0x2bc)
[  294.991244] [] (sock_ioctl) from []
(do_vfs_ioctl+0x420/0x6b0)
[  294.999208] [] (do_vfs_ioctl) from []
(SyS_ioctl+0x6c/0x7c)
[  295.006880] [] (SyS_ioctl) from []
(ret_fast_syscall+0x0/0x54)
[  295.014835] Code: e1550004 e2444034 0a7d e5953018 (e5942008)
[  295.021544] ---[ end trace 66ed188198f4e24e ]---

Signed-off-by: Uri Mashiach <uri.mashi...@compulab.co.il>
---
 drivers/net/wireless/ti/wlcore/spi.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/spi.c 
b/drivers/net/wireless/ti/wlcore/spi.c
index f1ac283..720e4e4 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -73,7 +73,10 @@
  */
 #define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
 
-#define WSPI_MAX_NUM_OF_CHUNKS (SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE)
+/* Maximum number of SPI write chunks */
+#define WSPI_MAX_NUM_OF_CHUNKS \
+   ((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
+
 
 struct wl12xx_spi_glue {
struct device *dev;
@@ -268,9 +271,10 @@ static int __must_check wl12xx_spi_raw_write(struct device 
*child, int addr,
 void *buf, size_t len, bool fixed)
 {
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
-   struct spi_transfer t[2 * (WSPI_MAX_NUM_OF_CHUNKS + 1)];
+   /* SPI write buffers - 2 for each chunk */
+   struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
struct spi_message m;
-   u32 commands[WSPI_MAX_NUM_OF_CHUNKS];
+   u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
u32 *cmd;
u32 chunk_len;
int i;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html