diff mbox

[v2,1/2] ARM: shmobile: r8a7778: add HPB-DMAC support

Message ID 201307230222.04763.sergei.shtylyov@cogentembedded.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sergei Shtylyov July 22, 2013, 10:22 p.m. UTC
From: Max Filippov <max.filippov@cogentembedded.com>

Add HPB-DMAC platform device on R8A7778 SoC along with its slave and channel
configurations.

Signed-off-by: Max Filippov <max.filippov@cogentembedded.com>
[Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed <mach/dma.h>
to <mach/r8a7778.h>, removed #include <mach/dma.h> from setup-r8a7778.c, removed
SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and
hpb_dmae_channels[].]
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
Changes in version 2:
- moved *enum* declaring HPB-DMAC slave IDs from the separate header file to
  <mach/r8a7778.h>, removed #include <mach/dma.h> from setup-r8a7778.c;
- removed SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[]
  and hpb_dmae_channels[].

 arch/arm/mach-shmobile/include/mach/r8a7778.h |    8 ++
 arch/arm/mach-shmobile/setup-r8a7778.c        |   80 ++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)

Comments

Simon Horman July 26, 2013, 12:10 a.m. UTC | #1
[ Cc Morimoto-san ]

On Tue, Jul 23, 2013 at 02:22:04AM +0400, Sergei Shtylyov wrote:
> From: Max Filippov <max.filippov@cogentembedded.com>
> 
> Add HPB-DMAC platform device on R8A7778 SoC along with its slave and channel
> configurations.
> 
> Signed-off-by: Max Filippov <max.filippov@cogentembedded.com>
> [Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed <mach/dma.h>
> to <mach/r8a7778.h>, removed #include <mach/dma.h> from setup-r8a7778.c, removed
> SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and
> hpb_dmae_channels[].]
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> 
> ---
> Changes in version 2:
> - moved *enum* declaring HPB-DMAC slave IDs from the separate header file to
>   <mach/r8a7778.h>, removed #include <mach/dma.h> from setup-r8a7778.c;
> - removed SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[]
>   and hpb_dmae_channels[].
> 
>  arch/arm/mach-shmobile/include/mach/r8a7778.h |    8 ++
>  arch/arm/mach-shmobile/setup-r8a7778.c        |   80 ++++++++++++++++++++++++++
>  2 files changed, 88 insertions(+)

Morimoto-san, Magnus,

could you please review this?

> 
> Index: renesas/arch/arm/mach-shmobile/include/mach/r8a7778.h
> ===================================================================
> --- renesas.orig/arch/arm/mach-shmobile/include/mach/r8a7778.h
> +++ renesas/arch/arm/mach-shmobile/include/mach/r8a7778.h
> @@ -1,6 +1,7 @@
>  /*
>   * Copyright (C) 2013  Renesas Solutions Corp.
>   * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> + * Copyright (C) 2013  Cogent Embedded, Inc.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
> @@ -23,6 +24,13 @@
>  #include <linux/sh_eth.h>
>  #include <linux/platform_data/usb-rcar-phy.h>
>  
> +/* HPB-DMA slave IDs */
> +enum {
> +	HPBDMA_SLAVE_DUMMY,
> +	HPBDMA_SLAVE_SDHI0_TX,
> +	HPBDMA_SLAVE_SDHI0_RX,
> +};
> +
>  extern void r8a7778_add_standard_devices(void);
>  extern void r8a7778_add_standard_devices_dt(void);
>  extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata);
> Index: renesas/arch/arm/mach-shmobile/setup-r8a7778.c
> ===================================================================
> --- renesas.orig/arch/arm/mach-shmobile/setup-r8a7778.c
> +++ renesas/arch/arm/mach-shmobile/setup-r8a7778.c
> @@ -24,6 +24,7 @@
>  #include <linux/irqchip/arm-gic.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> +#include <linux/platform_data/dma-rcar-hpbdma.h>
>  #include <linux/platform_data/gpio-rcar.h>
>  #include <linux/platform_data/irq-renesas-intc-irqpin.h>
>  #include <linux/platform_device.h>
> @@ -333,6 +334,84 @@ void __init r8a7778_add_mmc_device(struc
>  		info, sizeof(*info));
>  }
>  
> +/* HPB-DMA */
> +
> +/* Asynchronous mode register (ASYNCMDR) bits */
> +#define	ASYNCMDR_ASMD22_MASK	BIT(2)	/* SDHI0 */
> +#define	ASYNCMDR_ASMD22_SINGLE	BIT(2)	/* SDHI0 */
> +#define	ASYNCMDR_ASMD22_MULTI	0	/* SDHI0 */
> +#define	ASYNCMDR_ASMD21_MASK	BIT(1)	/* SDHI0 */
> +#define	ASYNCMDR_ASMD21_SINGLE	BIT(1)	/* SDHI0 */
> +#define	ASYNCMDR_ASMD21_MULTI	0	/* SDHI0 */
> +
> +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
> +	{
> +		.id	= HPBDMA_SLAVE_SDHI0_TX,
> +		.addr	= 0xffe4c000 + 0x30,
> +		.dcr	= DCR_SPDS_16BIT | DCR_DMDL | DCR_DPDS_16BIT,
> +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
> +			  ASYNCRSTR_ASRST23,
> +		.mdr	= ASYNCMDR_ASMD21_SINGLE,
> +		.mdm	= ASYNCMDR_ASMD21_MASK,
> +		.port	= 0x0D0C,
> +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
> +		.dma_ch	= 21,
> +	}, {
> +		.id	= HPBDMA_SLAVE_SDHI0_RX,
> +		.addr	= 0xffe4c000 + 0x30,
> +		.dcr	= DCR_SMDL | DCR_SPDS_16BIT | DCR_DPDS_16BIT,
> +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
> +			  ASYNCRSTR_ASRST23,
> +		.mdr	= ASYNCMDR_ASMD22_SINGLE,
> +		.mdm	= ASYNCMDR_ASMD22_MASK,
> +		.port	= 0x0D0C,
> +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
> +		.dma_ch	= 22,
> +	},
> +};
> +
> +static const struct hpb_dmae_channel hpb_dmae_channels[] = {
> +	/* ch. 21 SD0 */
> +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX),
> +	/* ch. 22 SD0 */
> +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX),
> +};
> +
> +static struct hpb_dmae_pdata dma_platform_data __initdata = {
> +	.slaves			= hpb_dmae_slaves,
> +	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves),
> +	.channels		= hpb_dmae_channels,
> +	.num_channels		= ARRAY_SIZE(hpb_dmae_channels),
> +	.ts_shift		= {
> +		[XMIT_SZ_8BIT]	= 0,
> +		[XMIT_SZ_16BIT]	= 1,
> +		[XMIT_SZ_32BIT]	= 2,
> +	},
> +	.num_hw_channels	= 39,
> +};
> +
> +static struct resource hpb_dmae_resources[] __initdata = {
> +	/* Channel registers */
> +	DEFINE_RES_MEM(0xffc08000, 0x1000),
> +	/* Common registers */
> +	DEFINE_RES_MEM(0xffc09000, 0x170),
> +	/* Asynchronous reset registers */
> +	DEFINE_RES_MEM(0xffc00300, 4),
> +	/* Asynchronous mode registers */
> +	DEFINE_RES_MEM(0xffc00400, 4),
> +	/* IRQ for DMA channels */
> +	DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ),
> +};
> +
> +static void __init r8a7778_register_hpb_dmae(void)
> +{
> +	platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
> +					  hpb_dmae_resources,
> +					  ARRAY_SIZE(hpb_dmae_resources),
> +					  &dma_platform_data,
> +					  sizeof(dma_platform_data));
> +}
> +
>  void __init r8a7778_add_standard_devices(void)
>  {
>  	int i;
> @@ -355,6 +434,7 @@ void __init r8a7778_add_standard_devices
>  
>  	r8a7778_register_tmu(0);
>  	r8a7778_register_tmu(1);
> +	r8a7778_register_hpb_dmae();
>  }
>  
>  void __init r8a7778_init_late(void)
>
Kuninori Morimoto July 26, 2013, 1:39 a.m. UTC | #2
Hi

> > +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
> > +	{
> > +		.id	= HPBDMA_SLAVE_SDHI0_TX,
> > +		.addr	= 0xffe4c000 + 0x30,
> > +		.dcr	= DCR_SPDS_16BIT | DCR_DMDL | DCR_DPDS_16BIT,
> > +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
> > +			  ASYNCRSTR_ASRST23,
> > +		.mdr	= ASYNCMDR_ASMD21_SINGLE,
> > +		.mdm	= ASYNCMDR_ASMD21_MASK,
> > +		.port	= 0x0D0C,
> > +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
> > +		.dma_ch	= 21,
> > +	}, {
> > +		.id	= HPBDMA_SLAVE_SDHI0_RX,
> > +		.addr	= 0xffe4c000 + 0x30,
> > +		.dcr	= DCR_SMDL | DCR_SPDS_16BIT | DCR_DPDS_16BIT,
> > +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
> > +			  ASYNCRSTR_ASRST23,
> > +		.mdr	= ASYNCMDR_ASMD22_SINGLE,
> > +		.mdm	= ASYNCMDR_ASMD22_MASK,
> > +		.port	= 0x0D0C,
> > +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
> > +		.dma_ch	= 22,
> > +	},

I'm not sure detail of SDHI, but TX and RX are using same .port = 0x0D0C.
Is this correct ?
And what is 0x0C port ?
My datasheet doens't have it on Ch21 - Ch23

> > +static const struct hpb_dmae_channel hpb_dmae_channels[] = {
> > +	/* ch. 21 SD0 */
> > +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX),
> > +	/* ch. 22 SD0 */
> > +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX),
> > +};
> > +
> > +static struct hpb_dmae_pdata dma_platform_data __initdata = {
> > +	.slaves			= hpb_dmae_slaves,
> > +	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves),
> > +	.channels		= hpb_dmae_channels,
> > +	.num_channels		= ARRAY_SIZE(hpb_dmae_channels),
> > +	.ts_shift		= {
> > +		[XMIT_SZ_8BIT]	= 0,
> > +		[XMIT_SZ_16BIT]	= 1,
> > +		[XMIT_SZ_32BIT]	= 2,
> > +	},
> > +	.num_hw_channels	= 39,
> > +};

This is not a big deal, but according to .num_hw_channels,
we will have max 39 channels (or more over).

I want 1 line for 1 channels on hpb_dmae_channels.
like this

static const struct hpb_dmae_channel hpb_dmae_channels[] = {
	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch21 */
	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch22 */
}


Best regards
---
Kuninori Morimoto
Sergei Shtylyov July 29, 2013, 10:46 p.m. UTC | #3
Hello.

On 07/26/2013 05:39 AM, Kuninori Morimoto wrote:

>>> +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
>>> +	{
>>> +		.id	= HPBDMA_SLAVE_SDHI0_TX,
>>> +		.addr	= 0xffe4c000 + 0x30,
>>> +		.dcr	= DCR_SPDS_16BIT | DCR_DMDL | DCR_DPDS_16BIT,
>>> +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
>>> +			  ASYNCRSTR_ASRST23,
>>> +		.mdr	= ASYNCMDR_ASMD21_SINGLE,
>>> +		.mdm	= ASYNCMDR_ASMD21_MASK,
>>> +		.port	= 0x0D0C,
>>> +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
>>> +		.dma_ch	= 21,
>>> +	}, {
>>> +		.id	= HPBDMA_SLAVE_SDHI0_RX,
>>> +		.addr	= 0xffe4c000 + 0x30,
>>> +		.dcr	= DCR_SMDL | DCR_SPDS_16BIT | DCR_DPDS_16BIT,
>>> +		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
>>> +			  ASYNCRSTR_ASRST23,
>>> +		.mdr	= ASYNCMDR_ASMD22_SINGLE,
>>> +		.mdm	= ASYNCMDR_ASMD22_MASK,
>>> +		.port	= 0x0D0C,
>>> +		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
>>> +		.dma_ch	= 22,
>>> +	},

> I'm not sure detail of SDHI, but TX and RX are using same .port = 0x0D0C.

    It's not one port, it's a pair of ports, source and destination.

> Is this correct ?
> And what is 0x0C port ?

    SDHI0 if you look into the table 16.7 of the R-Car M1A manual 1.00 for the 
channels 21 thru 23.

> My datasheet doens't have it on Ch21 - Ch23

    Maybe you're looking at the wrong table or an obsolete manual?

>>> +static const struct hpb_dmae_channel hpb_dmae_channels[] = {
>>> +	/* ch. 21 SD0 */
>>> +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX),
>>> +	/* ch. 22 SD0 */
>>> +	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX),
>>> +};
>>> +
>>> +static struct hpb_dmae_pdata dma_platform_data __initdata = {
>>> +	.slaves			= hpb_dmae_slaves,
>>> +	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves),
>>> +	.channels		= hpb_dmae_channels,
>>> +	.num_channels		= ARRAY_SIZE(hpb_dmae_channels),
>>> +	.ts_shift		= {
>>> +		[XMIT_SZ_8BIT]	= 0,
>>> +		[XMIT_SZ_16BIT]	= 1,
>>> +		[XMIT_SZ_32BIT]	= 2,
>>> +	},
>>> +	.num_hw_channels	= 39,
>>> +};

> This is not a big deal, but according to .num_hw_channels,
> we will have max 39 channels (or more over).

> I want 1 line for 1 channels on hpb_dmae_channels.
> like this

> static const struct hpb_dmae_channel hpb_dmae_channels[] = {
> 	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch21 */
> 	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch22 */
> }

    OK, done.

> Best regards
> ---
> Kuninori Morimoto

WBR, Sergei
Kuninori Morimoto July 30, 2013, 12:30 a.m. UTC | #4
Hi Sergei

> > Is this correct ?
> > And what is 0x0C port ?
> 
>     SDHI0 if you look into the table 16.7 of the R-Car M1A manual 1.00 for the 
> channels 21 thru 23.

Ahh... yes, indeed
sorry for my noise

> > I want 1 line for 1 channels on hpb_dmae_channels.
> > like this
> 
> > static const struct hpb_dmae_channel hpb_dmae_channels[] = {
> > 	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch21 */
> > 	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch22 */
> > }
> 
>     OK, done.

Thank you
diff mbox

Patch

Index: renesas/arch/arm/mach-shmobile/include/mach/r8a7778.h
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/include/mach/r8a7778.h
+++ renesas/arch/arm/mach-shmobile/include/mach/r8a7778.h
@@ -1,6 +1,7 @@ 
 /*
  * Copyright (C) 2013  Renesas Solutions Corp.
  * Copyright (C) 2013  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2013  Cogent Embedded, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,6 +24,13 @@ 
 #include <linux/sh_eth.h>
 #include <linux/platform_data/usb-rcar-phy.h>
 
+/* HPB-DMA slave IDs */
+enum {
+	HPBDMA_SLAVE_DUMMY,
+	HPBDMA_SLAVE_SDHI0_TX,
+	HPBDMA_SLAVE_SDHI0_RX,
+};
+
 extern void r8a7778_add_standard_devices(void);
 extern void r8a7778_add_standard_devices_dt(void);
 extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata);
Index: renesas/arch/arm/mach-shmobile/setup-r8a7778.c
===================================================================
--- renesas.orig/arch/arm/mach-shmobile/setup-r8a7778.c
+++ renesas/arch/arm/mach-shmobile/setup-r8a7778.c
@@ -24,6 +24,7 @@ 
 #include <linux/irqchip/arm-gic.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
+#include <linux/platform_data/dma-rcar-hpbdma.h>
 #include <linux/platform_data/gpio-rcar.h>
 #include <linux/platform_data/irq-renesas-intc-irqpin.h>
 #include <linux/platform_device.h>
@@ -333,6 +334,84 @@  void __init r8a7778_add_mmc_device(struc
 		info, sizeof(*info));
 }
 
+/* HPB-DMA */
+
+/* Asynchronous mode register (ASYNCMDR) bits */
+#define	ASYNCMDR_ASMD22_MASK	BIT(2)	/* SDHI0 */
+#define	ASYNCMDR_ASMD22_SINGLE	BIT(2)	/* SDHI0 */
+#define	ASYNCMDR_ASMD22_MULTI	0	/* SDHI0 */
+#define	ASYNCMDR_ASMD21_MASK	BIT(1)	/* SDHI0 */
+#define	ASYNCMDR_ASMD21_SINGLE	BIT(1)	/* SDHI0 */
+#define	ASYNCMDR_ASMD21_MULTI	0	/* SDHI0 */
+
+static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = {
+	{
+		.id	= HPBDMA_SLAVE_SDHI0_TX,
+		.addr	= 0xffe4c000 + 0x30,
+		.dcr	= DCR_SPDS_16BIT | DCR_DMDL | DCR_DPDS_16BIT,
+		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
+			  ASYNCRSTR_ASRST23,
+		.mdr	= ASYNCMDR_ASMD21_SINGLE,
+		.mdm	= ASYNCMDR_ASMD21_MASK,
+		.port	= 0x0D0C,
+		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+		.dma_ch	= 21,
+	}, {
+		.id	= HPBDMA_SLAVE_SDHI0_RX,
+		.addr	= 0xffe4c000 + 0x30,
+		.dcr	= DCR_SMDL | DCR_SPDS_16BIT | DCR_DPDS_16BIT,
+		.rstr	= ASYNCRSTR_ASRST21 | ASYNCRSTR_ASRST22 |
+			  ASYNCRSTR_ASRST23,
+		.mdr	= ASYNCMDR_ASMD22_SINGLE,
+		.mdm	= ASYNCMDR_ASMD22_MASK,
+		.port	= 0x0D0C,
+		.flags	= HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE,
+		.dma_ch	= 22,
+	},
+};
+
+static const struct hpb_dmae_channel hpb_dmae_channels[] = {
+	/* ch. 21 SD0 */
+	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX),
+	/* ch. 22 SD0 */
+	HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX),
+};
+
+static struct hpb_dmae_pdata dma_platform_data __initdata = {
+	.slaves			= hpb_dmae_slaves,
+	.num_slaves		= ARRAY_SIZE(hpb_dmae_slaves),
+	.channels		= hpb_dmae_channels,
+	.num_channels		= ARRAY_SIZE(hpb_dmae_channels),
+	.ts_shift		= {
+		[XMIT_SZ_8BIT]	= 0,
+		[XMIT_SZ_16BIT]	= 1,
+		[XMIT_SZ_32BIT]	= 2,
+	},
+	.num_hw_channels	= 39,
+};
+
+static struct resource hpb_dmae_resources[] __initdata = {
+	/* Channel registers */
+	DEFINE_RES_MEM(0xffc08000, 0x1000),
+	/* Common registers */
+	DEFINE_RES_MEM(0xffc09000, 0x170),
+	/* Asynchronous reset registers */
+	DEFINE_RES_MEM(0xffc00300, 4),
+	/* Asynchronous mode registers */
+	DEFINE_RES_MEM(0xffc00400, 4),
+	/* IRQ for DMA channels */
+	DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ),
+};
+
+static void __init r8a7778_register_hpb_dmae(void)
+{
+	platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1,
+					  hpb_dmae_resources,
+					  ARRAY_SIZE(hpb_dmae_resources),
+					  &dma_platform_data,
+					  sizeof(dma_platform_data));
+}
+
 void __init r8a7778_add_standard_devices(void)
 {
 	int i;
@@ -355,6 +434,7 @@  void __init r8a7778_add_standard_devices
 
 	r8a7778_register_tmu(0);
 	r8a7778_register_tmu(1);
+	r8a7778_register_hpb_dmae();
 }
 
 void __init r8a7778_init_late(void)