Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26f6cb99 authored by Anton Vorontsov's avatar Anton Vorontsov Committed by Kumar Gala
Browse files

[POWERPC] fsl_soc: add support for fsl_spi



Add helper function to setup SPI bus/device information

Signed-off-by: default avatarAnton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent af6a9aab
Loading
Loading
Loading
Loading
+87 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
@@ -1199,3 +1200,89 @@ static int __init cpm_smc_uart_of_init(void)
arch_initcall(cpm_smc_uart_of_init);

#endif /* CONFIG_8xx */

int __init fsl_spi_init(struct spi_board_info *board_infos,
			unsigned int num_board_infos,
			void (*activate_cs)(u8 cs, u8 polarity),
			void (*deactivate_cs)(u8 cs, u8 polarity))
{
	struct device_node *np;
	unsigned int i;
	const u32 *sysclk;

	np = of_find_node_by_type(NULL, "qe");
	if (!np)
		return -ENODEV;

	sysclk = of_get_property(np, "bus-frequency", NULL);
	if (!sysclk)
		return -ENODEV;

	for (np = NULL, i = 1;
	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
	     i++) {
		int ret = 0;
		unsigned int j;
		const void *prop;
		struct resource res[2];
		struct platform_device *pdev;
		struct fsl_spi_platform_data pdata = {
			.activate_cs = activate_cs,
			.deactivate_cs = deactivate_cs,
		};

		memset(res, 0, sizeof(res));

		pdata.sysclk = *sysclk;

		prop = of_get_property(np, "reg", NULL);
		if (!prop)
			goto err;
		pdata.bus_num = *(u32 *)prop;

		prop = of_get_property(np, "mode", NULL);
		if (prop && !strcmp(prop, "cpu-qe"))
			pdata.qe_mode = 1;

		for (j = 0; j < num_board_infos; j++) {
			if (board_infos[j].bus_num == pdata.bus_num)
				pdata.max_chipselect++;
		}

		if (!pdata.max_chipselect)
			goto err;

		ret = of_address_to_resource(np, 0, &res[0]);
		if (ret)
			goto err;

		ret = of_irq_to_resource(np, 0, &res[1]);
		if (ret == NO_IRQ)
			goto err;

		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 spi_register_board_info(board_infos, num_board_infos);
}
+7 −0
Original line number Diff line number Diff line
@@ -8,5 +8,12 @@ extern phys_addr_t get_immrbase(void);
extern u32 get_brgfreq(void);
extern u32 get_baudrate(void);

struct spi_board_info;

extern int fsl_spi_init(struct spi_board_info *board_infos,
			unsigned int num_board_infos,
			void (*activate_cs)(u8 cs, u8 polarity),
			void (*deactivate_cs)(u8 cs, u8 polarity));

#endif
#endif