diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts index 6946ad9c8bea..118961f60cb3 100644 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts +++ b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts @@ -770,6 +770,14 @@ cs-gpios = <&gpio GPIOX_10 GPIO_ACTIVE_LOW>, <&gpio GPIOA_4 GPIO_ACTIVE_LOW>; + can0: can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + spi-max-frequency = <10000000>; + status = "disabled"; + gpio-irq = <&gpio GPIOX_3 GPIO_ACTIVE_LOW>; + }; + spidev@0 { status = "disabled"; diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index f3f05fea8e1f..6cbc69fb8476 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -77,6 +77,11 @@ #include #include +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) +#include +#include +#endif + /* SPI interface instruction set */ #define INSTRUCTION_WRITE 0x02 #define INSTRUCTION_READ 0x03 @@ -282,6 +287,29 @@ static inline int mcp251x_is_##_model(struct spi_device *spi) \ MCP251X_IS(2510); MCP251X_IS(2515); +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) +static unsigned int gpio_irq; +int odroidg12_irq_init(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct device_node *np; + int ret = 0; + + np = dev->of_node; + gpio_irq = of_get_named_gpio(np, "gpio-irq", 0); + if (!gpio_is_valid(gpio_irq)) + return -EINVAL; + + if (gpio_request(gpio_irq, "can_irq_gpio") != 0) { + gpio_free(gpio_irq); + return -EIO; + } + gpio_direction_input(gpio_irq); + spi->irq = gpio_to_irq(gpio_irq); + return ret; +} +#endif + static void mcp251x_clean(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); @@ -1039,7 +1067,11 @@ static int mcp251x_can_probe(struct spi_device *spi) if (pdata) freq = pdata->oscillator_frequency; else +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + freq = spi->max_speed_hz; +#else return PTR_ERR(clk); +#endif } else { freq = clk_get_rate(clk); } @@ -1151,6 +1183,9 @@ static int mcp251x_can_probe(struct spi_device *spi) goto error_probe; } +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + odroidg12_irq_init(spi); +#endif mcp251x_hw_sleep(spi); ret = register_candev(net); @@ -1190,6 +1225,10 @@ static int mcp251x_can_remove(struct spi_device *spi) free_candev(net); +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + if (gpio_is_valid(gpio_irq)) + gpio_free(gpio_irq); +#endif return 0; }