Add device tree support for imx spi driver
Subsystems (6)
cover Add device tree support for imx spi driver
The patch set makes some cleanups on imx spi driver to get it ready for adding device tree probe and then add the support.
Those two dt helper function related patches are carried here to resolve the dependency. They should be on the way to sit on Grant's devicetree/next branch.
Rob Herring (1):
dt: add helper function to read u32 arrays
Shawn Guo (5):
ARM: mxc: remove unnecessary header file inclusion from gpio.h spi/imx: use soc name in spi device type naming scheme spi/imx: copy gpio number passed by platform data into driver private data
dt: add empty of_property_read_u32[_array] for non-dt spi/imx: add device tree probe support
.../devicetree/bindings/spi/fsl-imx-cspi.txt | 22 + arch/arm/mach-imx/clock-imx25.c | 7 +- arch/arm/mach-mx5/clock-mx51-mx53.c | 11 +- arch/arm/plat-mxc/devices/platform-spi_imx.c | 12 +- arch/arm/plat-mxc/include/mach/gpio.h | 2 - drivers/of/base.c | 19 +- drivers/spi/Kconfig | 15 - drivers/spi/spi-imx.c | 468 ++++++++++---------- include/linux/of.h | 29 ++- 9 files changed, 317 insertions(+), 268 deletions(-)
PATCH 1/6 ARM: mxc: remove unnecessary header file inclusion from gpio.h
The mach/gpio.h is included by asm/gpio.h, and in turn it gets included all over the place. Including unnecessary headers there brings indirect inclusion trouble.
As an example, spi-imx calls cpu_is_mx21() but never explicitly includes mach/hardware.h. However it works because the header is included in mach/gpio.h.
The patch cleans the unnecessary header file from mach/gpio.h, and includes headers explicitly where needed.
--- arch/arm/plat-mxc/include/mach/gpio.h | 2 -- drivers/spi/spi-imx.c | 1 + 2 files changed, 1 insertions(+), 2 deletions(-)
arch/arm/plat-mxc/include/mach/gpio.h +0 -2
@@ -19,8 +19,6 @@#ifndef __ASM_ARCH_MXC_GPIO_H__#define __ASM_ARCH_MXC_GPIO_H__ -#include <linux/spinlock.h> -#include <mach/hardware.h> #include <asm-generic/gpio.h>
drivers/spi/spi-imx.c +1 -0
@@ -36,6 +36,7 @@#include <linux/types.h> #include <mach/spi.h> +#include <mach/hardware.h> #define DRIVER_NAME "spi_imx"
Signature · 1 line
1.7.4.1
PATCH 2/6 spi/imx: use soc name in spi device type naming scheme
In reply to Shawn GuoSoftware defined version number is not stable enough to be used in device type naming scheme. The patch changes it to use implicit soc name for spi device type definition. In this way, we can easily align the naming scheme with device tree binding, which comes later.
--- arch/arm/mach-imx/clock-imx25.c | 7 +- arch/arm/mach-mx5/clock-mx51-mx53.c | 11 +- arch/arm/plat-mxc/devices/platform-spi_imx.c | 12 +- drivers/spi/Kconfig | 15 - drivers/spi/spi-imx.c | 423 ++++++++++++-------------- 5 files changed, 219 insertions(+), 249 deletions(-)
arch/arm/mach-imx/clock-imx25.c +4 -3
@@ -283,9 +283,10 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk) _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)_REGISTER_CLOCK ("mxc_nand.0" ,NULL , nfc_clk) - _REGISTER_CLOCK("imx25-cspi.0", NULL, cspi1_clk) - _REGISTER_CLOCK("imx25-cspi.1", NULL, cspi2_clk) - _REGISTER_CLOCK("imx25-cspi.2", NULL, cspi3_clk) + /* i.mx25 has the i.mx35 type cspi */ + _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk) + _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk) + _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk) _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk) _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)_REGISTER_CLOCK ("mxc_pwm.2" ,NULL , pwm3_clk)
arch/arm/mach-mx5/clock-mx51-mx53.c +7 -4
@@ -1453,7 +1453,8 @@ static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)_REGISTER_CLOCK ("imx51-ecspi.1" ,NULL , ecspi2_clk) - _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) + /* i.mx51 has the i.mx35 type cspi */ + _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk) _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk)_REGISTER_CLOCK ("sdhci-esdhc-imx51.2" ,NULL , esdhc3_clk)
@@ -1486,9 +1487,11 @@ static struct clk_lookup mx53_lookups[] = { _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk) _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk)_REGISTER_CLOCK ("sdhci-esdhc-imx53.3" ,NULL , esdhc4_mx53_clk) - _REGISTER_CLOCK("imx53-ecspi.0", NULL, ecspi1_clk) - _REGISTER_CLOCK("imx53-ecspi.1", NULL, ecspi2_clk) - _REGISTER_CLOCK("imx53-cspi.0", NULL, cspi_clk) + /* i.mx53 has the i.mx51 type ecspi */ + _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) +_REGISTER_CLOCK ("imx51-ecspi.1" ,NULL , ecspi2_clk) + /* i.mx53 has the i.mx35 type cspi */ + _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)_REGISTER_CLOCK ("imx-sdma" ,NULL , sdma_clk)
arch/arm/plat-mxc/devices/platform-spi_imx.c +8 -4
@@ -40,9 +40,10 @@ const struct imx_spi_imx_data imx21_cspi_data[] __initconst = {#endif #ifdef CONFIG_SOC_IMX25 +/* i.mx25 has the i.mx35 type cspi */ const struct imx_spi_imx_data imx25_cspi_data[]__initconst = { #define imx25_cspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX25, CSPI, "imx25-cspi", _id, _hwid, SZ_16K) + imx_spi_imx_data_entry(MX25, CSPI, "imx35-cspi", _id, _hwid, SZ_16K)imx25_cspi_data_entry (0 ,1 ),imx25_cspi_data_entry (1 ,2 ), imx25_cspi_data_entry(2, 3),
@@ -79,8 +80,9 @@ const struct imx_spi_imx_data imx35_cspi_data[] __initconst = {#endif /* ifdef CONFIG_SOC_IMX35 */ #ifdef CONFIG_SOC_IMX51 +/* i.mx51 has the i.mx35 type cspi */ const struct imx_spi_imx_data imx51_cspi_data__initconst = - imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 2, , SZ_4K); + imx_spi_imx_data_entry_single(MX51, CSPI, "imx35-cspi", 2, , SZ_4K);const struct imx_spi_imx_data imx51_ecspi_data[]__initconst = { #define imx51_ecspi_data_entry(_id, _hwid) \
@@ -91,12 +93,14 @@ const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {#endif /* ifdef CONFIG_SOC_IMX51 */ #ifdef CONFIG_SOC_IMX53 +/* i.mx53 has the i.mx35 type cspi */ const struct imx_spi_imx_data imx53_cspi_data__initconst = - imx_spi_imx_data_entry_single(MX53, CSPI, "imx53-cspi", 0, , SZ_4K); + imx_spi_imx_data_entry_single(MX53, CSPI, "imx35-cspi", 0, , SZ_4K); +/* i.mx53 has the i.mx51 type ecspi */ const struct imx_spi_imx_data imx53_ecspi_data[]__initconst = { #define imx53_ecspi_data_entry(_id, _hwid) \ - imx_spi_imx_data_entry(MX53, ECSPI, "imx53-ecspi", _id, _hwid, SZ_4K) + imx_spi_imx_data_entry(MX53, ECSPI, "imx51-ecspi", _id, _hwid, SZ_4K)imx53_ecspi_data_entry (0 ,1 ),imx53_ecspi_data_entry (1 ,2 ), };
drivers/spi/Kconfig +0 -15
@@ -154,21 +154,6 @@ config SPI_GPIO GPIO operations, you should be able to leverage that for better speed with a custom version of this driver; see the source code. -config SPI_IMX_VER_IMX1 - def_bool y if SOC_IMX1 - -config SPI_IMX_VER_0_0 - def_bool y if SOC_IMX21 || SOC_IMX27 - -config SPI_IMX_VER_0_4 - def_bool y if SOC_IMX31 - -config SPI_IMX_VER_0_7 - def_bool y if ARCH_MX25 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 - -config SPI_IMX_VER_2_3 - def_bool y if SOC_IMX51 || SOC_IMX53 - config SPI_IMX tristate "Freescale i.MX SPI controllers" depends on ARCH_MXC
drivers/spi/spi-imx.c +200 -223
656 lines not on this page · raw message
Signature · 1 line
1.7.4.1
Sascha Hauer
maintainerPATCH 2/6 spi/imx: use soc name in spi device type naming scheme
Quoted 9 lines · Shawn Guo
Software defined version number is not stable enough to be used in device type naming scheme. The patch changes it to use implicit soc name for spi device type definition. In this way, we can easily align the naming scheme with device tree binding, which comes later.
Signed-off-by Shawn Guo <[email protected]>Cc Uwe Kleine-K?nig <[email protected]>Cc Sascha Hauer <[email protected]>Cc Grant Likely <[email protected]>
Quoted 7 lines
--- arch/arm/mach-imx/clock-imx25.c | 7 +- arch/arm/mach-mx5/clock-mx51-mx53.c | 11 +- arch/arm/plat-mxc/devices/platform-spi_imx.c | 12 +- drivers/spi/Kconfig | 15 - drivers/spi/spi-imx.c | 423 ++++++++++++-------------- 5 files changed, 219 insertions(+), 249 deletions(-)
Generally this patch is too big for me to get the warm feeling that everything will just work. Renaming from spi_ver_xy to imx_xy is fine, but should be done in smaller steps and where possible not across subsystems.
I increasingly see patches touching arch/ and drivers/ and I think there's a high risk of merge conflicts upstream. This will not help making Linus happy.
Please try harder to make patches orthogonal and don't try to do too much at once.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH 2/6 spi/imx: use soc name in spi device type naming scheme
Quoted 18 lines · Sascha Hauer
Quoted 9 lines · Shawn Guo
Software defined version number is not stable enough to be used in device type naming scheme. The patch changes it to use implicit soc name for spi device type definition. In this way, we can easily align the naming scheme with device tree binding, which comes later.
Signed-off-by Shawn Guo <[email protected]>Cc Uwe Kleine-K?nig <[email protected]>Cc Sascha Hauer <[email protected]>Cc Grant Likely <[email protected]>Quoted 7 lines
--- arch/arm/mach-imx/clock-imx25.c | 7 +- arch/arm/mach-mx5/clock-mx51-mx53.c | 11 +- arch/arm/plat-mxc/devices/platform-spi_imx.c | 12 +- drivers/spi/Kconfig | 15 - drivers/spi/spi-imx.c | 423 ++++++++++++-------------- 5 files changed, 219 insertions(+), 249 deletions(-)
Quoted 5 lines
Generally this patch is too big for me to get the warm feeling that everything will just work. Renaming from
spi_ver_xytoimx_xyis fine, but should be done in smaller steps and where possible not across subsystems.
Okay, I will split the patch into small pieces to win your warm feeling :)
Quoted 4 lines
I increasingly see patches touching
arch/anddrivers/and I think there's a high risk of merge conflicts upstream. This will not help making Linus happy.
Yes, I increasingly run into the situation touching arch/ and drivers/ when working on dt migration because of the device renaming. May I have to your suggestion on how to separate drivers/ patch from arch/ one in orthogonal way, while keeping both trees working/bisectable?
Signature · 2 lines
Regards, Shawn
Sascha Hauer
maintainerPATCH 2/6 spi/imx: use soc name in spi device type naming scheme
Quoted 27 lines · Shawn Guo
Quoted 18 lines · Sascha Hauer
Quoted 9 lines · Shawn Guo
Software defined version number is not stable enough to be used in device type naming scheme. The patch changes it to use implicit soc name for spi device type definition. In this way, we can easily align the naming scheme with device tree binding, which comes later.
Signed-off-by Shawn Guo <[email protected]>Cc Uwe Kleine-K?nig <[email protected]>Cc Sascha Hauer <[email protected]>Cc Grant Likely <[email protected]>Quoted 7 lines
--- arch/arm/mach-imx/clock-imx25.c | 7 +- arch/arm/mach-mx5/clock-mx51-mx53.c | 11 +- arch/arm/plat-mxc/devices/platform-spi_imx.c | 12 +- drivers/spi/Kconfig | 15 - drivers/spi/spi-imx.c | 423 ++++++++++++-------------- 5 files changed, 219 insertions(+), 249 deletions(-)Quoted 5 lines
Generally this patch is too big for me to get the warm feeling that everything will just work. Renaming from
spi_ver_xytoimx_xyis fine, but should be done in smaller steps and where possible not across subsystems.Okay, I will split the patch into small pieces to win your warm feeling :)
Quoted 8 lines
Quoted 4 lines
I increasingly see patches touching
arch/anddrivers/and I think there's a high risk of merge conflicts upstream. This will not help making Linus happy.Yes, I increasingly run into the situation touching
arch/anddrivers/when working on dt migration because of the device renaming. May I have to your suggestion on how to separatedrivers/patch fromarch/one in orthogonal way, while keeping both trees working/bisectable?
You could for example keep the platform bindings for the old names and just add new ones. Then, when all patches are in, remove the old bindings. Of course this slows down things. You could also do all necessary preparations and do the actual renaming of the devices during -rc time.
Sascha
Signature · 4 lines
Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
PATCH 3/6 spi/imx: copy gpio number passed by platform data into driver private data
In reply to Shawn GuoIt copies gpio number passed via platform data embedded pointer into driver private data, so that we do not need to refer to this embedded pointer passed by platform data after probe function exits.
--- drivers/spi/spi-imx.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)
drivers/spi/spi-imx.c +7 -5
@@ -84,7 +84,6 @@ struct spi_imx_data {int irq;struct clk *clk;unsigned long spi_clk; -int *chipselect;unsigned int count;void (*tx)(struct spi_imx_data *);
@@ -94,6 +93,7 @@ struct spi_imx_data {unsigned int txfifo;/* number of words pushed in tx FIFO */ struct spi_imx_devtype_data *devtype_data; +int chipselect[0 ]; };static inline int is_imx27_cspi (struct spi_imx_data *d)
@@ -743,7 +743,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)struct spi_master *master;struct spi_imx_data *spi_imx;struct resource *res; -int i, ret; +int i, ret, num_cs; mxc_platform_info =dev_get_platdata (&pdev->dev);if (!mxc_platform_info) {
@@ -751,20 +751,22 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)return -EINVAL ; } - master =spi_alloc_master (&pdev->dev,sizeof (struct spi_imx_data )); + num_cs = mxc_platform_info->num_chipselect; + master =spi_alloc_master (&pdev->dev, +sizeof (struct spi_imx_data ) +sizeof (int ) * num_cs);if (!master)return -ENOMEM ;platform_set_drvdata (pdev, master); master->bus_num = pdev->id; - master->num_chipselect = mxc_platform_info->num_chipselect; + master->num_chipselect = num_cs; spi_imx =spi_master_get_devdata (master); spi_imx->bitbang.master =spi_master_get (master); - spi_imx->chipselect = mxc_platform_info->chipselect;for (i =0 ; i < master->num_chipselect; i++) { + spi_imx->chipselect[i] = mxc_platform_info->chipselect[i];if (spi_imx->chipselect[i] <0 )continue ; ret =gpio_request (spi_imx->chipselect[i],DRIVER_NAME );
Signature · 1 line
1.7.4.1
PATCH 4/6 dt: add helper function to read u32 arrays
In reply to Shawn GuoFrom: Rob Herring <[email protected]>
Rework of_property_read_u32 to read an array of values. Then of_property_read_u32 becomes an inline with array size of 1.
Also make struct device_node ptr const.
--- drivers/of/base.c | 19 +++++++++++++------ include/linux/of.h | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-)
drivers/of/base.c +13 -6
@@ -620,32 +620,39 @@ struct device_node *of_find_node_by_phandle(phandle handle)EXPORT_SYMBOL (of_find_node_by_phandle);/** -* of_property_read_u32 - Find and read a 32 bit integer from a property +* of_property_read_u32_array - Find and read an array of 32 bit integers +* from a property. +* * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_value: pointer to return value, modified only if return value is 0. * -* Search for a property in a device node and read a 32-bit value from +* Search for a property in a device node and read 32-bit value(s) from * it. Returns 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * * The out_value is modified only if a valid u32 value can be decoded. */ -int of_property_read_u32 (struct device_node *np,char *propname,u32 *out_value) +int of_property_read_u32_array (const struct device_node *np,char *propname, +u32 *out_values,size_t sz) {struct property *prop =of_find_property (np, propname,NULL ); +const __be32 *val;if (!prop)return -EINVAL ;if (!prop->value)return -ENODATA ; -if (sizeof (*out_value) > prop->length) +if ((sz *sizeof (*out_values)) > prop->length)return -EOVERFLOW ; - *out_value =be32_to_cpup (prop->value); + + val = prop->value; +while (sz--) + *out_values++ =be32_to_cpup (val++);return 0 ; } -EXPORT_SYMBOL_GPL (of_property_read_u32); +EXPORT_SYMBOL_GPL (of_property_read_u32_array);/** * of_property_read_string - Find and read a string from a property
include/linux/of.h +12 -2
@@ -196,8 +196,18 @@ extern struct device_node *of_find_node_with_property(extern struct property *of_find_property (const struct device_node *np,const char *name,int *lenp); -extern int of_property_read_u32 (struct device_node *np,char *propname, -u32 *out_value); +extern int of_property_read_u32_array (const struct device_node *np, +char *propname, +u32 *out_values, +size_t sz); + +static inline int of_property_read_u32 (const struct device_node *np, +char *propname, +u32 *out_value) +{ +return of_property_read_u32_array (np, propname, out_value,1 ); +} +extern int of_property_read_string (struct device_node *np,char *propname,const char **out_string); extern int of_device_is_compatible(const struct device_node *device,
Signature · 1 line
1.7.4.1
PATCH 5/6 dt: add empty of_property_read_u32[_array] for non-dt
In reply to Shawn GuoThe patch adds empty functions of_property_read_u32 and of_property_read_u32_array for non-dt build, so that drivers migrating to dt can save some '#ifdef CONFIG_OF'.
--- include/linux/of.h | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
include/linux/of.h +15 -0
@@ -255,5 +255,20 @@ static inline bool of_have_populated_dt(void)return false; } +static inline int of_property_read_u32_array (const struct device_node *np, +char *propname, +u32 *out_values, +size_t sz) +{ +return -ENOSYS ; +} + +static inline int of_property_read_u32 (const struct device_node *np, +char *propname, +u32 *out_value) +{ +return -ENOSYS ; +} +#endif /* CONFIG_OF */ #endif /* _LINUX_OF_H */
Signature · 1 line
1.7.4.1
PATCH 5/6 dt: add empty of_property_read_u32[_array] for non-dt
Shawn,
Quoted 27 lines · Shawn Guo
The patch adds empty functions
of_property_read_u32andof_property_read_u32_arrayfor non-dt build, so that drivers migrating to dt can save some '#ifdefCONFIG_OF'.Signed-off-by Shawn Guo <[email protected]>Cc Rob Herring <[email protected]>Cc Thomas Abraham <[email protected]>Cc Grant Likely <[email protected]>--- include/linux/of.h | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)include/linux/of.h +7
-0@@ -255,5 +255,20 @@ static inline bool of_have_populated_dt(void)return false; } +static inline int of_property_read_u32_array (const struct device_node *np, +char *propname, +u32 *out_values, +size_t sz) +{ +return -ENOSYS ; +}
include/linux/of.h static inline bool of_have_populated_dt(void) · line 274
Quoted 10 lines
include/linux/of.h +8
-0+ +static inline int of_property_read_u32 (const struct device_node *np, +char *propname, +u32 *out_value) +{ +return -ENOSYS ; +} +#endif /* CONFIG_OF */ #endif /* _LINUX_OF_H */
You should include the string read function as well for completeness.
Rob
Grant Likely
AppliedPATCH 5/6 dt: add empty of_property_read_u32[_array] for non-dt
In reply to Shawn GuoQuoted 8 lines · Shawn Guo
The patch adds empty functions
of_property_read_u32andof_property_read_u32_arrayfor non-dt build, so that drivers migrating to dt can save some '#ifdefCONFIG_OF'.Signed-off-by Shawn Guo <[email protected]>Cc Rob Herring <[email protected]>Cc Thomas Abraham <[email protected]>Cc Grant Likely <[email protected]>
Applied, thanks, and added the string version.
Quoted 32 lines
--- include/linux/of.h | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)include/linux/of.h +15
-0@@ -255,5 +255,20 @@ static inline bool of_have_populated_dt(void)return false; } +static inline int of_property_read_u32_array (const struct device_node *np, +char *propname, +u32 *out_values, +size_t sz) +{ +return -ENOSYS ; +} + +static inline int of_property_read_u32 (const struct device_node *np, +char *propname, +u32 *out_value) +{ +return -ENOSYS ; +} +#endif /* CONFIG_OF */ #endif /* _LINUX_OF_H */ Signature · 1 line
1.7.4.1
PATCH 6/6 spi/imx: add device tree probe support
In reply to Shawn GuoIt adds device tree probe support for spi-imx driver.
--- .../devicetree/bindings/spi/fsl-imx-cspi.txt | 22 +++++++++++ drivers/spi/spi-imx.c | 38 ++++++++++++++++---- 2 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt
Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt new file +22 -0
@@ -0,0 +1,22 @@ +* Freescale (Enhanced) Configurable Serial Peripheral Interface + (CSPI/eCSPI) for i.MX + +Required properties: +- compatible : Should be "fsl,<soc>-cspi" or "fsl,<soc>-ecspi" +- reg : Offset and length of the register set for the device +- interrupts : Should contain CSPI/eCSPI interrupt +- fsl,spi-num-chipselects : Contains the number of the chipselect +- cs-gpios : Specifies the gpio pins to be used for chipselects. + +Example: + +ecspi at 70010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx51-ecspi"; + reg = <0x70010000 0x4000>; + interrupts = <36>; + fsl,spi-num-chipselects = <2>; + cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */ + <&gpio3 25 0>; /* GPIO4_25 */ +};
drivers/spi/spi-imx.c +31 -7
@@ -34,6 +34,9 @@#include <linux/spi/spi.h> #include <linux/spi/spi_bitbang.h> #include <linux/types.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> #include <mach/spi.h>
@@ -606,6 +609,16 @@ static struct platform_device_id spi_imx_devtype[] = { } }; +static const struct of_device_id spi_imx_dt_ids[] = { + { .compatible ="fsl,imx1-cspi" , .data = &imx1_cspi_devtype_data, }, + { .compatible ="fsl,imx21-cspi" , .data = &imx21_cspi_devtype_data, }, + { .compatible ="fsl,imx27-cspi" , .data = &imx27_cspi_devtype_data, }, + { .compatible ="fsl,imx31-cspi" , .data = &imx31_cspi_devtype_data, }, + { .compatible ="fsl,imx35-cspi" , .data = &imx35_cspi_devtype_data, }, + { .compatible ="fsl,imx51-ecspi" , .data = &imx51_ecspi_devtype_data, }, + {/* sentinel */ } +}; +static void spi_imx_chipselect (struct spi_device *spi,int is_active) {struct spi_imx_data *spi_imx =spi_master_get_devdata (spi->master);
@@ -739,19 +752,25 @@ static void spi_imx_cleanup(struct spi_device *spi)static int __devinit spi_imx_probe (struct platform_device *pdev) { -struct spi_imx_master *mxc_platform_info; +struct device_node *np = pdev->dev.of_node; +const struct of_device_id *of_id = +of_match_device (spi_imx_dt_ids, &pdev->dev); +struct spi_imx_master *mxc_platform_info = +dev_get_platdata (&pdev->dev);struct spi_master *master;struct spi_imx_data *spi_imx;struct resource *res;int i, ret, num_cs; - mxc_platform_info =dev_get_platdata (&pdev->dev); -if (!mxc_platform_info) { +if (!np && !mxc_platform_info) {dev_err (&pdev->dev,"can't get the platform data\n" );return -EINVAL ; } - num_cs = mxc_platform_info->num_chipselect; + ret =of_property_read_u32 (np,"fsl,spi-num-chipselects" , &num_cs); +if (ret <0 ) + num_cs = mxc_platform_info->num_chipselect; + master =spi_alloc_master (&pdev->dev,sizeof (struct spi_imx_data ) +sizeof (int ) * num_cs);if (!master)
@@ -766,9 +785,12 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.master =spi_master_get (master);for (i =0 ; i < master->num_chipselect; i++) { - spi_imx->chipselect[i] = mxc_platform_info->chipselect[i]; -if (spi_imx->chipselect[i] <0 ) +int cs_gpio =of_get_named_gpio (np,"cs-gpios" , i); +if (cs_gpio <0 ) + cs_gpio = mxc_platform_info->chipselect[i]; +if (cs_gpio <0 )continue ; + spi_imx->chipselect[i] = cs_gpio; ret =gpio_request (spi_imx->chipselect[i],DRIVER_NAME );if (ret) {while (i >0 ) {
@@ -790,7 +812,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)init_completion (&spi_imx->xfer_done); - spi_imx->devtype_data = + spi_imx->devtype_data = of_id ? of_id->data : (struct spi_imx_devtype_data *) pdev->id_entry->driver_data; res =platform_get_resource (pdev,IORESOURCE_MEM ,0 );
@@ -838,6 +860,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) spi_imx->devtype_data->intctrl (spi_imx,0 ); + master->dev.of_node = pdev->dev.of_node; ret =spi_bitbang_start (&spi_imx->bitbang);if (ret) {dev_err (&pdev->dev,"bitbang start failed with %d\n" , ret);
@@ -900,6 +923,7 @@ static struct platform_driver spi_imx_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, + .of_match_table = spi_imx_dt_ids, }, .id_table = spi_imx_devtype, .probe = spi_imx_probe,
Signature · 1 line
1.7.4.1
cover Add device tree support for imx spi driver
In reply to Shawn GuoQuoted 10 lines · Shawn Guo
The patch set makes some cleanups on imx spi driver to get it ready for adding device tree probe and then add the support.
Those two dt helper function related patches are carried here to resolve the dependency. They should be on the way to sit on Grant's devicetree/next branch.
Rob Herring (1):
dt: add helper function to read u32 arrays
Quoted 6 lines
Shawn Guo (5):
ARM: mxc: remove unnecessary header file inclusion fromgpio.hspi/imx: use soc name in spi device type naming scheme spi/imx: copy gpio number passed by platform data into driver private data
dt: add empty of_property_read_u32[_array] for non-dt spi/imx: add device tree probe support
Okay, I tried to apply this series, but the first patch that removes the includes caused a build failure, so I've dropped it. What tree are these patches based on top of?
g.
cover Add device tree support for imx spi driver
Quoted 18 lines · Grant Likely
Quoted 10 lines · Shawn Guo
The patch set makes some cleanups on imx spi driver to get it ready for adding device tree probe and then add the support.
Those two dt helper function related patches are carried here to resolve the dependency. They should be on the way to sit on Grant's devicetree/next branch.
Rob Herring (1):
dt: add helper function to read u32 arraysQuoted 6 lines
Shawn Guo (5):
ARM: mxc: remove unnecessary header file inclusion fromgpio.hspi/imx: use soc name in spi device type naming scheme spi/imx: copy gpio number passed by platform data into driver private data
dt: add empty of_property_read_u32[_array] for non-dt spi/imx: add device tree probe support
Quoted 4 lines
Okay, I tried to apply this series, but the first patch that removes the includes caused a build failure, so I've dropped it. What tree are these patches based on top of?
I based the series off linux-next. Since it will go through your spi/next tree, I will repost the series against it, with splitting patch #2 into small pieces to address Sascha's comment.
Signature · 2 lines
Regards, Shawn