Skip to contentSkip to conversation

fsl_soc: add support for fsl_spi

RFC PATCH In review Anton Vorontsov 4 participants 7 messages Jul 26, 2007 – Jul 27, 2007 PowerPC

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 fsl_soc: add support for fsl_spi

---
 arch/powerpc/sysdev/fsl_soc.c |   76 +++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/sysdev/fsl_soc.h |    3 ++
 2 files changed, 79 insertions(+), 0 deletions(-)
arch/powerpc/sysdev/fsl_soc.c +76 -0
index 3289fab..0599851 100644
@@ -1125,3 +1125,79 @@ err:
 arch_initcall(cpm_smc_uart_of_init);
 
 #endif /* CONFIG_8xx */
+
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);
+
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {
+		int ret = 0;
+		const char *devid, *sysclk, *mode, *max_cs;
+		struct resource res[2];
+		struct platform_device *pdev = NULL;
+		struct fsl_spi_platform_data pdata = {
+			.activate_cs = fsl_spi_activate_cs,
+			.deactivate_cs = fsl_spi_deactivate_cs,
+		};
+
+		memset(res, 0, sizeof(res));
+
+		devid = of_get_property(np, "device-id", NULL);
+		sysclk = of_get_property(np, "sysclk", NULL);
+		mode = of_get_property(np, "mode", NULL);
+		max_cs = of_get_property(np, "max-chipselect", NULL);
+		if (!devid || !sysclk || !mode || !max_cs)
+			goto err;
+
+		pdata.bus_num = *(u32 *)devid;
+		pdata.sysclk = *(u32 *)sysclk;
+		pdata.max_chipselect = *(u32 *)max_cs;
+		if (!strcmp(mode, "qe"))
+			pdata.qe_mode = 1;
+
+		ret = of_address_to_resource(np, 0, &res[0]);
+		if (ret)
+			goto err;
+
+		res[1].start = res[2].end = irq_of_parse_and_map(np, 0);
+		if (res[1].start == NO_IRQ)
+			goto err;
+
+		res[1].name = "mpc83xx_spi";
+		res[1].flags = IORESOURCE_IRQ;;
+
+		pdev = platform_device_alloc("mpc83xx_spi", i);
+		if (!pdev)
+			goto err;
+
+		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_register(pdev);
+		if (ret)
+			goto unreg;
+
+		continue;
+unreg:
+		platform_device_del(pdev);
+err:
+		continue;
+	}
+
+	return 0;
+}
+
+arch_initcall(fsl_spi_of_init);
arch/powerpc/sysdev/fsl_soc.h +3 -0
index 04e145b..c9de2a2 100644
@@ -8,5 +8,8 @@ extern phys_addr_t get_immrbase(void);
 extern u32 get_brgfreq(void);
 extern u32 get_baudrate(void);
 
+extern void (*fsl_spi_activate_cs)(u8 cs, u8 polarity);
+extern void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity);
+
 #endif
 #endif
Signature · 1 line
1.5.0.6
#1 lore raw

arch/powerpc/sysdev/fsl_soc.c err: · line 1132

Quoted 4 lines · Anton Vorontsov
arch/powerpc/sysdev/fsl_soc.c +4 -0
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);

What are these for? It looks like you're using them to set pins, but that should be done in the firmware (and if the firmware sucks, then do it in the platform code at bootup).

arch/powerpc/sysdev/fsl_soc.c err: · line 1141

Quoted 8 lines
arch/powerpc/sysdev/fsl_soc.c +8 -0
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {

s/fsl_spi/fsl,mpc8323-spi/, please.

Why not make the fsl spi driver an of_platform device?

-Scott

#2 lore raw
Quoted 10 lines · On Thu, 26 Jul 2007 11:45:08 -0500 Scott Wood <[email protected]> wrote:

arch/powerpc/sysdev/fsl_soc.c err: · line 1132

Quoted 4 lines · Anton Vorontsov
arch/powerpc/sysdev/fsl_soc.c +4 -0
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);

What are these for? It looks like you're using them to set pins, but that should be done in the firmware (and if the firmware sucks, then do it in the platform code at bootup).

That is not exactly the point.
I won't respond for Anton, but we already had such hooks justified in SPI case iirc.

Quoted 11 lines

arch/powerpc/sysdev/fsl_soc.c err: · line 1141

Quoted 8 lines
arch/powerpc/sysdev/fsl_soc.c +8 -0
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {

s/fsl_spi/fsl,mpc8323-spi/, please.

Quoted 2 lines

Why not make the fsl spi driver an of_platform device?

Because this particular thing is not ppc-only from what I recall.

Quoted 5 lines

-Scott
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Signature · 2 lines
Sincerely, 
Vitaly
#3 lore raw
Quoted 5 lines · Vitaly Bordug
Quoted 1 line · On Thu, 26 Jul 2007 11:45:08 -0500 Scott Wood <[email protected]> wrote:

Why not make the fsl spi driver an of_platform device?

Because this particular thing is not ppc-only from what I recall.

spi_mpc83xx.c isn't ppc-only?

Even if it weren't, the OF stuff has been moved out of arch, so a non-arch-specific driver can support both platform and of_platform devices directly.

-Scott

#4 lore raw
In reply to Vitaly Bordug
Quoted 13 lines · Vitaly Bordug
Quoted 10 lines · On Thu, 26 Jul 2007 11:45:08 -0500 Scott Wood <[email protected]> wrote:

arch/powerpc/sysdev/fsl_soc.c err: · line 1132

Quoted 4 lines · Anton Vorontsov
arch/powerpc/sysdev/fsl_soc.c +4 -0
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);

What are these for? It looks like you're using them to set pins, but that should be done in the firmware (and if the firmware sucks, then do it in the platform code at bootup).

Quoted 2 lines

That is not exactly the point.
I won't respond for Anton, but we already had such hooks justified in SPI case iirc.

No they are used for runtime chip select handling. The SPI controller is able to handle multiple devices, however the chipselect is not specified by SPI and thus it left to board code.

Quoted 11 lines
Quoted 11 lines

arch/powerpc/sysdev/fsl_soc.c err: · line 1141

Quoted 8 lines
arch/powerpc/sysdev/fsl_soc.c +8 -0
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {

s/fsl_spi/fsl,mpc8323-spi/, please.

Quoted 3 lines
Quoted 2 lines

Why not make the fsl spi driver an of_platform device?

Because this particular thing is not ppc-only from what I recall.

The device node name already existed before this patch.

- k

#5 lore raw
In reply to Scott Wood
Quoted 9 lines · Scott Wood

arch/powerpc/sysdev/fsl_soc.c err: · line 1132

Quoted 4 lines · Anton Vorontsov
arch/powerpc/sysdev/fsl_soc.c +4 -0
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);

What are these for? It looks like you're using them to set pins, but that should be done in the firmware (and if the firmware sucks, then do it in the platform code at bootup).

Nope, this is not to set [initial state of] pins. SPI layer needs this to trigger MMC's chipselect, it's wired as usual GPIO pin, which should be asserted (and then deasserted) by software at proper time.

Every board may have different implementation of activate_cs/deactivate_cs, in mpc8323_rdb case it's implemented using par_io_data_set().

(1)
Kumar Gala suggested to not use arch_initcall, but call fsl_spi_init() explicitly by board file. So these global *_cs functions will go away.

Quoted 10 lines

arch/powerpc/sysdev/fsl_soc.c err: · line 1141

Quoted 8 lines
arch/powerpc/sysdev/fsl_soc.c +8 -0
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {

s/fsl_spi/fsl,mpc8323-spi/, please.

Will do for mpc832x_rdb. Should I also prepare patch to change all instances of "fsl_spi" in the arch/powerpc/boot/dts/*?

Quoted 1 line

Why not make the fsl spi driver an of_platform device?

Well, I guess this is rhetoric question. Is fsl_soc.c's OF<->platform_devices bindings officially deprecated?

If they're, I'll surely volunteer to convert it to of_platform. But then (1) should be solved another way, yet don't know how.

Quoted 1 line

-Scott

Thanks!

Signature · 4 lines
Anton Vorontsov
email: [email protected]
backup email: [email protected]
irc://irc.freenode.net/bd2
#6 lore raw
In reply to Anton Vorontsov
Quoted 6 lines · Anton Vorontsov
---
 arch/powerpc/sysdev/fsl_soc.c |   76 ++++++++++++++++++++++++++++++ 
+++++++++++
 arch/powerpc/sysdev/fsl_soc.h |    3 ++
 2 files changed, 79 insertions(+), 0 deletions(-)

There should be 2nd patch with updates to documentation for the SPI device node.

Quoted 6 lines
arch/powerpc/sysdev/fsl_soc.c +0 -0
index 3289fab..0599851 100644

arch/powerpc/sysdev/fsl_soc.c err: · line 1133

Quoted 9 lines
arch/powerpc/sysdev/fsl_soc.c +6 -0
@@ -1125,3 +1125,79 @@ err:
 arch_initcall(cpm_smc_uart_of_init);
 
 #endif /* CONFIG_8xx */
+
+void (*fsl_spi_activate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_activate_cs);
+void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity) = NULL;
+EXPORT_SYMBOL(fsl_spi_deactivate_cs);
+

I don't think we should do it this way. We shouldn't arch_initcall() scan for fsl_spi, but have the board code call a function and pass some things into it.

Quoted 89 lines
arch/powerpc/sysdev/fsl_soc.c +70 -0
+static int __init fsl_spi_of_init(void)
+{
+	struct device_node *np;
+	unsigned int i;
+
+	for (np = NULL, i = 1;
+	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+	     i++) {
+		int ret = 0;
+		const char *devid, *sysclk, *mode, *max_cs;
+		struct resource res[2];
+		struct platform_device *pdev = NULL;
+		struct fsl_spi_platform_data pdata = {
+			.activate_cs = fsl_spi_activate_cs,
+			.deactivate_cs = fsl_spi_deactivate_cs,
+		};
+
+		memset(res, 0, sizeof(res));
+
+		devid = of_get_property(np, "device-id", NULL);
+		sysclk = of_get_property(np, "sysclk", NULL);
+		mode = of_get_property(np, "mode", NULL);
+		max_cs = of_get_property(np, "max-chipselect", NULL);
+		if (!devid || !sysclk || !mode || !max_cs)
+			goto err;
+
+		pdata.bus_num = *(u32 *)devid;
+		pdata.sysclk = *(u32 *)sysclk;
+		pdata.max_chipselect = *(u32 *)max_cs;
+		if (!strcmp(mode, "qe"))
+			pdata.qe_mode = 1;
+
+		ret = of_address_to_resource(np, 0, &res[0]);
+		if (ret)
+			goto err;
+
+		res[1].start = res[2].end = irq_of_parse_and_map(np, 0);
+		if (res[1].start == NO_IRQ)
+			goto err;
+
+		res[1].name = "mpc83xx_spi";
+		res[1].flags = IORESOURCE_IRQ;;
+
+		pdev = platform_device_alloc("mpc83xx_spi", i);
+		if (!pdev)
+			goto err;
+
+		ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+		if (ret)
+			goto unreg;
+
+		ret = platform_device_register(pdev);
+		if (ret)
+			goto unreg;
+
+		continue;
+unreg:
+		platform_device_del(pdev);
+err:
+		continue;
+	}
+
+	return 0;
+}
+
+arch_initcall(fsl_spi_of_init);
arch/powerpc/sysdev/fsl_soc.h +3 -0
index 04e145b..c9de2a2 100644
@@ -8,5 +8,8 @@ extern phys_addr_t get_immrbase(void);
 extern u32 get_brgfreq(void);
 extern u32 get_baudrate(void);
 
+extern void (*fsl_spi_activate_cs)(u8 cs, u8 polarity);
+extern void (*fsl_spi_deactivate_cs)(u8 cs, u8 polarity);
+
 #endif
 #endif
Signature · 5 lines
1.5.0.6
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev