Message ID | 20230314163201.955689-1-arnd@kernel.org |
---|---|
State | New |
Headers | show |
Series | p54spi: convert to devicetree | expand |
On Tue, 2023-03-14 at 17:30 +0100, Arnd Bergmann wrote: > > As I don't have an N8x0, this is completely untested. > > I listed the driver authors (Johannes and Christian) as the maintainers > of the binding document, but I don't know if they actually have this > hardware. It might be better to list someone who is actually using it. Wow, umm, yeah I still have an N810 but ... If anyone wants the device, shout, I'll give it away. I think I checked fairly recently (within a year maybe) it still booted :-) So yeah, it's probably not a great idea to list me there, I don't even know these details, and probably never did, I'm pretty sure I never installed a custom kernel on it. johannes
Hi, On 3/14/23 17:30, Arnd Bergmann wrote: > The Prism54 SPI driver hardcodes GPIO numbers and expects users to > pass them as module parameters, apparently a relic from its life as a > staging driver. This works because there is only one user, the Nokia > N8x0 tablet. > > Convert this to the gpio descriptor interface and move the gpio > line information into devicetree to improve this and simplify the > code at the same time. Yes, this is definitely the right idea/way. From what I remember, Kalle Valo was partially involved in p54spi/stlc45xx. The details are very fuzzy. So, I could be totally wrong. From what I remember Kalle was working for Nokia (or as a contractor for Nokia?) at the time. > Signed-off-by: Arnd Bergmann <arnd@arndb.de> I've seen the device-tree comments. That said, this is/was overdue. You can definitely have this for a v2 :). Acked-by: Christian Lamparter <chunkeey@gmail.com> Thanks you! Christian > --- > As I don't have an N8x0, this is completely untested. > > I listed the driver authors (Johannes and Christian) as the maintainers > of the binding document, but I don't know if they actually have this > hardware. It might be better to list someone who is actually using it. > > Among the various chip identifications, I wasn't sure which one to > use for the compatible string and the name of the binding document. > I picked st,stlc4560 as that was cited as the version in the N800 > on multiple websites. > --- > .../bindings/net/wireless/st,stlc45xx.yaml | 64 +++++++++++++++++ > MAINTAINERS | 1 + > arch/arm/boot/dts/omap2.dtsi | 4 ++ > arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 12 ++++ > arch/arm/mach-omap2/board-n8x0.c | 18 ----- > drivers/net/wireless/intersil/p54/p54spi.c | 69 +++++++------------ > drivers/net/wireless/intersil/p54/p54spi.h | 3 + > 7 files changed, 109 insertions(+), 62 deletions(-) > create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml > > diff --git a/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml > new file mode 100644 > index 000000000000..45bc4fab409a > --- /dev/null > +++ b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml > @@ -0,0 +1,64 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/net/wireless/st,stlc45xx.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: ST/Intersil/Conexant stlc45xx/p54spi/cx3110x SPI wireless device > + > +maintainers: > + - Johannes Berg <johannes@sipsolutions.net> > + - Christian Lamparter <chunkeey@web.de> Can you please change that to: Christian Lamparter <chunkeey@gmail.com> ? (the @web.de/googlemail.com address still work too, but they are now just forwarding) > +description: | > + The SPI variant of the Intersil Prism54 wireless device was sold > + under a variety of names, including ST Microelectronics STLC5460 > + and Conexant CX3110x. > + > +allOf: > + - $ref: ieee80211.yaml# > + - $ref: /schemas/spi/spi-peripheral-props.yaml# > + > +properties: > + compatible: > + enum: > + - st,stlc4550 > + - st,stlc4560 > + - isil,p54spi > + - cnxt,3110x > + > + reg: > + maxItems: 1 > + > + interrupts: > + maxItems: 1 > + > + power-gpios: > + maxItems: 1 > + > +required: > + - compatible > + - reg > + - interrupts > + > +unevaluatedProperties: false > + > +examples: > + - | > + gpio { > + gpio-controller; > + #gpio-cells = <1>; > + #interupt-cells = <1>; > + }; > + spi { > + #address-cells = <1>; > + #size-cells = <0>; > + > + wifi@0 { > + reg = <0>; > + compatible = "st,stlc4560"; > + spi-max-frequency = <48000000>; > + interrupts-extended = <&gpio 23>; > + power-gpios = <&gpio 1>; > + }; > + };
On Tue, Mar 14, 2023, at 20:57, Krzysztof Kozlowski wrote: > On 14/03/2023 17:30, Arnd Bergmann wrote: > > Please split bindings to separate patch. > >> MAINTAINERS | 1 + >> arch/arm/boot/dts/omap2.dtsi | 4 ++ >> arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 12 ++++ > > DTS as well... ok >> +maintainers: >> + - Johannes Berg <johannes@sipsolutions.net> >> + - Christian Lamparter <chunkeey@web.de> >> + >> +description: | > > You can drop '|'. ok >> +properties: >> + compatible: >> + enum: >> + - st,stlc4550 >> + - st,stlc4560 >> + - isil,p54spi >> + - cnxt,3110x > > Order above entries by name. ok >> + >> + power-gpios: > > If this is GPIO driving some power pin, then it should be > "powerdown-gpios" (like in /bindings/gpio/gpio-consumer-common.yaml) As far as I can tell, it's the opposite: the gpio turns the power on in 'high' state. I could make it GPIO_ACTIVE_LOW and call it powerdown, if you think that's better, but I don't think that is how it was meant. >> +examples: >> + - | >> + gpio { > > Align example with above |, so four spaces. Or better indent entire > example with four spaces. Ok, that makes it much more readable. >> + gpio-controller; >> + #gpio-cells = <1>; >> + #interupt-cells = <1>; >> + }; > > Drop "gpio" node. It's not needed for the example. ok. >> + spi { >> + #address-cells = <1>; >> + #size-cells = <0>; >> + >> + wifi@0 { >> + reg = <0>; >> + compatible = "st,stlc4560"; > > compatible before reg. ok. Arnd
Christian Lamparter <chunkeey@gmail.com> writes: > Hi, > > On 3/14/23 17:30, Arnd Bergmann wrote: >> The Prism54 SPI driver hardcodes GPIO numbers and expects users to >> pass them as module parameters, apparently a relic from its life as a >> staging driver. This works because there is only one user, the Nokia >> N8x0 tablet. >> >> Convert this to the gpio descriptor interface and move the gpio >> line information into devicetree to improve this and simplify the >> code at the same time. > > Yes, this is definitely the right idea/way. From what I remember, Kalle > Valo was partially involved in p54spi/stlc45xx. The details are very fuzzy. > So, I could be totally wrong. From what I remember Kalle was working > for Nokia (or as a contractor for Nokia?) at the time. I wrote stlc45xx driver as part of my thesis when working for Nokia and I think then someone wrote p54spi after that. Oh man, this was a long time ago so hard to remember :)
On 14/03/2023 22:40, Arnd Bergmann wrote: >>> + >>> + power-gpios: >> >> If this is GPIO driving some power pin, then it should be >> "powerdown-gpios" (like in /bindings/gpio/gpio-consumer-common.yaml) > > As far as I can tell, it's the opposite: the gpio turns the power on > in 'high' state. I could make it GPIO_ACTIVE_LOW and call it powerdown, > if you think that's better, but I don't think that is how it was > meant. Whether this is active low or high, I think does not matter. If this is pin responsible to control the power, then we use the name "powerdown-gpios". Effectively powerup GPIO is the same as powerdown, just reversed. Best regards, Krzysztof
On Wed, Mar 15, 2023, at 07:32, Krzysztof Kozlowski wrote: > On 14/03/2023 22:40, Arnd Bergmann wrote: > >>>> + >>>> + power-gpios: >>> >>> If this is GPIO driving some power pin, then it should be >>> "powerdown-gpios" (like in /bindings/gpio/gpio-consumer-common.yaml) >> >> As far as I can tell, it's the opposite: the gpio turns the power on >> in 'high' state. I could make it GPIO_ACTIVE_LOW and call it powerdown, >> if you think that's better, but I don't think that is how it was >> meant. > > Whether this is active low or high, I think does not matter. If this is > pin responsible to control the power, then we use the name > "powerdown-gpios". Effectively powerup GPIO is the same as powerdown, > just reversed. Ok, so should I make this GPIO_ACTIVE_LOW and adapt the patch to call it powerdown in both the code and dt for consistency? Arnd
On 15/03/2023 07:50, Arnd Bergmann wrote: > On Wed, Mar 15, 2023, at 07:32, Krzysztof Kozlowski wrote: >> On 14/03/2023 22:40, Arnd Bergmann wrote: >> >>>>> + >>>>> + power-gpios: >>>> >>>> If this is GPIO driving some power pin, then it should be >>>> "powerdown-gpios" (like in /bindings/gpio/gpio-consumer-common.yaml) >>> >>> As far as I can tell, it's the opposite: the gpio turns the power on >>> in 'high' state. I could make it GPIO_ACTIVE_LOW and call it powerdown, >>> if you think that's better, but I don't think that is how it was >>> meant. >> >> Whether this is active low or high, I think does not matter. If this is >> pin responsible to control the power, then we use the name >> "powerdown-gpios". Effectively powerup GPIO is the same as powerdown, >> just reversed. > > Ok, so should I make this GPIO_ACTIVE_LOW and adapt the patch to > call it powerdown in both the code and dt for consistency? If you have schematics (or datasheet) then this should reflect truth. If not, then judging by the old code it is something like powerdown, so yes - ACTIVE_LOW and reverse values in the code. Best regards, Krzysztof
On Tue, Mar 14, 2023 at 05:30:56PM +0100, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@arndb.de> > > The Prism54 SPI driver hardcodes GPIO numbers and expects users to > pass them as module parameters, apparently a relic from its life as a > staging driver. This works because there is only one user, the Nokia > N8x0 tablet. > > Convert this to the gpio descriptor interface and move the gpio > line information into devicetree to improve this and simplify the > code at the same time. > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > --- > As I don't have an N8x0, this is completely untested. > > I listed the driver authors (Johannes and Christian) as the maintainers > of the binding document, but I don't know if they actually have this > hardware. It might be better to list someone who is actually using it. > > Among the various chip identifications, I wasn't sure which one to > use for the compatible string and the name of the binding document. > I picked st,stlc4560 as that was cited as the version in the N800 > on multiple websites. > --- > .../bindings/net/wireless/st,stlc45xx.yaml | 64 +++++++++++++++++ > MAINTAINERS | 1 + > arch/arm/boot/dts/omap2.dtsi | 4 ++ > arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 12 ++++ > arch/arm/mach-omap2/board-n8x0.c | 18 ----- > drivers/net/wireless/intersil/p54/p54spi.c | 69 +++++++------------ > drivers/net/wireless/intersil/p54/p54spi.h | 3 + > 7 files changed, 109 insertions(+), 62 deletions(-) > create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml Binding looks fine, but I assume you'll split this into at least 3 patches? Rob
diff --git a/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml new file mode 100644 index 000000000000..45bc4fab409a --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/wireless/st,stlc45xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST/Intersil/Conexant stlc45xx/p54spi/cx3110x SPI wireless device + +maintainers: + - Johannes Berg <johannes@sipsolutions.net> + - Christian Lamparter <chunkeey@web.de> + +description: | + The SPI variant of the Intersil Prism54 wireless device was sold + under a variety of names, including ST Microelectronics STLC5460 + and Conexant CX3110x. + +allOf: + - $ref: ieee80211.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - st,stlc4550 + - st,stlc4560 + - isil,p54spi + - cnxt,3110x + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + power-gpios: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + gpio { + gpio-controller; + #gpio-cells = <1>; + #interupt-cells = <1>; + }; + spi { + #address-cells = <1>; + #size-cells = <0>; + + wifi@0 { + reg = <0>; + compatible = "st,stlc4560"; + spi-max-frequency = <48000000>; + interrupts-extended = <&gpio 23>; + power-gpios = <&gpio 1>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 25a0981c74b6..a238b1ad5878 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15754,6 +15754,7 @@ M: Christian Lamparter <chunkeey@googlemail.com> L: linux-wireless@vger.kernel.org S: Maintained W: https://wireless.wiki.kernel.org/en/users/Drivers/p54 +F: Documentation/devicetree/bindings/net/wireless/st,stlc45xx.yaml F: drivers/net/wireless/intersil/p54/ PACKET SOCKETS diff --git a/arch/arm/boot/dts/omap2.dtsi b/arch/arm/boot/dts/omap2.dtsi index afabb36a8ac1..fdc1790adf43 100644 --- a/arch/arm/boot/dts/omap2.dtsi +++ b/arch/arm/boot/dts/omap2.dtsi @@ -129,6 +129,8 @@ i2c2: i2c@48072000 { }; mcspi1: spi@48098000 { + #address-cells = <1>; + #size-cells = <0>; compatible = "ti,omap2-mcspi"; ti,hwmods = "mcspi1"; reg = <0x48098000 0x100>; @@ -140,6 +142,8 @@ mcspi1: spi@48098000 { }; mcspi2: spi@4809a000 { + #address-cells = <1>; + #size-cells = <0>; compatible = "ti,omap2-mcspi"; ti,hwmods = "mcspi2"; reg = <0x4809a000 0x100>; diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi index 63b0b4921e4e..483ad1411f99 100644 --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi @@ -109,3 +109,15 @@ partition@5 { }; }; }; + +&mcspi2 { + status = "okay"; + + wifi@0 { + reg = <0>; + compatible = "st,stlc4560"; + spi-max-frequency = <48000000>; + interrupts-extended = <&gpio3 23 IRQ_TYPE_EDGE_RISING>; + gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>; /* gpio 97 */ + }; +}; diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 3353b0a923d9..6a2949f50653 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -19,7 +19,6 @@ #include <linux/spi/spi.h> #include <linux/usb/musb.h> #include <linux/mmc/host.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/platform_data/mmc-omap.h> #include <linux/mfd/menelaus.h> @@ -142,21 +141,6 @@ static void __init n8x0_usb_init(void) {} #endif /*CONFIG_USB_MUSB_TUSB6010 */ - -static struct omap2_mcspi_device_config p54spi_mcspi_config = { - .turbo_mode = 0, -}; - -static struct spi_board_info n800_spi_board_info[] __initdata = { - { - .modalias = "p54spi", - .bus_num = 2, - .chip_select = 0, - .max_speed_hz = 48000000, - .controller_data = &p54spi_mcspi_config, - }, -}; - #if defined(CONFIG_MENELAUS) && IS_ENABLED(CONFIG_MMC_OMAP) /* @@ -585,7 +569,5 @@ omap_late_initcall(n8x0_late_initcall); void * __init n8x0_legacy_init(void) { board_check_revision(); - spi_register_board_info(n800_spi_board_info, - ARRAY_SIZE(n800_spi_board_info)); return &mmc1_data; } diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c index 19152fd449ba..8e294ba806e3 100644 --- a/drivers/net/wireless/intersil/p54/p54spi.c +++ b/drivers/net/wireless/intersil/p54/p54spi.c @@ -8,6 +8,7 @@ */ #include <linux/module.h> +#include <linux/mod_devicetable.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/firmware.h> @@ -15,7 +16,7 @@ #include <linux/irq.h> #include <linux/spi/spi.h> #include <linux/etherdevice.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include "p54spi.h" @@ -29,19 +30,6 @@ MODULE_FIRMWARE("3826.arm"); -/* gpios should be handled in board files and provided via platform data, - * but because it's currently impossible for p54spi to have a header file - * in include/linux, let's use module paramaters for now - */ - -static int p54spi_gpio_power = 97; -module_param(p54spi_gpio_power, int, 0444); -MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line"); - -static int p54spi_gpio_irq = 87; -module_param(p54spi_gpio_irq, int, 0444); -MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line"); - static void p54spi_spi_read(struct p54s_priv *priv, u8 address, void *buf, size_t len) { @@ -261,14 +249,14 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev) static void p54spi_power_off(struct p54s_priv *priv) { - disable_irq(gpio_to_irq(p54spi_gpio_irq)); - gpio_set_value(p54spi_gpio_power, 0); + disable_irq(priv->irq); + gpiod_set_value(priv->gpio_power, 0); } static void p54spi_power_on(struct p54s_priv *priv) { - gpio_set_value(p54spi_gpio_power, 1); - enable_irq(gpio_to_irq(p54spi_gpio_irq)); + gpiod_set_value(priv->gpio_power, 1); + enable_irq(priv->irq); /* need to wait a while before device can be accessed, the length * is just a guess @@ -607,32 +595,20 @@ static int p54spi_probe(struct spi_device *spi) goto err_free; } - ret = gpio_request(p54spi_gpio_power, "p54spi power"); - if (ret < 0) { + priv->gpio_power = gpiod_get(&spi->dev, "power", GPIOD_OUT_LOW); + if (IS_ERR(priv->gpio_power)) { + ret = PTR_ERR(priv->gpio_power); dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); goto err_free; } - ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); - if (ret < 0) { - dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); - goto err_free_gpio_power; - } - - gpio_direction_output(p54spi_gpio_power, 0); - gpio_direction_input(p54spi_gpio_irq); - - ret = request_irq(gpio_to_irq(p54spi_gpio_irq), - p54spi_interrupt, 0, "p54spi", - priv->spi); + ret = request_irq(spi->irq, p54spi_interrupt, 0, "p54spi", priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); - goto err_free_gpio_irq; + goto err_free_gpio_power; } - irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); - - disable_irq(gpio_to_irq(p54spi_gpio_irq)); + disable_irq(priv->irq); INIT_WORK(&priv->work, p54spi_work); init_completion(&priv->fw_comp); @@ -660,11 +636,9 @@ static int p54spi_probe(struct spi_device *spi) err_free_common: release_firmware(priv->firmware); - free_irq(gpio_to_irq(p54spi_gpio_irq), spi); -err_free_gpio_irq: - gpio_free(p54spi_gpio_irq); + free_irq(priv->irq, spi); err_free_gpio_power: - gpio_free(p54spi_gpio_power); + gpiod_put(priv->gpio_power); err_free: p54_free_common(priv->hw); return ret; @@ -676,10 +650,8 @@ static void p54spi_remove(struct spi_device *spi) p54_unregister_common(priv->hw); - free_irq(gpio_to_irq(p54spi_gpio_irq), spi); - - gpio_free(p54spi_gpio_power); - gpio_free(p54spi_gpio_irq); + free_irq(priv->irq, spi); + gpiod_put(priv->gpio_power); release_firmware(priv->firmware); mutex_destroy(&priv->mutex); @@ -687,10 +659,19 @@ static void p54spi_remove(struct spi_device *spi) p54_free_common(priv->hw); } +struct of_device_id p54spi_of_ids[] = { + { .compatible = "cnxt,3110x", }, + { .compatible = "isil,p54spi", }, + { .compatible = "st,stlc4550", }, + { .compatible = "st,stlc4560", }, + { }, +}; +MODULE_DEVICE_TABLE(of, p54spi_of_ids); static struct spi_driver p54spi_driver = { .driver = { .name = "p54spi", + .of_match_table = p54spi_of_ids, }, .probe = p54spi_probe, diff --git a/drivers/net/wireless/intersil/p54/p54spi.h b/drivers/net/wireless/intersil/p54/p54spi.h index e5619a13fd61..aae6fc64972a 100644 --- a/drivers/net/wireless/intersil/p54/p54spi.h +++ b/drivers/net/wireless/intersil/p54/p54spi.h @@ -107,6 +107,9 @@ struct p54s_priv { enum fw_state fw_state; const struct firmware *firmware; + + struct gpio_desc *gpio_power; + int irq; }; #endif /* P54SPI_H */