aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-22 16:16:01 -0400
commit06b8147c5dbd385b5b97ca74e19f6f3951ebc1cb (patch)
tree6ed9de7ca0ab3a65af6a189a89deb0a36ab35f6b /include
parent53baaaa9682c230410a057263d1ce2922f43ddc4 (diff)
parent8725f25acc656c1522d48a6746055099efdaca4c (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (49 commits) powerpc: Fix build bug with binutils < 2.18 and GCC < 4.2 powerpc/eeh: Don't panic when EEH_MAX_FAILS is exceeded fbdev: Teaches offb about palette on radeon r5xx/r6xx powerpc/cell/edac: Log a syndrome code in case of correctable error powerpc/cell: Add DMA_ATTR_WEAK_ORDERING dma attribute and use in Cell IOMMU code powerpc: Indicate which oprofile counters to use while in compat mode powerpc/boot: Change spaces to tabs powerpc: Remove duplicate 6xx option in Kconfig powerpc: Use PPC_LONG and PPC_LONG_ALIGN in lib/string.S powerpc: Use PPC_LONG_ALIGN in uaccess.h powerpc: Add a #define for aligning to a long-sized boundary powerpc: Fix OF parsing of 64 bits PCI addresses powerpc: Use WARN_ON(1) instead of __WARN() powerpc: Fix support for latencytop powerpc/ps3: Update ps3_defconfig powerpc/ps3: Add a sub-match id to ps3_system_bus powerpc: Add a 6xx defconfig powerpc/dma: Use the struct dma_attrs in iommu code powerpc/cell: Add support for power button of future IBM cell blades powerpc/cell: Cleanup sysreset_hack for IBM cell blades ...
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/asm-compat.h2
-rw-r--r--include/asm-powerpc/machdep.h3
-rw-r--r--include/asm-powerpc/pgtable-ppc32.h15
-rw-r--r--include/asm-powerpc/pmi.h1
-rw-r--r--include/asm-powerpc/ps3.h7
-rw-r--r--include/asm-powerpc/reg.h4
-rw-r--r--include/asm-powerpc/uaccess.h21
-rw-r--r--include/asm-powerpc/ucc_fast.h8
-rw-r--r--include/linux/dma-attrs.h1
-rw-r--r--include/linux/fs_enet_pd.h4
-rw-r--r--include/linux/fsl_devices.h7
-rw-r--r--include/linux/of_gpio.h2
12 files changed, 42 insertions, 33 deletions
diff --git a/include/asm-powerpc/asm-compat.h b/include/asm-powerpc/asm-compat.h
index 8ec2e1da68bf..8f0fe7971949 100644
--- a/include/asm-powerpc/asm-compat.h
+++ b/include/asm-powerpc/asm-compat.h
@@ -22,6 +22,7 @@
22#define PPC_STL stringify_in_c(std) 22#define PPC_STL stringify_in_c(std)
23#define PPC_LCMPI stringify_in_c(cmpdi) 23#define PPC_LCMPI stringify_in_c(cmpdi)
24#define PPC_LONG stringify_in_c(.llong) 24#define PPC_LONG stringify_in_c(.llong)
25#define PPC_LONG_ALIGN stringify_in_c(.balign 8)
25#define PPC_TLNEI stringify_in_c(tdnei) 26#define PPC_TLNEI stringify_in_c(tdnei)
26#define PPC_LLARX stringify_in_c(ldarx) 27#define PPC_LLARX stringify_in_c(ldarx)
27#define PPC_STLCX stringify_in_c(stdcx.) 28#define PPC_STLCX stringify_in_c(stdcx.)
@@ -43,6 +44,7 @@
43#define PPC_STL stringify_in_c(stw) 44#define PPC_STL stringify_in_c(stw)
44#define PPC_LCMPI stringify_in_c(cmpwi) 45#define PPC_LCMPI stringify_in_c(cmpwi)
45#define PPC_LONG stringify_in_c(.long) 46#define PPC_LONG stringify_in_c(.long)
47#define PPC_LONG_ALIGN stringify_in_c(.balign 4)
46#define PPC_TLNEI stringify_in_c(twnei) 48#define PPC_TLNEI stringify_in_c(twnei)
47#define PPC_LLARX stringify_in_c(lwarx) 49#define PPC_LLARX stringify_in_c(lwarx)
48#define PPC_STLCX stringify_in_c(stwcx.) 50#define PPC_STLCX stringify_in_c(stwcx.)
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 989922621e35..1233d735fd28 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -80,7 +80,8 @@ struct machdep_calls {
80 long index, 80 long index,
81 long npages, 81 long npages,
82 unsigned long uaddr, 82 unsigned long uaddr,
83 enum dma_data_direction direction); 83 enum dma_data_direction direction,
84 struct dma_attrs *attrs);
84 void (*tce_free)(struct iommu_table *tbl, 85 void (*tce_free)(struct iommu_table *tbl,
85 long index, 86 long index,
86 long npages); 87 long npages);
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
index 73015f0139de..3a96d001cb75 100644
--- a/include/asm-powerpc/pgtable-ppc32.h
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -295,10 +295,10 @@ extern int icache_44x_need_flush;
295#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */ 295#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
296#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */ 296#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
297#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */ 297#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
298#define _PAGE_ACCESSED 0x00004 /* S: Page referenced */ 298#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
299#define _PAGE_HWWRITE 0x00008 /* H: Dirty & RW, set in exception */ 299#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
300#define _PAGE_RW 0x00010 /* S: Write permission */ 300#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
301#define _PAGE_HWEXEC 0x00020 /* H: UX permission */ 301#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
302 302
303#define _PAGE_ENDIAN 0x00040 /* H: E bit */ 303#define _PAGE_ENDIAN 0x00040 /* H: E bit */
304#define _PAGE_GUARDED 0x00080 /* H: G bit */ 304#define _PAGE_GUARDED 0x00080 /* H: G bit */
@@ -307,21 +307,14 @@ extern int icache_44x_need_flush;
307#define _PAGE_WRITETHRU 0x00400 /* H: W bit */ 307#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
308 308
309#ifdef CONFIG_PTE_64BIT 309#ifdef CONFIG_PTE_64BIT
310#define _PAGE_DIRTY 0x08000 /* S: Page dirty */
311
312/* ERPN in a PTE never gets cleared, ignore it */ 310/* ERPN in a PTE never gets cleared, ignore it */
313#define _PTE_NONE_MASK 0xffffffffffff0000ULL 311#define _PTE_NONE_MASK 0xffffffffffff0000ULL
314#else
315#define _PAGE_DIRTY 0x00800 /* S: Page dirty */
316#endif 312#endif
317 313
318#define _PMD_PRESENT 0 314#define _PMD_PRESENT 0
319#define _PMD_PRESENT_MASK (PAGE_MASK) 315#define _PMD_PRESENT_MASK (PAGE_MASK)
320#define _PMD_BAD (~PAGE_MASK) 316#define _PMD_BAD (~PAGE_MASK)
321 317
322/* Until my rework is finished, FSL BookE still needs atomic PTE updates */
323#define PTE_ATOMIC_UPDATES 1
324
325#elif defined(CONFIG_8xx) 318#elif defined(CONFIG_8xx)
326/* Definitions for 8xx embedded chips. */ 319/* Definitions for 8xx embedded chips. */
327#define _PAGE_PRESENT 0x0001 /* Page is valid */ 320#define _PAGE_PRESENT 0x0001 /* Page is valid */
diff --git a/include/asm-powerpc/pmi.h b/include/asm-powerpc/pmi.h
index e1dc090748df..b4e91fbf5081 100644
--- a/include/asm-powerpc/pmi.h
+++ b/include/asm-powerpc/pmi.h
@@ -30,6 +30,7 @@
30#ifdef __KERNEL__ 30#ifdef __KERNEL__
31 31
32#define PMI_TYPE_FREQ_CHANGE 0x01 32#define PMI_TYPE_FREQ_CHANGE 0x01
33#define PMI_TYPE_POWER_BUTTON 0x02
33#define PMI_READ_TYPE 0 34#define PMI_READ_TYPE 0
34#define PMI_READ_DATA0 1 35#define PMI_READ_DATA0 1
35#define PMI_READ_DATA1 2 36#define PMI_READ_DATA1 2
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 81ffe3b3c1ce..f9e34c493cbb 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -337,12 +337,18 @@ enum ps3_system_bus_device_type {
337 PS3_DEVICE_TYPE_LPM, 337 PS3_DEVICE_TYPE_LPM,
338}; 338};
339 339
340enum ps3_match_sub_id {
341 /* for PS3_MATCH_ID_GRAPHICS */
342 PS3_MATCH_SUB_ID_FB = 1,
343};
344
340/** 345/**
341 * struct ps3_system_bus_device - a device on the system bus 346 * struct ps3_system_bus_device - a device on the system bus
342 */ 347 */
343 348
344struct ps3_system_bus_device { 349struct ps3_system_bus_device {
345 enum ps3_match_id match_id; 350 enum ps3_match_id match_id;
351 enum ps3_match_sub_id match_sub_id;
346 enum ps3_system_bus_device_type dev_type; 352 enum ps3_system_bus_device_type dev_type;
347 353
348 u64 bus_id; /* SB */ 354 u64 bus_id; /* SB */
@@ -371,6 +377,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev);
371 377
372struct ps3_system_bus_driver { 378struct ps3_system_bus_driver {
373 enum ps3_match_id match_id; 379 enum ps3_match_id match_id;
380 enum ps3_match_sub_id match_sub_id;
374 struct device_driver core; 381 struct device_driver core;
375 int (*probe)(struct ps3_system_bus_device *); 382 int (*probe)(struct ps3_system_bus_device *);
376 int (*remove)(struct ps3_system_bus_device *); 383 int (*remove)(struct ps3_system_bus_device *);
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index bbccadfee0d6..c6d1ab650778 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -155,10 +155,12 @@
155#define CTRL_RUNLATCH 0x1 155#define CTRL_RUNLATCH 0x1
156#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ 156#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */
157#define DABR_TRANSLATION (1UL << 2) 157#define DABR_TRANSLATION (1UL << 2)
158#define SPRN_DABR2 0x13D /* e300 */
158#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ 159#define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */
159#define DABRX_USER (1UL << 0) 160#define DABRX_USER (1UL << 0)
160#define DABRX_KERNEL (1UL << 1) 161#define DABRX_KERNEL (1UL << 1)
161#define SPRN_DAR 0x013 /* Data Address Register */ 162#define SPRN_DAR 0x013 /* Data Address Register */
163#define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */
162#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ 164#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */
163#define DSISR_NOHPTE 0x40000000 /* no translation found */ 165#define DSISR_NOHPTE 0x40000000 /* no translation found */
164#define DSISR_PROTFAULT 0x08000000 /* protection fault */ 166#define DSISR_PROTFAULT 0x08000000 /* protection fault */
@@ -264,6 +266,8 @@
264#define HID1_PS (1<<16) /* 750FX PLL selection */ 266#define HID1_PS (1<<16) /* 750FX PLL selection */
265#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ 267#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
266#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ 268#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
269#define SPRN_IABR2 0x3FA /* 83xx */
270#define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */
267#define SPRN_HID4 0x3F4 /* 970 HID4 */ 271#define SPRN_HID4 0x3F4 /* 970 HID4 */
268#define SPRN_HID5 0x3F6 /* 970 HID5 */ 272#define SPRN_HID5 0x3F6 /* 970 HID5 */
269#define SPRN_HID6 0x3F9 /* BE HID 6 */ 273#define SPRN_HID6 0x3F9 /* BE HID 6 */
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h
index 1a0736f8803f..bd0fb8495154 100644
--- a/include/asm-powerpc/uaccess.h
+++ b/include/asm-powerpc/uaccess.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <asm/asm-compat.h>
9#include <asm/processor.h> 10#include <asm/processor.h>
10#include <asm/page.h> 11#include <asm/page.h>
11 12
@@ -141,12 +142,11 @@ extern long __put_user_bad(void);
141 " b 2b\n" \ 142 " b 2b\n" \
142 ".previous\n" \ 143 ".previous\n" \
143 ".section __ex_table,\"a\"\n" \ 144 ".section __ex_table,\"a\"\n" \
144 " .balign %5\n" \ 145 PPC_LONG_ALIGN "\n" \
145 PPC_LONG "1b,3b\n" \ 146 PPC_LONG "1b,3b\n" \
146 ".previous" \ 147 ".previous" \
147 : "=r" (err) \ 148 : "=r" (err) \
148 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ 149 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
149 "i"(sizeof(unsigned long)))
150 150
151#ifdef __powerpc64__ 151#ifdef __powerpc64__
152#define __put_user_asm2(x, ptr, retval) \ 152#define __put_user_asm2(x, ptr, retval) \
@@ -162,13 +162,12 @@ extern long __put_user_bad(void);
162 " b 3b\n" \ 162 " b 3b\n" \
163 ".previous\n" \ 163 ".previous\n" \
164 ".section __ex_table,\"a\"\n" \ 164 ".section __ex_table,\"a\"\n" \
165 " .balign %5\n" \ 165 PPC_LONG_ALIGN "\n" \
166 PPC_LONG "1b,4b\n" \ 166 PPC_LONG "1b,4b\n" \
167 PPC_LONG "2b,4b\n" \ 167 PPC_LONG "2b,4b\n" \
168 ".previous" \ 168 ".previous" \
169 : "=r" (err) \ 169 : "=r" (err) \
170 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err),\ 170 : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
171 "i"(sizeof(unsigned long)))
172#endif /* __powerpc64__ */ 171#endif /* __powerpc64__ */
173 172
174#define __put_user_size(x, ptr, size, retval) \ 173#define __put_user_size(x, ptr, size, retval) \
@@ -226,12 +225,11 @@ extern long __get_user_bad(void);
226 " b 2b\n" \ 225 " b 2b\n" \
227 ".previous\n" \ 226 ".previous\n" \
228 ".section __ex_table,\"a\"\n" \ 227 ".section __ex_table,\"a\"\n" \
229 " .balign %5\n" \ 228 PPC_LONG_ALIGN "\n" \
230 PPC_LONG "1b,3b\n" \ 229 PPC_LONG "1b,3b\n" \
231 ".previous" \ 230 ".previous" \
232 : "=r" (err), "=r" (x) \ 231 : "=r" (err), "=r" (x) \
233 : "b" (addr), "i" (-EFAULT), "0" (err), \ 232 : "b" (addr), "i" (-EFAULT), "0" (err))
234 "i"(sizeof(unsigned long)))
235 233
236#ifdef __powerpc64__ 234#ifdef __powerpc64__
237#define __get_user_asm2(x, addr, err) \ 235#define __get_user_asm2(x, addr, err) \
@@ -249,13 +247,12 @@ extern long __get_user_bad(void);
249 " b 3b\n" \ 247 " b 3b\n" \
250 ".previous\n" \ 248 ".previous\n" \
251 ".section __ex_table,\"a\"\n" \ 249 ".section __ex_table,\"a\"\n" \
252 " .balign %5\n" \ 250 PPC_LONG_ALIGN "\n" \
253 PPC_LONG "1b,4b\n" \ 251 PPC_LONG "1b,4b\n" \
254 PPC_LONG "2b,4b\n" \ 252 PPC_LONG "2b,4b\n" \
255 ".previous" \ 253 ".previous" \
256 : "=r" (err), "=&r" (x) \ 254 : "=r" (err), "=&r" (x) \
257 : "b" (addr), "i" (-EFAULT), "0" (err), \ 255 : "b" (addr), "i" (-EFAULT), "0" (err))
258 "i"(sizeof(unsigned long)))
259#endif /* __powerpc64__ */ 256#endif /* __powerpc64__ */
260 257
261#define __get_user_size(x, ptr, size, retval) \ 258#define __get_user_size(x, ptr, size, retval) \
diff --git a/include/asm-powerpc/ucc_fast.h b/include/asm-powerpc/ucc_fast.h
index f529f70b1d82..fce16abe7ee1 100644
--- a/include/asm-powerpc/ucc_fast.h
+++ b/include/asm-powerpc/ucc_fast.h
@@ -156,11 +156,11 @@ struct ucc_fast_info {
156 156
157struct ucc_fast_private { 157struct ucc_fast_private {
158 struct ucc_fast_info *uf_info; 158 struct ucc_fast_info *uf_info;
159 struct ucc_fast *uf_regs; /* a pointer to memory map of UCC regs. */ 159 struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */
160 u32 *p_ucce; /* a pointer to the event register in memory. */ 160 u32 __iomem *p_ucce; /* a pointer to the event register in memory. */
161 u32 *p_uccm; /* a pointer to the mask register in memory. */ 161 u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */
162#ifdef CONFIG_UGETH_TX_ON_DEMAND 162#ifdef CONFIG_UGETH_TX_ON_DEMAND
163 u16 *p_utodr; /* pointer to the transmit on demand register */ 163 u16 __iomem *p_utodr; /* pointer to the transmit on demand register */
164#endif 164#endif
165 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ 165 int enabled_tx; /* Whether channel is enabled for Tx (ENT) */
166 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ 166 int enabled_rx; /* Whether channel is enabled for Rx (ENR) */
diff --git a/include/linux/dma-attrs.h b/include/linux/dma-attrs.h
index 1677e2bfa00c..71ad34eca6e3 100644
--- a/include/linux/dma-attrs.h
+++ b/include/linux/dma-attrs.h
@@ -12,6 +12,7 @@
12 */ 12 */
13enum dma_attr { 13enum dma_attr {
14 DMA_ATTR_WRITE_BARRIER, 14 DMA_ATTR_WRITE_BARRIER,
15 DMA_ATTR_WEAK_ORDERING,
15 DMA_ATTR_MAX, 16 DMA_ATTR_MAX,
16}; 17};
17 18
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 9bc045b8c478..0ba21ee0f58c 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -135,11 +135,7 @@ struct fs_platform_info {
135 u32 device_flags; 135 u32 device_flags;
136 136
137 int phy_addr; /* the phy address (-1 no phy) */ 137 int phy_addr; /* the phy address (-1 no phy) */
138#ifdef CONFIG_PPC_CPM_NEW_BINDING
139 char bus_id[16]; 138 char bus_id[16];
140#else
141 const char* bus_id;
142#endif
143 int phy_irq; /* the phy irq (if it exists) */ 139 int phy_irq; /* the phy irq (if it exists) */
144 140
145 const struct fs_mii_bus_info *bus_info; 141 const struct fs_mii_bus_info *bus_info;
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index c415a496de3a..4e625e0094c8 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -69,6 +69,7 @@ struct gianfar_mdio_data {
69#define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020 69#define FSL_GIANFAR_DEV_HAS_VLAN 0x00000020
70#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040 70#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH 0x00000040
71#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080 71#define FSL_GIANFAR_DEV_HAS_PADDING 0x00000080
72#define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET 0x00000100
72 73
73/* Flags in gianfar_platform_data */ 74/* Flags in gianfar_platform_data */
74#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */ 75#define FSL_GIANFAR_BRD_HAS_PHY_INTR 0x00000001 /* set or use a timer */
@@ -125,4 +126,10 @@ struct mpc8xx_pcmcia_ops {
125 int(*voltage_set)(int slot, int vcc, int vpp); 126 int(*voltage_set)(int slot, int vcc, int vpp);
126}; 127};
127 128
129/* Returns non-zero if the current suspend operation would
130 * lead to a deep sleep (i.e. power removed from the core,
131 * instead of just the clock).
132 */
133int fsl_deep_sleep(void);
134
128#endif /* _FSL_DEVICE_H_ */ 135#endif /* _FSL_DEVICE_H_ */
diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h
index 2ee97e9877a7..67db101d0eb8 100644
--- a/include/linux/of_gpio.h
+++ b/include/linux/of_gpio.h
@@ -15,7 +15,7 @@
15#define __LINUX_OF_GPIO_H 15#define __LINUX_OF_GPIO_H
16 16
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <asm/gpio.h> 18#include <linux/gpio.h>
19 19
20#ifdef CONFIG_OF_GPIO 20#ifdef CONFIG_OF_GPIO
21 21