From: Masahiro A. <m-...@aa...> - 2003-04-18 05:13:34
|
We at A&D develops SH4-based system, and it received modification/addition of feature. There are now 3 revision. We needed to distinguish each configuration from software standpoint, both in driver and in user-mode apps. So, we've modified machvec a little and also added entry to /proc for being able to see the machine information. Mr. Hiroki HATTORI of Computron have developed those code for us. He'd been inspired by the idea in linux-arm/xscale tree. This code includes example code for our system, ADX. Any suggestions/opinions welcomed. ----- diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/config.in linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/config.in --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/config.in Thu Mar 27 14:32:48 2003 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/config.in Tue Apr 1 18:15:19 2003 @@ -181,6 +181,8 @@ int 'HD64465 IRQ' CONFIG_HD64465_IRQ 5 fi +tristate "Device info (/proc/deviceinfo) support" CONFIG_DEVICEINFO + bool 'Wakeup UBC on startup' CONFIG_UBC_WAKEUP bool 'DMA controller (DMAC) support' CONFIG_SH_DMA diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/Makefile linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/Makefile --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/Makefile Thu Mar 27 14:31:32 2003 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/Makefile Tue Apr 1 18:15:19 2003 @@ -12,7 +12,7 @@ O_TARGET := kernel.o -export-objs := io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o +export-objs := io.o io_generic.o io_hd64461.o setup_hd64461.o sh_ksyms.o io_adx.o obj-y := process.o signal.o entry.o traps.o irq.o irq_ipr.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ @@ -24,6 +24,7 @@ obj-$(CONFIG_SH_DMA) += dma.o obj-$(CONFIG_SH_STANDARD_BIOS) += sh_bios.o obj-$(CONFIG_SH_KGDB) += kgdb_stub.o kgdb_jmp.o +obj-$(CONFIG_DEVICEINFO) += deviceinfo.o ifeq ($(CONFIG_PCI),y) ifeq ($(CONFIG_SH_DREAMCAST),y) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/deviceinfo.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/deviceinfo.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/deviceinfo.c Thu Jan 1 09:00:00 1970 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/deviceinfo.c Wed Apr 2 19:39:19 2003 @@ -0,0 +1,70 @@ +/* + * linux/arch/sh/kernel/deviceinfo.c + * + * by Hiroki Hattori <ha...@co...> + * Masahiro Abe <m-...@aa...> + * Copyright (C) 2003 A&D Co., Ltd. <http://www.aandd.co.jp> + * + * /proc filesystem for device specific data. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include <linux/config.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/proc_fs.h> +#include <asm/machvec.h> +#include <asm/io.h> +#include <asm/uaccess.h> + +static struct proc_dir_entry* root_entry = NULL; + +static int +read_ushort(char* page, char** start, off_t off, + int count, int* eof, void* data) +{ + return sprintf(page, "%d\n", *(unsigned short*)data); +} + +static int +read_string(char* page, char** start, off_t off, + int count, int* eof, void* data) +{ + return sprintf(page, "%s\n", (char *)data); +} + +static int __init +init_deviceinfo(void) +{ + printk("Registering /proc/deviceinfo filesystem ...\n"); + + root_entry = proc_mkdir("deviceinfo", NULL); + + create_proc_read_entry("name", 0, root_entry, read_string, &sh_mv.mv_name); + create_proc_read_entry("type", 0, root_entry, read_ushort, &sh_mv.mv_mach_type); + create_proc_read_entry("subtype", 0, root_entry, read_ushort, &sh_mv.mv_mach_subtype); +#if defined(CONFIG_SH_ADX) + create_proc_read_entry("display-type", 0, root_entry, read_ushort, &sh_mv.mv_mach_LCD); + create_proc_read_entry("display-name", 0, root_entry, read_string, &sh_mv.mv_mach_LCD_name); +#endif + return 0; +} + +static void __exit +exit_deviceinfo(void) +{ + printk("Unregistering /proc/deviceinfo filesystem ...\n"); + + remove_proc_entry("deviceinfo", NULL); +} + +module_init (init_deviceinfo); +module_exit (exit_deviceinfo); + +MODULE_AUTHOR ("A&D Co., Ltd"); +MODULE_DESCRIPTION ("/proc filesystem for device specific data."); diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_7751se.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_7751se.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_7751se.c Thu Oct 11 13:47:27 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_7751se.c Tue Apr 1 18:15:19 2003 @@ -74,5 +74,10 @@ mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_7751se: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_SE, + mv_mach_subtype: MACH_SUBTYPE_7751SE, +#endif }; ALIAS_MV(7751se) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_adx.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_adx.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_adx.c Thu Oct 11 13:47:27 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_adx.c Wed Apr 2 19:37:14 2003 @@ -69,5 +69,10 @@ mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_adx: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_ADX, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(adx) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_bigsur.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_bigsur.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_bigsur.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_bigsur.c Tue Apr 1 18:15:19 2003 @@ -73,5 +73,9 @@ mv_rtc_gettimeofday: sh_rtc_gettimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday, +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_BIGSUR, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(bigsur) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_cat68701.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_cat68701.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_cat68701.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_cat68701.c Tue Apr 1 18:15:19 2003 @@ -68,5 +68,9 @@ mv_rtc_gettimeofday: sh_rtc_gettimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday, +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_CAT68701, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(cat68701) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_dc.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_dc.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_dc.c Thu Mar 27 14:31:32 2003 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_dc.c Tue Apr 1 18:15:19 2003 @@ -69,5 +69,10 @@ mv_rtc_settimeofday: aica_rtc_settimeofday, mv_hw_dreamcast: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_DREAMCAST, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(dreamcast) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_dmida.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_dmida.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_dmida.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_dmida.c Tue Apr 1 18:15:19 2003 @@ -68,6 +68,11 @@ mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_hd64465: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_DMIDA, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(dmida) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_ec3104.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_ec3104.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_ec3104.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_ec3104.c Tue Apr 1 18:15:19 2003 @@ -64,6 +64,11 @@ mv_rtc_gettimeofday: sh_rtc_gettimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_EC3104, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(ec3104) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_hp600.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_hp600.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_hp600.c Thu Oct 11 13:47:27 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_hp600.c Tue Apr 1 18:15:19 2003 @@ -64,6 +64,11 @@ mv_hw_hp600: 1, mv_hw_hp620: 1, mv_hw_hd64461: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_HP6xx, + mv_mach_subtype: MACH_SUBTYPE_HP620, +#endif }; ALIAS_MV(hp620) @@ -109,6 +114,11 @@ mv_hw_hp600: 1, mv_hw_hp680: 1, mv_hw_hd64461: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_HP6xx, + mv_mach_subtype: MACH_SUBTYPE_HP680, +#endif }; ALIAS_MV(hp680) @@ -154,5 +164,10 @@ mv_hw_hp600: 1, mv_hw_hp690: 1, mv_hw_hd64461: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_HP6xx, + mv_mach_subtype: MACH_SUBTYPE_HP690, +#endif }; ALIAS_MV(hp690) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_se.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_se.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_se.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_se.c Tue Apr 1 18:15:19 2003 @@ -80,5 +80,10 @@ mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_se: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_SE, + mv_mach_subtype: MACH_SUBTYPE_SE, +#endif }; ALIAS_MV(se) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_unknown.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_unknown.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/mach_unknown.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/mach_unknown.c Tue Apr 1 18:15:19 2003 @@ -68,5 +68,10 @@ mv_rtc_gettimeofday: sh_rtc_gettimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_UNKNOWN, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(unknown) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_adx.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_adx.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_adx.c Thu Oct 11 13:47:27 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_adx.c Wed Apr 2 19:43:37 2003 @@ -1,7 +1,7 @@ /* * linux/arch/sh/kernel/setup_adx.c * - * Copyright (C) 2001 A&D Co., Ltd. + * Copyright (C) 2001-2003 A&D Co., Ltd. * * I/O routine and setup routines for A&D ADX Board * @@ -15,11 +15,63 @@ #include <asm/machvec.h> #include <asm/irq.h> #include <linux/module.h> +#include <linux/string.h> + +#define ADX_IRQMASK_REG 0xa6000008 + +#define ADX_STATUS_REG 0xa6000006 +#define ADX_STATUS_ID_MASK 0x0007 +#define ADX_STATUS_COM_MASK 0x0010 +#define ADX_STATUS_ETH_MASK 0x0020 +#define ADX_STATUS_FRR 0x0040 +#define ADX_STATUS_CFR 0x0080 + +#define ADX_MACH_ID_MAGIC_PHASE1 0x06 +#define ADX_MACH_ID_MAGIC_PHASE2 0x05 +#define ADX_MACH_ID_MAGIC_PHASE3_OR_LATER 0x00 + +#define MACH_ADX_LCD_UNKNOWN 0 +#define MACH_ADX_LCD_PHASE1 1 +#define MACH_ADX_LCD_PHASE2 2 +#define MACH_ADX_LCD_PHASE3 3 + +static const char* adx_lcd_names[] = { + "UNKNOWN", + "Phase-1 : Epson s1d13706 & OPTREX 320x240x8 Mono STN", + "Phase-2 : Epson s1d13806 & NEC 320x240x8 Color TFT", + "Phase-3 : Epson s1d13706 & Kyocera 320x240x8 Color STN", +}; void setup_adx(void) { - /* nothing to do just yet */ -/* printk("setup_adx()\n");*/ +#if defined(CONFIG_DEVICEINFO) + /* + * Setup machine vector + */ + /* Machine type and subtype */ + switch (readw(ADX_STATUS_REG) & ADX_STATUS_ID_MASK) { + case ADX_MACH_ID_MAGIC_PHASE1: + sh_mv.mv_mach_subtype = MACH_SUBTYPE_ADX_PHASE1; + sh_mv.mv_mach_LCD = MACH_ADX_LCD_PHASE1; + break; + case ADX_MACH_ID_MAGIC_PHASE2: + sh_mv.mv_mach_subtype = MACH_SUBTYPE_ADX_PHASE2; + sh_mv.mv_mach_LCD = MACH_ADX_LCD_PHASE2; + break; + case ADX_MACH_ID_MAGIC_PHASE3_OR_LATER: + sh_mv.mv_mach_subtype = MACH_SUBTYPE_ADX_PHASE3; + sh_mv.mv_mach_LCD = MACH_ADX_LCD_PHASE3; + break; + default: + sh_mv.mv_mach_subtype = MACH_SUBTYPE_UNKNOWN; + sh_mv.mv_mach_LCD = MACH_ADX_LCD_UNKNOWN; + break; + } + strcpy(sh_mv.mv_mach_LCD_name, adx_lcd_names[sh_mv.mv_mach_LCD]); + + printk("ADX Machine Type Detected...mach_subtype=%d, mach_LCD=%d\n", + sh_mv.mv_mach_subtype, sh_mv.mv_mach_LCD); +#endif } void init_adx_IRQ(void) @@ -28,7 +80,7 @@ /* printk("init_adx_IRQ()\n");*/ /* setup irq_mask_register */ - irq_mask_register = (unsigned short *)0xa6000008; + irq_mask_register = (unsigned short *)ADX_IRQMASK_REG; /* cover all external interrupt area by maskreg_irq_type * (Actually, irq15 doesn't exist) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_cqreek.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_cqreek.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_cqreek.c Thu Mar 27 14:32:48 2003 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_cqreek.c Tue Apr 1 18:15:19 2003 @@ -248,5 +248,10 @@ mv_rtc_gettimeofday: sh_rtc_gettimeofday, mv_rtc_settimeofday: sh_rtc_settimeofday, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_CQREEK, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(cqreek) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_sh2000.c linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_sh2000.c --- linux-sh-2.4.18cvs-se-mc-sm-rtl/arch/sh/kernel/setup_sh2000.c Sat Jul 21 13:25:08 2001 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/arch/sh/kernel/setup_sh2000.c Tue Apr 1 18:15:19 2003 @@ -91,5 +91,10 @@ mv_rtc_settimeofday: sh_rtc_settimeofday, mv_hw_sh2000: 1, + +#if defined(CONFIG_DEVICEINFO) + mv_mach_type: MACH_TYPE_SH2000, + mv_mach_subtype: MACH_SUBTYPE_UNKNOWN, +#endif }; ALIAS_MV(sh2000) diff -ruN -X /root/dontdiff linux-sh-2.4.18cvs-se-mc-sm-rtl/include/asm-sh/machvec.h linux-sh-2.4.18cvs-se-mc-sm-rtl-di/include/asm-sh/machvec.h --- linux-sh-2.4.18cvs-se-mc-sm-rtl/include/asm-sh/machvec.h Thu Apr 17 20:26:53 2003 +++ linux-sh-2.4.18cvs-se-mc-sm-rtl-di/include/asm-sh/machvec.h Wed Apr 2 19:36:49 2003 @@ -15,9 +15,11 @@ struct timeval; +#define MV_NAME_SIZE 32 + struct sh_machine_vector { - const char *mv_name; + const char mv_name[MV_NAME_SIZE]; int mv_nr_irqs; @@ -78,6 +80,16 @@ unsigned int mv_hw_bigsur : 1; unsigned int mv_hw_7751se: 1; unsigned int mv_hw_adx : 1; + +#if defined(CONFIG_DEVICEINFO) + unsigned short mv_mach_type; + unsigned short mv_mach_subtype; +#if defined(CONFIG_SH_ADX) +#define MV_LCD_NAME_SIZE 256 + unsigned short mv_mach_LCD; + const char mv_mach_LCD_name[MV_LCD_NAME_SIZE]; +#endif +#endif }; extern struct sh_machine_vector sh_mv; @@ -163,5 +175,35 @@ # define MACH_ADX 0 # endif #endif + +// mv_mach_type +#define MACH_TYPE_UNKNOWN 0 +#define MACH_TYPE_SE 1 +#define MACH_TYPE_HP6xx 2 +#define MACH_TYPE_SH2000 3 +#define MACH_TYPE_EC3104 4 +#define MACH_TYPE_DREAMCAST 5 +#define MACH_TYPE_BIGSUR 6 +#define MACH_TYPE_ADX 7 +#define MACH_TYPE_CAT68701 8 +#define MACH_TYPE_DMIDA 9 +#define MACH_TYPE_CQREEK 10 + +// mv_mach_subtype +#define MACH_SUBTYPE_UNKNOWN 0 + +// mv_mach_subtype - SE +#define MACH_SUBTYPE_SE 1 +#define MACH_SUBTYPE_7751SE 2 + +// mv_mach_subtype - HP6x0 +#define MACH_SUBTYPE_HP620 1 +#define MACH_SUBTYPE_HP680 2 +#define MACH_SUBTYPE_HP690 3 + +// mv_mach_subtype - ADX +#define MACH_SUBTYPE_ADX_PHASE1 1 +#define MACH_SUBTYPE_ADX_PHASE2 2 +#define MACH_SUBTYPE_ADX_PHASE3 3 #endif /* _ASM_SH_MACHVEC_H */ ----- ================================= Masahiro ABE, A&D Co., Ltd. Japan |