* Strange results with changing HZ
From: Wojciech Kromer @ 2005-11-21 7:44 UTC (permalink / raw)
To: linuxppc-embedded
My system is:
- 2.4.25 kernel from denx.de
- uclibc (gcc 3.4.2) + busybox
- changed HZ to 1000
- rebuild kernel only
AFAIR there souldn't be any need to recompile user apps.
I have strange results.
Sleep and timeout selects works fine, but alarm functions seems to be
too fast.
For example included program or ping waits too short.
it is OK:
# time alarm_test
alarm fired after 0.099166s
real 0m 0.11s
user 0m 0.00s
sys 0m 0.00s
#
# time sleep 1
real 0m 1.01s
user 0m 0.00s
sys 0m 0.00s
# time sleep 10
real 0m 10.01s
user 0m 0.00s
sys 0m 0.00s
but:
# alarm_test
alarm fired after 0.099709s
# alarm_test
alarm fired after 0.099710s
------------------------------------ alarm_test.c :
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
static void sighand(int sig)
{
}
int main()
{
struct timeval tv1, tv2;
sigset_t set;
sigfillset(&set);
sigdelset(&set, SIGALRM);
sigdelset(&set, SIGINT);
signal(SIGALRM, sighand);
gettimeofday(&tv1, NULL);
alarm(1);
sigsuspend(&set);
gettimeofday(&tv2, NULL);
tv1.tv_sec = tv2.tv_sec - tv1.tv_sec - (tv2.tv_usec < tv1.tv_usec);
tv1.tv_usec = tv2.tv_usec - tv1.tv_usec + (tv2.tv_usec < tv1.tv_usec) *
1000000;
printf("alarm fired after %ld.%06lds\n",
tv1.tv_sec, tv1.tv_usec);
return 0;
}
^ permalink raw reply
* [PATCH] ppc32: Add support for PM82x Boards
From: Heiko Schocher @ 2005-11-21 10:24 UTC (permalink / raw)
To: linuxppc-dev
Hello
the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
the Microsys PM82x Boards. Verified on the PM827 Board.
not included yet: support for MTD, I2C, RTC.
Note: 2 previously submitted Patches are required:
Thu, 4 Nov 2005 [PATCH] ppc32: Fix SCC Uart write problem after 2. open()
Tue, 3 Nov 2005 [PATCH] ppc32: fix: swallowed chars when booting.
Signed-off-by: Heiko Schocher <hs@denx.de>
---
arch/ppc/8260_io/Kconfig | 7
arch/ppc/8260_io/fcc_enet.c | 117 ++++
arch/ppc/Kconfig | 7
arch/ppc/configs/pm82x_defconfig | 897
+++++++++++++++++++++++++++++++
arch/ppc/platforms/Makefile | 1
arch/ppc/platforms/pm82x.h | 48 ++
arch/ppc/platforms/pm82x_setup.c | 40 +
arch/ppc/syslib/m8260_setup.c | 24 +
arch/ppc/syslib/m82xx_pci.c | 15 -
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 56 ++
include/asm-ppc/cpm2.h | 2
include/asm-ppc/mpc8260.h | 4
12 files changed, 1212 insertions(+), 6 deletions(-)
diff --git a/arch/ppc/8260_io/Kconfig b/arch/ppc/8260_io/Kconfig
index ea9651e..0cb917d 100644
--- a/arch/ppc/8260_io/Kconfig
+++ b/arch/ppc/8260_io/Kconfig
@@ -23,6 +23,10 @@ config FCC1_ENET
help
Use CPM2 fast Ethernet controller 1 to drive Ethernet (default).
+config DB_CR826_J30x_ON
+ bool " DB CR826 Legacy Jumper ON"
+ depends on PM82X
+
config FCC2_ENET
bool "Ethernet on FCC2"
depends on FEC_ENET
@@ -59,6 +63,9 @@ config FCC_DM9131
config FCC_DM9161
bool "DM9161"
+config FCC_AMD79C873
+ bool "AMD79C873"
+
config FCC_GENERIC_PHY
bool "Generic"
endchoice
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 4edeede..2f67f5b 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -202,8 +202,18 @@ static int fcc_enet_set_mac_address(stru
#define PC_F1RXCLK PC_CLK(F1_RXCLK)
#define PC_F1TXCLK PC_CLK(F1_TXCLK)
+#if defined(CONFIG_PM82X)
+#ifndef CONFIG_DB_CR826_J30x_ON
+#define CMX1_CLK_ROUTE ((uint)0x35000000)
+#define CMX1_CLK_MASK ((uint)0x7f000000)
+#else
+#define CMX1_CLK_ROUTE ((uint)0x37000000)
+#define CMX1_CLK_MASK ((uint)0x7f000000)
+#endif
+#else
#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS(F1_TXCLK))
#define CMX1_CLK_MASK ((uint)0xff000000)
+#endif
#define PC_F2RXCLK PC_CLK(F2_RXCLK)
#define PC_F2TXCLK PC_CLK(F2_TXCLK)
@@ -297,6 +307,14 @@ static int fcc_enet_set_mac_address(stru
#elif defined(CONFIG_EST8260) || defined(CONFIG_ADS8260) ||
defined(CONFIG_PQ2FADS)
#define PC_MDIO ((uint)0x00400000)
#define PC_MDCK ((uint)0x00200000)
+#elif defined (CONFIG_PM82X)
+#ifndef CONFIG_DB_CR826_J30x_ON
+#define PC_MDIO ((uint)0x00000080) /* MDIO on PC24 */
+#define PC_MDCK ((uint)0x00000100) /* MDCK on PC23 */
+#else
+#define PC_MDIO ((uint)0x00000100) /* MDIO on PA23 */
+#define PC_MDCK ((uint)0x00000200) /* MDCK on PA22 */
+#endif /* CONFIG_DB_CR826_J30x_ON */
#else
#define PC_MDIO ((uint)0x00000004)
#define PC_MDCK ((uint)0x00000020)
@@ -875,6 +893,28 @@ static void mii_parse_anar(uint mii_reg,
fep->phy_status = s;
}
+#ifdef CONFIG_FCC_AMD79C873
+/* Some boards don't have the MDIRQ line connected (PM82x is such a board)
*/
+
+static void mii_waitfor_anc(uint mii_reg, struct net_device *dev)
+{
+ struct fcc_enet_private *fep;
+ int regval;
+ int i;
+
+ fep = dev->priv;
+ regval = mk_mii_read(MII_BMSR) | (fep->phy_addr << 23);
+
+ for (i = 0; i < 1000; i++) {
+ if (mii_send_receive(fep->fip, regval) & 0x20)
+ return;
+ udelay(10000);
+ }
+
+ printk("%s: autonegotiation timeout\n", dev->name);
+}
+#endif
+
/* ------------------------------------------------------------------------
- */
/* Generic PHY support. Should work for all PHYs, but does not support
link
* change interrupts.
@@ -1150,6 +1190,72 @@ static phy_info_t phy_info_qs6612 = {
#endif /* CONFIG_FEC_QS6612 */
+/* ------------------------------------------------------------------------
- */
+/* The AMD Am79C873 PHY is on PM82x */
+
+#ifdef CONFIG_FCC_AMD79C873
+
+#define MII_79C873_IER 17 /* Interrupt Enable Register */
+#define MII_79C873_DR 18 /* Diagnostic Register */
+
+static void mii_parse_79c873_cr(uint mii_reg, struct net_device *dev)
+{
+ volatile struct fcc_enet_private *fep = dev->priv;
+ uint s = fep->phy_status;
+
+ s &= ~(PHY_STAT_SPMASK);
+
+ if (mii_reg & 0x2000) {
+ if (mii_reg & 0x0100)
+ s |= PHY_STAT_100FDX;
+ else
+ s |= PHY_STAT_100HDX;
+ } else {
+ if (mii_reg & 0x0100)
+ s |= PHY_STAT_10FDX;
+ else
+ s |= PHY_STAT_10HDX;
+ }
+
+ fep->phy_status = s;
+}
+
+static phy_info_t phy_info_79c873 = {
+ 0x00181b80,
+ "AMD79C873",
+
+ (const phy_cmd_t []) { /* config */
+ { mk_mii_read(MII_BMCR), mii_parse_cr },
+ { mk_mii_read(MII_ADVERTISE), mii_parse_anar },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* startup */
+#if 0
+ { mk_mii_write(MII_79C873_IER, 0xff00), NULL },
+#endif
+ { mk_mii_write(MII_BMCR, 0x1200), NULL }, /* autonegotiate */
+#ifdef CONFIG_PM82X
+ { mk_mii_read(MII_BMSR), mii_waitfor_anc },
+#endif
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* ack_int */
+ /* read SR twice: to acknowledge and to get link status */
+ { mk_mii_read(MII_BMSR), mii_parse_sr },
+ { mk_mii_read(MII_BMSR), mii_parse_sr },
+
+ /* find out the current link parameters */
+
+ { mk_mii_read(MII_BMCR), mii_parse_79c873_cr },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ { mk_mii_write(MII_79C873_IER, 0x0000), NULL },
+ { mk_mii_end, }
+ },
+};
+
+#endif /* CONFIG_FCC_AMD79C873 */
/* ------------------------------------------------------------------------
- */
/* The Davicom DM9131 is used on the HYMOD board */
@@ -1381,6 +1487,10 @@ static phy_info_t *phy_info[] = {
&phy_info_dm9161,
#endif /* CONFIG_FCC_DM9161 */
+#ifdef CONFIG_FCC_AMD79C873
+ &phy_info_79c873,
+#endif /* CONFIG_FCC_AMD79C873 */
+
#ifdef CONFIG_FCC_GENERIC_PHY
/* Generic PHY support. This must be the last PHY in the table.
* It will be used to support any PHY that doesn't match a previous
@@ -1847,8 +1957,10 @@ init_fcc_ioports(fcc_info_t *fip, volati
#ifdef CONFIG_USE_MDIO
/* ....and the MII serial clock/data.
*/
+#ifndef CONFIG_PM82X
io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck);
io->iop_podrc &= ~(fip->fc_mdio | fip->fc_mdck);
+#endif
io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck);
io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck);
#endif /* CONFIG_USE_MDIO */
@@ -2380,6 +2492,11 @@ fcc_enet_open(struct net_device *dev)
schedule();
mii_do_cmd(dev, fep->phy->startup);
+#ifdef CONFIG_PM82X
+ /* Read the autonegotiation results */
+ mii_do_cmd(dev, fep->phy->ack_int);
+ mii_do_cmd(dev, phy_cmd_relink);
+#endif /* CONFIG_PM82X */
netif_start_queue(dev);
return 0; /* Success */
}
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 8fa51b0..1add0a9 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -667,6 +667,11 @@ config TQM8260
End of Life: not yet :-)
URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
+config PM82X
+ bool "PM82X"
+ help
+ This option enables support for the MicroSys PM82x evaluation boards.
+
config ADS8272
bool "ADS8272"
@@ -723,7 +728,7 @@ config PPC_MPC52xx
config 8260
bool "CPM2 Support" if WILLOW
depends on 6xx
- default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx ||
PQ2FADS
+ default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx ||
PQ2FADS || PM82X
help
The MPC8260 is a typical embedded CPU made by Motorola. Selecting
this option means that you wish to build a kernel for a machine with
diff --git a/arch/ppc/configs/pm82x_defconfig
b/arch/ppc/configs/pm82x_defconfig
new file mode 100644
index 0000000..13f0e8a
--- /dev/null
+++ b/arch/ppc/configs/pm82x_defconfig
@@ -0,0 +1,897 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Mon Oct 17 12:21:11 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Processor
+#
+CONFIG_6xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_EMBEDDEDBOOT=y
+CONFIG_PPC_STD_MMU=y
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+# CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+CONFIG_PM82X=y
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_EV64360 is not set
+CONFIG_8260=y
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD is not set
+# CONFIG_SMP is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_8260=y
+# CONFIG_8260_PCI9 is not set
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_8=y
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_CFI_I1 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_I4=y
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SBC8240 is not set
+CONFIG_MTD_PM82X=y
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+CONFIG_SERIAL_CPM_SCC3=y
+CONFIG_SERIAL_CPM_SCC4=y
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+CONFIG_I2C_MPC8260=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+CONFIG_SENSORS_PCF8563=y
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+# CONFIG_SCC_ENET is not set
+CONFIG_FEC_ENET=y
+CONFIG_USE_MDIO=y
+
+#
+# CPM2 Options
+#
+CONFIG_FCC1_ENET=y
+# CONFIG_DB_CR826_J30x_ON is not set
+# CONFIG_FCC2_ENET is not set
+# CONFIG_FCC3_ENET is not set
+# CONFIG_FCC_LXT970 is not set
+CONFIG_FCC_LXT971=y
+# CONFIG_FCC_QS6612 is not set
+# CONFIG_FCC_DM9131 is not set
+# CONFIG_FCC_DM9161 is not set
+# CONFIG_FCC_AMD79C873 is not set
+# CONFIG_FCC_GENERIC_PHY is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_XMON is not set
+# CONFIG_BDI_SWITCH is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7c5cdab..becaed3 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_bac
obj-$(CONFIG_PREP_RESIDUAL) += residual.o
obj-$(CONFIG_PQ2ADS) += pq2ads.o
obj-$(CONFIG_TQM8260) += tqm8260_setup.o
+obj-$(CONFIG_PM82X) += pm82x_setup.o
obj-$(CONFIG_CPCI690) += cpci690.o
obj-$(CONFIG_EV64260) += ev64260.o
obj-$(CONFIG_CHESTNUT) += chestnut.o
diff --git a/arch/ppc/platforms/pm82x.h b/arch/ppc/platforms/pm82x.h
new file mode 100644
index 0000000..ee12e1d
--- /dev/null
+++ b/arch/ppc/platforms/pm82x.h
@@ -0,0 +1,48 @@
+/*
+ * PM82X board specific definitions
+ *
+ * Copyright (c) 2005 Heiko Schocher (hs@denx.de)
+ */
+
+#ifndef __MACH_PM82X_H
+#define __MACH_PM82X_H
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+#if defined(CONFIG_PCI)
+/* #include <platforms/m8260_pci.h> */
+#endif
+
+#define CPM_MAP_ADDR ((uint)0xF0000000)
+#define I2C_ADDR_RTC 0x51
+
+/* For our show_cpuinfo hooks. */
+#define CPUINFO_VENDOR "Microsys"
+#define CPUINFO_MACHINE "PM82x PowerPC"
+
+#if defined (CONFIG_MTD_NAND_DISKONCHIP)
+#define BOOTROM_RESTART_ADDR ((uint)0x40000100)
+#else
+#define BOOTROM_RESTART_ADDR ((uint)0xFF800100)
+#endif
+
+/* PPC Sys identification */
+#define BOARD_CHIP_NAME "8250"
+
+#ifdef CONFIG_PCI
+/* PCI interrupt controller */
+#define PCI_INT_STAT_REG 0xF8200000
+#define PCI_INT_MASK_REG 0xF8200004
+#define PIRQA (NR_CPM_INTS + 0)
+#define PIRQB (NR_CPM_INTS + 1)
+#define PIRQC (NR_CPM_INTS + 2)
+#define PIRQD (NR_CPM_INTS + 3)
+
+#define PCI_INT_TO_SIU SIU_INT_IRQ2
+
+#endif /* CONFIG_PCI */
+
+
+#endif /* __MACH_PM82X_H */
diff --git a/arch/ppc/platforms/pm82x_setup.c
b/arch/ppc/platforms/pm82x_setup.c
new file mode 100644
index 0000000..dd8ea88
--- /dev/null
+++ b/arch/ppc/platforms/pm82x_setup.c
@@ -0,0 +1,40 @@
+/*
+ * arch/ppc/platforms/pm82x_setup.c
+ *
+ * PM82X platform support
+ *
+ * Author: Heiko Schocher <hs@denx.de>
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/machdep.h>
+
+static int
+pm82x_set_rtc_time(unsigned long time)
+{
+ ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt = time;
+ ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcntsc = 0x3;
+ return(0);
+}
+
+static unsigned long
+pm82x_get_rtc_time(void)
+{
+ return ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt;
+}
+
+void __init
+m82xx_board_init(void)
+{
+ /* Anything special for this platform */
+ ppc_md.set_rtc_time = pm82x_set_rtc_time;
+ ppc_md.get_rtc_time = pm82x_get_rtc_time;
+}
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 76a2aa4..f4b0f3a 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -51,6 +51,16 @@ m8260_setup_arch(void)
/* Reset the Communication Processor Module. */
cpm2_reset();
+
+#ifdef CONFIG_PM82X
+ /* On PM82x BRG1 is not initialized by the firmware (as the console
+ * is on SMC2). We initialize it here to avoid "realtime clock stuck"
+ * messages. Later on, when the RTC driver loads up, it re-installs
+ * its own handlers.
+ */
+ cpm_setbrg(0, 9600);
+#endif /* CONFIG_PM82X */
+
#ifdef CONFIG_8260_PCI9
/* Initialise IDMA for PCI erratum workaround */
idma_pci9_init();
@@ -156,9 +166,9 @@ m8260_show_cpuinfo(struct seq_file *m)
"core clock\t: %u MHz\n"
"CPM clock\t: %u MHz\n"
"bus clock\t: %u MHz\n",
- CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
- bp->bi_baudrate, bp->bi_intfreq / 1000000,
- bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
+ CPUINFO_VENDOR, CPUINFO_MACHINE, (unsigned int) bp->bi_memsize,
+ (int) bp->bi_baudrate, (unsigned int) bp->bi_intfreq / 1000000,
+ (unsigned int) bp->bi_cpmfreq / 1000000, (unsigned int) bp->bi_busfreq
/ 1000000);
return 0;
}
@@ -176,7 +186,15 @@ m8260_init_IRQ(void)
/* Initialize the default interrupt mapping priorities,
* in case the boot rom changed something on us.
*/
+#ifndef CONFIG_PM82X
cpm2_immr->im_intctl.ic_siprr = 0x05309770;
+ cpm2_immr->im_intctl.ic_scprrh = 0x05309770;
+ cpm2_immr->im_intctl.ic_scprrl = 0x05309770;
+#else
+ cpm2_immr->im_intctl.ic_siprr = 0x0530b370;
+ cpm2_immr->im_intctl.ic_scprrh = 0x0530b370;
+ cpm2_immr->im_intctl.ic_scprrl = 0x0530b370;
+#endif
#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) ||
defined(CONFIG_PQ2FADS))
/* Initialize stuff for the 82xx CPLD IC and install demux */
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index 1d1c395..5af560e 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -300,6 +300,19 @@ pq2ads_setup_pci(struct pci_controller *
}
+void m8260_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev) {
+#ifdef CONFIG_PM82X
+ if (dev->bus->number == 0 && (dev->devfn & ~0x7) == (0xD << 3)) {
+ dev->irq = SIU_INT_IRQ5;
+ }
+#endif
+ }
+}
+
void __init pq2_find_bridges(void)
{
extern int pci_assign_all_buses;
@@ -377,7 +390,7 @@ void __init pq2_find_bridges(void)
hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
ppc_md.pci_map_irq = pq2pci_map_irq;
- ppc_md.pcibios_fixup = NULL;
+ ppc_md.pcibios_fixup = m8260_pcibios_fixup;
ppc_md.pcibios_fixup_bus = NULL;
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53e..39776bc 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -95,8 +95,13 @@ void smc1_lineif(struct uart_cpm_port *p
io->iop_pdird &= ~0x00800000;
io->iop_psord &= ~0x00c00000;
+#if defined(CONFIG_PM82X)
+ /* Wire BRG7 to SMC1 */
+ cpm2_immr->im_cpmux.cmx_smr &= 0x1f;
+#else
/* Wire BRG1 to SMC1 */
cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+#endif
pinfo->brg = 1;
}
@@ -104,14 +109,29 @@ void smc2_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ /* SMC2 is only on port A */
+ io->iop_ppard |= 0x08000000;
+ io->iop_pdird &= ~0x08000000;
+ io->iop_psord |= 0x08000000;
+ io->iop_pparc |= 0x00010000;
+ io->iop_pdirc |= 0x00010000;
+ io->iop_psorc &= ~0x00010000;
+#else
/* SMC2 is only on port A */
io->iop_ppara |= 0x00c00000;
io->iop_pdira |= 0x00400000;
io->iop_pdira &= ~0x00800000;
io->iop_psora &= ~0x00c00000;
+#endif
+#if defined(CONFIG_PM82X)
+ /* Wire BRG8 to SMC2 */
+ cpm2_immr->im_cpmux.cmx_smr &= 0xf1;
+#else
/* Wire BRG2 to SMC2 */
cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+#endif
pinfo->brg = 2;
}
@@ -119,12 +139,22 @@ void scc1_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ io->iop_ppard |= 0x00000001; /* Rx */
+ io->iop_pparb |= 0x00000008; /* Tx */
+
+ io->iop_psord &= ~0x00000001; /* Rx */
+ io->iop_psorb |= 0x00000008; /* Tx */
+ io->iop_pdird &= ~0x00000001; /* Rx */
+ io->iop_pdirb |= 0x00000008; /* Tx */
+#else
/* Use Port D for SCC1 instead of other functions. */
io->iop_ppard |= 0x00000003;
io->iop_psord &= ~0x00000001; /* Rx */
io->iop_psord |= 0x00000002; /* Tx */
io->iop_pdird &= ~0x00000001; /* Rx */
io->iop_pdird |= 0x00000002; /* Tx */
+#endif
/* Wire BRG1 to SCC1 */
cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
@@ -149,6 +179,14 @@ void scc2_lineif(struct uart_cpm_port *p
io->iop_psord &= ~0x00000010; /* Tx */
io->iop_pdird &= ~0x00000008; /* Rx */
io->iop_pdird |= 0x00000010; /* Tx */
+#elif defined(CONFIG_PM82X)
+ volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ io->iop_pparb |= 0x00010000; /* Rx */
+ io->iop_pdirb &= ~0x00010000;
+ io->iop_psorb &= ~0x00010000;
+ io->iop_ppard |= 0x00000010; /* Tx */
+ io->iop_pdird |= 0x00000010;
+ io->iop_psord &= ~0x00000010;
#else
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
@@ -165,12 +203,21 @@ void scc2_lineif(struct uart_cpm_port *p
void scc3_lineif(struct uart_cpm_port *pinfo)
{
+#if defined(CONFIG_PM82X)
+ volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ io->iop_pparb |= 0x00820000; /* Rx */
+ io->iop_pdirb &= ~0x00020000;
+ io->iop_psorb &= ~0x00020000;
+ io->iop_pdirb |= 0x00800000; /* Tx */
+ io->iop_psorb |= 0x00800000;
+#else
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
+#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
pinfo->brg = 3;
@@ -180,10 +227,19 @@ void scc4_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ io->iop_ppard |= 0x00000200; /* Rx */
+ io->iop_pdird &= ~0x00000200;
+ io->iop_psord &= ~0x00000200;
+ io->iop_ppard |= 0x00000400; /* Tx */
+ io->iop_pdird |= 0x00000400;
+ io->iop_psord &= ~0x00000400;
+#else
io->iop_ppard |= 0x00000600;
io->iop_psord &= ~0x00000600; /* Tx/Rx */
io->iop_pdird &= ~0x00000200; /* Rx */
io->iop_pdird |= 0x00000400; /* Tx */
+#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 43d2ebb..0e7a03c 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -181,7 +181,7 @@ typedef struct cpm_buf_desc {
*/
#define PROFF_SMC1 (0)
#define PROFF_SMC2 (64)
-
+#define PROFF_I2C ((16 * 1024) - 64)
/* Define enough so I can at least use the serial port as a UART.
*/
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 3214526..501ea8e 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -36,6 +36,10 @@
#include <platforms/tqm8260.h>
#endif
+#ifdef CONFIG_PM82X
+#include <platforms/pm82x.h>
+#endif
+
#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS)
#include <platforms/pq2ads.h>
#endif
\f
!-------------------------------------------------------------flip-
^ permalink raw reply related
* [PATCH] ppc32: Add defconfig File for PM826 Board.
From: Heiko Schocher @ 2005-11-21 10:30 UTC (permalink / raw)
To: linuxppc-dev
Hello,
the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds the defconfig
File for the PM826 Board from Microsys.
Signed-off-by: Heiko Schocher <hs@denx.de>
---
arch/ppc/configs/pm826_defconfig | 808
++++++++++++++++++++++++++++++++++++++
1 files changed, 808 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/configs/pm826_defconfig
b/arch/ppc/configs/pm826_defconfig
new file mode 100644
index 0000000..24a3488
--- /dev/null
+++ b/arch/ppc/configs/pm826_defconfig
@@ -0,0 +1,808 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc5
+# Sun Oct 30 14:34:35 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Processor
+#
+CONFIG_6xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_EMBEDDEDBOOT=y
+CONFIG_PPC_STD_MMU=y
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+# CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+CONFIG_PM82X=y
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_EV64360 is not set
+# CONFIG_TQM834x is not set
+CONFIG_8260=y
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD is not set
+# CONFIG_SMP is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_8=y
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_CFI_I1 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_I4=y
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SBC8240 is not set
+CONFIG_MTD_PM82X=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_USE_MDIO=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+CONFIG_SERIAL_CPM_SCC3=y
+CONFIG_SERIAL_CPM_SCC4=y
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_MPC is not set
+CONFIG_I2C_MPC8260=y
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+CONFIG_SENSORS_PCF8563=y
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+# CONFIG_SCC_ENET is not set
+CONFIG_FEC_ENET=y
+
+#
+# CPM2 Options
+#
+CONFIG_FCC1_ENET=y
+# CONFIG_DB_CR826_J30x_ON is not set
+# CONFIG_FCC2_ENET is not set
+# CONFIG_FCC3_ENET is not set
+# CONFIG_FCC_LXT970 is not set
+CONFIG_FCC_LXT971=y
+# CONFIG_FCC_QS6612 is not set
+# CONFIG_FCC_DM9131 is not set
+# CONFIG_FCC_DM9161 is not set
+# CONFIG_FCC_AMD79C873 is not set
+# CONFIG_FCC_GENERIC_PHY is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_XMON is not set
+# CONFIG_BDI_SWITCH is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
\f
!-------------------------------------------------------------flip-
^ permalink raw reply related
* Re: [PATCH] ppc32: Add support for PM82x Boards
From: Stephen Rothwell @ 2005-11-21 10:32 UTC (permalink / raw)
To: hs; +Cc: linuxppc-dev
In-Reply-To: <AHEILKONAKAEJPHNMOPNKELACDAA.hs@denx.de>
[-- Attachment #1: Type: text/plain, Size: 771 bytes --]
Hi Heiko,
On Mon, 21 Nov 2005 11:24:58 +0100 "Heiko Schocher" <hs@denx.de> wrote:
>
> Hello
>
> the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
> f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
> the Microsys PM82x Boards. Verified on the PM827 Board.
>
> not included yet: support for MTD, I2C, RTC.
>
> Note: 2 previously submitted Patches are required:
>
> Thu, 4 Nov 2005 [PATCH] ppc32: Fix SCC Uart write problem after 2. open()
> Tue, 3 Nov 2005 [PATCH] ppc32: fix: swallowed chars when booting.
>
> Signed-off-by: Heiko Schocher <hs@denx.de>
Unfortunately, the patch was badly wrapped by your mailer ...
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* [PATCH] MTD: Add support for the PM82x Boards.
From: Heiko Schocher @ 2005-11-21 10:34 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-mtd
Hello,
the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
the NOR flashes and for the DiskOnChip on the PM82X Boards
from Microsys.
Signed-off-by: Heiko Schocher <hs@denx.de>
---
drivers/mtd/chips/jedec_probe.c | 50 +++++
drivers/mtd/devices/docprobe.c | 4
drivers/mtd/maps/Kconfig | 6 +
drivers/mtd/maps/Makefile | 1
drivers/mtd/maps/pm82x.c | 360
+++++++++++++++++++++++++++++++++++++++
drivers/mtd/nand/diskonchip.c | 4
6 files changed, 425 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/chips/jedec_probe.c
b/drivers/mtd/chips/jedec_probe.c
index edb306c..e230127 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -104,6 +104,11 @@
#define I28F320B3B 0x8897
#define I28F640B3T 0x8898
#define I28F640B3B 0x8899
+#define I28F640C3B 0x88CD
+#define I28F160F3T 0x88F3
+#define I28F160F3B 0x88F4
+#define I28F160C3T 0x88C2
+#define I28F160C3B 0x88C3
#define I82802AB 0x00ad
#define I82802AC 0x00ac
@@ -1080,6 +1085,51 @@ static const struct amd_flash_info jedec
}
}, {
.mfr_id = MANUFACTURER_INTEL,
+ .dev_id = I28F640C3B,
+ .name = "Intel 28F640C3B",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
+ },
+ .DevSize = SIZE_8MiB,
+ .CmdSet = P_ID_INTEL_STD,
+ .NumEraseRegions= 2,
+ .regions = {
+ ERASEINFO(0x02000, 8),
+ ERASEINFO(0x10000, 127),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_INTEL,
+ .dev_id = I28F160C3B,
+ .name = "Intel 28F160C3B",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
+ },
+ .DevSize = SIZE_2MiB,
+ .CmdSet = P_ID_INTEL_STD,
+ .NumEraseRegions= 2,
+ .regions = {
+ ERASEINFO(0x02000, 8),
+ ERASEINFO(0x10000, 31),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_INTEL,
+ .dev_id = I28F160C3T,
+ .name = "Intel 28F160C3T",
+ .uaddr = {
+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
+ },
+ .DevSize = SIZE_2MiB,
+ .CmdSet = P_ID_INTEL_STD,
+ .NumEraseRegions= 2,
+ .regions = {
+ ERASEINFO(0x10000, 31),
+ ERASEINFO(0x02000, 8),
+ }
+ }, {
+ .mfr_id = MANUFACTURER_INTEL,
.dev_id = I82802AB,
.name = "Intel 82802AB",
.uaddr = {
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 13178b9..b051bc7 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -81,7 +81,11 @@ static unsigned long __initdata doc_loca
0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__)
+#if defined(CONFIG_PM82X)
+ 0xff800000,
+#else
0xe4000000,
+#endif
#elif defined(CONFIG_MOMENCO_OCELOT)
0x2f000000,
0xff000000,
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 846a533..237abe8 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -256,6 +256,12 @@ config MTD_SBC8240
Flash access on the SBC8240 board from Wind River. See
<http://www.windriver.com/products/sbc8240/>
+config MTD_PM82X
+ tristate "Flash device on PM82X Boards"
+ depends on PPC32 && 6xx && 8260 && MTD_COMPLEX_MAPPINGS && MTD_PARTITIONS
+ help
+ Flash access on the PM82X boards from Microsys.
+
config MTD_TQM8XXL
tristate "CFI Flash device mapped on TQM8XXL"
depends on MTD_CFI && TQM8xxL
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7d9e940..ecdc515 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -73,3 +73,4 @@ obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
+obj-$(CONFIG_MTD_PM82X) += pm82x.o
diff --git a/drivers/mtd/maps/pm82x.c b/drivers/mtd/maps/pm82x.c
new file mode 100644
index 0000000..dc0bc48
--- /dev/null
+++ b/drivers/mtd/maps/pm82x.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright(C) 2005
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * Copyright(C) 2005
+ * Josef Wagner, MicroSys GmbH <wagner@microsys.de>
+ *
+ * This code is GPLed
+ *
+ */
+
+/*
+ * PM825/PM826 uses 4 x Intel 28F160C3B (16 Mbit)
+ * 4 x Intel 28F160C3 (16 Mbit) in one bank (64 bit bankwidth)
+ * for a total of 8MB flash
+ *
+ * PM827/PM828 uses 4 x Intel 28F640C3 (64 Mbit)
+ * in one bank (64 bit bankwidth)
+ * for a total of 32MB flash
+
+ * Thus we have to chose:
+ * - Support 64-bit bankwidth => CONFIG_MTD_CFI_B8
+ * - Support 4-chip flash interleave => CONFIG_MTD_CFI_I4
+*/
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/ppcboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#if 0 /* Debugging turned off */
+# define debugk(fmt,args...) printk(fmt ,##args)
+#else
+# define debugk(fmt,args...)
+#endif
+
+#define FLASH_BANK_MAX 1
+
+/* The "residual" data board information structure the boot loader
+ * hands to us.
+ */
+extern unsigned char __res[];
+
+/* trivial struct to describe partition information */
+struct mtd_part_def
+{
+ int nums;
+ unsigned char *type;
+ struct mtd_partition* mtd_part;
+};
+
+static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
+static struct map_info* map_banks[FLASH_BANK_MAX];
+static struct mtd_part_def part_banks[FLASH_BANK_MAX];
+static unsigned long num_banks;
+static unsigned long start_scan_addr;
+
+static map_word pm82x_read64(struct map_info *map, unsigned long ofs)
+{
+ map_word val;
+ val.x[0] = *((volatile __u32 *)(map->map_priv_1 + ofs));
+ val.x[1] = *(((volatile __u32 *)(map->map_priv_1 + ofs)) + 1);
+ return val;
+}
+
+static void pm82x_copy_from(struct map_info *map,
+ void *to, unsigned long from, ssize_t len)
+{
+ memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
+}
+
+static void pm82x_write64 (struct map_info *map, map_word map_d,
+ unsigned long adr)
+{
+ ulong addr = map->map_priv_1 + adr;
+ __u64 d = ((__u64)map_d.x[0] << 32) + map_d.x[1];
+ __u64 * data = &d;
+ ulong flags;
+ volatile ulong msr;
+ ulong saved_msr;
+ volatile long saved_fr[2];
+
+ local_irq_save (flags);
+
+ __asm__ __volatile__ ("mfmsr %0" : "=r" (msr):);
+ saved_msr = msr;
+ msr |= MSR_FP;
+ msr &= ~(MSR_FE0 | MSR_FE1);
+
+ __asm__ __volatile__ (
+ "mtmsr %0\n"
+ "isync\n"
+ :
+ : "r" (msr));
+
+ __asm__ __volatile__ (
+ "stfd 1, 0(%2)\n"
+ "lfd 1, 0(%0)\n"
+ "stfd 1, 0(%1)\n"
+ "lfd 1, 0(%2)\n"
+ :
+ : "r" (data), "r" (addr), "b" (saved_fr)
+ );
+
+ __asm__ __volatile__ (
+ "mtmsr %0\n"
+ "isync\n"
+ :
+ : "r" (saved_msr));
+
+ local_irq_restore (flags);
+}
+
+static void pm82x_copy_to(struct map_info *map,
+ unsigned long to, const void *from, ssize_t len)
+{
+ memcpy_toio((void *)(map->map_priv_1 + to), from, len);
+}
+
+/*
+ * The following defines the partition layout of PM825/PM826 boards.
+ *
+ * See include/linux/mtd/partitions.h for definition of the
+ * mtd_partition structure.
+ *
+ */
+
+#ifdef CONFIG_MTD_PARTITIONS
+/* partition definition for first (and only) flash bank
+ * also ref. to "drivers/char/flash_config.c"
+ */
+static struct mtd_partition pm82x_partitions_8M[] = {
+ {
+ name: "U-Boot", /* U-Boot image */
+ offset: 0x00000000,
+ size: 0x00040000, /* 256 KB */
+ },
+ {
+ name: "kernel", /* Linux kernel image */
+ offset: 0x00040000,
+ size: 0x000C0000, /* 768 KB */
+ },
+ {
+ name: "ramdisk", /* Ramdisk image */
+ offset: 0x00100000,
+ size: 0x00300000, /* 3 MB */
+ },
+ {
+ name: "user", /* User file system */
+ offset: 0x00400000,
+ size: 0x00400000, /* 4 MB */
+ },
+};
+
+static struct mtd_partition pm82x_partitions_32M[] = {
+ {
+ name: "U-Boot", /* U-Boot image */
+ offset: 0x00000000,
+ size: 0x00040000, /* 256 KB */
+ },
+ {
+ name: "kernel", /* Linux kernel image */
+ offset: 0x00040000,
+ size: 0x000C0000, /* 768 KB */
+ },
+ {
+ name: "ramdisk", /* Ramdisk image */
+ offset: 0x00100000,
+ size: 0x00300000, /* 3 MB */
+ },
+ {
+ name: "user", /* User file system */
+ offset: 0x00400000,
+ size: 0x01C00000, /* 28 MB */
+ },
+};
+
+#endif /* CONFIG_MTD_PARTITIONS */
+
+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
+
+int __init init_pm82x_mtd(void)
+{
+ int idx = 0, ret = 0;
+ unsigned long flash_addr, flash_size, mtd_size = 0;
+
+ /* pointer to PM82x board info data */
+ bd_t *bd = (bd_t *)__res;
+
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ int n;
+ char mtdid[10];
+ const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+ flash_addr = bd->bi_flashstart;
+ flash_size = bd->bi_flashsize;
+
+ /* request maximum flash size address space */
+ start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
+ if (!start_scan_addr) {
+ printk("%s: Failed to ioremap address: 0x%lx\n",
+ __FUNCTION__, flash_addr);
+ return -EIO;
+ }
+
+ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (mtd_size >= flash_size)
+ break;
+
+ debugk ("%s: chip probing count %d\n", __FUNCTION__, idx);
+
+ map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info),
+ GFP_KERNEL);
+ if (map_banks[idx] == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx], 0, sizeof(struct map_info));
+ map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
+ if (map_banks[idx]->name == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx]->name, 0, 16);
+
+ sprintf(map_banks[idx]->name, "PM82x-%d", idx);
+ map_banks[idx]->size = flash_size;
+ map_banks[idx]->bankwidth = 8;
+ map_banks[idx]->read = pm82x_read64;
+ map_banks[idx]->copy_from = pm82x_copy_from;
+ map_banks[idx]->write = pm82x_write64;
+ map_banks[idx]->copy_to = pm82x_copy_to;
+ map_banks[idx]->map_priv_1=
+ start_scan_addr + ((idx > 0) ?
+ (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
+
+ /* start to probe flash chips */
+ mtd_banks[idx] = do_map_probe("jedec_probe", map_banks[idx]);
+ if (mtd_banks[idx]) {
+ mtd_banks[idx]->owner = THIS_MODULE;
+ mtd_size += mtd_banks[idx]->size;
+ num_banks++;
+ debugk ("%s: bank %ld, name: %s, size: %d bytes \n",
+ __FUNCTION__,
+ num_banks,
+ mtd_banks[idx]->name,
+ mtd_banks[idx]->size);
+ }
+ }
+
+ /* no supported flash chips found */
+ if (!num_banks) {
+ printk("PM82x: No supported flash chips found!\n");
+ ret = -ENXIO;
+ goto error_mem;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+ /*
+ * Select static partition definitions
+ */
+ if (flash_size == 0x800000) {
+ part_banks[0].mtd_part = pm82x_partitions_8M;
+ part_banks[0].nums = NB_OF(pm82x_partitions_8M);
+ } else {
+ part_banks[0].mtd_part = pm82x_partitions_32M;
+ part_banks[0].nums = NB_OF(pm82x_partitions_32M);
+ }
+ part_banks[0].type = "static image";
+
+ for(idx = 0; idx < num_banks ; idx++) {
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ sprintf(mtdid, "%d", idx);
+ n = parse_mtd_partitions(mtd_banks[idx],
+ part_probes,
+ &part_banks[idx].mtd_part,
+ 0);
+ debugk ("%s: %d command line partitions on bank %s\n",
+ __FUNCTION__, n, mtdid);
+ if (n > 0) {
+ part_banks[idx].type = "command line";
+ part_banks[idx].nums = n;
+ }
+#endif /* CONFIG_MTD_CMDLINE_PARTS */
+
+ if (part_banks[idx].nums == 0) {
+ printk (KERN_NOTICE
+ "PM82x flash bank %d: no partition info "
+ "available, registering whole device\n", idx);
+ add_mtd_device(mtd_banks[idx]);
+ } else {
+ printk (KERN_NOTICE
+ "PM82x flash bank %d: Using %s partition "
+ "definition\n", idx, part_banks[idx].type);
+ add_mtd_partitions (mtd_banks[idx],
+ part_banks[idx].mtd_part,
+ part_banks[idx].nums);
+ }
+ }
+#else /* ! CONFIG_MTD_PARTITIONS */
+ printk (KERN_NOTICE "PM82x flash: registering %d flash banks "
+ "at once\n", num_banks);
+
+ for(idx = 0 ; idx < num_banks ; idx++) {
+ add_mtd_device(mtd_banks[idx]);
+ }
+#endif /* CONFIG_MTD_PARTITIONS */
+
+ return 0;
+error_mem:
+ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (map_banks[idx] != NULL) {
+ if (map_banks[idx]->name != NULL) {
+ kfree(map_banks[idx]->name);
+ map_banks[idx]->name = NULL;
+ }
+ kfree(map_banks[idx]);
+ map_banks[idx] = NULL;
+ }
+ }
+
+ iounmap((void *)start_scan_addr);
+
+ return ret;
+}
+
+static void __exit cleanup_pm82x_mtd(void)
+{
+ unsigned int idx = 0;
+ for(idx = 0 ; idx < num_banks ; idx++) {
+ /* destroy mtd_info previously allocated */
+ if (mtd_banks[idx]) {
+ del_mtd_partitions(mtd_banks[idx]);
+ map_destroy(mtd_banks[idx]);
+ }
+ /* release map_info not used anymore */
+ kfree(map_banks[idx]->name);
+ kfree(map_banks[idx]);
+ }
+ if (start_scan_addr) {
+ iounmap((void *)start_scan_addr);
+ start_scan_addr = 0;
+ }
+}
+
+module_init(init_pm82x_mtd);
+module_exit(cleanup_pm82x_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
+MODULE_DESCRIPTION("MTD map driver for PM82x boards");
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 21d4e8f..bf7cf54 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -55,7 +55,11 @@ static unsigned long __initdata doc_loca
0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__)
+#if defined(CONFIG_PM82X)
+ 0xff800000,
+#else
0xe4000000,
+#endif
#elif defined(CONFIG_MOMENCO_OCELOT)
0x2f000000,
0xff000000,
\f
!-------------------------------------------------------------flip-
^ permalink raw reply related
* Re : anyone used i2c-algo-8260 for the MPC8272 family?
From: Sam Song @ 2005-11-21 11:17 UTC (permalink / raw)
To: linuxppc-embedded
> Ron Kellam <ronkbox-news@yahoo.com> wrote:
> Anyone have this working, or any thoughts to
> contribute?
What the kernel version are you talking about?
For 2.4.31, it worked on my custom 8248 platform.
Sure, some porting work involved.
As for 2.6, I also haven't made it work. I tried
the official 2.6.13-rc3 kernel and denx-2.6.14
kernel. Both no luck. I also want to know something
in this regards.
Thanks,
Sam
___________________________________________________________
雅虎邮箱超强增值服务-2G超大空间、pop3收信、无限量邮件提醒
http://cn.mail.yahoo.com
^ permalink raw reply
* Re: Strange results with changing HZ
From: David Jander @ 2005-11-21 11:43 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <43817ACF.1030903@dgt.com.pl>
On Monday 21 November 2005 08:44, Wojciech Kromer wrote:
> My system is:
> - 2.4.25 kernel from denx.de
> - uclibc (gcc 3.4.2) + busybox
> - changed HZ to 1000
> - rebuild kernel only
>
> AFAIR there souldn't be any need to recompile user apps.
Just an uneducated guess, but are you sure uclibc doesn't depend on HZ at all?
Some things might be just straight syscalls, others might be implemented in
userspace (inside uclibc)... for example alarm(1) programming an alarm on
jiffies+1/HZ, and HZ being compiled in from kernel headers ?
I may just be talking rubbish though.
Greetings,
--
David Jander
^ permalink raw reply
* Re: Re : anyone used i2c-algo-8260 for the MPC8272 family?
From: Ron Kellam @ 2005-11-21 12:09 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20051121111704.89583.qmail@web15803.mail.cnb.yahoo.com>
On Mon, 21 Nov 2005 19:17:03 +0800 (CST), Sam Song
<samlinuxppc@yahoo.com.cn> wrote:
>What the kernel version are you talking about?
Sorry - forgot to give details. I'm currently using denx-2.4.25.
>For 2.4.31, it worked on my custom 8248 platform.
>Sure, some porting work involved.
What sort of porting work was involved? If you are using the CPM I2C
module and not bit-bashing, then there's very little to port It's not
as though you have much choice in which I/O pins to use...
>As for 2.6, I also haven't made it work. I tried
>the official 2.6.13-rc3 kernel and denx-2.6.14
>kernel. Both no luck. I also want to know something
>in this regards.
I'll be moving to 2.6.?? in a couple of weeks. Seems I'll also stike
problems there too.
Regards,
Ron
^ permalink raw reply
* RE: [PATCH] ppc32: Add support for PM82x Boards
From: Heiko Schocher @ 2005-11-21 13:27 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20051121213208.1bd0dea4.sfr@canb.auug.org.au>
Hello Stephen,
On Monday, November 21, 2005 11:32 AM Stephen Rothwell wrote:
>> the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
>> f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
>> the Microsys PM82x Boards. Verified on the PM827 Board.
>>
>> not included yet: support for MTD, I2C, RTC.
>>
>> Note: 2 previously submitted Patches are required:
>>
>> Thu, 4 Nov 2005 [PATCH] ppc32: Fix SCC Uart write problem after 2.
>> open() Tue, 3 Nov 2005 [PATCH] ppc32: fix: swallowed chars when
>> booting.
>>
>> Signed-off-by: Heiko Schocher <hs@denx.de>
>
> Unfortunately, the patch was badly wrapped by your mailer ...
Sorry, you are right. Here comes the Patch again ...
---
arch/ppc/8260_io/Kconfig | 7
arch/ppc/8260_io/fcc_enet.c | 117 ++++
arch/ppc/Kconfig | 7
arch/ppc/configs/pm82x_defconfig | 897 +++++++++++++++++++++++++++++++
arch/ppc/platforms/Makefile | 1
arch/ppc/platforms/pm82x.h | 48 ++
arch/ppc/platforms/pm82x_setup.c | 40 +
arch/ppc/syslib/m8260_setup.c | 24 +
arch/ppc/syslib/m82xx_pci.c | 15 -
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 56 ++
include/asm-ppc/cpm2.h | 2
include/asm-ppc/mpc8260.h | 4
12 files changed, 1212 insertions(+), 6 deletions(-)
diff --git a/arch/ppc/8260_io/Kconfig b/arch/ppc/8260_io/Kconfig
index ea9651e..0cb917d 100644
--- a/arch/ppc/8260_io/Kconfig
+++ b/arch/ppc/8260_io/Kconfig
@@ -23,6 +23,10 @@ config FCC1_ENET
help
Use CPM2 fast Ethernet controller 1 to drive Ethernet (default).
+config DB_CR826_J30x_ON
+ bool " DB CR826 Legacy Jumper ON"
+ depends on PM82X
+
config FCC2_ENET
bool "Ethernet on FCC2"
depends on FEC_ENET
@@ -59,6 +63,9 @@ config FCC_DM9131
config FCC_DM9161
bool "DM9161"
+config FCC_AMD79C873
+ bool "AMD79C873"
+
config FCC_GENERIC_PHY
bool "Generic"
endchoice
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
index 4edeede..2f67f5b 100644
--- a/arch/ppc/8260_io/fcc_enet.c
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -202,8 +202,18 @@ static int fcc_enet_set_mac_address(stru
#define PC_F1RXCLK PC_CLK(F1_RXCLK)
#define PC_F1TXCLK PC_CLK(F1_TXCLK)
+#if defined(CONFIG_PM82X)
+#ifndef CONFIG_DB_CR826_J30x_ON
+#define CMX1_CLK_ROUTE ((uint)0x35000000)
+#define CMX1_CLK_MASK ((uint)0x7f000000)
+#else
+#define CMX1_CLK_ROUTE ((uint)0x37000000)
+#define CMX1_CLK_MASK ((uint)0x7f000000)
+#endif
+#else
#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS(F1_TXCLK))
#define CMX1_CLK_MASK ((uint)0xff000000)
+#endif
#define PC_F2RXCLK PC_CLK(F2_RXCLK)
#define PC_F2TXCLK PC_CLK(F2_TXCLK)
@@ -297,6 +307,14 @@ static int fcc_enet_set_mac_address(stru
#elif defined(CONFIG_EST8260) || defined(CONFIG_ADS8260) || defined(CONFIG_PQ2FADS)
#define PC_MDIO ((uint)0x00400000)
#define PC_MDCK ((uint)0x00200000)
+#elif defined (CONFIG_PM82X)
+#ifndef CONFIG_DB_CR826_J30x_ON
+#define PC_MDIO ((uint)0x00000080) /* MDIO on PC24 */
+#define PC_MDCK ((uint)0x00000100) /* MDCK on PC23 */
+#else
+#define PC_MDIO ((uint)0x00000100) /* MDIO on PA23 */
+#define PC_MDCK ((uint)0x00000200) /* MDCK on PA22 */
+#endif /* CONFIG_DB_CR826_J30x_ON */
#else
#define PC_MDIO ((uint)0x00000004)
#define PC_MDCK ((uint)0x00000020)
@@ -875,6 +893,28 @@ static void mii_parse_anar(uint mii_reg,
fep->phy_status = s;
}
+#ifdef CONFIG_FCC_AMD79C873
+/* Some boards don't have the MDIRQ line connected (PM82x is such a board) */
+
+static void mii_waitfor_anc(uint mii_reg, struct net_device *dev)
+{
+ struct fcc_enet_private *fep;
+ int regval;
+ int i;
+
+ fep = dev->priv;
+ regval = mk_mii_read(MII_BMSR) | (fep->phy_addr << 23);
+
+ for (i = 0; i < 1000; i++) {
+ if (mii_send_receive(fep->fip, regval) & 0x20)
+ return;
+ udelay(10000);
+ }
+
+ printk("%s: autonegotiation timeout\n", dev->name);
+}
+#endif
+
/* ------------------------------------------------------------------------- */
/* Generic PHY support. Should work for all PHYs, but does not support link
* change interrupts.
@@ -1150,6 +1190,72 @@ static phy_info_t phy_info_qs6612 = {
#endif /* CONFIG_FEC_QS6612 */
+/* ------------------------------------------------------------------------- */
+/* The AMD Am79C873 PHY is on PM82x */
+
+#ifdef CONFIG_FCC_AMD79C873
+
+#define MII_79C873_IER 17 /* Interrupt Enable Register */
+#define MII_79C873_DR 18 /* Diagnostic Register */
+
+static void mii_parse_79c873_cr(uint mii_reg, struct net_device *dev)
+{
+ volatile struct fcc_enet_private *fep = dev->priv;
+ uint s = fep->phy_status;
+
+ s &= ~(PHY_STAT_SPMASK);
+
+ if (mii_reg & 0x2000) {
+ if (mii_reg & 0x0100)
+ s |= PHY_STAT_100FDX;
+ else
+ s |= PHY_STAT_100HDX;
+ } else {
+ if (mii_reg & 0x0100)
+ s |= PHY_STAT_10FDX;
+ else
+ s |= PHY_STAT_10HDX;
+ }
+
+ fep->phy_status = s;
+}
+
+static phy_info_t phy_info_79c873 = {
+ 0x00181b80,
+ "AMD79C873",
+
+ (const phy_cmd_t []) { /* config */
+ { mk_mii_read(MII_BMCR), mii_parse_cr },
+ { mk_mii_read(MII_ADVERTISE), mii_parse_anar },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* startup */
+#if 0
+ { mk_mii_write(MII_79C873_IER, 0xff00), NULL },
+#endif
+ { mk_mii_write(MII_BMCR, 0x1200), NULL }, /* autonegotiate */
+#ifdef CONFIG_PM82X
+ { mk_mii_read(MII_BMSR), mii_waitfor_anc },
+#endif
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* ack_int */
+ /* read SR twice: to acknowledge and to get link status */
+ { mk_mii_read(MII_BMSR), mii_parse_sr },
+ { mk_mii_read(MII_BMSR), mii_parse_sr },
+
+ /* find out the current link parameters */
+
+ { mk_mii_read(MII_BMCR), mii_parse_79c873_cr },
+ { mk_mii_end, }
+ },
+ (const phy_cmd_t []) { /* shutdown - disable interrupts */
+ { mk_mii_write(MII_79C873_IER, 0x0000), NULL },
+ { mk_mii_end, }
+ },
+};
+
+#endif /* CONFIG_FCC_AMD79C873 */
/* ------------------------------------------------------------------------- */
/* The Davicom DM9131 is used on the HYMOD board */
@@ -1381,6 +1487,10 @@ static phy_info_t *phy_info[] = {
&phy_info_dm9161,
#endif /* CONFIG_FCC_DM9161 */
+#ifdef CONFIG_FCC_AMD79C873
+ &phy_info_79c873,
+#endif /* CONFIG_FCC_AMD79C873 */
+
#ifdef CONFIG_FCC_GENERIC_PHY
/* Generic PHY support. This must be the last PHY in the table.
* It will be used to support any PHY that doesn't match a previous
@@ -1847,8 +1957,10 @@ init_fcc_ioports(fcc_info_t *fip, volati
#ifdef CONFIG_USE_MDIO
/* ....and the MII serial clock/data.
*/
+#ifndef CONFIG_PM82X
io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck);
io->iop_podrc &= ~(fip->fc_mdio | fip->fc_mdck);
+#endif
io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck);
io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck);
#endif /* CONFIG_USE_MDIO */
@@ -2380,6 +2492,11 @@ fcc_enet_open(struct net_device *dev)
schedule();
mii_do_cmd(dev, fep->phy->startup);
+#ifdef CONFIG_PM82X
+ /* Read the autonegotiation results */
+ mii_do_cmd(dev, fep->phy->ack_int);
+ mii_do_cmd(dev, phy_cmd_relink);
+#endif /* CONFIG_PM82X */
netif_start_queue(dev);
return 0; /* Success */
}
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 8fa51b0..1add0a9 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -667,6 +667,11 @@ config TQM8260
End of Life: not yet :-)
URL: <http://www.denx.de/PDF/TQM82xx_SPEC_Rev005.pdf>
+config PM82X
+ bool "PM82X"
+ help
+ This option enables support for the MicroSys PM82x evaluation boards.
+
config ADS8272
bool "ADS8272"
@@ -723,7 +728,7 @@ config PPC_MPC52xx
config 8260
bool "CPM2 Support" if WILLOW
depends on 6xx
- default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS
+ default y if TQM8260 || RPX8260 || EST8260 || SBS8260 || SBC82xx || PQ2FADS || PM82X
help
The MPC8260 is a typical embedded CPU made by Motorola. Selecting
this option means that you wish to build a kernel for a machine with
diff --git a/arch/ppc/configs/pm82x_defconfig b/arch/ppc/configs/pm82x_defconfig
new file mode 100644
index 0000000..13f0e8a
--- /dev/null
+++ b/arch/ppc/configs/pm82x_defconfig
@@ -0,0 +1,897 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14-rc3
+# Mon Oct 17 12:21:11 2005
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Processor
+#
+CONFIG_6xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+CONFIG_PPC_FPU=y
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+CONFIG_EMBEDDEDBOOT=y
+CONFIG_PPC_STD_MMU=y
+
+#
+# Platform options
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+# CONFIG_APUS is not set
+# CONFIG_KATANA is not set
+# CONFIG_WILLOW is not set
+# CONFIG_CPCI690 is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_CHESTNUT is not set
+# CONFIG_SPRUCE is not set
+# CONFIG_HDPU is not set
+# CONFIG_EV64260 is not set
+# CONFIG_LOPEC is not set
+# CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
+# CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
+# CONFIG_SANDPOINT is not set
+# CONFIG_RADSTONE_PPC7D is not set
+# CONFIG_PAL4 is not set
+# CONFIG_GEMINI is not set
+# CONFIG_EST8260 is not set
+# CONFIG_SBC82xx is not set
+# CONFIG_SBS8260 is not set
+# CONFIG_RPX8260 is not set
+# CONFIG_TQM8260 is not set
+CONFIG_PM82X=y
+# CONFIG_ADS8272 is not set
+# CONFIG_PQ2FADS is not set
+# CONFIG_LITE5200 is not set
+# CONFIG_MPC834x_SYS is not set
+# CONFIG_EV64360 is not set
+CONFIG_8260=y
+CONFIG_CPM2=y
+# CONFIG_PC_KEYBOARD is not set
+# CONFIG_SMP is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_8260=y
+# CONFIG_8260_PCI9 is not set
+CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+CONFIG_NFTL=y
+# CONFIG_NFTL_RW is not set
+# CONFIG_INFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_8=y
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+# CONFIG_MTD_CFI_I1 is not set
+# CONFIG_MTD_CFI_I2 is not set
+CONFIG_MTD_CFI_I4=y
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_SBC8240 is not set
+CONFIG_MTD_PM82X=y
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_DISKONCHIP=y
+# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0
+# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_LBD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+CONFIG_EEPRO100=y
+# CONFIG_E100 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_CPM=y
+CONFIG_SERIAL_CPM_CONSOLE=y
+CONFIG_SERIAL_CPM_SCC1=y
+CONFIG_SERIAL_CPM_SCC2=y
+CONFIG_SERIAL_CPM_SCC3=y
+CONFIG_SERIAL_CPM_SCC4=y
+CONFIG_SERIAL_CPM_SMC1=y
+CONFIG_SERIAL_CPM_SMC2=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+CONFIG_I2C_MPC8260=y
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+CONFIG_SENSORS_PCF8563=y
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+# CONFIG_SCC_ENET is not set
+CONFIG_FEC_ENET=y
+CONFIG_USE_MDIO=y
+
+#
+# CPM2 Options
+#
+CONFIG_FCC1_ENET=y
+# CONFIG_DB_CR826_J30x_ON is not set
+# CONFIG_FCC2_ENET is not set
+# CONFIG_FCC3_ENET is not set
+# CONFIG_FCC_LXT970 is not set
+CONFIG_FCC_LXT971=y
+# CONFIG_FCC_QS6612 is not set
+# CONFIG_FCC_DM9131 is not set
+# CONFIG_FCC_DM9161 is not set
+# CONFIG_FCC_AMD79C873 is not set
+# CONFIG_FCC_GENERIC_PHY is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC32 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC16=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_KGDB_CONSOLE is not set
+# CONFIG_XMON is not set
+# CONFIG_BDI_SWITCH is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7c5cdab..becaed3 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_bac
obj-$(CONFIG_PREP_RESIDUAL) += residual.o
obj-$(CONFIG_PQ2ADS) += pq2ads.o
obj-$(CONFIG_TQM8260) += tqm8260_setup.o
+obj-$(CONFIG_PM82X) += pm82x_setup.o
obj-$(CONFIG_CPCI690) += cpci690.o
obj-$(CONFIG_EV64260) += ev64260.o
obj-$(CONFIG_CHESTNUT) += chestnut.o
diff --git a/arch/ppc/platforms/pm82x.h b/arch/ppc/platforms/pm82x.h
new file mode 100644
index 0000000..ee12e1d
--- /dev/null
+++ b/arch/ppc/platforms/pm82x.h
@@ -0,0 +1,48 @@
+/*
+ * PM82X board specific definitions
+ *
+ * Copyright (c) 2005 Heiko Schocher (hs@denx.de)
+ */
+
+#ifndef __MACH_PM82X_H
+#define __MACH_PM82X_H
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+#if defined(CONFIG_PCI)
+/* #include <platforms/m8260_pci.h> */
+#endif
+
+#define CPM_MAP_ADDR ((uint)0xF0000000)
+#define I2C_ADDR_RTC 0x51
+
+/* For our show_cpuinfo hooks. */
+#define CPUINFO_VENDOR "Microsys"
+#define CPUINFO_MACHINE "PM82x PowerPC"
+
+#if defined (CONFIG_MTD_NAND_DISKONCHIP)
+#define BOOTROM_RESTART_ADDR ((uint)0x40000100)
+#else
+#define BOOTROM_RESTART_ADDR ((uint)0xFF800100)
+#endif
+
+/* PPC Sys identification */
+#define BOARD_CHIP_NAME "8250"
+
+#ifdef CONFIG_PCI
+/* PCI interrupt controller */
+#define PCI_INT_STAT_REG 0xF8200000
+#define PCI_INT_MASK_REG 0xF8200004
+#define PIRQA (NR_CPM_INTS + 0)
+#define PIRQB (NR_CPM_INTS + 1)
+#define PIRQC (NR_CPM_INTS + 2)
+#define PIRQD (NR_CPM_INTS + 3)
+
+#define PCI_INT_TO_SIU SIU_INT_IRQ2
+
+#endif /* CONFIG_PCI */
+
+
+#endif /* __MACH_PM82X_H */
diff --git a/arch/ppc/platforms/pm82x_setup.c b/arch/ppc/platforms/pm82x_setup.c
new file mode 100644
index 0000000..dd8ea88
--- /dev/null
+++ b/arch/ppc/platforms/pm82x_setup.c
@@ -0,0 +1,40 @@
+/*
+ * arch/ppc/platforms/pm82x_setup.c
+ *
+ * PM82X platform support
+ *
+ * Author: Heiko Schocher <hs@denx.de>
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/init.h>
+
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/machdep.h>
+
+static int
+pm82x_set_rtc_time(unsigned long time)
+{
+ ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt = time;
+ ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcntsc = 0x3;
+ return(0);
+}
+
+static unsigned long
+pm82x_get_rtc_time(void)
+{
+ return ((cpm2_map_t *)CPM_MAP_ADDR)->im_sit.sit_tmcnt;
+}
+
+void __init
+m82xx_board_init(void)
+{
+ /* Anything special for this platform */
+ ppc_md.set_rtc_time = pm82x_set_rtc_time;
+ ppc_md.get_rtc_time = pm82x_get_rtc_time;
+}
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 76a2aa4..f4b0f3a 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -51,6 +51,16 @@ m8260_setup_arch(void)
/* Reset the Communication Processor Module. */
cpm2_reset();
+
+#ifdef CONFIG_PM82X
+ /* On PM82x BRG1 is not initialized by the firmware (as the console
+ * is on SMC2). We initialize it here to avoid "realtime clock stuck"
+ * messages. Later on, when the RTC driver loads up, it re-installs
+ * its own handlers.
+ */
+ cpm_setbrg(0, 9600);
+#endif /* CONFIG_PM82X */
+
#ifdef CONFIG_8260_PCI9
/* Initialise IDMA for PCI erratum workaround */
idma_pci9_init();
@@ -156,9 +166,9 @@ m8260_show_cpuinfo(struct seq_file *m)
"core clock\t: %u MHz\n"
"CPM clock\t: %u MHz\n"
"bus clock\t: %u MHz\n",
- CPUINFO_VENDOR, CPUINFO_MACHINE, bp->bi_memsize,
- bp->bi_baudrate, bp->bi_intfreq / 1000000,
- bp->bi_cpmfreq / 1000000, bp->bi_busfreq / 1000000);
+ CPUINFO_VENDOR, CPUINFO_MACHINE, (unsigned int) bp->bi_memsize,
+ (int) bp->bi_baudrate, (unsigned int) bp->bi_intfreq / 1000000,
+ (unsigned int) bp->bi_cpmfreq / 1000000, (unsigned int) bp->bi_busfreq / 1000000);
return 0;
}
@@ -176,7 +186,15 @@ m8260_init_IRQ(void)
/* Initialize the default interrupt mapping priorities,
* in case the boot rom changed something on us.
*/
+#ifndef CONFIG_PM82X
cpm2_immr->im_intctl.ic_siprr = 0x05309770;
+ cpm2_immr->im_intctl.ic_scprrh = 0x05309770;
+ cpm2_immr->im_intctl.ic_scprrl = 0x05309770;
+#else
+ cpm2_immr->im_intctl.ic_siprr = 0x0530b370;
+ cpm2_immr->im_intctl.ic_scprrh = 0x0530b370;
+ cpm2_immr->im_intctl.ic_scprrl = 0x0530b370;
+#endif
#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
/* Initialize stuff for the 82xx CPLD IC and install demux */
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index 1d1c395..5af560e 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -300,6 +300,19 @@ pq2ads_setup_pci(struct pci_controller *
}
+void m8260_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev) {
+#ifdef CONFIG_PM82X
+ if (dev->bus->number == 0 && (dev->devfn & ~0x7) == (0xD << 3)) {
+ dev->irq = SIU_INT_IRQ5;
+ }
+#endif
+ }
+}
+
void __init pq2_find_bridges(void)
{
extern int pci_assign_all_buses;
@@ -377,7 +390,7 @@ void __init pq2_find_bridges(void)
hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
ppc_md.pci_map_irq = pq2pci_map_irq;
- ppc_md.pcibios_fixup = NULL;
+ ppc_md.pcibios_fixup = m8260_pcibios_fixup;
ppc_md.pcibios_fixup_bus = NULL;
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53e..39776bc 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -95,8 +95,13 @@ void smc1_lineif(struct uart_cpm_port *p
io->iop_pdird &= ~0x00800000;
io->iop_psord &= ~0x00c00000;
+#if defined(CONFIG_PM82X)
+ /* Wire BRG7 to SMC1 */
+ cpm2_immr->im_cpmux.cmx_smr &= 0x1f;
+#else
/* Wire BRG1 to SMC1 */
cpm2_immr->im_cpmux.cmx_smr &= 0x0f;
+#endif
pinfo->brg = 1;
}
@@ -104,14 +109,29 @@ void smc2_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ /* SMC2 is only on port A */
+ io->iop_ppard |= 0x08000000;
+ io->iop_pdird &= ~0x08000000;
+ io->iop_psord |= 0x08000000;
+ io->iop_pparc |= 0x00010000;
+ io->iop_pdirc |= 0x00010000;
+ io->iop_psorc &= ~0x00010000;
+#else
/* SMC2 is only on port A */
io->iop_ppara |= 0x00c00000;
io->iop_pdira |= 0x00400000;
io->iop_pdira &= ~0x00800000;
io->iop_psora &= ~0x00c00000;
+#endif
+#if defined(CONFIG_PM82X)
+ /* Wire BRG8 to SMC2 */
+ cpm2_immr->im_cpmux.cmx_smr &= 0xf1;
+#else
/* Wire BRG2 to SMC2 */
cpm2_immr->im_cpmux.cmx_smr &= 0xf0;
+#endif
pinfo->brg = 2;
}
@@ -119,12 +139,22 @@ void scc1_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ io->iop_ppard |= 0x00000001; /* Rx */
+ io->iop_pparb |= 0x00000008; /* Tx */
+
+ io->iop_psord &= ~0x00000001; /* Rx */
+ io->iop_psorb |= 0x00000008; /* Tx */
+ io->iop_pdird &= ~0x00000001; /* Rx */
+ io->iop_pdirb |= 0x00000008; /* Tx */
+#else
/* Use Port D for SCC1 instead of other functions. */
io->iop_ppard |= 0x00000003;
io->iop_psord &= ~0x00000001; /* Rx */
io->iop_psord |= 0x00000002; /* Tx */
io->iop_pdird &= ~0x00000001; /* Rx */
io->iop_pdird |= 0x00000002; /* Tx */
+#endif
/* Wire BRG1 to SCC1 */
cpm2_immr->im_cpmux.cmx_scr &= 0x00ffffff;
@@ -149,6 +179,14 @@ void scc2_lineif(struct uart_cpm_port *p
io->iop_psord &= ~0x00000010; /* Tx */
io->iop_pdird &= ~0x00000008; /* Rx */
io->iop_pdird |= 0x00000010; /* Tx */
+#elif defined(CONFIG_PM82X)
+ volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ io->iop_pparb |= 0x00010000; /* Rx */
+ io->iop_pdirb &= ~0x00010000;
+ io->iop_psorb &= ~0x00010000;
+ io->iop_ppard |= 0x00000010; /* Tx */
+ io->iop_pdird |= 0x00000010;
+ io->iop_psord &= ~0x00000010;
#else
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
@@ -165,12 +203,21 @@ void scc2_lineif(struct uart_cpm_port *p
void scc3_lineif(struct uart_cpm_port *pinfo)
{
+#if defined(CONFIG_PM82X)
+ volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+ io->iop_pparb |= 0x00820000; /* Rx */
+ io->iop_pdirb &= ~0x00020000;
+ io->iop_psorb &= ~0x00020000;
+ io->iop_pdirb |= 0x00800000; /* Tx */
+ io->iop_psorb |= 0x00800000;
+#else
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
io->iop_psorb |= 0x00880000;
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
+#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xffff00ff;
cpm2_immr->im_cpmux.cmx_scr |= 0x00001200;
pinfo->brg = 3;
@@ -180,10 +227,19 @@ void scc4_lineif(struct uart_cpm_port *p
{
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
+#if defined(CONFIG_PM82X)
+ io->iop_ppard |= 0x00000200; /* Rx */
+ io->iop_pdird &= ~0x00000200;
+ io->iop_psord &= ~0x00000200;
+ io->iop_ppard |= 0x00000400; /* Tx */
+ io->iop_pdird |= 0x00000400;
+ io->iop_psord &= ~0x00000400;
+#else
io->iop_ppard |= 0x00000600;
io->iop_psord &= ~0x00000600; /* Tx/Rx */
io->iop_pdird &= ~0x00000200; /* Rx */
io->iop_pdird |= 0x00000400; /* Tx */
+#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xffffff00;
cpm2_immr->im_cpmux.cmx_scr |= 0x0000001b;
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
index 43d2ebb..0e7a03c 100644
--- a/include/asm-ppc/cpm2.h
+++ b/include/asm-ppc/cpm2.h
@@ -181,7 +181,7 @@ typedef struct cpm_buf_desc {
*/
#define PROFF_SMC1 (0)
#define PROFF_SMC2 (64)
-
+#define PROFF_I2C ((16 * 1024) - 64)
/* Define enough so I can at least use the serial port as a UART.
*/
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 3214526..501ea8e 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -36,6 +36,10 @@
#include <platforms/tqm8260.h>
#endif
+#ifdef CONFIG_PM82X
+#include <platforms/pm82x.h>
+#endif
+
#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS)
#include <platforms/pq2ads.h>
#endif
\f
!-------------------------------------------------------------flip-
^ permalink raw reply related
* [PATCH 1/3] ppc32: Fix a few issues in Yucca PCIe functionality
From: Ruslan V. Sushko @ 2005-11-21 14:25 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 412 bytes --]
This patch includes following changes:
1) Fix wrong PCIe config space address calculation for slot #3 (Using an
signed integer for port numbering will cause wrong address accessing)
2) Fix the PCI bus numbering assignment. This will be an issues if more
than one PCI card is inserted.
3) Add verbose error checking.
4) Remove commented or unused lines.
Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>
[-- Attachment #2: yucca_pcie_fix.patch --]
[-- Type: text/x-patch, Size: 7605 bytes --]
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
--- a/arch/ppc/platforms/4xx/yucca.c
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -240,13 +240,9 @@ yucca_setup_hoses(void)
{
struct pci_controller *hose;
char name[20];
+ int bus_no = 0;
int i;
- if (0 && ppc440spe_init_pcie()) {
- printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
- return;
- }
-
for (i = 0; i <= 2; ++i) {
if (!yucca_pcie_card_present(i))
continue;
@@ -280,12 +276,14 @@ yucca_setup_hoses(void)
IORESOURCE_MEM,
name);
- hose->first_busno = 0;
- hose->last_busno = 15;
+ hose->first_busno = bus_no;
+ hose->last_busno = 0xFF;
hose_type[hose->index] = HOSE_PCIE0 + i;
ppc440spe_setup_pcie(hose, i);
hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+ bus_no = hose->last_busno + 1;
+ printk(KERN_INFO "%s: resources allocated\n", name);
}
ppc_md.pci_swizzle = common_swizzle;
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
--- a/arch/ppc/syslib/ppc440spe_pcie.c
+++ b/arch/ppc/syslib/ppc440spe_pcie.c
@@ -47,8 +47,6 @@ pcie_read_config(struct pci_bus *bus, un
break;
}
- if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
-
return PCIBIOS_SUCCESSFUL;
}
@@ -93,9 +91,10 @@ enum {
LNKW_X8 = 0x8
};
-static void check_error(void)
+static int check_error(void)
{
u32 valPE0, valPE1, valPE2;
+ int err = 0;
/* SDR0_PEGPLLLCT1 reset */
if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
@@ -111,6 +110,7 @@ static void check_error(void)
!(valPE1 & 0x01000000) ||
!(valPE2 & 0x01000000)) {
printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n");
+ err = -1;
}
/* SDR0_PExRCSSET rstdl */
@@ -118,6 +118,7 @@ static void check_error(void)
!(valPE1 & 0x00010000) ||
!(valPE2 & 0x00010000)) {
printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n");
+ err = -1;
}
/* SDR0_PExRCSSET rstpyn */
@@ -132,6 +133,7 @@ static void check_error(void)
(valPE1 & 0x10000000) ||
(valPE2 & 0x10000000)) {
printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n");
+ err = -1;
}
/* SDR0_PExRCSSET rdy */
@@ -139,6 +141,7 @@ static void check_error(void)
(valPE1 & 0x00100000) ||
(valPE2 & 0x00100000)) {
printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n");
+ err = -1;
}
/* SDR0_PExRCSSET shutdown */
@@ -146,7 +149,9 @@ static void check_error(void)
(valPE1 & 0x00000100) ||
(valPE2 & 0x00000100)) {
printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n");
+ err = -1;
}
+ return err;
}
/*
@@ -157,33 +162,37 @@ int ppc440spe_init_pcie(void)
/* Set PLL clock receiver to LVPECL */
SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
- check_error();
-
- printk(KERN_INFO "PCIE initialization OK\n");
-
- if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
- printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+ if (check_error()) {
+ return -1;
+ }
+
+ if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000)) {
+ printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration "
+ "failed (0x%08x)\n",
SDR_READ(PESDR0_PLLLCT2));
+ return -1;
+ }
/* De-assert reset of PCIe PLL, wait for lock */
SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
udelay(3);
+ printk(KERN_INFO "PCIE initialization OK\n");
return 0;
}
-int ppc440spe_init_pcie_rootport(int port)
+int ppc440spe_init_pcie_rootport(u32 port)
{
static int core_init;
void __iomem *utl_base;
+ int attempts;
u32 val = 0;
- int i;
if (!core_init) {
+ if(ppc440spe_init_pcie()) {
+ return -1;
+ }
++core_init;
- i = ppc440spe_init_pcie();
- if (i)
- return i;
}
/*
@@ -254,16 +263,11 @@ int ppc440spe_init_pcie_rootport(int por
case 2: val = SDR_READ(PESDR2_RCSSTS); break;
}
- if (!(val & (1 << 20)))
- printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
- else
- printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
-
- switch (port) {
- case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
- case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
- case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
- }
+ if (val & (1 << 20)) {
+ printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n",
+ port, val);
+ return -1;
+ }
/*
* Map UTL registers at 0xc_1000_0n00
@@ -335,44 +339,47 @@ int ppc440spe_init_pcie_rootport(int por
/*
* Check for VC0 active and assert RDY.
*/
+
+ attempts = 10;
switch (port) {
case 0:
- if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
- printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ while(!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
- break;
+ break;
case 1:
- if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
- printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ while(!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printk(KERN_WARNING "PCIE1: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
break;
case 2:
- if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
- printk(KERN_WARNING "PCIE0: VC0 not active\n");
+ while(!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) {
+ if (!(attempts--)) {
+ printk(KERN_WARNING "PCIE2: VC0 not active\n");
+ return -1;
+ }
+ mdelay(1000);
+ }
SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
break;
}
-#if 0
- /* Dump all config regs */
- for (i = 0x300; i <= 0x320; ++i)
- printk("[%04x] 0x%08x\n", i, SDR_READ(i));
- for (i = 0x340; i <= 0x353; ++i)
- printk("[%04x] 0x%08x\n", i, SDR_READ(i));
- for (i = 0x370; i <= 0x383; ++i)
- printk("[%04x] 0x%08x\n", i, SDR_READ(i));
- for (i = 0x3a0; i <= 0x3a2; ++i)
- printk("[%04x] 0x%08x\n", i, SDR_READ(i));
- for (i = 0x3c0; i <= 0x3c3; ++i)
- printk("[%04x] 0x%08x\n", i, SDR_READ(i));
-#endif
-
mdelay(100);
return 0;
}
-void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
+void ppc440spe_setup_pcie(struct pci_controller *hose, u32 port)
{
void __iomem *mbase;
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
--- a/arch/ppc/syslib/ppc440spe_pcie.h
+++ b/arch/ppc/syslib/ppc440spe_pcie.h
@@ -143,7 +143,7 @@
#define PECFG_POM0LAH 0x384
int ppc440spe_init_pcie(void);
-int ppc440spe_init_pcie_rootport(int port);
-void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+int ppc440spe_init_pcie_rootport(u32 port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, u32 port);
#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
^ permalink raw reply
* [PATCH 2/3] ppc32: PCIX support for Yucca board
From: Ruslan V. Sushko @ 2005-11-21 14:26 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 103 bytes --]
This patch adds PCI-X support for Yucca board
Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>
[-- Attachment #2: yucca_pcix_support.patch --]
[-- Type: text/x-patch, Size: 9028 bytes --]
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
--- a/arch/ppc/platforms/4xx/yucca.c
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -58,6 +58,25 @@ extern bd_t __res;
static struct ibm44x_clocks clocks __initdata;
+unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = {
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ15: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ14: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ13: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ12: PCI-X slot */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ11: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ10: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ6: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ1: EXT */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: EXT */
+};
+
static void __init
yucca_calibrate_decr(void)
{
@@ -80,13 +99,83 @@ yucca_show_cpuinfo(struct seq_file *m)
return 0;
}
-static enum {
- HOSE_UNKNOWN,
+static void __init yucca_set_emacdata(void)
+{
+ struct ocp_def *def;
+ struct ocp_func_emac_data *emacdata;
+
+ /* Set phy_map, phy_mode, and mac_addr for the EMAC */
+ def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+ emacdata = def->additions;
+ emacdata->phy_map = 0x00000001; /* Skip 0x00 */
+ emacdata->phy_mode = PHY_MODE_GMII;
+ memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+}
+
+enum yucca_hoses {
HOSE_PCIX,
HOSE_PCIE0,
HOSE_PCIE1,
- HOSE_PCIE2
-} hose_type[4];
+ HOSE_PCIE2,
+ HOSE_MAX
+};
+
+static enum yucca_hoses hose_type[4];
+
+#define is_pcix_hose(_hs_) ((_hs_) == HOSE_PCIX)
+#define is_pcie_hose(_hs_) (((_hs_) >= HOSE_PCIE0) && ((_hs_) <= HOSE_PCIE2))
+#define pcie_hose_num(_hs_) ((_hs_) - HOSE_PCIE0)
+
+#define PCIX_READW(offset) \
+ (readw((void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEW(value, offset) \
+ (writew(value, (void *)((u32)pcix_reg_base+offset)))
+
+#define PCIX_WRITEL(value, offset) \
+ (writel(value, (void *)((u32)pcix_reg_base+offset)))
+
+static void __init
+ppc440spe_setup_pcix(struct pci_controller *hose)
+{
+ void *pcix_reg_base;
+
+ pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX_REG_SIZE);
+
+ /* Disable all windows */
+ PCIX_WRITEL(0, PCIX0_POM0SA);
+ PCIX_WRITEL(0, PCIX0_POM1SA);
+ PCIX_WRITEL(0, PCIX0_POM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SAH);
+ PCIX_WRITEL(0, PCIX0_PIM1SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SAH);
+
+ /*
+ * Setup 512MB PLB->PCI outbound mem window
+ * (a_n000_0000->0_n000_0000)
+ * */
+ PCIX_WRITEL(0x0000000d, PCIX0_POM0LAH);
+ PCIX_WRITEL(hose->mem_space.start, PCIX0_POM0LAL);
+ PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+ PCIX_WRITEL(hose->mem_space.start, PCIX0_POM0PCIAL);
+ PCIX_WRITEL(~(hose->mem_space.end - hose->mem_space.start) | 1 ,
+ PCIX0_POM0SA);
+
+ /* Setup 1GB PCI->PLB inbound memory window at 0, enable MSIs */
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+ PCIX_WRITEL(0xc0000007, PCIX0_PIM0SA);
+ PCIX_WRITEL(0xffffffff, PCIX0_PIM0SAH);
+
+ /* Enable PCIX0 I/O, Mem, and Busmaster cycles */
+ PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER, PCIX0_COMMAND);
+
+ iounmap(pcix_reg_base);
+ eieio();
+}
static inline int
yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
@@ -100,7 +189,7 @@ yucca_map_irq(struct pci_dev *dev, unsig
* A B C D
*/
{
- { 81, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */
+ { 49, -1, -1, -1 }, /* IDSEL 1 - PCIX0 Slot 0 */
};
const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
@@ -141,25 +230,16 @@ yucca_map_irq(struct pci_dev *dev, unsig
return -1;
}
-static void __init yucca_set_emacdata(void)
-{
- struct ocp_def *def;
- struct ocp_func_emac_data *emacdata;
-
- /* Set phy_map, phy_mode, and mac_addr for the EMAC */
- def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
- emacdata = def->additions;
- emacdata->phy_map = 0x00000001; /* Skip 0x00 */
- emacdata->phy_mode = PHY_MODE_GMII;
- memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
-}
-
static int __init yucca_pcie_card_present(int port)
{
void __iomem *pcie_fpga_base;
u16 reg;
pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+ if (!pcie_fpga_base) {
+ printk(KERN_ERR "FPGA remap filed\n");
+ return 0;
+ }
reg = in_be16(pcie_fpga_base + FPGA_REG1C);
iounmap(pcie_fpga_base);
@@ -240,35 +320,44 @@ yucca_setup_hoses(void)
{
struct pci_controller *hose;
char name[20];
+ enum yucca_hoses hs;
int bus_no = 0;
- int i;
- for (i = 0; i <= 2; ++i) {
- if (!yucca_pcie_card_present(i))
- continue;
-
- printk(KERN_INFO "PCIE%d: card present\n", i);
- yucca_setup_pcie_fpga_rootpoint(i);
- if (ppc440spe_init_pcie_rootport(i)) {
- printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
- continue;
- }
+ for (hs = HOSE_PCIX; hs < HOSE_MAX; ++hs) {
+ if (is_pcie_hose(hs)) {
+ if (!yucca_pcie_card_present(pcie_hose_num(hs)))
+ continue;
+
+ printk(KERN_INFO "PCIE%d: card present\n",
+ pcie_hose_num(hs));
+
+ yucca_setup_pcie_fpga_rootpoint(pcie_hose_num(hs));
+ if (ppc440spe_init_pcie_rootport(pcie_hose_num(hs))) {
+ printk(KERN_ERR "PCIE%d: initialization "
+ "failed\n", pcie_hose_num(hs));
+ continue;
+ }
+ }
hose = pcibios_alloc_controller();
+
if (!hose)
return;
- sprintf(name, "PCIE%d host bridge", i);
+ sprintf(name, "PCI%s%d host bridge",
+ is_pcix_hose(hs) ? "X" : "E",
+ is_pcie_hose(hs) ? pcie_hose_num(hs) : 0
+ );
pci_init_resource(&hose->io_resource,
YUCCA_PCIX_LOWER_IO,
YUCCA_PCIX_UPPER_IO,
IORESOURCE_IO,
name);
- hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
- i * YUCCA_PCIE_MEM_SIZE;
+ hose->mem_space.start = YUCCA_PCIX_LOWER_MEM +
+ hs * YUCCA_PCIX_MEM_SIZE;
hose->mem_space.end = hose->mem_space.start +
- YUCCA_PCIE_MEM_SIZE - 1;
+ YUCCA_PCIX_MEM_SIZE - 1;
pci_init_resource(&hose->mem_resources[0],
hose->mem_space.start,
@@ -278,9 +367,24 @@ yucca_setup_hoses(void)
hose->first_busno = bus_no;
hose->last_busno = 0xFF;
- hose_type[hose->index] = HOSE_PCIE0 + i;
+ hose_type[hose->index] = hs;
+
+ if (is_pcix_hose(hs)) {
+ hose->io_space.start = YUCCA_PCIX_LOWER_IO;
+ hose->io_space.end = YUCCA_PCIX_UPPER_IO;
+ isa_io_base =
+ (unsigned long)
+ ioremap64(PCIX0_IO_BASE, PCIX_IO_SIZE);
+ hose->io_base_virt = (void *)isa_io_base;
+
+ ppc440spe_setup_pcix(hose);
+
+ setup_indirect_pci(hose, PCIX0_CFGA, PCIX0_CFGD);
+ hose->set_cfg_type = 1;
+ } else {
+ ppc440spe_setup_pcie(hose, pcie_hose_num(hs));
+ }
- ppc440spe_setup_pcie(hose, i);
hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
bus_no = hose->last_busno + 1;
printk(KERN_INFO "%s: resources allocated\n", name);
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -557,12 +557,19 @@
#define PCIX1_CFGD 0x1ec00004UL
#define PCIX2_CFGD 0x2ec00004UL
+#if defined (CONFIG_440SPE)
+#define PCIX0_IO_BASE 0x0000000C08000000ULL
+#else
#define PCIX0_IO_BASE 0x0000000908000000ULL
#define PCIX1_IO_BASE 0x0000000908000000ULL
#define PCIX2_IO_BASE 0x0000000908000000ULL
+#endif
+
#define PCIX_IO_SIZE 0x00010000
-#ifdef CONFIG_440SP
+#if defined (CONFIG_440SPE)
+#define PCIX0_REG_BASE 0x0000000c0ec80000ULL
+#elif defined(CONFIG_440SP)
#define PCIX0_REG_BASE 0x000000090ec80000ULL
#else
#define PCIX0_REG_BASE 0x000000020ec80000ULL
^ permalink raw reply
* [PATCH 3/3] ppc32: MTD support for Yucca board
From: Ruslan V. Sushko @ 2005-11-21 14:26 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 141 bytes --]
Following patch adds MTD support for Yucca embedded memories(Flashes,
SRAM, FRAM).
Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>
[-- Attachment #2: yucca_mtd_support.patch --]
[-- Type: text/x-patch, Size: 14582 bytes --]
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
--- a/arch/ppc/platforms/4xx/yucca.h
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -32,12 +32,88 @@
/* External timer clock frequency */
#define YUCCA_TMR_CLK 25000000
+/* System Memory map (physical address, not effective address)
+ * Flash and other devices via EBC.
+ *
+ * This should be the same mapping as done by PIBS in the
+ * (not mandatory but ease code reading between two codes)
+ * xxx/boardlib/ebc.c
+ *
+ * depending of the switch setting off the board, the location of devices
+ * in the address map are not the same:
+ */
+/* Common definitions */
+
+#define BOARD_SMALL_FLASH_SIZE 0x100000 /* 1M */
+#define BOARD_FRAM_SIZE 0x8000
+#define BOARD_SRAM_SIZE 0x100000
+#define BOARD_OPER_FLASH_SIZE 0x400000 /* 4M */
+
+
+/* Configuration 1:
+ * the small flash and sram are placed on top (CS0)
+ * the Large flash is placed below (CS2)
+ * The FPGA and FRAM at the end (CS1)
+ * xxxx----xxxx----
+ */
+#define BOARD_CONF1_SMALL_FLASH 0x00000004FFF00000ull
+#define BOARD_CONF1_FRAM 0x00000004FF000000ull
+#define BOARD_CONF1_OPER_FLASH 0x00000004E7C00000ull
+#define BOARD_CONF1_SRAM 0x00000004E7000000ull
+
+/* Configuration 2:
+ * the small flash and sram are placed on top (CS0)
+ * but now sram before smal flash
+ * the Large flash is placed below (no change) (CS2)
+ * The FPGA and FRAM stay in same place. (CS1)
+ * xxxx----xxxx----
+ */
+#define BOARD_CONF2_OPER_FLASH 0x00000004FFC00000ull
+#define BOARD_CONF2_SRAM 0x00000004FF000000ull
+#define BOARD_CONF2_SMALL_FLASH 0x00000004E7F00000ull
+#define BOARD_CONF2_FRAM 0x00000004E7000000ull
+
+/* Configuration 3:
+ * the Large flash is placed on top, (CS0)
+ * the small flash and sram are placed below. (CS2)
+ * The FPGA and FRAM stay in same place. (CS1)
+ * xxxx----xxxx----
+ */
+#define BOARD_CONF3_SRAM 0x00000004FFF00000ull
+#define BOARD_CONF3_OPER_FLASH 0x00000004FF000000ull
+#define BOARD_CONF3_SMALL_FLASH 0x00000004E7F00000ull
+#define BOARD_CONF3_FRAM 0x00000004E7000000ull
+
/*
* FPGA registers
*/
#define YUCCA_FPGA_REG_BASE 0x00000004e2000000ULL
#define YUCCA_FPGA_REG_SIZE 0x24
+#define FPGA_REG10 0x10 /* Ethernet/Reset/Boot
+ configs */
+#define FPGA_REG10_ETH_MODE10 0x8000
+#define FPGA_REG10_ETH_MODE100 0x4000
+#define FPGA_REG10_ETH_MODE1000 0x2000
+#define FPGA_REG10_ETH_FORCE_DUPLEX 0x1000
+#define FPGA_REG10_LOG_RESET_ETHERNET 0x0800
+#define FPGA_REG10_ETH_AUTO_NEGO 0x0400
+#define FPGA_REG10_LOG_INT_ETH 0x0200
+#define FPGA_REG10_LOG_RESET_HISR 0x0080
+#define FPGA_REG10_LOG_RESET_DISPLAY 0x0040
+#define FPGA_REG10_LOG_RESET_SDRAM 0x0020
+#define FPGA_REG10_LOG_OPBOOT 0x0010
+#define FPGA_REG10_LOG_SRAM_BOOT 0x0008
+#define FPGA_REG10_LOG_BTBOOT 0x0004
+
+/*Boot configurations */
+#define BOARD_CONFIG_MASK (0x001C)
+#define BOARD_CONFIG_1 (0x0018)
+#define BOARD_CONFIG_2 (0x000C)
+#define BOARD_CONFIG_3 (0x0014)
+#define BOARD_BOOT_OPER_FLASH(x) (((x) & BOARD_CONFIG_MASK) == \
+ BOARD_CONFIG_2)
+
#define FPGA_REG1A 0x1a
#define FPGA_REG1A_PE0_GLED 0x8000
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -339,6 +339,14 @@ config MTD_OCOTEA
Ocotea board. If you have one of these boards and would like to
use the flash chips on it, say 'Y'.
+config MTD_YUCCA
+ tristate "Flash devices mapped on IBM 440SPe Yucca"
+ depends on MTD_CFI && YUCCA
+ help
+ This enables access routines for the flash chips on the IBM 440SPe
+ Yucca board. If you have one of these boards and would like to
+ use the flash chips on it, say 'Y'.
+
config MTD_REDWOOD
tristate "CFI Flash devices mapped on IBM Redwood"
depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NETtel) += nettel.o
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
obj-$(CONFIG_MTD_EBONY) += ebony.o
obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
+obj-$(CONFIG_MTD_YUCCA) += yucca_flash.o
obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
obj-$(CONFIG_MTD_WALNUT) += walnut.o
diff --git a/drivers/mtd/maps/yucca_flash.c b/drivers/mtd/maps/yucca_flash.c
new file mode 100644
--- /dev/null
+++ b/drivers/mtd/maps/yucca_flash.c
@@ -0,0 +1,297 @@
+/*
+ * Mapping for Yucca user flash
+ *
+ * This was derived from the luan.c
+ *
+ * Ruslan Sushko <rsushko@ru.mvista.com>
+ * Matt Porter <mporter@mvista.com>
+ *
+ * Copyright (C) 2002-2005 MontaVista Software Inc.
+ * (C) Copyright IBM Corp. 2004
+ *
+ * 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 the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/config.h>
+#include <linux/version.h>
+#include <asm/io.h>
+
+static struct mtd_info *oper_flash_mtd = NULL;
+static struct mtd_info *small_flash_mtd = NULL;
+static struct mtd_info *fram_mtd = NULL;
+static struct mtd_info *sram_mtd = NULL;
+
+static struct map_info yucca_sram_map = {
+ .name = "Yucca SRAM",
+ .size = BOARD_SRAM_SIZE,
+ .bankwidth = 2,
+};
+
+static struct map_info yucca_fram_map = {
+ .name = "Yucca FRAM",
+ .size = BOARD_FRAM_SIZE,
+ .bankwidth = 1,
+};
+
+static struct map_info yucca_small_map = {
+ .name = "Yucca small flash",
+ .size = BOARD_SMALL_FLASH_SIZE,
+ .bankwidth = 1,
+};
+
+static struct map_info yucca_oper_map = {
+ .name = "Yucca Operational flash",
+ .size = BOARD_OPER_FLASH_SIZE,
+ .bankwidth = 2,
+};
+
+static struct mtd_partition yucca_sram_partitions[] = {
+ {
+ .name = "SRAM",
+ .offset = 0x0,
+ .size = 0x100000,
+ }
+};
+
+static struct mtd_partition yucca_fram_partitions[] = {
+ {
+ .name = "FRAM",
+ .offset = 0x0,
+ .size = 0x8000,
+ }
+};
+
+static struct mtd_partition yucca_small_partitions[] = {
+ {
+ .name = "U-boot",
+ .offset = 0x0,
+ .size = 0x100000,
+ }
+};
+
+static struct mtd_partition yucca_oper_partitions[] = {
+ {
+ .name = "Linux Kernel",
+ .offset = 0,
+ .size = 0x100000,
+ },
+ {
+ .name = "Free Area",
+ .offset = 0x100000,
+ .size = 0x300000,
+ }
+};
+
+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
+static void cleanup_yucca(void);
+
+
+int __init init_yucca(void)
+{
+ u16 fpga10_reg;
+ volatile u16 *fpga_adr;
+ unsigned long long small_flash_base, oper_flash_base;
+ unsigned long long sram_base, fram_base;
+ int memconfig = 0;
+ int err = 0;
+
+ fpga_adr = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+ if (!fpga_adr)
+ return -ENOMEM;
+
+
+ fpga10_reg = *((u16*)((u32)fpga_adr + FPGA_REG10));
+ iounmap(fpga_adr);
+ switch (fpga10_reg & BOARD_CONFIG_MASK) {
+ default:
+ printk("Memory config switches are invalid: "
+ "fpga10_reg= %x. Using default configuration\n",
+ fpga10_reg);
+ case BOARD_CONFIG_1:
+ memconfig = 1;
+ small_flash_base = BOARD_CONF1_SMALL_FLASH;
+ oper_flash_base = BOARD_CONF1_OPER_FLASH;
+ sram_base = BOARD_CONF1_SRAM;
+ fram_base = BOARD_CONF1_FRAM;
+ break;
+ case BOARD_CONFIG_2:
+ memconfig = 2;
+ small_flash_base = BOARD_CONF2_SMALL_FLASH;
+ oper_flash_base = BOARD_CONF2_OPER_FLASH;
+ sram_base = BOARD_CONF2_SRAM;
+ fram_base = BOARD_CONF3_FRAM;
+ break;
+ case BOARD_CONFIG_3:
+ memconfig = 3;
+ small_flash_base = BOARD_CONF3_SMALL_FLASH;
+ oper_flash_base = BOARD_CONF3_OPER_FLASH;
+ sram_base = BOARD_CONF3_SRAM;
+ fram_base = BOARD_CONF3_FRAM;
+ break;
+ }
+
+ printk("Using EBC memory configuration #%d\n", memconfig);
+
+ yucca_small_map.phys = small_flash_base;
+ yucca_small_map.virt = ioremap64(small_flash_base,
+ yucca_small_map.size);
+
+ if (!yucca_small_map.virt) {
+ printk("Failed to ioremap small flash\n");
+ err = -EIO;
+ goto ret_err;
+ }
+
+ simple_map_init(&yucca_small_map);
+
+ small_flash_mtd = do_map_probe("map_rom", &yucca_small_map);
+ if (small_flash_mtd) {
+ small_flash_mtd->owner = THIS_MODULE;
+ add_mtd_partitions(small_flash_mtd, yucca_small_partitions,
+ NB_OF(yucca_small_partitions));
+ } else {
+ printk("map probe failed for small flash\n");
+ err = -ENXIO;
+ goto ret_err;
+ }
+
+ yucca_oper_map.phys = oper_flash_base;
+ yucca_oper_map.virt = ioremap64(oper_flash_base,
+ yucca_oper_map.size);
+
+ if (!yucca_oper_map.virt) {
+ printk("Failed to ioremap oper flash\n");
+ err = -EIO;
+ goto ret_err;
+ }
+
+ simple_map_init(&yucca_oper_map);
+
+ oper_flash_mtd = do_map_probe("cfi_probe", &yucca_oper_map);
+ if (oper_flash_mtd) {
+ oper_flash_mtd->owner = THIS_MODULE;
+ add_mtd_partitions(oper_flash_mtd, yucca_oper_partitions,
+ NB_OF(yucca_oper_partitions));
+ } else {
+ printk("map probe failed for oper flash\n");
+ err = -ENXIO;
+ goto ret_err;
+ }
+
+ yucca_sram_map.phys = sram_base;
+ yucca_sram_map.virt = ioremap64(sram_base,
+ yucca_sram_map.size);
+
+ if (!yucca_sram_map.virt) {
+ printk("Failed to ioremap SRAM\n");
+ err = -EIO;
+ goto ret_err;
+ }
+
+ simple_map_init(&yucca_sram_map);
+
+ sram_mtd = do_map_probe("map_ram", &yucca_sram_map);
+ if (sram_mtd) {
+ sram_mtd->owner = THIS_MODULE;
+ add_mtd_partitions(sram_mtd, yucca_sram_partitions,
+ NB_OF(yucca_sram_partitions));
+ } else {
+ printk("map probe failed for SRAM\n");
+ err = -ENXIO;
+ goto ret_err;
+ }
+
+ yucca_fram_map.phys = fram_base;
+ yucca_fram_map.virt = ioremap64(fram_base,
+ yucca_fram_map.size);
+
+ if (!yucca_fram_map.virt) {
+ printk("Failed to ioremap FRAM\n");
+ err = -EIO;
+ goto ret_err;
+ }
+
+ simple_map_init(&yucca_fram_map);
+
+ fram_mtd = do_map_probe("map_ram", &yucca_fram_map);
+ if (fram_mtd) {
+ fram_mtd->owner = THIS_MODULE;
+ add_mtd_partitions(fram_mtd, yucca_fram_partitions,
+ NB_OF(yucca_fram_partitions));
+ } else {
+ printk("map probe failed for FRAM\n");
+ err = -ENXIO;
+ goto ret_err;
+ }
+ return 0;
+ret_err:
+ cleanup_yucca();
+ return err;
+}
+
+static void cleanup_yucca(void)
+{
+ if (yucca_small_map.virt) {
+ iounmap((void *)yucca_small_map.virt);
+ yucca_small_map.virt = 0;
+ }
+
+ if (yucca_oper_map.virt) {
+ iounmap((void *)yucca_oper_map.virt);
+ yucca_oper_map.virt = 0;
+ }
+
+ if (yucca_fram_map.virt) {
+ iounmap((void *)yucca_fram_map.virt);
+ yucca_fram_map.virt = 0;
+ }
+
+ if (yucca_sram_map.virt) {
+ iounmap((void *)yucca_sram_map.virt);
+ yucca_sram_map.virt = 0;
+ }
+
+ if (oper_flash_mtd) {
+ del_mtd_partitions(oper_flash_mtd);
+ map_destroy(oper_flash_mtd);
+ }
+
+ if (small_flash_mtd) {
+ del_mtd_partitions(small_flash_mtd);
+ map_destroy(small_flash_mtd);
+ }
+
+ if (fram_mtd) {
+ del_mtd_partitions(fram_mtd);
+ map_destroy(fram_mtd);
+ }
+
+ if (sram_mtd) {
+ del_mtd_partitions(sram_mtd);
+ map_destroy(sram_mtd);
+ }
+
+}
+
+static void __exit rem_yucca(void)
+{
+ cleanup_yucca();
+}
+
+module_init(init_yucca);
+module_exit(rem_yucca);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ruslan V. Sushko <rsushko@ru.mvista.com>");
+MODULE_DESCRIPTION("MTD map and partitions for AMCC 440SPe Yucca board");
+
^ permalink raw reply
* Re: [PATCH 3/3] ppc32: MTD support for Yucca board
From: Vitaly Bordug @ 2005-11-21 15:02 UTC (permalink / raw)
To: Ruslan V. Sushko; +Cc: linuxppc-embedded
In-Reply-To: <1132583169.11785.44.camel@mephisto.spb.rtsoft.ru>
Guess this should come through MTD community (linux-mtd@lists.infradead.org), rebased to
the MTD tree of course.
Ruslan V. Sushko wrote:
> Following patch adds MTD support for Yucca embedded memories(Flashes,
> SRAM, FRAM).
>
>
> Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>
>
>
> ------------------------------------------------------------------------
>
> diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
> --- a/arch/ppc/platforms/4xx/yucca.h
> +++ b/arch/ppc/platforms/4xx/yucca.h
> @@ -32,12 +32,88 @@
> /* External timer clock frequency */
> #define YUCCA_TMR_CLK 25000000
>
> +/* System Memory map (physical address, not effective address)
> + * Flash and other devices via EBC.
> + *
> + * This should be the same mapping as done by PIBS in the
> + * (not mandatory but ease code reading between two codes)
> + * xxx/boardlib/ebc.c
> + *
> + * depending of the switch setting off the board, the location of devices
> + * in the address map are not the same:
> + */
> +/* Common definitions */
> +
> +#define BOARD_SMALL_FLASH_SIZE 0x100000 /* 1M */
> +#define BOARD_FRAM_SIZE 0x8000
> +#define BOARD_SRAM_SIZE 0x100000
> +#define BOARD_OPER_FLASH_SIZE 0x400000 /* 4M */
> +
> +
> +/* Configuration 1:
> + * the small flash and sram are placed on top (CS0)
> + * the Large flash is placed below (CS2)
> + * The FPGA and FRAM at the end (CS1)
> + * xxxx----xxxx----
> + */
> +#define BOARD_CONF1_SMALL_FLASH 0x00000004FFF00000ull
> +#define BOARD_CONF1_FRAM 0x00000004FF000000ull
> +#define BOARD_CONF1_OPER_FLASH 0x00000004E7C00000ull
> +#define BOARD_CONF1_SRAM 0x00000004E7000000ull
> +
> +/* Configuration 2:
> + * the small flash and sram are placed on top (CS0)
> + * but now sram before smal flash
> + * the Large flash is placed below (no change) (CS2)
> + * The FPGA and FRAM stay in same place. (CS1)
> + * xxxx----xxxx----
> + */
> +#define BOARD_CONF2_OPER_FLASH 0x00000004FFC00000ull
> +#define BOARD_CONF2_SRAM 0x00000004FF000000ull
> +#define BOARD_CONF2_SMALL_FLASH 0x00000004E7F00000ull
> +#define BOARD_CONF2_FRAM 0x00000004E7000000ull
> +
> +/* Configuration 3:
> + * the Large flash is placed on top, (CS0)
> + * the small flash and sram are placed below. (CS2)
> + * The FPGA and FRAM stay in same place. (CS1)
> + * xxxx----xxxx----
> + */
> +#define BOARD_CONF3_SRAM 0x00000004FFF00000ull
> +#define BOARD_CONF3_OPER_FLASH 0x00000004FF000000ull
> +#define BOARD_CONF3_SMALL_FLASH 0x00000004E7F00000ull
> +#define BOARD_CONF3_FRAM 0x00000004E7000000ull
> +
> /*
> * FPGA registers
> */
> #define YUCCA_FPGA_REG_BASE 0x00000004e2000000ULL
> #define YUCCA_FPGA_REG_SIZE 0x24
>
> +#define FPGA_REG10 0x10 /* Ethernet/Reset/Boot
> + configs */
> +#define FPGA_REG10_ETH_MODE10 0x8000
> +#define FPGA_REG10_ETH_MODE100 0x4000
> +#define FPGA_REG10_ETH_MODE1000 0x2000
> +#define FPGA_REG10_ETH_FORCE_DUPLEX 0x1000
> +#define FPGA_REG10_LOG_RESET_ETHERNET 0x0800
> +#define FPGA_REG10_ETH_AUTO_NEGO 0x0400
> +#define FPGA_REG10_LOG_INT_ETH 0x0200
> +#define FPGA_REG10_LOG_RESET_HISR 0x0080
> +#define FPGA_REG10_LOG_RESET_DISPLAY 0x0040
> +#define FPGA_REG10_LOG_RESET_SDRAM 0x0020
> +#define FPGA_REG10_LOG_OPBOOT 0x0010
> +#define FPGA_REG10_LOG_SRAM_BOOT 0x0008
> +#define FPGA_REG10_LOG_BTBOOT 0x0004
> +
> +/*Boot configurations */
> +#define BOARD_CONFIG_MASK (0x001C)
> +#define BOARD_CONFIG_1 (0x0018)
> +#define BOARD_CONFIG_2 (0x000C)
> +#define BOARD_CONFIG_3 (0x0014)
> +#define BOARD_BOOT_OPER_FLASH(x) (((x) & BOARD_CONFIG_MASK) == \
> + BOARD_CONFIG_2)
> +
> #define FPGA_REG1A 0x1a
>
> #define FPGA_REG1A_PE0_GLED 0x8000
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -339,6 +339,14 @@ config MTD_OCOTEA
> Ocotea board. If you have one of these boards and would like to
> use the flash chips on it, say 'Y'.
>
> +config MTD_YUCCA
> + tristate "Flash devices mapped on IBM 440SPe Yucca"
> + depends on MTD_CFI && YUCCA
> + help
> + This enables access routines for the flash chips on the IBM 440SPe
> + Yucca board. If you have one of these boards and would like to
> + use the flash chips on it, say 'Y'.
> +
> config MTD_REDWOOD
> tristate "CFI Flash devices mapped on IBM Redwood"
> depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
> diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
> --- a/drivers/mtd/maps/Makefile
> +++ b/drivers/mtd/maps/Makefile
> @@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NETtel) += nettel.o
> obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
> obj-$(CONFIG_MTD_EBONY) += ebony.o
> obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
> +obj-$(CONFIG_MTD_YUCCA) += yucca_flash.o
> obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
> obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
> obj-$(CONFIG_MTD_WALNUT) += walnut.o
> diff --git a/drivers/mtd/maps/yucca_flash.c b/drivers/mtd/maps/yucca_flash.c
> new file mode 100644
> --- /dev/null
> +++ b/drivers/mtd/maps/yucca_flash.c
> @@ -0,0 +1,297 @@
> +/*
> + * Mapping for Yucca user flash
> + *
> + * This was derived from the luan.c
> + *
> + * Ruslan Sushko <rsushko@ru.mvista.com>
> + * Matt Porter <mporter@mvista.com>
> + *
> + * Copyright (C) 2002-2005 MontaVista Software Inc.
> + * (C) Copyright IBM Corp. 2004
> + *
> + * 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 the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/map.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/config.h>
> +#include <linux/version.h>
> +#include <asm/io.h>
> +
> +static struct mtd_info *oper_flash_mtd = NULL;
> +static struct mtd_info *small_flash_mtd = NULL;
> +static struct mtd_info *fram_mtd = NULL;
> +static struct mtd_info *sram_mtd = NULL;
> +
> +static struct map_info yucca_sram_map = {
> + .name = "Yucca SRAM",
> + .size = BOARD_SRAM_SIZE,
> + .bankwidth = 2,
> +};
> +
> +static struct map_info yucca_fram_map = {
> + .name = "Yucca FRAM",
> + .size = BOARD_FRAM_SIZE,
> + .bankwidth = 1,
> +};
> +
> +static struct map_info yucca_small_map = {
> + .name = "Yucca small flash",
> + .size = BOARD_SMALL_FLASH_SIZE,
> + .bankwidth = 1,
> +};
> +
> +static struct map_info yucca_oper_map = {
> + .name = "Yucca Operational flash",
> + .size = BOARD_OPER_FLASH_SIZE,
> + .bankwidth = 2,
> +};
> +
> +static struct mtd_partition yucca_sram_partitions[] = {
> + {
> + .name = "SRAM",
> + .offset = 0x0,
> + .size = 0x100000,
> + }
> +};
> +
> +static struct mtd_partition yucca_fram_partitions[] = {
> + {
> + .name = "FRAM",
> + .offset = 0x0,
> + .size = 0x8000,
> + }
> +};
> +
> +static struct mtd_partition yucca_small_partitions[] = {
> + {
> + .name = "U-boot",
> + .offset = 0x0,
> + .size = 0x100000,
> + }
> +};
> +
> +static struct mtd_partition yucca_oper_partitions[] = {
> + {
> + .name = "Linux Kernel",
> + .offset = 0,
> + .size = 0x100000,
> + },
> + {
> + .name = "Free Area",
> + .offset = 0x100000,
> + .size = 0x300000,
> + }
> +};
> +
> +#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
> +static void cleanup_yucca(void);
> +
> +
> +int __init init_yucca(void)
> +{
> + u16 fpga10_reg;
> + volatile u16 *fpga_adr;
> + unsigned long long small_flash_base, oper_flash_base;
> + unsigned long long sram_base, fram_base;
> + int memconfig = 0;
> + int err = 0;
> +
> + fpga_adr = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
> + if (!fpga_adr)
> + return -ENOMEM;
> +
> +
> + fpga10_reg = *((u16*)((u32)fpga_adr + FPGA_REG10));
> + iounmap(fpga_adr);
> + switch (fpga10_reg & BOARD_CONFIG_MASK) {
> + default:
> + printk("Memory config switches are invalid: "
> + "fpga10_reg= %x. Using default configuration\n",
> + fpga10_reg);
> + case BOARD_CONFIG_1:
> + memconfig = 1;
> + small_flash_base = BOARD_CONF1_SMALL_FLASH;
> + oper_flash_base = BOARD_CONF1_OPER_FLASH;
> + sram_base = BOARD_CONF1_SRAM;
> + fram_base = BOARD_CONF1_FRAM;
> + break;
> + case BOARD_CONFIG_2:
> + memconfig = 2;
> + small_flash_base = BOARD_CONF2_SMALL_FLASH;
> + oper_flash_base = BOARD_CONF2_OPER_FLASH;
> + sram_base = BOARD_CONF2_SRAM;
> + fram_base = BOARD_CONF3_FRAM;
> + break;
> + case BOARD_CONFIG_3:
> + memconfig = 3;
> + small_flash_base = BOARD_CONF3_SMALL_FLASH;
> + oper_flash_base = BOARD_CONF3_OPER_FLASH;
> + sram_base = BOARD_CONF3_SRAM;
> + fram_base = BOARD_CONF3_FRAM;
> + break;
> + }
> +
> + printk("Using EBC memory configuration #%d\n", memconfig);
> +
> + yucca_small_map.phys = small_flash_base;
> + yucca_small_map.virt = ioremap64(small_flash_base,
> + yucca_small_map.size);
> +
> + if (!yucca_small_map.virt) {
> + printk("Failed to ioremap small flash\n");
> + err = -EIO;
> + goto ret_err;
> + }
> +
> + simple_map_init(&yucca_small_map);
> +
> + small_flash_mtd = do_map_probe("map_rom", &yucca_small_map);
> + if (small_flash_mtd) {
> + small_flash_mtd->owner = THIS_MODULE;
> + add_mtd_partitions(small_flash_mtd, yucca_small_partitions,
> + NB_OF(yucca_small_partitions));
> + } else {
> + printk("map probe failed for small flash\n");
> + err = -ENXIO;
> + goto ret_err;
> + }
> +
> + yucca_oper_map.phys = oper_flash_base;
> + yucca_oper_map.virt = ioremap64(oper_flash_base,
> + yucca_oper_map.size);
> +
> + if (!yucca_oper_map.virt) {
> + printk("Failed to ioremap oper flash\n");
> + err = -EIO;
> + goto ret_err;
> + }
> +
> + simple_map_init(&yucca_oper_map);
> +
> + oper_flash_mtd = do_map_probe("cfi_probe", &yucca_oper_map);
> + if (oper_flash_mtd) {
> + oper_flash_mtd->owner = THIS_MODULE;
> + add_mtd_partitions(oper_flash_mtd, yucca_oper_partitions,
> + NB_OF(yucca_oper_partitions));
> + } else {
> + printk("map probe failed for oper flash\n");
> + err = -ENXIO;
> + goto ret_err;
> + }
> +
> + yucca_sram_map.phys = sram_base;
> + yucca_sram_map.virt = ioremap64(sram_base,
> + yucca_sram_map.size);
> +
> + if (!yucca_sram_map.virt) {
> + printk("Failed to ioremap SRAM\n");
> + err = -EIO;
> + goto ret_err;
> + }
> +
> + simple_map_init(&yucca_sram_map);
> +
> + sram_mtd = do_map_probe("map_ram", &yucca_sram_map);
> + if (sram_mtd) {
> + sram_mtd->owner = THIS_MODULE;
> + add_mtd_partitions(sram_mtd, yucca_sram_partitions,
> + NB_OF(yucca_sram_partitions));
> + } else {
> + printk("map probe failed for SRAM\n");
> + err = -ENXIO;
> + goto ret_err;
> + }
> +
> + yucca_fram_map.phys = fram_base;
> + yucca_fram_map.virt = ioremap64(fram_base,
> + yucca_fram_map.size);
> +
> + if (!yucca_fram_map.virt) {
> + printk("Failed to ioremap FRAM\n");
> + err = -EIO;
> + goto ret_err;
> + }
> +
> + simple_map_init(&yucca_fram_map);
> +
> + fram_mtd = do_map_probe("map_ram", &yucca_fram_map);
> + if (fram_mtd) {
> + fram_mtd->owner = THIS_MODULE;
> + add_mtd_partitions(fram_mtd, yucca_fram_partitions,
> + NB_OF(yucca_fram_partitions));
> + } else {
> + printk("map probe failed for FRAM\n");
> + err = -ENXIO;
> + goto ret_err;
> + }
> + return 0;
> +ret_err:
> + cleanup_yucca();
> + return err;
> +}
> +
> +static void cleanup_yucca(void)
> +{
> + if (yucca_small_map.virt) {
> + iounmap((void *)yucca_small_map.virt);
> + yucca_small_map.virt = 0;
> + }
> +
> + if (yucca_oper_map.virt) {
> + iounmap((void *)yucca_oper_map.virt);
> + yucca_oper_map.virt = 0;
> + }
> +
> + if (yucca_fram_map.virt) {
> + iounmap((void *)yucca_fram_map.virt);
> + yucca_fram_map.virt = 0;
> + }
> +
> + if (yucca_sram_map.virt) {
> + iounmap((void *)yucca_sram_map.virt);
> + yucca_sram_map.virt = 0;
> + }
> +
> + if (oper_flash_mtd) {
> + del_mtd_partitions(oper_flash_mtd);
> + map_destroy(oper_flash_mtd);
> + }
> +
> + if (small_flash_mtd) {
> + del_mtd_partitions(small_flash_mtd);
> + map_destroy(small_flash_mtd);
> + }
> +
> + if (fram_mtd) {
> + del_mtd_partitions(fram_mtd);
> + map_destroy(fram_mtd);
> + }
> +
> + if (sram_mtd) {
> + del_mtd_partitions(sram_mtd);
> + map_destroy(sram_mtd);
> + }
> +
> +}
> +
> +static void __exit rem_yucca(void)
> +{
> + cleanup_yucca();
> +}
> +
> +module_init(init_yucca);
> +module_exit(rem_yucca);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Ruslan V. Sushko <rsushko@ru.mvista.com>");
> +MODULE_DESCRIPTION("MTD map and partitions for AMCC 440SPe Yucca board");
> +
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
--
Sincerely,
Vitaly
^ permalink raw reply
* MPC8272 Fast Ethernet Controller drver
From: alexv @ 2005-11-21 15:08 UTC (permalink / raw)
To: linuxppc-dev
Hi,
my new project uses a MPC8272. but i couldn't find any good tutorial or
things like that describing the registers and all
especially about CPM,FCC.. Presently I am doing my assembly language
progamming using powerPC tutorial.
Can any one help me.
Thanks and Regards,
Alex
***************************************************************************
This message is proprietary to Future Software Limited (FSL)
and is intended solely for the use of the individual to whom it
is addressed. It may contain privileged or confidential information
and should not be circulated or used for any purpose other than for
what it is intended.
If you have received this message in error, please notify the
originator immediately. If you are not the intended recipient,
you are notified that you are strictly prohibited from using,
copying, altering, or disclosing the contents of this message.
FSL accepts no responsibility for loss or damage arising from
the use of the information transmitted by this email including
damage from virus.
***************************************************************************
^ permalink raw reply
* [PATCH] I2C: Add I2C support for the MPC8260
From: Heiko Schocher @ 2005-11-21 15:55 UTC (permalink / raw)
To: linuxppc-dev; +Cc: lm-sensors
Hello,
the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
the I2C on a MPC8260.
---
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1
drivers/i2c/busses/i2c-mpc8260.c | 617 ++++++++++++++++++++++++++++++++++++++
include/linux/i2c-algo-8260.h | 26 ++
include/linux/i2c-id.h | 3
5 files changed, 657 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 4010fe9..77f9c69 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -270,6 +270,16 @@ config I2C_MPC
This driver can also be built as a module. If so, the module
will be called i2c-mpc.
+config I2C_MPC8260
+ tristate "MPC 8260"
+ depends on I2C && PPC32
+ help
+ If you say yes to this option, support will be included for the
+ I2C interface on the MPC8260.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-m8260.
+
config I2C_NFORCE2
tristate "Nvidia nForce2, nForce3 and nForce4"
depends on I2C && PCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index f1df00f..b4d8cea 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
obj-$(CONFIG_SCx200_ACB) += scx200_acb.o
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
+obj-$(CONFIG_I2C_MPC8260) += i2c-mpc8260.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/busses/i2c-mpc8260.c b/drivers/i2c/busses/i2c-mpc8260.c
new file mode 100644
index 0000000..f1bfa51
--- /dev/null
+++ b/drivers/i2c/busses/i2c-mpc8260.c
@@ -0,0 +1,617 @@
+/*
+ * (C) Copyright 2005
+ * Heiko Schocher <hs@denx.de>
+ *
+ * This is a combined i2c adapter and algorithm driver for the
+ * MPC8260 Processor
+ *
+ * Release 0.1
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <linux/fsl_devices.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include <linux/i2c-algo-8260.h>
+#include <linux/platform_device.h>
+
+#define CPM_MAX_READ 513
+
+static wait_queue_head_t iic_wait;
+static ushort r_tbase, r_rbase;
+
+int cpm_scan = 0;
+int cpm_debug = 0;
+
+struct mpc_i2c {
+ u32 interrupt;
+ wait_queue_head_t queue;
+ struct i2c_adapter adap;
+ int irq;
+ u32 flags;
+ struct i2c_algo_8260_data *data;
+};
+
+static struct i2c_algo_8260_data pm82x_data;
+
+static void
+mpc8260_iic_init(struct i2c_algo_8260_data *data)
+{
+ volatile cpm_cpm2_t *cp;
+ volatile cpm2_map_t *immap;
+
+ cp = cpmp; /* Get pointer to Communication Processor */
+ immap = (cpm2_map_t *)CPM_MAP_ADDR; /* and to internal registers */
+
+ *(ushort *)(&immap->im_dprambase[PROFF_I2C_BASE]) = PROFF_I2C;
+ data->iip = (iic_t *)&immap->im_dprambase[PROFF_I2C];
+
+ data->i2c = (i2c_cpm2_t *)&(immap->im_i2c);
+ data->cp = cp;
+
+ /* Initialize Port D IIC pins.
+ */
+ immap->im_ioport.iop_ppard |= 0x00030000;
+ immap->im_ioport.iop_pdird &= ~0x00030000;
+ immap->im_ioport.iop_podrd |= 0x00030000;
+ immap->im_ioport.iop_psord |= 0x00030000;
+
+ /* Allocate space for two transmit and two receive buffer
+ * descriptors in the DP ram.
+ */
+ data->dp_addr = cpm_dpalloc(sizeof(cbd_t) * 4, 8);
+
+ /* ptr to i2c area */
+ data->i2c = (i2c_cpm2_t *)&(((cpm2_map_t *)CPM_MAP_ADDR)->im_i2c);
+}
+
+static irqreturn_t mpc8260_i2c_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct mpc_i2c *mpc_i2c = dev_id;
+ struct i2c_algo_8260_data *cpm_adap = mpc_i2c->data;
+ volatile i2c_cpm2_t *i2c = cpm_adap->i2c;
+
+ if (cpm_debug > 1)
+ printk(KERN_DEBUG "cpm_iic_interrupt(dev_id=%p)\n", dev_id);
+
+ /* Clear interrupt.
+ */
+ i2c->i2c_i2cer = 0xff;
+
+ /* Get 'me going again.
+ */
+ wake_up_interruptible(&iic_wait);
+ return IRQ_HANDLED;
+}
+
+
+static void
+cpm_iic_init(struct i2c_algo_8260_data *cpm_adap)
+{
+ volatile iic_t *iip = cpm_adap->iip;
+ volatile i2c_cpm2_t *i2c = cpm_adap->i2c;
+
+ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_init() - iip=%p\n",iip);
+
+ /* Initialize the parameter ram.
+ * We need to make sure many things are initialized to zero,
+ * especially in the case of a microcode patch.
+ */
+ iip->iic_rstate = 0;
+ iip->iic_rdp = 0;
+ iip->iic_rbptr = 0;
+ iip->iic_rbc = 0;
+ iip->iic_rxtmp = 0;
+ iip->iic_tstate = 0;
+ iip->iic_tdp = 0;
+ iip->iic_tbptr = 0;
+ iip->iic_tbc = 0;
+ iip->iic_txtmp = 0;
+
+ /* Set up the IIC parameters in the parameter ram.
+ */
+ iip->iic_tbase = r_tbase = cpm_adap->dp_addr;
+ iip->iic_rbase = r_rbase = cpm_adap->dp_addr + sizeof(cbd_t)*2;
+
+ iip->iic_tfcr = CPMFCR_GBL | CPMFCR_EB;
+ iip->iic_rfcr = CPMFCR_GBL | CPMFCR_EB;
+
+ /* Set maximum receive size.
+ */
+ iip->iic_mrblr = CPM_MAX_READ;
+
+ /* Initialize Tx/Rx parameters.
+ */
+ {
+ volatile cpm_cpm2_t *cp = cpm_adap->cp;
+ cp->cp_cpcr =
+ mk_cr_cmd(CPM_CR_I2C_PAGE, CPM_CR_I2C_SBLOCK, 0x00, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+ }
+
+ /* Select an arbitrary address. Just make sure it is unique.
+ */
+ i2c->i2c_i2add = 0x34;
+
+ /* Divider is 2 * ( 15 + 3 )
+ */
+ i2c->i2c_i2brg = 0x0f;
+
+ /* Pre-divider is BRGCLK/4
+ */
+ i2c->i2c_i2mod = 0x06;
+
+ /* Disable interrupts.
+ */
+ i2c->i2c_i2cmr = 0;
+ i2c->i2c_i2cer = 0xff;
+
+ init_waitqueue_head(&iic_wait);
+}
+
+
+#if 0
+static int
+cpm_iic_shutdown(struct i2c_algo_8260_data *cpm_adap)
+{
+ volatile i2c_cpm2_t *i2c = cpm_adap->i2c;
+
+ /* Shut down IIC.
+ */
+ i2c->i2c_i2mod = 0;
+ i2c->i2c_i2cmr = 0;
+ i2c->i2c_i2cer = 0xff;
+
+ return(0);
+}
+#endif
+
+static void
+cpm_reset_iic_params(volatile iic_t *iip)
+{
+ iip->iic_tbase = r_tbase;
+ iip->iic_rbase = r_rbase;
+
+ iip->iic_tfcr = CPMFCR_GBL | CPMFCR_EB;
+ iip->iic_rfcr = CPMFCR_GBL | CPMFCR_EB;
+
+ iip->iic_mrblr = CPM_MAX_READ;
+
+ iip->iic_rstate = 0;
+ iip->iic_rdp = 0;
+ iip->iic_rbptr = 0;
+ iip->iic_rbc = 0;
+ iip->iic_rxtmp = 0;
+ iip->iic_tstate = 0;
+ iip->iic_tdp = 0;
+ iip->iic_tbptr = 0;
+ iip->iic_tbc = 0;
+ iip->iic_txtmp = 0;
+}
+
+#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */
+#define CPM_CR_CLOSE_RXBD ((ushort)0x0007)
+
+static void force_close(struct i2c_algo_8260_data *cpm)
+{
+#if 0
+ volatile cpm_cpm2_t *cp = cpm->cp;
+
+ if (cpm_debug) printk(KERN_DEBUG "force_close()\n");
+ cp->cp_cpcr =
+ mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) |
+ CPM_CR_FLG;
+
+ while (cp->cp_cpcr & CPM_CR_FLG);
+#endif
+}
+
+
+/* Read from IIC...
+ * abyte = address byte, with r/w flag already set
+ */
+static int
+cpm_iic_read(struct i2c_algo_8260_data *cpm, u_char abyte, char *buf, int count)
+{
+ volatile cpm2_map_t *immap = (cpm2_map_t *)CPM_MAP_ADDR;
+ volatile iic_t *iip = cpm->iip;
+ volatile i2c_cpm2_t *i2c = cpm->i2c;
+ volatile cbd_t *tbdf, *rbdf;
+ u_char *tb;
+ unsigned long flags;
+
+ if (count >= CPM_MAX_READ)
+ return -EINVAL;
+
+ tbdf = (cbd_t *)&immap->im_dprambase[iip->iic_tbase];
+ rbdf = (cbd_t *)&immap->im_dprambase[iip->iic_rbase];
+
+ /* To read, we need an empty buffer of the proper length.
+ * All that is used is the first byte for address, the remainder
+ * is just used for timing (and doesn't really have to exist).
+ */
+ if (/*cpm->reloc*/0) {
+ cpm_reset_iic_params(iip);
+ }
+ tb = cpm->temp;
+ tb = (u_char *)(((uint)tb + 15) & ~15);
+ tb[0] = abyte; /* Device address byte w/rw flag */
+
+ dma_cache_wback_inv (tb, 1);
+
+ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_read(abyte=0x%x)\n", abyte);
+
+ tbdf->cbd_bufaddr = __pa(tb);
+ tbdf->cbd_datlen = count + 1;
+ tbdf->cbd_sc =
+ BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_WRAP | BD_IIC_START;
+
+ rbdf->cbd_datlen = 0;
+ rbdf->cbd_bufaddr = __pa(buf);
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+ if (count > 0 && count < CPM_MAX_READ)
+ iip->iic_mrblr = count; /* prevent excessive read */
+
+ dma_cache_inv (buf, count);
+
+ /* Chip bug, set enable here */
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com = 0x81; /* Start master */
+
+ /* Wait for IIC transfer */
+ interruptible_sleep_on(&iic_wait);
+ local_irq_restore(flags);
+ if (signal_pending(current))
+ return -EIO;
+
+ if (cpm_debug) {
+ printk(KERN_DEBUG "tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
+ if (tbdf->cbd_sc & BD_SC_NAK) {
+ printk(KERN_INFO "IIC read; no ack\n");
+ return 0;
+ }
+
+ if (rbdf->cbd_sc & BD_SC_EMPTY) {
+ printk(KERN_INFO "IIC read; complete but rbuf empty\n");
+ force_close(cpm);
+ printk(KERN_INFO "tx sc %04x, rx sc %04x\n",
+ tbdf->cbd_sc, rbdf->cbd_sc);
+ }
+
+ if (cpm_debug) printk(KERN_DEBUG "read %d bytes\n", rbdf->cbd_datlen);
+
+ if (rbdf->cbd_datlen < count) {
+ printk(KERN_INFO "IIC read; short, wanted %d got %d\n",
+ count, rbdf->cbd_datlen);
+ return 0;
+ }
+ if (cpm_debug) {
+ int u;
+ for (u = 0; u < count; u++) {
+ printk(KERN_DEBUG "buf[%d] = 0x%x\n", u, buf[u]);
+ }
+ }
+
+
+ return count;
+}
+
+/* Write to IIC...
+ * addr = address byte, with r/w flag already set
+ */
+static int
+cpm_iic_write(struct i2c_algo_8260_data *cpm, u_char abyte, char *buf,int count)
+{
+ volatile cpm2_map_t *immap = (cpm2_map_t *)CPM_MAP_ADDR;
+ volatile iic_t *iip = cpm->iip;
+ volatile i2c_cpm2_t *i2c = cpm->i2c;
+ volatile cbd_t *tbdf;
+ u_char *tb;
+ unsigned long flags;
+
+ tb = cpm->temp;
+ tb = (u_char *)(((uint)tb + 15) & ~15);
+ *tb = abyte; /* Device address byte w/rw flag */
+
+ dma_cache_wback_inv (tb, 1);
+ dma_cache_wback_inv (buf, count);
+
+ if (cpm_debug) printk(KERN_DEBUG "cpm_iic_write(abyte=0x%x)\n", abyte);
+ if (cpm_debug) printk(KERN_DEBUG "buf[0] = 0x%x, buf[1] = 0x%x\n", buf[0], buf[1]);
+
+ /* set up 2 descriptors */
+ tbdf = (cbd_t *)&immap->im_dprambase[iip->iic_tbase];
+
+ tbdf[0].cbd_bufaddr = __pa(tb);
+ tbdf[0].cbd_datlen = 1;
+ tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START;
+
+ tbdf[1].cbd_bufaddr = __pa(buf);
+ tbdf[1].cbd_datlen = count;
+ tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP;
+
+ /* Chip bug, set enable here */
+ local_irq_save(flags);;
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com = 0x81; /* Start master */
+
+ /* Wait for IIC transfer */
+ interruptible_sleep_on(&iic_wait);
+ local_irq_restore(flags);
+ if (signal_pending(current))
+ return -EIO;
+
+ if (cpm_debug) {
+ printk(KERN_DEBUG "tx0 sc %04x, tx1 sc %04x\n",
+ tbdf[0].cbd_sc, tbdf[1].cbd_sc);
+ }
+
+ if (tbdf->cbd_sc & BD_SC_NAK) {
+ printk(KERN_INFO "IIC write; no ack\n");
+ return 0;
+ }
+
+ if (tbdf->cbd_sc & BD_SC_READY) {
+ printk(KERN_INFO "IIC write; complete but tbuf ready\n");
+ return 0;
+ }
+
+ return count;
+}
+
+#if 0
+/* See if an IIC address exists..
+ * addr = 7 bit address, unshifted
+ */
+static int
+cpm_iic_tryaddress(struct i2c_algo_8260_data *cpm, int addr)
+{
+ volatile cpm2_map_t *immap = (cpm2_map_t *)CPM_MAP_ADDR;
+ volatile iic_t *iip = cpm->iip;
+ volatile i2c_cpm2_t *i2c = cpm->i2c;
+ volatile cbd_t *tbdf, *rbdf;
+ u_char *tb;
+ unsigned long flags, len;
+
+ if (cpm_debug > 1)
+ printk(KERN_DEBUG "cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr);
+
+ if (cpm_debug && addr == 0) {
+ printk(KERN_DEBUG "iip %p, dp_addr 0x%x\n", cpm->iip, cpm->dp_addr);
+ printk(KERN_DEBUG "iic_tbase %d, r_tbase %d\n", iip->iic_tbase, r_tbase);
+ }
+
+ tbdf = (cbd_t *)&immap->im_dprambase[iip->iic_tbase];
+ rbdf = (cbd_t *)&immap->im_dprambase[iip->iic_rbase];
+
+ tb = cpm->temp;
+ tb = (u_char *)(((uint)tb + 15) & ~15);
+
+ /* do a simple read */
+ tb[0] = (addr << 1) | 1; /* device address (+ read) */
+ len = 2;
+
+ dma_cache_wback_inv (tb, 1);
+
+ tbdf->cbd_bufaddr = __pa(tb);
+ tbdf->cbd_datlen = len;
+ tbdf->cbd_sc =
+ BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST |
+ BD_SC_WRAP | BD_IIC_START;
+
+ rbdf->cbd_datlen = 0;
+ rbdf->cbd_bufaddr = __pa(tb+2);
+ rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+ local_irq_save(flags);
+ i2c->i2c_i2cmr = 0x13; /* Enable some interupts */
+ i2c->i2c_i2cer = 0xff;
+ i2c->i2c_i2mod |= 1; /* Enable */
+ i2c->i2c_i2com = 0x81; /* Start master */
+
+ if (cpm_debug > 1) printk(KERN_DEBUG "about to sleep\n");
+
+ /* wait for IIC transfer */
+ interruptible_sleep_on(&iic_wait);
+ local_irq_restore(flags);
+ if (signal_pending(current))
+ return -EIO;
+
+ if (cpm_debug > 1) printk(KERN_DEBUG "back from sleep\n");
+
+ if (tbdf->cbd_sc & BD_SC_NAK) {
+ if (cpm_debug > 1) printk(KERN_DEBUG "IIC try; no ack\n");
+ return 0;
+ }
+
+ if (tbdf->cbd_sc & BD_SC_READY) {
+ printk(KERN_INFO "IIC try; complete but tbuf ready\n");
+ }
+
+ return 1;
+}
+#endif
+
+static int mpc8260_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct i2c_msg *pmsg;
+ int i;
+ int ret = 0;
+ struct mpc_i2c *mpc_i2c = i2c_get_adapdata(adap);
+ struct i2c_algo_8260_data *data = mpc_i2c->data;
+ u_char addr;
+
+ for (i = 0; i < num; i++) {
+ pmsg = &msgs[i];
+
+ if (cpm_debug)
+ printk(KERN_DEBUG "i2c-algo-8260.o: "
+ "#%d addr=0x%x flags=0x%x len=%d\n",
+ i, pmsg->addr, pmsg->flags, pmsg->len);
+
+ addr = pmsg->addr << 1;
+ if (pmsg->flags & I2C_M_RD )
+ addr |= 1;
+ if (pmsg->flags & I2C_M_REV_DIR_ADDR )
+ addr ^= 1;
+
+ if (!(pmsg->flags & I2C_M_NOSTART)) {
+ }
+ if (pmsg->flags & I2C_M_RD ) {
+ /* read bytes into buffer*/
+ ret = cpm_iic_read(data, addr, pmsg->buf, pmsg->len);
+ if (cpm_debug)
+ printk(KERN_DEBUG "i2c-algo-8260.o: read %d bytes\n", ret);
+ if (ret < pmsg->len ) {
+ return (ret<0)? ret : -EREMOTEIO;
+ }
+ } else {
+ /* write bytes from buffer */
+ ret = cpm_iic_write(data, addr, pmsg->buf, pmsg->len);
+ if (cpm_debug)
+ printk(KERN_DEBUG "i2c-algo-8260.o: wrote %d\n", ret);
+ if (ret < pmsg->len ) {
+ return (ret<0) ? ret : -EREMOTEIO;
+ }
+ }
+ }
+ return (ret < 0) ? ret : num;
+}
+
+static u32 mpc8260_functionality(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+ I2C_FUNC_PROTOCOL_MANGLING;
+}
+
+static struct i2c_algorithm mpc8260_algo = {
+ .master_xfer = mpc8260_xfer,
+ .functionality = mpc8260_functionality,
+};
+
+static struct i2c_adapter mpc8260_ops = {
+ .owner = THIS_MODULE,
+ .name = "MPC 8260 adapter",
+ .id = I2C_HW_MPC8260,
+ .algo = &mpc8260_algo,
+ .class = I2C_CLASS_HWMON,
+ .timeout = 1,
+ .retries = 1
+};
+
+static int fsl_i2c_probe(struct device *device)
+{
+ int result = 0;
+ struct mpc_i2c *i2c;
+ struct platform_device *pdev = to_platform_device(device);
+ struct fsl_i2c_platform_data *pdata;
+
+ pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
+
+ if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ memset(i2c, 0, sizeof(*i2c));
+
+ i2c->data = &pm82x_data;
+ /* CPM Plattform initialisation */
+ mpc8260_iic_init (i2c->data);
+ /* CPM init */
+ cpm_iic_init (i2c->data);
+ i2c->irq = platform_get_irq(pdev, 0);
+
+ if (i2c->irq != 0) {
+ if ((result = request_irq(i2c->irq, mpc8260_i2c_isr,
+ SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
+ printk(KERN_ERR
+ "i2c-mpc - failed to attach interrupt\n");
+ goto fail_irq;
+ }
+ }
+ dev_set_drvdata(device, i2c);
+
+ i2c->adap = mpc8260_ops;
+ i2c_set_adapdata(&i2c->adap, i2c);
+ i2c->adap.dev.parent = &pdev->dev;
+ if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
+ printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
+ goto fail_add;
+ }
+
+ return result;
+
+ fail_add:
+ if (i2c->irq != 0)
+ free_irq(i2c->irq, NULL);
+ fail_irq:
+ kfree(i2c);
+ return result;
+};
+
+static int fsl_i2c_remove(struct device *device)
+{
+ struct mpc_i2c *i2c = dev_get_drvdata(device);
+
+ /* hier noich irgendwo das dpalloc wieder freigeben */
+ cpm_dpfree (i2c->data->dp_addr);
+
+ i2c_del_adapter(&i2c->adap);
+ dev_set_drvdata(device, NULL);
+
+ if (i2c->irq != 0)
+ free_irq(i2c->irq, i2c);
+
+ kfree(i2c);
+ return 0;
+};
+
+/* Structure for a device driver */
+static struct device_driver fsl_i2c_driver = {
+ .name = "fsl-cpm-i2c",
+ .bus = &platform_bus_type,
+ .probe = fsl_i2c_probe,
+ .remove = fsl_i2c_remove,
+};
+
+static int __init fsl_i2c_init(void)
+{
+ return driver_register(&fsl_i2c_driver);
+}
+
+static void __exit fsl_i2c_exit(void)
+{
+ driver_unregister(&fsl_i2c_driver);
+}
+
+module_init(fsl_i2c_init);
+module_exit(fsl_i2c_exit);
+
+MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
+MODULE_DESCRIPTION
+ ("I2C-Bus adapter for MPC8260 processors");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c-algo-8260.h b/include/linux/i2c-algo-8260.h
new file mode 100644
index 0000000..73b3e33
--- /dev/null
+++ b/include/linux/i2c-algo-8260.h
@@ -0,0 +1,26 @@
+/* ------------------------------------------------------------------------- */
+/* i2c-algo-8260.h i2c driver algorithms for MPX8260 CPM */
+/* ------------------------------------------------------------------------- */
+
+/* $Id$ */
+
+#ifndef I2C_ALGO_8260_H
+#define I2C_ALGO_8260_H 1
+
+#include <linux/i2c.h>
+
+struct i2c_algo_8260_data {
+ uint dp_addr;
+ int reloc;
+ volatile i2c_cpm2_t *i2c;
+ volatile iic_t *iip;
+ volatile cpm_cpm2_t *cp;
+
+ int (*setisr) (int irq,
+ void (*func)(int, void (*)(void *), void *),
+ void *data);
+
+ u_char temp[513];
+};
+
+#endif /* I2C_ALGO_8260_H */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 1543daa..35b0a57 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -223,6 +223,9 @@
/* --- PowerPC on-chip adapters */
#define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */
+/* --- MPC8260 PowerPC adapters */
+#define I2C_HW_MPC8260 0x100002 /* MPC8260 I2C adapter */
+
/* --- Broadcom SiByte adapters */
#define I2C_HW_SIBYTE 0x150000
\f
!-------------------------------------------------------------flip-
Signed-off-by: Heiko Schocher <hs@denx.de>
^ permalink raw reply related
* Re: [PATCH 3/3] ppc32: MTD support for Yucca board
From: Matt Porter @ 2005-11-21 15:57 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: Ruslan V. Sushko, linuxppc-embedded
In-Reply-To: <4381E1A1.1060405@ru.mvista.com>
On Mon, Nov 21, 2005 at 06:02:57PM +0300, Vitaly Bordug wrote:
> Guess this should come through MTD community (linux-mtd@lists.infradead.org), rebased to
> the MTD tree of course.
Indeed, however, it need to be split so the driver/mtd portion goes to
the MTD maintainers. The arch/ppc portion will go in through the powerpc
tree.
-Matt
^ permalink raw reply
* [PATCH] I2C: Added support for the PCF8563 chip.
From: Heiko Schocher @ 2005-11-21 16:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: lm-sensors
Hello,
the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
the PCF8563 RTC on the PM82X Boards from Microsys.
Signed-off-by: Heiko Schocher <hs@denx.de>
---
drivers/i2c/chips/Kconfig | 9 +
drivers/i2c/chips/Makefile | 1
drivers/i2c/chips/pcf8563.c | 549 +++++++++++++++++++++++++++++++++++++++++++
include/linux/i2c-id.h | 1
4 files changed, 560 insertions(+), 0 deletions(-)
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index f9fae28..c470b0d 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -46,6 +46,15 @@ config SENSORS_PCF8574
This driver can also be built as a module. If so, the module
will be called pcf8574.
+config SENSORS_PCF8563
+ tristate "Philips PCF8563 RTC Chip"
+ depends on I2C && EXPERIMENTAL
+ help
+ If you say yes here you get support for Philips PCF8563 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called i2c-pcf8563.
+
config SENSORS_PCA9539
tristate "Philips PCA9539 16-bit I/O port"
depends on I2C && EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 46178b5..e37835a 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_SENSORS_MAX6875) += max6875
obj-$(CONFIG_SENSORS_M41T00) += m41t00.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
+obj-$(CONFIG_SENSORS_PCF8563) += pcf8563.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
diff --git a/drivers/i2c/chips/pcf8563.c b/drivers/i2c/chips/pcf8563.c
new file mode 100644
index 0000000..8c4018b
--- /dev/null
+++ b/drivers/i2c/chips/pcf8563.c
@@ -0,0 +1,549 @@
+/*
+ * linux/drivers/i2c/chips/pcf8563.c
+ *
+ * Copyright (C) 2002-2004 Stefan Eletzhofer
+ *
+ * based on linux/drivers/acron/char/pcf8583.c
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for system3's PHILIPS PCF 8563 chip
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/rtc.h> /* get the user-level API */
+#include <linux/init.h>
+#include <linux/list.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+
+#include "rtc8564.h"
+
+#ifdef DEBUG
+# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0);
+#else
+# define _DBG(x, fmt, args...) do { } while(0);
+#endif
+
+#define _DBGRTCTM(x, rtctm) if (debug>x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \
+ "mon=%d, year=%d, wday=%d\n", __FUNCTION__, \
+ (rtctm).tm_sec, (rtctm).tm_min, (rtctm).tm_hour, (rtctm).tm_mday, \
+ (rtctm).tm_mon, (rtctm).tm_year, (rtctm).tm_wday);
+
+struct pcf8563_data {
+ struct i2c_client client;
+ struct list_head list;
+ u16 ctrl;
+};
+
+/*
+ * Internal variables
+ */
+static LIST_HEAD(pcf8563_clients);
+
+static struct i2c_client *myclient = NULL;
+
+static inline u8 _pcf8563_ctrl1(struct i2c_client *client)
+{
+ struct pcf8563_data *data = i2c_get_clientdata(client);
+ return data->ctrl & 0xff;
+}
+static inline u8 _pcf8563_ctrl2(struct i2c_client *client)
+{
+ struct pcf8563_data *data = i2c_get_clientdata(client);
+ return (data->ctrl & 0xff00) >> 8;
+}
+
+#define CTRL1(c) _pcf8563_ctrl1(c)
+#define CTRL2(c) _pcf8563_ctrl2(c)
+
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+
+static int debug = 0;
+module_param(debug, int, S_IRUGO | S_IWUSR);
+
+static struct i2c_driver pcf8563_driver;
+
+static int pcf8563_read_mem(struct i2c_client *client, struct mem *mem);
+static int pcf8563_write_mem(struct i2c_client *client, struct mem *mem);
+static unsigned long pcf8563_get_rtc_time(void);
+static int pcf8563_set_rtc_time(unsigned long now);
+
+/* save/restore old machdep pointers */
+int (*save_set_rtc_time)(unsigned long);
+unsigned long (*save_get_rtc_time)(void);
+
+static int pcf8563_read(struct i2c_client *client, unsigned char adr,
+ unsigned char *buf, unsigned char len)
+{
+ int ret = -EIO;
+ unsigned char addr[1] = { adr };
+ struct i2c_msg msgs[2] = {
+ {client->addr, 0, 1, addr},
+ {client->addr, I2C_M_RD, len, buf}
+ };
+
+ _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len);
+
+ if (!buf) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = i2c_transfer(client->adapter, msgs, 2);
+ if (ret == 2) {
+ ret = 0;
+ }
+
+done:
+ return ret;
+}
+
+static int pcf8563_write(struct i2c_client *client, unsigned char adr,
+ unsigned char *data, unsigned char len)
+{
+ int ret = 0;
+ unsigned char _data[16];
+ struct i2c_msg wr;
+ int i;
+
+ if (!data || len > 15) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len);
+
+ _data[0] = adr;
+ for (i = 0; i < len; i++) {
+ _data[i + 1] = data[i];
+ _DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]);
+ }
+
+ wr.addr = client->addr;
+ wr.flags = 0;
+ wr.len = len + 1;
+ wr.buf = _data;
+
+ ret = i2c_transfer(client->adapter, &wr, 1);
+ if (ret == 1) {
+ ret = 0;
+ }
+
+done:
+ return ret;
+}
+
+static void pcf8563_set_system_time (void)
+{
+ unsigned long now, flags;
+ extern time_t last_rtc_update;
+ extern seqlock_t xtime_lock;
+
+ /* Switching kernel RTC pointers */
+ _DBG (2,"RTC switching kernel pointers\n");
+
+ save_set_rtc_time = ppc_md.set_rtc_time;
+ save_get_rtc_time = ppc_md.get_rtc_time;
+
+ ppc_md.set_rtc_time = pcf8563_set_rtc_time;
+ ppc_md.get_rtc_time = pcf8563_get_rtc_time;
+
+ /*
+ * Set system time
+ * Code copied from arch/ppc/kernel/time.c
+ */
+ write_seqlock_irqsave(&xtime_lock, flags);
+
+ now = pcf8563_get_rtc_time();
+ _DBG (2,"Set System Time from RTC Time: %lu\n", now);
+ xtime.tv_nsec = 0;
+ xtime.tv_sec = now;
+
+ last_rtc_update = now - 658;
+
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_state = TIME_ERROR;
+ time_maxerror = NTP_PHASE_LIMIT;
+ time_esterror = NTP_PHASE_LIMIT;
+
+ write_sequnlock_irqrestore(&xtime_lock, flags);
+
+#if 0
+ /*
+ * Check for low voltage
+ */
+ if (rtc_rd (0x02) & 0x80) {
+ printk (KERN_CRIT
+ "PCF8563 RTC Low Voltage - date/time not reliable\n");
+ }
+
+ /*
+ * Reset any error conditions, alarms, etc.
+ */
+ pcf8563_reset_rtc ();
+#endif
+}
+
+static int pcf8563_attach(struct i2c_adapter *adap, int addr, int kind)
+{
+ int ret;
+ struct i2c_client *new_client;
+ struct pcf8563_data *d;
+ unsigned char data[10];
+ unsigned char ad[1] = { 0 };
+ struct i2c_msg ctrl_wr[1] = {
+ {addr, 0, 2, data}
+ };
+ struct i2c_msg ctrl_rd[2] = {
+ {addr, 0, 1, ad},
+ {addr, I2C_M_RD, 2, data}
+ };
+
+ d = kmalloc(sizeof(struct pcf8563_data), GFP_KERNEL);
+ if (!d) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ memset(d, 0, sizeof(struct pcf8563_data));
+ INIT_LIST_HEAD(&d->list);
+
+ new_client = &d->client;
+
+ strlcpy(new_client->name, "RTC8563", I2C_NAME_SIZE);
+ i2c_set_clientdata(new_client, d);
+ new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY;
+ new_client->addr = addr;
+ new_client->adapter = adap;
+ new_client->driver = &pcf8563_driver;
+
+ _DBG(1, "client=%p", new_client);
+
+ /* init ctrl1 reg */
+ data[0] = 0;
+ data[1] = 0;
+ ret = i2c_transfer(new_client->adapter, ctrl_wr, 1);
+ if (ret != 1) {
+ printk(KERN_INFO "pcf8563: cant init ctrl1\n");
+ ret = -ENODEV;
+ goto done;
+ }
+ /* read back ctrl1 and ctrl2 */
+ ret = i2c_transfer(new_client->adapter, ctrl_rd, 2);
+ if (ret != 2) {
+ printk(KERN_INFO "pcf8563: cant read ctrl\n");
+ ret = -ENODEV;
+ goto done;
+ }
+ d->ctrl = data[0] | (data[1] << 8);
+
+ _DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x",
+ data[0], data[1]);
+
+ ret = i2c_attach_client(new_client);
+
+ /* Add client to local list */
+ list_add(&d->list, &pcf8563_clients);
+
+done:
+ if (ret) {
+ kfree(d);
+ } else {
+ myclient = new_client;
+ pcf8563_set_system_time();
+ }
+ return ret;
+}
+
+static int pcf8563_probe(struct i2c_adapter *adap)
+{
+ /*
+ * Probing seems to confuse the RTC on PM826 and CPU86 and UC100.
+ * Not sure if it's true for other boards though - thus the
+ * conditional.
+ */
+#if defined(CONFIG_PM82X)
+ pcf8563_attach(adap, 0x51, 0);
+ return 0;
+#else
+ return i2c_probe(adap, &addr_data, pcf8563_attach);
+#endif
+}
+
+static int pcf8563_detach(struct i2c_client *client)
+{
+ struct pcf8563_data *data = i2c_get_clientdata(client);
+
+ i2c_detach_client(client);
+ kfree(i2c_get_clientdata(client));
+ list_del(&data->list);
+ return 0;
+}
+
+static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *dt)
+{
+ int ret = -EIO;
+ unsigned char buf[15];
+
+ _DBG(1, "client=%p, dt=%p", client, dt);
+
+ if (!dt)
+ return -EINVAL;
+
+ memset(buf, 0, sizeof(buf));
+
+ ret = pcf8563_read(client, 0, buf, 15);
+ if (ret)
+ return ret;
+
+ dt->tm_year = 1900 + BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
+ if (buf[RTC8564_REG_MON_CENT] & 0x80)
+ dt->tm_year += 100;
+ dt->tm_mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
+ dt->tm_wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
+ dt->tm_mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
+
+ dt->tm_sec = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
+/* dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; */
+ dt->tm_min = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
+ dt->tm_hour = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
+
+ _DBGRTCTM(2, *dt);
+ return 0;
+}
+
+static int
+pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
+{
+ int ret, len = 5;
+ unsigned char buf[15];
+ unsigned char val;
+
+ _DBG(1, "client=%p, dt=%p", client, dt);
+
+ if (!dt)
+ return -EINVAL;
+
+ _DBGRTCTM(2, *dt);
+
+ buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
+ buf[RTC8564_REG_CTRL2] = CTRL2(client);
+ buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->tm_sec);
+ buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->tm_min);
+ buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->tm_hour);
+
+ if (datetoo) {
+ len += 5;
+ buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->tm_mday);
+ buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->tm_wday);
+ buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->tm_mon) & 0x1f;
+ if (dt->tm_year >= 2000) {
+ val = dt->tm_year - 2000;
+ buf[RTC8564_REG_MON_CENT] |= (1 << 7);
+ } else {
+ val = dt->tm_year - 1900;
+ }
+ buf[RTC8564_REG_YEAR] = BIN_TO_BCD(val);
+ }
+
+ ret = pcf8563_write(client, 0, buf, len);
+ if (ret) {
+ _DBG(1, "error writing data! %d", ret);
+ }
+
+ buf[RTC8564_REG_CTRL1] = CTRL1(client);
+ ret = pcf8563_write(client, 0, buf, 1);
+ if (ret) {
+ _DBG(1, "error writing data! %d", ret);
+ }
+
+ return ret;
+}
+
+static int pcf8563_get_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+ struct pcf8563_data *data = i2c_get_clientdata(client);
+
+ if (!ctrl)
+ return -1;
+
+ *ctrl = data->ctrl;
+ return 0;
+}
+
+static int pcf8563_set_ctrl(struct i2c_client *client, unsigned int *ctrl)
+{
+ struct pcf8563_data *data = i2c_get_clientdata(client);
+ unsigned char buf[2];
+
+ if (!ctrl)
+ return -1;
+
+ buf[0] = *ctrl & 0xff;
+ buf[1] = (*ctrl & 0xff00) >> 8;
+ data->ctrl = *ctrl;
+
+ return pcf8563_write(client, 0, buf, 2);
+}
+
+static int pcf8563_read_mem(struct i2c_client *client, struct mem *mem)
+{
+
+ if (!mem)
+ return -EINVAL;
+
+ return pcf8563_read(client, mem->loc, mem->data, mem->nr);
+}
+
+static int pcf8563_write_mem(struct i2c_client *client, struct mem *mem)
+{
+
+ if (!mem)
+ return -EINVAL;
+
+ return pcf8563_write(client, mem->loc, mem->data, mem->nr);
+}
+
+static int
+pcf8563_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+
+ _DBG(1, "cmd=%d", cmd);
+
+ switch (cmd) {
+ case RTC_GETDATETIME:
+ return pcf8563_get_datetime(client, arg);
+
+ case RTC_SETTIME:
+ return pcf8563_set_datetime(client, arg, 0);
+
+ case RTC_SETDATETIME:
+ return pcf8563_set_datetime(client, arg, 1);
+
+ case RTC_GETCTRL:
+ return pcf8563_get_ctrl(client, arg);
+
+ case RTC_SETCTRL:
+ return pcf8563_set_ctrl(client, arg);
+
+ case MEM_READ:
+ return pcf8563_read_mem(client, arg);
+
+ case MEM_WRITE:
+ return pcf8563_write_mem(client, arg);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+/*
+ * Public API for access to specific device. Useful for low-level
+ * RTC access from kernel code.
+ */
+int pcf8563_do_command(int bus, int cmd, void *arg)
+{
+ struct list_head *walk;
+ struct list_head *tmp;
+ struct pcf8563_data *data;
+
+ list_for_each_safe(walk, tmp, &pcf8563_clients) {
+ data = list_entry(walk, struct pcf8563_data, list);
+ if (data->client.adapter->nr == bus) {
+ return pcf8563_command(&data->client, cmd, arg);
+ }
+ }
+
+ return -ENODEV;
+}
+
+extern spinlock_t rtc_lock;
+/***************************************************************************
+ *
+ * get RTC time:
+ */
+static unsigned long pcf8563_get_rtc_time(void)
+{
+ struct rtc_time tm;
+ int result;
+
+ spin_lock(&rtc_lock);
+ result = pcf8563_do_command(0, RTC_GETDATETIME, &tm);
+ spin_unlock(&rtc_lock);
+
+ if (result == 0)
+ result = mktime(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ return result;
+}
+
+/***************************************************************************
+ *
+ * set RTC time:
+ */
+static int pcf8563_set_rtc_time(unsigned long now)
+{
+ struct rtc_time tm;
+ unsigned char century, year, mon, wday, mday, hour, min, sec;
+
+ to_tm (now, &tm);
+
+ _DBG (2, "Set RTC [dec] year=%d mon=%d day=%d hour=%d min=%d sec=%d\n",
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+ century = (tm.tm_year >= 2000) ? 0x80 : 0;
+ year = BIN_TO_BCD (tm.tm_year % 100);
+ mon = BIN_TO_BCD (tm.tm_mon) | century;
+ wday = BIN_TO_BCD (tm.tm_wday);
+ mday = BIN_TO_BCD (tm.tm_mday);
+ hour = BIN_TO_BCD (tm.tm_hour);
+ min = BIN_TO_BCD (tm.tm_min);
+ sec = BIN_TO_BCD (tm.tm_sec);
+
+ _DBG (2, "Set RTC [bcd] year=%X mon=%X day=%X "
+ "hour=%X min=%X sec=%X wday=%X\n",
+ year, mon, mday, hour, min, sec, wday);
+
+ pcf8563_set_datetime(myclient, &tm, 1);
+
+ return (0);
+}
+
+static struct i2c_driver pcf8563_driver = {
+ .owner = THIS_MODULE,
+ .name = "PCF8563",
+ .id = I2C_DRIVERID_RTC8564,
+ .flags = I2C_DF_NOTIFY,
+ .attach_adapter = pcf8563_probe,
+ .detach_client = pcf8563_detach,
+ .command = pcf8563_command
+};
+
+static __init int pcf8563_init(void)
+{
+ return i2c_add_driver(&pcf8563_driver);
+}
+
+static __exit void pcf8563_exit(void)
+{
+ ppc_md.set_rtc_time = save_set_rtc_time;
+ ppc_md.get_rtc_time = save_get_rtc_time;
+
+ i2c_del_driver(&pcf8563_driver);
+}
+
+MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>");
+MODULE_DESCRIPTION("EPSON RTC8563 Driver");
+MODULE_LICENSE("GPL");
+
+module_init(pcf8563_init);
+module_exit(pcf8563_exit);
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 1ce4b54..b16c548 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -99,6 +99,7 @@
#define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
#define I2C_DRIVERID_SAA7114H 64 /* video decoder */
#define I2C_DRIVERID_DS1374 65 /* DS1374 real time clock */
+#define I2C_DRIVERID_PCF8563 66 /* real time clock */
#define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
\f
!-------------------------------------------------------------flip-
^ permalink raw reply related
* anyone used i2c-algo-8260 for the MPC8272 family?
From: Heiko Schocher @ 2005-11-21 16:57 UTC (permalink / raw)
To: linuxppc-embedded
Hi Ron,
> There are some subtle differences b/t the 8260 family and 8272 family.
> The 8272 family only has 8KB DPRAM (c.f. 16KB), so I believe the
> definition of PROFF_I2C in include/linux/cpm_8260.h should be
> different. I've changed it from:
>
> #define PROFF_I2C ((16 * 1024) - 64)
> to
> #define PROFF_I2C ((8 * 1024) - 64)
>
> but still get no I2C activity, and a kernel hang.
I think your change above is right for a MPC8247.
> Anyone have this working, or any thoughts to contribute?
Look at my Patch, which I just posted at linuxppc-dev, which
(I hope) will help you (!! it is for a MPC8260 based Board):
http://ozlabs.org/pipermail/linuxppc-dev/2005-November/020492.html
or have a look at the Git repository at Denx:
http://source.denx.net/git/linux-2.6-denx.git
where you can find the complete PM82x port for the 2.6.14 Kernel.
Best regards,
Heiko
^ permalink raw reply
* Re: [PATCH 1/3] ppc32: Fix a few issues in Yucca PCIe functionality
From: Dale Farnsworth @ 2005-11-21 17:47 UTC (permalink / raw)
To: Ruslan V. Sushko, linuxppc-embedded
In-Reply-To: <1132583152.11785.41.camel@mephisto.spb.rtsoft.ru>
On Mon, Nov 21, 2005 at 02:25:52PM +0000, Ruslan V. Sushko wrote:
> This patch includes following changes:
>
> 1) Fix wrong PCIe config space address calculation for slot #3 (Using an
> signed integer for port numbering will cause wrong address accessing)
> 2) Fix the PCI bus numbering assignment. This will be an issues if more
> than one PCI card is inserted.
> 3) Add verbose error checking.
> 4) Remove commented or unused lines.
>
> Signed-off-by: Ruslan V. Sushko <rsushko@ru.mvista.com>
There are a couple of whitespace/style problems in these 3 patches.
Please clean them up and re-submit.
> diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
> --- a/arch/ppc/platforms/4xx/yucca.c
> +++ b/arch/ppc/platforms/4xx/yucca.c
> @@ -280,12 +276,14 @@ yucca_setup_hoses(void)
> IORESOURCE_MEM,
> name);
>
> - hose->first_busno = 0;
> - hose->last_busno = 15;
> + hose->first_busno = bus_no;
> + hose->last_busno = 0xFF;
> hose_type[hose->index] = HOSE_PCIE0 + i;
>
> ppc440spe_setup_pcie(hose, i);
> hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
> + bus_no = hose->last_busno + 1;
> + printk(KERN_INFO "%s: resources allocated\n", name);
The above two lines have leading spaces instead of tabs. The same
problem exists in several other lines added by the patches.
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
--- a/arch/ppc/syslib/ppc440spe_pcie.c
+++ b/arch/ppc/syslib/ppc440spe_pcie.c
> @@ -157,33 +162,37 @@ int ppc440spe_init_pcie(void)
> /* Set PLL clock receiver to LVPECL */
> SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
>
> - check_error();
> -
> - printk(KERN_INFO "PCIE initialization OK\n");
> -
> - if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
> - printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
> + if (check_error()) {
> + return -1;
> + }
The above braces aren't needed.
> +
> + if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000)) {
> + printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration "
> + "failed (0x%08x)\n",
> SDR_READ(PESDR0_PLLLCT2));
> + return -1;
> + }
>
> /* De-assert reset of PCIe PLL, wait for lock */
> SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
> udelay(3);
> + printk(KERN_INFO "PCIE initialization OK\n");
>
> return 0;
> }
>
> -int ppc440spe_init_pcie_rootport(int port)
> +int ppc440spe_init_pcie_rootport(u32 port)
> {
> static int core_init;
> void __iomem *utl_base;
> + int attempts;
> u32 val = 0;
> - int i;
>
> if (!core_init) {
> + if(ppc440spe_init_pcie()) {
> + return -1;
> + }
Again, the above braces are unnecessary.
Thanks,
-Dale Farnsworth
^ permalink raw reply
* Re: [PATCH] MTD: Add support for the PM82x Boards.
From: David Woodhouse @ 2005-11-21 20:29 UTC (permalink / raw)
To: hs; +Cc: linuxppc-dev, linux-mtd
In-Reply-To: <AHEILKONAKAEJPHNMOPNIELBCDAA.hs@denx.de>
On Mon, 2005-11-21 at 11:34 +0100, Heiko Schocher wrote:
> Hello,
>
> the following Patch (against 2.6 kernel.org tree, COMMIT_ID:
> f093182d313edde9b1f86dbdaf40ba4da2dbd0e7) adds support for
> the NOR flashes and for the DiskOnChip on the PM82X Boards
> from Microsys.
Please use the new DiskOnChip driver in drivers/mtd/nand/ not the old
one.
--
dwmw2
^ permalink raw reply
* Re: PowerBook5,8 - TrackPad update
From: Parag Warudkar @ 2005-11-21 23:57 UTC (permalink / raw)
To: Parag Warudkar; +Cc: linuxppc-dev, debian-powerpc, linux-kernel
In-Reply-To: <111520052143.16540.437A5680000BE8A60000409C220076369200009A9B9CD3040A029D0A05@comcast.net>
[-- Attachment #1: Type: text/plain, Size: 1833 bytes --]
On Nov 15, 2005, at 4:43 PM, Parag Warudkar wrote:
> Just a heads up - After some lame hacking I finally have got the
> trackpad on the PB5,8 (15" Late Oct 2005) to work.
>
> Ok, here is the current definition of working - mouse moves but for
> that you have to roll over on the trackpad ;)!
>
> Currently negotiating with it so that it's happy with the fingers!! :D
>
> Will post the modified source once for appletouch once it starts
> working acceptably.
>
Ok, the format interpretation of the trackpad data is taking up more
of my time and brain than I was happy with! :)
If someone wants to take this up, here is something small to begin
with -
So far the three simple changes that are required for the original
appletouch.c in order to get it to produce _some_ wayward mouse
movements and reliable button clicks at the least are
1) #define ATP_DATASIZE 81 - This needs to be made a module parameter
and if not specified should be detected and set in code - to 81 if
the machine_is_compatible() with the older powerbooks and 256 if the
machine_is_compatible() with newer (Oct 05) PowerBooks
2) Convert the appletouch.c to use input_allocate_device()
3) Change the code to lookup either the 80th or 255th byte for button
press depending upon it's old or new trackpad
Attached is the code which takes care of above 3 - tested but it
should be considered half baked for obvious reasons and in addition I
added some relayfs write calls so the received data can be sampled by
writing a user space client for reading the relayfs file. The code
might break the existing (old) trackpads as the detection might not
be correct.
Needless to say the complete logic of interpreting the data and
determining pressure and movement needs to be changed such that it
works for old as well as new.
[-- Attachment #2: appletouch.c --]
[-- Type: application/octet-stream, Size: 14729 bytes --]
/*
* Apple USB Touchpad (for post-February 2005 PowerBooks) driver
*
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
* Copyright (C) 2005 Stelian Pop (stelian@popies.net)
* Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
* Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
* Copyright (C) 2005 Parag Warudkar (parag.warudkar@gmail.com)
*
* Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
* Nov 2005 - Parag Warudkar
* o Added support for Oct 2005 Powerbooks
* o Converted to use input_device_allocate()
* o Added ability to export data via debugfs
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/usb_input.h>
#include <linux/debugfs.h>
#include <linux/relayfs_fs.h>
#if !defined(PPC) && !defined(POWERPC)
#error "Module intended for PowerPC based PowerBooks!"
#endif
/* Apple has powerbooks which have the keyboard with different Product IDs */
#define APPLE_VENDOR_ID 0x05AC
#define ATP_DEVICE(prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = APPLE_VENDOR_ID, \
.idProduct = (prod), \
.bInterfaceClass = 0x03, \
.bInterfaceProtocol = 0x02
/* table of devices that work with this driver */
static struct usb_device_id atp_table [] = {
{ ATP_DEVICE(0x020E) },
{ ATP_DEVICE(0x020F) },
{ ATP_DEVICE(0x030A) },
{ ATP_DEVICE(0x030B) },
{ ATP_DEVICE(0x0214) }, /* PowerBooks Late Oct 2005 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, atp_table);
struct rchan* rch=NULL;
struct rchan_callbacks* rcb =NULL;
/* Debugfs data */
struct atp_dbg_data {
};
/*
* number of sensors. Note that only 16 instead of 26 X (horizontal)
* sensors exist on 12" and 15" PowerBooks. All models have 16 Y
* (vertical) sensors.
*/
#define ATP_MAX_XSENSORS 26
#define ATP_MAX_YSENSORS 16
/* amount of fuzz this touchpad generates */
#define ATP_FUZZ 16
/* maximum pressure this driver will report */
#define ATP_PRESSURE 300
/*
* multiplication factor for the X and Y coordinates.
* We try to keep the touchpad aspect ratio while still doing only simple
* arithmetics.
* The factors below give coordinates like:
* 0 <= x < 960 on 12" and 15" Powerbooks
* 0 <= x < 1600 on 17" Powerbooks
* 0 <= y < 646
*/
#define ATP_XFACT 64
#define ATP_YFACT 43
/*
* Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
* ignored.
*/
#define ATP_THRESHOLD 5
typedef enum PB_MAC_TYPE {
PowerBook54,
PowerBook56,
PowerBook58,
PowerBook59,
Unknown
}PB_MAC_TYPE;
/* Structure to hold all of our device specific stuff */
struct atp {
struct usb_device * udev; /* usb device */
struct urb * urb; /* usb request block */
signed char * data; /* transferred data */
int open; /* non-zero if opened */
struct input_dev *input; /* input dev */
int valid; /* are the sensors valid ? */
int x_old; /* last reported x/y, */
int y_old; /* used for smoothing */
/* current value of the sensors */
signed char xy_cur[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
/* last value of the sensors */
signed char xy_old[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
/* accumulated sensors */
int xy_acc[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
PB_MAC_TYPE mtype;
};
#define dbg_dump(msg, tab) \
if (debug > 1) { \
int i; \
printk("appletouch: %s %lld", msg, (long long)jiffies); \
for (i = 0; i < ATP_MAX_XSENSORS + ATP_MAX_YSENSORS; i++) \
printk(" %02x", tab[i]); \
printk("\n"); \
}
#define dprintk(format, a...) \
do { \
if (debug) printk(format, ##a); \
} while (0)
MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Parag Warudkar");
MODULE_DESCRIPTION("Apple Al PowerBook USB touchpad driver");
MODULE_LICENSE("GPL");
static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activate debugging output");
/* USB URB buffer length - 81 works on Feb 05 models.
* Oct 05 models fail with EOVERFLOW, detected and corrected
* separately.
*/
static int data_len = 81;
module_param(data_len, int, 0644);
MODULE_PARM_DESC(data_len, "Specify USB URB buffer length (auto-detected normally)");
PB_MAC_TYPE atp_machine_detect()
{
if(machine_is_compatible("PowerBook5,9"))
return PowerBook59;
if(machine_is_compatible("PowerBook5,8"))
return PowerBook58;
if(machine_is_compatible("PowerBook5,6"))
return PowerBook56;
if (machine_is_compatible("PowerBook5,4"))
return PowerBook54;
return Unknown;
}
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
int *z, int *fingers)
{
int i;
/* values to calculate mean */
int pcum = 0, psum = 0;
*fingers = 0;
for (i = 0; i < nb_sensors; i++) {
if (xy_sensors[i] < ATP_THRESHOLD)
continue;
if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD))
(*fingers)++;
pcum += xy_sensors[i] * i;
psum += xy_sensors[i];
}
if (psum > 0) {
*z = psum;
return pcum * fact / psum;
}
return 0;
}
static inline void atp_report_fingers(struct input_dev *input, int fingers)
{
input_report_key(input, BTN_TOOL_FINGER, fingers == 1);
input_report_key(input, BTN_TOOL_DOUBLETAP, fingers == 2);
input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
}
static void atp_complete(struct urb* urb, struct pt_regs* regs)
{
int x, y, x_z, y_z, x_f, y_f;
int retval, i;
struct atp *dev = urb->context;
static int ctr=1;
switch (urb->status) {
case 0:
/* success */
break;
case -EOVERFLOW:
if(ctr){
printk("appletouch: OVERFLOW with data length %d\n", data_len);
ctr=0;
}
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* This urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d",
__FUNCTION__, urb->status);
return;
default:
goto exit;
}
/* drop incomplete datasets */
if (dev->urb->actual_length != data_len) {
printk(KERN_WARNING "appletouch: incomplete data package length %d\n", dev->urb->actual_length);
goto exit;
}
if ( dev->data ) {
relay_write(rch, dev->data, dev->urb->actual_length);
}
/* reorder the sensors values */
for (i = 0; i < 8; i++) {
/* X values */
dev->xy_cur[i ] = dev->data[5 * i + 2];
dev->xy_cur[i + 8] = dev->data[5 * i + 4];
dev->xy_cur[i + 16] = dev->data[5 * i + 42];
if (i < 2)
dev->xy_cur[i + 24] = dev->data[5 * i + 44];
/* Y values */
dev->xy_cur[i + 26] = dev->data[5 * i + 1];
dev->xy_cur[i + 34] = dev->data[5 * i + 3];
}
dbg_dump("sample", dev->xy_cur);
if (!dev->valid) {
/* first sample */
dev->valid = 1;
dev->x_old = dev->y_old = -1;
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
/* 17" Powerbooks have 10 extra X sensors */
for (i = 16; i < ATP_MAX_XSENSORS; i++)
if (dev->xy_cur[i]) {
printk("appletouch: 17\" model detected.\n");
input_set_abs_params(dev->input, ABS_X, 0,
(ATP_MAX_XSENSORS - 1) *
ATP_XFACT - 1,
ATP_FUZZ, 0);
break;
}
goto exit;
}
for (i = 0; i < ATP_MAX_XSENSORS + ATP_MAX_YSENSORS; i++) {
/* accumulate the change */
signed char change = dev->xy_old[i] - dev->xy_cur[i];
dev->xy_acc[i] -= change;
/* prevent down drifting */
if (dev->xy_acc[i] < 0)
dev->xy_acc[i] = 0;
}
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
dbg_dump("accumulator", dev->xy_acc);
x = atp_calculate_abs(dev->xy_acc, ATP_MAX_XSENSORS,
ATP_XFACT, &x_z, &x_f);
y = atp_calculate_abs(dev->xy_acc + ATP_MAX_XSENSORS, ATP_MAX_YSENSORS,
ATP_YFACT, &y_z, &y_f);
if (x && y) {
if (dev->x_old != -1) {
x = (dev->x_old * 3 + x) >> 2;
y = (dev->y_old * 3 + y) >> 2;
dev->x_old = x;
dev->y_old = y;
if (debug > 1)
printk("appletouch: X: %3d Y: %3d "
"Xz: %3d Yz: %3d\n",
x, y, x_z, y_z);
input_report_key(dev->input, BTN_TOUCH, 1);
input_report_abs(dev->input, ABS_X, x);
input_report_abs(dev->input, ABS_Y, y);
input_report_abs(dev->input, ABS_PRESSURE,
min(ATP_PRESSURE, x_z + y_z));
atp_report_fingers(dev->input, max(x_f, y_f));
}
dev->x_old = x;
dev->y_old = y;
}
else if (!x && !y) {
dev->x_old = dev->y_old = -1;
input_report_key(dev->input, BTN_TOUCH, 0);
input_report_abs(dev->input, ABS_PRESSURE, 0);
atp_report_fingers(dev->input, 0);
/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
}
input_report_key(dev->input, BTN_LEFT, !!dev->data[data_len-1]);
input_sync(dev->input);
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
if (retval) {
err("%s - usb_submit_urb failed with result %d",
__FUNCTION__, retval);
}
}
static int atp_open(struct input_dev *input)
{
struct atp *dev = input->private;
if (usb_submit_urb(dev->urb, GFP_ATOMIC)) {
printk("atp: usb_submit_urb Error\n");
return -EIO;
}
dev->open = 1;
return 0;
}
static void atp_close(struct input_dev *input)
{
struct atp *dev = input->private;
usb_kill_urb(dev->urb);
dev->open = 0;
}
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
{
struct atp *dev = NULL;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int int_in_endpointAddr = 0;
int i, retval = -ENOMEM;
int regret=0;
printk(KERN_INFO "AppleTouch: Inside atp_probe\n");
/* allocate memory for our device state and initialize it */
dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
if (dev == NULL) {
err("Out of memory");
goto err_kmalloc;
}
memset(dev, 0, sizeof(struct atp));
dev->mtype = atp_machine_detect();
if(dev->mtype == Unknown)
{
printk(KERN_INFO "appletouch: Unknown machine type!\n");
return -ENODEV;
}
if(dev->mtype > 1)
{
if(data_len < 256)
{
printk(KERN_INFO "appletouch: Setting URB buffer length to 256\n");
data_len=256;
}
}
dev->udev = interface_to_usbdev(iface);
printk("appletouch: Machine type is: %d\n", dev->mtype);
/* set up the endpoint information */
/* use only the first interrupt-in endpoint */
iface_desc = iface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
if (!int_in_endpointAddr &&
(endpoint->bEndpointAddress & USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_INT)) {
/* we found an interrupt in endpoint */
int_in_endpointAddr = endpoint->bEndpointAddress;
printk(KERN_INFO "AppleTouch:atp_probe Found interrupt in endpoint: %d\n", int_in_endpointAddr);
break;
}
}
if (!int_in_endpointAddr) {
retval = -EIO;
err("Could not find int-in endpoint");
goto err_endpoint;
}
/* save our data pointer in this interface device */
usb_set_intfdata(iface, dev);
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->urb) {
retval = -ENOMEM;
goto err_usballoc;
}
dev->data = usb_buffer_alloc(dev->udev, data_len, GFP_KERNEL,
&dev->urb->transfer_dma);
if (!dev->data) {
retval = -ENOMEM;
goto err_usbbufalloc;
}
usb_fill_int_urb(dev->urb, dev->udev,
usb_rcvintpipe(dev->udev, int_in_endpointAddr),
dev->data, data_len, atp_complete, dev, 1);
dev->input = input_allocate_device();
dev->input->name = "appletouch";
dev->input->dev = &iface->dev;
dev->input->private = dev;
dev->input->open = atp_open;
dev->input->close = atp_close;
usb_to_input_id(dev->udev, &dev->input->id);
set_bit(EV_ABS, dev->input->evbit);
/*
* 12" and 15" Powerbooks only have 16 x sensors,
* 17" models are detected later.
*/
input_set_abs_params(dev->input, ABS_X, 0,
(16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
input_set_abs_params(dev->input, ABS_Y, 0,
(ATP_MAX_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
input_set_abs_params(dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
set_bit(EV_KEY, dev->input->evbit);
set_bit(BTN_TOUCH, dev->input->keybit);
set_bit(BTN_TOOL_FINGER, dev->input->keybit);
set_bit(BTN_TOOL_DOUBLETAP, dev->input->keybit);
set_bit(BTN_TOOL_TRIPLETAP, dev->input->keybit);
set_bit(BTN_LEFT, dev->input->keybit
);
regret = input_register_device(dev->input);
printk(KERN_INFO "input: appletouch connected, Reg code :%d\n", regret);
return 0;
err_usbbufalloc:
usb_free_urb(dev->urb);
err_usballoc:
usb_set_intfdata(iface, NULL);
err_endpoint:
kfree(dev);
err_kmalloc:
return retval;
}
static void atp_disconnect(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);
usb_set_intfdata(iface, NULL);
if (dev) {
usb_kill_urb(dev->urb);
input_unregister_device(dev->input);
usb_free_urb(dev->urb);
usb_buffer_free(dev->udev, data_len,
dev->data, dev->urb->transfer_dma);
kfree(dev);
}
printk(KERN_INFO "input: appletouch disconnected\n");
}
static int atp_suspend(struct usb_interface *iface, pm_message_t message)
{
struct atp *dev = usb_get_intfdata(iface);
usb_kill_urb(dev->urb);
dev->valid = 0;
return 0;
}
static int atp_resume(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);
if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
return -EIO;
return 0;
}
static struct usb_driver atp_driver = {
.owner = THIS_MODULE,
.name = "appletouch",
.probe = atp_probe,
.disconnect = atp_disconnect,
.suspend = atp_suspend,
.resume = atp_resume,
.id_table = atp_table,
};
static int __init atp_init(void)
{
rcb = kmalloc(sizeof(struct rchan_callbacks), GFP_KERNEL);
rcb->subbuf_start = NULL;
rcb->buf_mapped = NULL;
rcb->buf_unmapped = NULL;
rch = relay_open("atpdata", NULL, 256, 256, NULL);
if (!rch) return -ENOMEM;
return usb_register(&atp_driver);
}
static void __exit atp_exit(void)
{
relay_close(rch);
kfree(rcb);
usb_deregister(&atp_driver);
}
module_init(atp_init);
module_exit(atp_exit);
[-- Attachment #3: Type: text/plain, Size: 10 bytes --]
Parag
^ permalink raw reply
* Re: PowerBook5,8 - TrackPad update
From: Parag Warudkar @ 2005-11-22 0:08 UTC (permalink / raw)
To: Parag Warudkar; +Cc: linuxppc-dev, debian-powerpc, linux-kernel
In-Reply-To: <70210ED5-37CA-40BC-8293-FF1DAA3E8BD5@comcast.net>
[-- Attachment #1: Type: text/plain, Size: 328 bytes --]
On Nov 21, 2005, at 6:57 PM, Parag Warudkar wrote:
> <appletouch.c>
Oops - originally attached file has wrong comment, this one has
fixed comments - other wise the code is same.
Also, one more change required was to add ATP_DEVICE(0x0214) into the
usb_device_id table which I forgot
to mention in the last mail.
Parag
[-- Attachment #2: appletouch.c --]
[-- Type: application/octet-stream, Size: 14771 bytes --]
/*
* Apple USB Touchpad (for post-February 2005 PowerBooks) driver
*
* Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net)
* Copyright (C) 2005 Stelian Pop (stelian@popies.net)
* Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
* Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
* Copyright (C) 2005 Parag Warudkar (parag.warudkar@gmail.com)
*
* Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
* Nov 2005 - Parag Warudkar
* o Add preliminary support for Oct 2005 Powerbooks
* (Doesn't work fully yet)
* o Converted to use input_device_allocate()
* o Added ability to export data via relayfs
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/input.h>
#include <linux/usb_input.h>
#include <linux/debugfs.h>
#include <linux/relayfs_fs.h>
#if !defined(PPC) && !defined(POWERPC)
#error "Module intended for PowerPC based PowerBooks!"
#endif
/* Apple has powerbooks which have the keyboard with different Product IDs */
#define APPLE_VENDOR_ID 0x05AC
#define ATP_DEVICE(prod) \
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
USB_DEVICE_ID_MATCH_INT_CLASS | \
USB_DEVICE_ID_MATCH_INT_PROTOCOL, \
.idVendor = APPLE_VENDOR_ID, \
.idProduct = (prod), \
.bInterfaceClass = 0x03, \
.bInterfaceProtocol = 0x02
/* table of devices that work with this driver */
static struct usb_device_id atp_table [] = {
{ ATP_DEVICE(0x020E) },
{ ATP_DEVICE(0x020F) },
{ ATP_DEVICE(0x030A) },
{ ATP_DEVICE(0x030B) },
{ ATP_DEVICE(0x0214) }, /* PowerBooks Late Oct 2005 */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, atp_table);
struct rchan* rch=NULL;
struct rchan_callbacks* rcb =NULL;
/* Debugfs data */
struct atp_dbg_data {
};
/*
* number of sensors. Note that only 16 instead of 26 X (horizontal)
* sensors exist on 12" and 15" PowerBooks. All models have 16 Y
* (vertical) sensors.
*/
#define ATP_MAX_XSENSORS 26
#define ATP_MAX_YSENSORS 16
/* amount of fuzz this touchpad generates */
#define ATP_FUZZ 16
/* maximum pressure this driver will report */
#define ATP_PRESSURE 300
/*
* multiplication factor for the X and Y coordinates.
* We try to keep the touchpad aspect ratio while still doing only simple
* arithmetics.
* The factors below give coordinates like:
* 0 <= x < 960 on 12" and 15" Powerbooks
* 0 <= x < 1600 on 17" Powerbooks
* 0 <= y < 646
*/
#define ATP_XFACT 64
#define ATP_YFACT 43
/*
* Threshold for the touchpad sensors. Any change less than ATP_THRESHOLD is
* ignored.
*/
#define ATP_THRESHOLD 5
typedef enum PB_MAC_TYPE {
PowerBook54,
PowerBook56,
PowerBook58,
PowerBook59,
Unknown
}PB_MAC_TYPE;
/* Structure to hold all of our device specific stuff */
struct atp {
struct usb_device * udev; /* usb device */
struct urb * urb; /* usb request block */
signed char * data; /* transferred data */
int open; /* non-zero if opened */
struct input_dev *input; /* input dev */
int valid; /* are the sensors valid ? */
int x_old; /* last reported x/y, */
int y_old; /* used for smoothing */
/* current value of the sensors */
signed char xy_cur[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
/* last value of the sensors */
signed char xy_old[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
/* accumulated sensors */
int xy_acc[ATP_MAX_XSENSORS + ATP_MAX_YSENSORS];
PB_MAC_TYPE mtype;
};
#define dbg_dump(msg, tab) \
if (debug > 1) { \
int i; \
printk("appletouch: %s %lld", msg, (long long)jiffies); \
for (i = 0; i < ATP_MAX_XSENSORS + ATP_MAX_YSENSORS; i++) \
printk(" %02x", tab[i]); \
printk("\n"); \
}
#define dprintk(format, a...) \
do { \
if (debug) printk(format, ##a); \
} while (0)
MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Parag Warudkar");
MODULE_DESCRIPTION("Apple Al PowerBook USB touchpad driver");
MODULE_LICENSE("GPL");
static int debug = 1;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activate debugging output");
/* USB URB buffer length - 81 works on Feb 05 models.
* Oct 05 models fail with EOVERFLOW, detected and corrected
* separately.
*/
static int data_len = 81;
module_param(data_len, int, 0644);
MODULE_PARM_DESC(data_len, "Specify USB URB buffer length (auto-detected normally)");
PB_MAC_TYPE atp_machine_detect()
{
if(machine_is_compatible("PowerBook5,9"))
return PowerBook59;
if(machine_is_compatible("PowerBook5,8"))
return PowerBook58;
if(machine_is_compatible("PowerBook5,6"))
return PowerBook56;
if (machine_is_compatible("PowerBook5,4"))
return PowerBook54;
return Unknown;
}
static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
int *z, int *fingers)
{
int i;
/* values to calculate mean */
int pcum = 0, psum = 0;
*fingers = 0;
for (i = 0; i < nb_sensors; i++) {
if (xy_sensors[i] < ATP_THRESHOLD)
continue;
if ((i - 1 < 0) || (xy_sensors[i - 1] < ATP_THRESHOLD))
(*fingers)++;
pcum += xy_sensors[i] * i;
psum += xy_sensors[i];
}
if (psum > 0) {
*z = psum;
return pcum * fact / psum;
}
return 0;
}
static inline void atp_report_fingers(struct input_dev *input, int fingers)
{
input_report_key(input, BTN_TOOL_FINGER, fingers == 1);
input_report_key(input, BTN_TOOL_DOUBLETAP, fingers == 2);
input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
}
static void atp_complete(struct urb* urb, struct pt_regs* regs)
{
int x, y, x_z, y_z, x_f, y_f;
int retval, i;
struct atp *dev = urb->context;
static int ctr=1;
switch (urb->status) {
case 0:
/* success */
break;
case -EOVERFLOW:
if(ctr){
printk("appletouch: OVERFLOW with data length %d\n", data_len);
ctr=0;
}
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
/* This urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d",
__FUNCTION__, urb->status);
return;
default:
goto exit;
}
/* drop incomplete datasets */
if (dev->urb->actual_length != data_len) {
printk(KERN_WARNING "appletouch: incomplete data package length %d\n", dev->urb->actual_length);
goto exit;
}
if ( dev->data ) {
relay_write(rch, dev->data, dev->urb->actual_length);
}
/* reorder the sensors values */
for (i = 0; i < 8; i++) {
/* X values */
dev->xy_cur[i ] = dev->data[5 * i + 2];
dev->xy_cur[i + 8] = dev->data[5 * i + 4];
dev->xy_cur[i + 16] = dev->data[5 * i + 42];
if (i < 2)
dev->xy_cur[i + 24] = dev->data[5 * i + 44];
/* Y values */
dev->xy_cur[i + 26] = dev->data[5 * i + 1];
dev->xy_cur[i + 34] = dev->data[5 * i + 3];
}
dbg_dump("sample", dev->xy_cur);
if (!dev->valid) {
/* first sample */
dev->valid = 1;
dev->x_old = dev->y_old = -1;
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
/* 17" Powerbooks have 10 extra X sensors */
for (i = 16; i < ATP_MAX_XSENSORS; i++)
if (dev->xy_cur[i]) {
printk("appletouch: 17\" model detected.\n");
input_set_abs_params(dev->input, ABS_X, 0,
(ATP_MAX_XSENSORS - 1) *
ATP_XFACT - 1,
ATP_FUZZ, 0);
break;
}
goto exit;
}
for (i = 0; i < ATP_MAX_XSENSORS + ATP_MAX_YSENSORS; i++) {
/* accumulate the change */
signed char change = dev->xy_old[i] - dev->xy_cur[i];
dev->xy_acc[i] -= change;
/* prevent down drifting */
if (dev->xy_acc[i] < 0)
dev->xy_acc[i] = 0;
}
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
dbg_dump("accumulator", dev->xy_acc);
x = atp_calculate_abs(dev->xy_acc, ATP_MAX_XSENSORS,
ATP_XFACT, &x_z, &x_f);
y = atp_calculate_abs(dev->xy_acc + ATP_MAX_XSENSORS, ATP_MAX_YSENSORS,
ATP_YFACT, &y_z, &y_f);
if (x && y) {
if (dev->x_old != -1) {
x = (dev->x_old * 3 + x) >> 2;
y = (dev->y_old * 3 + y) >> 2;
dev->x_old = x;
dev->y_old = y;
if (debug > 1)
printk("appletouch: X: %3d Y: %3d "
"Xz: %3d Yz: %3d\n",
x, y, x_z, y_z);
input_report_key(dev->input, BTN_TOUCH, 1);
input_report_abs(dev->input, ABS_X, x);
input_report_abs(dev->input, ABS_Y, y);
input_report_abs(dev->input, ABS_PRESSURE,
min(ATP_PRESSURE, x_z + y_z));
atp_report_fingers(dev->input, max(x_f, y_f));
}
dev->x_old = x;
dev->y_old = y;
}
else if (!x && !y) {
dev->x_old = dev->y_old = -1;
input_report_key(dev->input, BTN_TOUCH, 0);
input_report_abs(dev->input, ABS_PRESSURE, 0);
atp_report_fingers(dev->input, 0);
/* reset the accumulator on release */
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
}
input_report_key(dev->input, BTN_LEFT, !!dev->data[data_len-1]);
input_sync(dev->input);
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
if (retval) {
err("%s - usb_submit_urb failed with result %d",
__FUNCTION__, retval);
}
}
static int atp_open(struct input_dev *input)
{
struct atp *dev = input->private;
if (usb_submit_urb(dev->urb, GFP_ATOMIC)) {
printk("atp: usb_submit_urb Error\n");
return -EIO;
}
dev->open = 1;
return 0;
}
static void atp_close(struct input_dev *input)
{
struct atp *dev = input->private;
usb_kill_urb(dev->urb);
dev->open = 0;
}
static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
{
struct atp *dev = NULL;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int int_in_endpointAddr = 0;
int i, retval = -ENOMEM;
int regret=0;
printk(KERN_INFO "AppleTouch: Inside atp_probe\n");
/* allocate memory for our device state and initialize it */
dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
if (dev == NULL) {
err("Out of memory");
goto err_kmalloc;
}
memset(dev, 0, sizeof(struct atp));
dev->mtype = atp_machine_detect();
if(dev->mtype == Unknown)
{
printk(KERN_INFO "appletouch: Unknown machine type!\n");
return -ENODEV;
}
if(dev->mtype > 1)
{
if(data_len < 256)
{
printk(KERN_INFO "appletouch: Setting URB buffer length to 256\n");
data_len=256;
}
}
dev->udev = interface_to_usbdev(iface);
printk("appletouch: Machine type is: %d\n", dev->mtype);
/* set up the endpoint information */
/* use only the first interrupt-in endpoint */
iface_desc = iface->cur_altsetting;
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
endpoint = &iface_desc->endpoint[i].desc;
if (!int_in_endpointAddr &&
(endpoint->bEndpointAddress & USB_DIR_IN) &&
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
== USB_ENDPOINT_XFER_INT)) {
/* we found an interrupt in endpoint */
int_in_endpointAddr = endpoint->bEndpointAddress;
printk(KERN_INFO "AppleTouch:atp_probe Found interrupt in endpoint: %d\n", int_in_endpointAddr);
break;
}
}
if (!int_in_endpointAddr) {
retval = -EIO;
err("Could not find int-in endpoint");
goto err_endpoint;
}
/* save our data pointer in this interface device */
usb_set_intfdata(iface, dev);
dev->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!dev->urb) {
retval = -ENOMEM;
goto err_usballoc;
}
dev->data = usb_buffer_alloc(dev->udev, data_len, GFP_KERNEL,
&dev->urb->transfer_dma);
if (!dev->data) {
retval = -ENOMEM;
goto err_usbbufalloc;
}
usb_fill_int_urb(dev->urb, dev->udev,
usb_rcvintpipe(dev->udev, int_in_endpointAddr),
dev->data, data_len, atp_complete, dev, 1);
dev->input = input_allocate_device();
dev->input->name = "appletouch";
dev->input->dev = &iface->dev;
dev->input->private = dev;
dev->input->open = atp_open;
dev->input->close = atp_close;
usb_to_input_id(dev->udev, &dev->input->id);
set_bit(EV_ABS, dev->input->evbit);
/*
* 12" and 15" Powerbooks only have 16 x sensors,
* 17" models are detected later.
*/
input_set_abs_params(dev->input, ABS_X, 0,
(16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
input_set_abs_params(dev->input, ABS_Y, 0,
(ATP_MAX_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
input_set_abs_params(dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
set_bit(EV_KEY, dev->input->evbit);
set_bit(BTN_TOUCH, dev->input->keybit);
set_bit(BTN_TOOL_FINGER, dev->input->keybit);
set_bit(BTN_TOOL_DOUBLETAP, dev->input->keybit);
set_bit(BTN_TOOL_TRIPLETAP, dev->input->keybit);
set_bit(BTN_LEFT, dev->input->keybit
);
regret = input_register_device(dev->input);
printk(KERN_INFO "input: appletouch connected, Reg code :%d\n", regret);
return 0;
err_usbbufalloc:
usb_free_urb(dev->urb);
err_usballoc:
usb_set_intfdata(iface, NULL);
err_endpoint:
kfree(dev);
err_kmalloc:
return retval;
}
static void atp_disconnect(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);
usb_set_intfdata(iface, NULL);
if (dev) {
usb_kill_urb(dev->urb);
input_unregister_device(dev->input);
usb_free_urb(dev->urb);
usb_buffer_free(dev->udev, data_len,
dev->data, dev->urb->transfer_dma);
kfree(dev);
}
printk(KERN_INFO "input: appletouch disconnected\n");
}
static int atp_suspend(struct usb_interface *iface, pm_message_t message)
{
struct atp *dev = usb_get_intfdata(iface);
usb_kill_urb(dev->urb);
dev->valid = 0;
return 0;
}
static int atp_resume(struct usb_interface *iface)
{
struct atp *dev = usb_get_intfdata(iface);
if (dev->open && usb_submit_urb(dev->urb, GFP_ATOMIC))
return -EIO;
return 0;
}
static struct usb_driver atp_driver = {
.owner = THIS_MODULE,
.name = "appletouch",
.probe = atp_probe,
.disconnect = atp_disconnect,
.suspend = atp_suspend,
.resume = atp_resume,
.id_table = atp_table,
};
static int __init atp_init(void)
{
rcb = kmalloc(sizeof(struct rchan_callbacks), GFP_KERNEL);
rcb->subbuf_start = NULL;
rcb->buf_mapped = NULL;
rcb->buf_unmapped = NULL;
rch = relay_open("atpdata", NULL, 256, 256, NULL);
if (!rch) return -ENOMEM;
return usb_register(&atp_driver);
}
static void __exit atp_exit(void)
{
relay_close(rch);
kfree(rcb);
usb_deregister(&atp_driver);
}
module_init(atp_init);
module_exit(atp_exit);
^ permalink raw reply
* anyone used i2c-algo-8260 for the MPC8272 family?
From: Ron Kellam @ 2005-11-22 3:19 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <qpr2o1dhoelk8rt11jl3lbangfs0hj710a@4ax.com>
I'm posting this just to capture the solution. An actual patch may
follow sometime down the track.
By looking over some code I got from Dave Bruce (thanks Dave!), I
tried replacing the use of __pa() with iopa(). With just this change,
the driver now "works for me".
I'm not sure of the details of the difference. Anyone care to
elaborate?
By the way, as stated in another thread, I'm working with a
denx-2.4.25 kernel.
Regards,
Ron Kellam.
^ permalink raw reply
* [PATCH] powerpc: Add OF address parsing code
From: Benjamin Herrenschmidt @ 2005-11-22 4:45 UTC (permalink / raw)
To: linuxppc64-dev; +Cc: linuxppc-dev list
Parsing addresses extracted from Open Firmware isn't a simple matter. We
have various bits of code that try to do it in various place, including
some heuristics in prom.c that pre-parse addresses at boot and fill
device-nodes "addrs", but those are dodgy at best and I want to
deprecate them. So this patch introduces a new set of routines that
should be capable of parsing most types of addresses and translating
them into CPU physical addresses. It currently works for things on PCI
busses and ISA busses and should work on "standard" busses like the root
bus or the MacIO bus that don't put funky flags in addresses. If you
have other bus types that do use funky flags, you'll have to add new bus
type translators, which is fairly easy.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This is not for 2.6.15. It's part of a series of patch which, when complete,
will unify serial port detection and udbg, and remove completely "addrs"
and the crappy heuristics from prom.c
Index: linux-serialfix/arch/powerpc/kernel/Makefile
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/Makefile 2005-11-22 14:41:26.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/Makefile 2005-11-22 15:43:43.000000000 +1100
@@ -12,7 +12,8 @@
endif
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
- irq.o align.o signal_32.o pmc.o vdso.o
+ irq.o align.o signal_32.o pmc.o vdso.o \
+ prom_parse.o
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o systbl.o \
Index: linux-serialfix/arch/powerpc/kernel/prom_parse.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-serialfix/arch/powerpc/kernel/prom_parse.c 2005-11-22 15:11:59.000000000 +1100
@@ -0,0 +1,404 @@
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/pci_regs.h>
+#include <linux/module.h>
+#include <asm/prom.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+/* Max address size we deal with */
+#define OF_MAX_ADDR_CELLS 4
+#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
+ (ns) > 0)
+
+/* Debug utility */
+#ifdef DEBUG
+static void of_dump_addr(const char *s, u32 *addr, int na)
+{
+ printk("%s", s);
+ while(na--)
+ printk(" %08x", *(addr++));
+ printk("\n");
+}
+#else
+static void of_dump_addr(const char *s, u32 *addr, int na) { }
+#endif
+
+/* Read a big address */
+static inline u64 of_read_addr(u32 *cell, int size)
+{
+ u64 r = 0;
+ while (size--)
+ r = (r << 32) | *(cell++);
+ return r;
+}
+
+/* Callbacks for bus specific translators */
+struct of_bus {
+ char *name;
+ int (*match)(struct device_node *parent);
+ void (*count_cells)(struct device_node *child,
+ int *addrc, int *sizec);
+ u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
+ int (*translate)(u32 *addr, u64 offset, int na);
+};
+
+
+/*
+ * Default translator (generic bus)
+ */
+
+static void of_default_count_cells(struct device_node *dev,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = prom_n_addr_cells(dev);
+ if (sizec)
+ *sizec = prom_n_size_cells(dev);
+}
+
+static u64 of_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ cp = of_read_addr(range, na);
+ s = of_read_addr(range + na + pna, ns);
+ da = of_read_addr(addr, na);
+
+ DBG("OF: default map, cp=%lx, s=%lx, da=%lx\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_default_translate(u32 *addr, u64 offset, int na)
+{
+ u64 a = of_read_addr(addr, na);
+ memset(addr, 0, na * 4);
+ a += offset;
+ if (na > 1)
+ addr[na - 2] = a >> 32;
+ addr[na - 1] = a & 0xffffffffu;
+
+ return 0;
+}
+
+
+/*
+ * PCI bus specific translator
+ */
+
+static int of_bus_pci_match(struct device_node *np)
+{
+ return !strcmp(np->type, "pci");
+}
+
+static void of_bus_pci_count_cells(struct device_node *np,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 3;
+ if (sizec)
+ *sizec = 2;
+}
+
+static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x03000000)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_addr(range + 1, na - 1);
+ s = of_read_addr(range + na + pna, ns);
+ da = of_read_addr(addr + 1, na - 1);
+
+ DBG("OF: PCI map, cp=%lx, s=%lx, da=%lx\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
+{
+ return of_default_translate(addr + 1, offset, na - 1);
+}
+
+/*
+ * ISA bus specific translator
+ */
+
+static int of_bus_isa_match(struct device_node *np)
+{
+ return !strcmp(np->name, "isa");
+}
+
+static void of_bus_isa_count_cells(struct device_node *child,
+ int *addrc, int *sizec)
+{
+ if (addrc)
+ *addrc = 2;
+ if (sizec)
+ *sizec = 1;
+}
+
+static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
+{
+ u64 cp, s, da;
+
+ /* Check address type match */
+ if ((addr[0] ^ range[0]) & 0x00000001)
+ return OF_BAD_ADDR;
+
+ /* Read address values, skipping high cell */
+ cp = of_read_addr(range + 1, na - 1);
+ s = of_read_addr(range + na + pna, ns);
+ da = of_read_addr(addr + 1, na - 1);
+
+ DBG("OF: ISA map, cp=%lx, s=%lx, da=%lx\n", cp, s, da);
+
+ if (da < cp || da >= (cp + s))
+ return OF_BAD_ADDR;
+ return da - cp;
+}
+
+static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
+{
+ return of_default_translate(addr + 1, offset, na - 1);
+}
+
+/*
+ * Array of bus specific translators
+ */
+
+static struct of_bus of_busses[] = {
+ /* PCI */
+ {
+ .name = "pci",
+ .match = of_bus_pci_match,
+ .count_cells = of_bus_pci_count_cells,
+ .map = of_bus_pci_map,
+ .translate = of_bus_pci_translate,
+ },
+ /* ISA */
+ {
+ .name = "isa",
+ .match = of_bus_isa_match,
+ .count_cells = of_bus_isa_count_cells,
+ .map = of_bus_isa_map,
+ .translate = of_bus_isa_translate,
+ },
+ /* Default */
+ {
+ .name = "default",
+ .match = NULL,
+ .count_cells = of_default_count_cells,
+ .map = of_default_map,
+ .translate = of_default_translate,
+ },
+};
+
+static struct of_bus *of_match_bus(struct device_node *np)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(of_busses); i ++)
+ if (!of_busses[i].match || of_busses[i].match(np))
+ return &of_busses[i];
+ BUG();
+ return NULL;
+}
+
+static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+ struct of_bus *pbus, u32 *addr,
+ int na, int ns, int pna)
+{
+ u32 *ranges;
+ unsigned int rlen;
+ int rone;
+ u64 offset = OF_BAD_ADDR;
+
+ /* No "ranges" property is not an error */
+ ranges = (u32 *)get_property(parent, "ranges", &rlen);
+ if (ranges == NULL) {
+ offset = of_read_addr(addr, na);
+ memset(addr, 0, pna);
+ goto finish;
+ }
+
+ DBG("OF: walking ranges...\n");
+
+ /* Now walk through the ranges */
+ rlen /= 4;
+ rone = na + pna + ns;
+ for (; rlen >= rone; rlen -= rone, ranges += rone) {
+ offset = bus->map(addr, ranges, na, ns, pna);
+ if (offset != OF_BAD_ADDR)
+ break;
+ }
+ if (offset == OF_BAD_ADDR) {
+ DBG("OF: not found !\n");
+ return 1;
+ }
+ memcpy(addr, ranges + na, 4 * pna);
+
+ finish:
+ of_dump_addr("OF: parent translation for:", addr, pna);
+ DBG("OF: with offset: %lx\n", offset);
+
+ /* Translate it into parent bus space */
+ return pbus->translate(addr, offset, pna);
+}
+
+
+/*
+ * Translate an address from the device-tree into a CPU physical address,
+ * this walks up the tree and applies the various bus mappings on the
+ * way.
+ *
+ * Note: We consider that crossing any level with #size-cells == 0 to mean
+ * that translation is impossible (that is we are not dealing with a value
+ * that can be mapped to a cpu physical address). This is not really specified
+ * that way, but this is traditionally the way IBM at least do things
+ */
+u64 of_translate_address(struct device_node *dev, u32 *in_addr)
+{
+ struct device_node *parent = NULL;
+ struct of_bus *bus, *pbus;
+ u32 addr[OF_MAX_ADDR_CELLS];
+ int na, ns, pna, pns;
+ u64 result = OF_BAD_ADDR;
+
+ DBG("OF: ** translation for device %s **\n", dev->full_name);
+
+ /* Increase refcount at current level */
+ of_node_get(dev);
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ goto bail;
+ bus = of_match_bus(parent);
+
+ /* Cound address cells & copy address locally */
+ bus->count_cells(dev, &na, &ns);
+ if (!OF_CHECK_COUNTS(na, ns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ goto bail;
+ }
+ memcpy(addr, in_addr, na * 4);
+
+ DBG("OF: bus is %s (na=%d, ns=%d) on %s\n",
+ bus->name, na, ns, parent->full_name);
+ of_dump_addr("OF: translating address:", addr, na);
+
+ /* Translate */
+ for (;;) {
+ /* Switch to parent bus */
+ of_node_put(dev);
+ dev = parent;
+ parent = of_get_parent(dev);
+
+ /* If root, we have finished */
+ if (parent == NULL) {
+ DBG("OF: reached root node\n");
+ result = of_read_addr(addr, na);
+ break;
+ }
+
+ /* Get new parent bus and counts */
+ pbus = of_match_bus(parent);
+ pbus->count_cells(dev, &pna, &pns);
+ if (!OF_CHECK_COUNTS(pna, pns)) {
+ printk(KERN_ERR "prom_parse: Bad cell count for %s\n",
+ dev->full_name);
+ break;
+ }
+
+ DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n",
+ pbus->name, pna, pns, parent->full_name);
+
+ /* Apply bus translation */
+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+ break;
+
+ /* Complete the move up one level */
+ na = pna;
+ ns = pns;
+ bus = pbus;
+
+ of_dump_addr("OF: one level translation:", addr, na);
+ }
+ bail:
+ of_node_put(parent);
+ of_node_put(dev);
+
+ return result;
+}
+EXPORT_SYMBOL(of_translate_address);
+
+u32 *of_get_address(struct device_node *dev, int index, u64 *size)
+{
+ u32 *prop;
+ unsigned int psize;
+ struct device_node *parent;
+ struct of_bus *bus;
+ int onesize, i, na, ns;
+
+ /* Get "reg" property */
+ prop = (u32 *)get_property(dev, "reg", &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+
+ /* Get parent & match bus type */
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return NULL;
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+ of_node_put(parent);
+ if (!OF_CHECK_COUNTS(na, ns))
+ return NULL;
+
+ onesize = na + ns;
+ for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
+ if (i == index) {
+ if (size)
+ *size = of_read_addr(prop + na, ns);
+ return prop;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_address);
+
+u32 *of_get_pci_addr(struct device_node *pd, int bar, u64 *out_size)
+{
+ u32 *prop;
+ unsigned int psize;
+
+ prop = (u32 *)get_property(pd, "assigned-addresses", &psize);
+ if (prop == NULL)
+ return NULL;
+ psize /= 4;
+ for (; psize >= 5; psize -= 5, prop += 5) {
+ if (bar == (((prop[0] & 0xff) - PCI_BASE_ADDRESS_0) / 4)) {
+ if (out_size)
+ *out_size = of_read_addr(prop + 3, 2);
+ return prop;
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL(of_get_pci_addr);
Index: linux-serialfix/include/asm-powerpc/mmu.h
===================================================================
--- linux-serialfix.orig/include/asm-powerpc/mmu.h 2005-11-22 14:41:26.000000000 +1100
+++ linux-serialfix/include/asm-powerpc/mmu.h 2005-11-22 14:41:49.000000000 +1100
@@ -393,6 +393,10 @@
#define VSID_SCRAMBLE(pvsid) (((pvsid) * VSID_MULTIPLIER) % VSID_MODULUS)
#define KERNEL_VSID(ea) VSID_SCRAMBLE(GET_ESID(ea))
+/* Physical address used by some IO functions */
+typedef unsigned long phys_addr_t;
+
+
#endif /* __ASSEMBLY */
#endif /* CONFIG_PPC64 */
Index: linux-serialfix/include/asm-powerpc/prom.h
===================================================================
--- linux-serialfix.orig/include/asm-powerpc/prom.h 2005-11-22 14:41:26.000000000 +1100
+++ linux-serialfix/include/asm-powerpc/prom.h 2005-11-22 14:41:49.000000000 +1100
@@ -223,5 +223,14 @@
int index, const char* name_postfix);
extern int release_OF_resource(struct device_node* node, int index);
+/*
+ * Address translation function(s)
+ */
+#define OF_BAD_ADDR ((u64)-1)
+extern u64 of_translate_address(struct device_node *np, u32 *addr);
+extern u32 *of_get_address(struct device_node *dev, int index, u64 *size);
+extern u32 *of_get_pci_addr(struct device_node *pd, int bar, u64 *out_size);
+
+
#endif /* __KERNEL__ */
#endif /* _POWERPC_PROM_H */
Index: linux-serialfix/include/asm-ppc/prom.h
===================================================================
--- linux-serialfix.orig/include/asm-ppc/prom.h 2005-11-22 14:41:26.000000000 +1100
+++ linux-serialfix/include/asm-ppc/prom.h 2005-11-22 14:41:49.000000000 +1100
@@ -136,5 +136,15 @@
#define PTRRELOC(x) ((typeof(x))add_reloc_offset((unsigned long)(x)))
#define PTRUNRELOC(x) ((typeof(x))sub_reloc_offset((unsigned long)(x)))
+
+/*
+ * Address translation function(s)
+ */
+#define OF_BAD_ADDR ((u64)-1)
+extern u64 of_translate_address(struct device_node *np, u32 *addr);
+extern u32 *of_get_address(struct device_node *dev, int index, u64 *size);
+extern u32 *of_get_pci_addr(struct device_node *pd, int bar, u64 *out_size);
+
+
#endif /* _PPC_PROM_H */
#endif /* __KERNEL__ */
^ permalink raw reply
* [PATCH] powerpc: serial port discovery
From: Benjamin Herrenschmidt @ 2005-11-22 4:49 UTC (permalink / raw)
To: linuxppc64-dev; +Cc: linuxppc-dev list
This moves the discovery of legacy serial ports to a separate file,
makes it common to ppc32 and ppc64, and reworks it to use the new OF
address translators to get to the ports early. This new version can also
detect some PCI serial cards using legacy chips and will probably match
those discovered port with the default console choice.
Only ppc64 gets udbg still yet, unifying udbg isn't finished yet.
It also adds some speed-probing code to udbg so that the default console
can come up at the same speed it was set to by the firmware.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
Same comments as for the previous one, this isn't 1.6.15 material.
Index: linux-serialfix/arch/powerpc/kernel/legacy_serial.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-serialfix/arch/powerpc/kernel/legacy_serial.c 2005-11-22 15:43:37.000000000 +1100
@@ -0,0 +1,478 @@
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/console.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <asm/prom.h>
+#include <asm/serial.h>
+#include <asm/udbg.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+#define MAX_LEGACY_SERIAL_PORTS 8
+
+static struct plat_serial8250_port
+legacy_serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
+static struct legacy_serial_info {
+ struct device_node *np;
+ unsigned int speed;
+ unsigned int clock;
+ phys_addr_t taddr;
+} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
+static unsigned int legacy_serial_count;
+static int legacy_serial_console = -1;
+
+static int __init add_legacy_port(struct device_node *np, int want_index,
+ int iotype, phys_addr_t base,
+ phys_addr_t taddr, unsigned long irq)
+{
+ u32 *clk, *spd, clock;
+ int index;
+
+ /* get clock freq. if present */
+ clk = (u32 *)get_property(np, "clock-frequency", NULL);
+ clock = clk ? *clk : BASE_BAUD * 16;
+
+ /* get default speed if present */
+ spd = (u32 *)get_property(np, "current-speed", NULL);
+
+ /* If we have a location index, then try to use it */
+ if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
+ index = want_index;
+ else
+ index = legacy_serial_count;
+
+ /* if our index is still out of range, that mean that
+ * array is full, we could scan for a free slot but that
+ * make little sense to bother, just skip the port
+ */
+ if (index >= MAX_LEGACY_SERIAL_PORTS)
+ return -1;
+ if (index >= legacy_serial_count)
+ legacy_serial_count = index + 1;
+
+ /* Check if there is a port who already claimed our slot */
+ if (legacy_serial_infos[index].np != 0) {
+ /* if we still have some room, move it, else override */
+ if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
+ printk(KERN_INFO "Moved legacy port %d -> %d\n",
+ index, legacy_serial_count);
+ legacy_serial_ports[legacy_serial_count] =
+ legacy_serial_ports[index];
+ legacy_serial_infos[legacy_serial_count] =
+ legacy_serial_infos[index];
+ legacy_serial_count++;
+ } else {
+ printk(KERN_INFO "Replacing legacy port %d\n", index);
+ }
+ }
+
+ /* Now fill the entry */
+ memset(&legacy_serial_ports[index], 0,
+ sizeof(struct plat_serial8250_port));
+ if (iotype == UPIO_PORT)
+ legacy_serial_ports[index].iobase = base;
+ else
+ legacy_serial_ports[index].membase = (void __iomem *)base;
+ legacy_serial_ports[index].iotype = iotype;
+ legacy_serial_ports[index].uartclk = clock;
+ legacy_serial_ports[index].irq = irq;
+ legacy_serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
+ legacy_serial_infos[index].taddr = taddr;
+ legacy_serial_infos[index].np = of_node_get(np);
+ legacy_serial_infos[index].clock = clock;
+ legacy_serial_infos[index].speed = spd ? *spd : 0;
+
+ printk(KERN_INFO "Found legacy serial port %d for %s\n",
+ index, np->full_name);
+ printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
+ (iotype == UPIO_PORT) ? "port" : "mem",
+ (unsigned long long)base, (unsigned long long)taddr, irq,
+ legacy_serial_ports[index].uartclk,
+ legacy_serial_infos[index].speed);
+
+ return index;
+}
+
+static int __init add_legacy_isa_port(struct device_node *np,
+ struct device_node *isa_bridge)
+{
+ u32 *reg;
+ char *typep;
+ int index = -1;
+ phys_addr_t taddr;
+
+ /* Get the ISA port number */
+ reg = (u32 *)get_property(np, "reg", NULL);
+ if (reg == NULL)
+ return -1;
+
+ /* Verify it's an IO port, we don't support anything else */
+ if (!(reg[0] & 0x00000001))
+ return -1;
+
+ /* Now look for an "ibm,aix-loc" property that gives us ordering
+ * if any...
+ */
+ typep = (char *)get_property(np, "ibm,aix-loc", NULL);
+
+ /* If we have a location index, then use it */
+ if (typep && *typep == 'S')
+ index = simple_strtol(typep+1, NULL, 0) - 1;
+
+ /* Translate ISA address */
+ taddr = of_translate_address(np, reg);
+
+ /* Add port, irq will be dealt with later */
+ return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ);
+
+}
+
+static int __init add_legacy_pci_port(struct device_node *np,
+ struct device_node *pci_dev)
+{
+ phys_addr_t addr, base;
+ u32 *addrp;
+ int iotype, index = -1;
+
+#if 0
+ /* We only support ports that have a clock frequency properly
+ * encoded in the device-tree (that is have an fcode). Anything
+ * else can't be used that early and will be normally probed by
+ * the generic 8250_pci driver later on.
+ */
+ if (get_property(np, "clock-frequency", NULL) == NULL)
+ return -1;
+#endif
+
+ /* Get the PCI address. Assume BAR 0 */
+ addrp = of_get_pci_addr(pci_dev, 0, NULL);
+ if (addrp == NULL)
+ return -1;
+
+ /* We only support BAR 0 for now */
+ iotype = (addrp[0] & 0x02000000) ? UPIO_MEM : UPIO_PORT;
+ addr = of_translate_address(pci_dev, addrp);
+
+ /* Set the IO base to the same as the translated address for MMIO,
+ * or to the domain local IO base for PIO (it will be fixed up later)
+ */
+ if (iotype == UPIO_MEM)
+ base = addr;
+ else
+ base = addrp[2];
+
+ /* Try to guess an index... If we have subdevices of the pci dev,
+ * we get to their "reg" property
+ */
+ if (np != pci_dev) {
+ u32 *reg = (u32 *)get_property(np, "reg", NULL);
+ if (reg && (*reg < 4))
+ index = legacy_serial_count + *reg;
+ }
+
+ /* Add port, irq will be dealt with later. We passed a translated
+ * IO port value. It will be fixed up later along with the irq
+ */
+ return add_legacy_port(np, index, iotype, base, addr, NO_IRQ);
+}
+
+/*
+ * This is called very early, as part of setup_system() or eventually
+ * setup_arch(), basically before anything else in this file. This function
+ * will try to build a list of all the available 8250-compatible serial ports
+ * in the machine using the Open Firmware device-tree. It currently only deals
+ * with ISA and PCI busses but could be extended. It allows a very early boot
+ * console to be initialized, that list is also used later to provide 8250 with
+ * the machine non-PCI ports and to properly pick the default console port
+ */
+void __init find_legacy_serial_ports(void)
+{
+ struct device_node *np, *stdout;
+ char *path;
+ int index;
+
+ DBG(" -> find_legacy_serial_port()\n");
+
+ /* Now find out if one of these is out firmware console */
+ path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (path == NULL) {
+ DBG(" no linux,stdout-path !\n");
+ return;
+ }
+ stdout = of_find_node_by_path(path);
+ if (stdout) {
+ DBG("stdout is %s\n", stdout->full_name);
+ }
+
+ /* First fill our array with ISA ports */
+ for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
+ struct device_node *isa = of_get_parent(np);
+ if (isa && !strcmp(isa->name, "isa")) {
+ index = add_legacy_isa_port(np, isa);
+ if (index >= 0 && np == stdout)
+ legacy_serial_console = index;
+ }
+ of_node_put(isa);
+ }
+
+ /* Next, try to locate PCI ports */
+ for (np = NULL; (np = of_find_all_nodes(np));) {
+ struct device_node *pci, *parent = of_get_parent(np);
+ if (parent && !strcmp(parent->name, "isa")) {
+ of_node_put(parent);
+ continue;
+ }
+ if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) {
+ of_node_put(parent);
+ continue;
+ }
+ /* Check for known pciclass, and also check wether we have
+ * a device with child nodes for ports or not
+ */
+ if (device_is_compatible(np, "pciclass,0700") ||
+ device_is_compatible(np, "pciclass,070002"))
+ pci = np;
+ else if (device_is_compatible(parent, "pciclass,0700") ||
+ device_is_compatible(parent, "pciclass,070002"))
+ pci = parent;
+ else {
+ of_node_put(parent);
+ continue;
+ }
+ index = add_legacy_pci_port(np, pci);
+ if (index >= 0 && np == stdout)
+ legacy_serial_console = index;
+ of_node_put(parent);
+ }
+
+ DBG("legacy_serial_console = %d\n", legacy_serial_console);
+
+ /* udbg is 64 bits only for now, that will change soon though ... */
+#ifdef CONFIG_PPC64
+ while (legacy_serial_console >= 0) {
+ struct legacy_serial_info *info =
+ &legacy_serial_infos[legacy_serial_console];
+ void __iomem *addr;
+
+ if (info->taddr == 0)
+ break;
+ addr = ioremap(info->taddr, 0x1000);
+ if (addr == NULL)
+ break;
+ if (info->speed == 0)
+ info->speed = udbg_probe_uart_speed(addr, info->clock);
+ DBG("default console speed = %d\n", info->speed);
+ udbg_init_uart(addr, info->speed, info->clock);
+ break;
+ }
+#endif /* CONFIG_PPC64 */
+
+ DBG(" <- find_legacy_serial_port()\n");
+}
+
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = legacy_serial_ports,
+ },
+};
+
+static void __init fixup_port_irq(int index,
+ struct device_node *np,
+ struct plat_serial8250_port *port)
+{
+ DBG("fixup_port_irq(%d)\n", index);
+
+ /* Check for interrupts in that node */
+ if (np->n_intrs > 0) {
+ port->irq = np->intrs[0].line;
+ DBG(" port %d (%s), irq=%d\n",
+ index, np->full_name, port->irq);
+ return;
+ }
+
+ /* Check for interrupts in the parent */
+ np = of_get_parent(np);
+ if (np == NULL)
+ return;
+
+ if (np->n_intrs > 0) {
+ port->irq = np->intrs[0].line;
+ DBG(" port %d (%s), irq=%d\n",
+ index, np->full_name, port->irq);
+ }
+ of_node_put(np);
+}
+
+static void __init fixup_port_pio(int index,
+ struct device_node *np,
+ struct plat_serial8250_port *port)
+{
+ struct pci_controller *hose;
+
+ DBG("fixup_port_pio(%d)\n", index);
+
+ hose = pci_find_hose_for_OF_device(np);
+ if (hose) {
+ unsigned long offset = (unsigned long)hose->io_base_virt -
+#ifdef CONFIG_PPC64
+ pci_io_base;
+#else
+ isa_io_base;
+#endif
+ DBG("port %d, IO %lx -> %lx\n",
+ index, port->iobase, port->iobase + offset);
+ port->iobase += offset;
+ }
+}
+
+/*
+ * This is called as an arch initcall, hopefully before the PCI bus is
+ * probed and/or the 8250 driver loaded since we need to register our
+ * platform devices before 8250 PCI ones are detected as some of them
+ * must properly "override" the platform ones.
+ *
+ * This function fixes up the interrupt value for platform ports as it
+ * couldn't be done earlier before interrupt maps have been parsed. It
+ * also "corrects" the IO address for PIO ports for the same reason,
+ * since earlier, the PHBs virtual IO space wasn't assigned yet. It then
+ * registers all those platform ports for use by the 8250 driver when it
+ * finally loads.
+ */
+static int __init serial_dev_init(void)
+{
+ int i;
+
+ if (legacy_serial_count == 0)
+ return -ENODEV;
+
+ /*
+ * Before we register the platfrom serial devices, we need
+ * to fixup their interrutps and their IO ports.
+ */
+ DBG("Fixing serial ports interrupts and IO ports ...\n");
+
+ for (i = 0; i < legacy_serial_count; i++) {
+ struct plat_serial8250_port *port = &legacy_serial_ports[i];
+ struct device_node *np = legacy_serial_infos[i].np;
+
+ if (port->irq == NO_IRQ)
+ fixup_port_irq(i, np, port);
+ if (port->iotype == UPIO_PORT)
+ fixup_port_pio(i, np, port);
+ }
+
+ DBG("Registering platform serial ports\n");
+
+ return platform_device_register(&serial_device);
+}
+arch_initcall(serial_dev_init);
+
+
+/*
+ * This is called very early, as part of console_init() (typically just after
+ * time_init()). This function is respondible for trying to find a good
+ * default console on serial ports. It tries to match the open firmware
+ * default output with one of the available serial console drivers, either
+ * one of the platform serial ports that have been probed earlier by
+ * find_legacy_serial_ports() or some more platform specific ones.
+ */
+static int __init check_legacy_serial_console(void)
+{
+ struct device_node *prom_stdout = NULL;
+ int speed = 0, offset = 0;
+ char *name;
+ u32 *spd;
+
+ DBG(" -> check_legacy_serial_console()\n");
+
+ /* The user has requested a console so this is already set up. */
+ if (strstr(saved_command_line, "console=")) {
+ DBG(" console was specified !\n");
+ return -EBUSY;
+ }
+
+ if (!of_chosen) {
+ DBG(" of_chosen is NULL !\n");
+ return -ENODEV;
+ }
+ /* We are getting a weird phandle from OF ... */
+ /* ... So use the full path instead */
+ name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+ if (name == NULL) {
+ DBG(" no linux,stdout-path !\n");
+ return -ENODEV;
+ }
+ prom_stdout = of_find_node_by_path(name);
+ if (!prom_stdout) {
+ DBG(" can't find stdout package %s !\n", name);
+ return -ENODEV;
+ }
+ DBG("stdout is %s\n", prom_stdout->full_name);
+
+ name = (char *)get_property(prom_stdout, "name", NULL);
+ if (!name) {
+ DBG(" stdout package has no name !\n");
+ goto not_found;
+ }
+ spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
+ if (spd)
+ speed = *spd;
+
+ if (0)
+ ;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ else if (strcmp(name, "serial") == 0) {
+ int i;
+ /* Look for it in probed array */
+ for (i = 0; i < legacy_serial_count; i++) {
+ if (prom_stdout != legacy_serial_infos[i].np)
+ continue;
+ offset = i;
+ speed = legacy_serial_infos[i].speed;
+ break;
+ }
+ if (i >= legacy_serial_count)
+ goto not_found;
+ }
+#endif /* CONFIG_SERIAL_8250_CONSOLE */
+#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
+ else if (strcmp(name, "ch-a") == 0)
+ offset = 0;
+ else if (strcmp(name, "ch-b") == 0)
+ offset = 1;
+#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
+ else
+ goto not_found;
+ of_node_put(prom_stdout);
+
+ DBG("Found serial console at ttyS%d\n", offset);
+
+ if (speed) {
+ static char __initdata opt[16];
+ sprintf(opt, "%d", speed);
+ return add_preferred_console("ttyS", offset, opt);
+ } else
+ return add_preferred_console("ttyS", offset, NULL);
+
+ not_found:
+ DBG("No preferred console found !\n");
+ of_node_put(prom_stdout);
+ return -ENODEV;
+}
+console_initcall(check_legacy_serial_console);
+
Index: linux-serialfix/arch/powerpc/kernel/Makefile
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/Makefile 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/Makefile 2005-11-22 15:12:20.000000000 +1100
@@ -32,10 +32,6 @@
obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
-obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o
-obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o
-udbgscc-$(CONFIG_PPC64) := udbg_scc.o
-obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y)
obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
ifeq ($(CONFIG_PPC_MERGE),y)
@@ -58,14 +54,15 @@
obj-$(CONFIG_6xx) += idle_6xx.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_KPROBES) += kprobes.o
-
+obj-$(CONFIG_PPC_MULTIPLATFORM) += legacy_serial.o
+obj64-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
+obj64-$(CONFIG_PPC_PMAC) += udbg_scc.o
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
pci_direct_iommu.o iomap.o
obj-$(CONFIG_PCI) += $(pci64-y)
-
kexec64-$(CONFIG_PPC64) += machine_kexec_64.o
obj-$(CONFIG_KEXEC) += $(kexec64-y)
Index: linux-serialfix/arch/powerpc/kernel/setup-common.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/setup-common.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/setup-common.c 2005-11-22 15:12:20.000000000 +1100
@@ -294,129 +294,6 @@
.show = show_cpuinfo,
};
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static int __init set_preferred_console(void)
-{
- struct device_node *prom_stdout = NULL;
- char *name;
- u32 *spd;
- int offset = 0;
-
- DBG(" -> set_preferred_console()\n");
-
- /* The user has requested a console so this is already set up. */
- if (strstr(saved_command_line, "console=")) {
- DBG(" console was specified !\n");
- return -EBUSY;
- }
-
- if (!of_chosen) {
- DBG(" of_chosen is NULL !\n");
- return -ENODEV;
- }
- /* We are getting a weird phandle from OF ... */
- /* ... So use the full path instead */
- name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
- if (name == NULL) {
- DBG(" no linux,stdout-path !\n");
- return -ENODEV;
- }
- prom_stdout = of_find_node_by_path(name);
- if (!prom_stdout) {
- DBG(" can't find stdout package %s !\n", name);
- return -ENODEV;
- }
- DBG("stdout is %s\n", prom_stdout->full_name);
-
- name = (char *)get_property(prom_stdout, "name", NULL);
- if (!name) {
- DBG(" stdout package has no name !\n");
- goto not_found;
- }
- spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
-
- if (0)
- ;
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- else if (strcmp(name, "serial") == 0) {
- int i;
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
- if (i > 8) {
- switch (reg[1]) {
- case 0x3f8:
- offset = 0;
- break;
- case 0x2f8:
- offset = 1;
- break;
- case 0x898:
- offset = 2;
- break;
- case 0x890:
- offset = 3;
- break;
- default:
- /* We dont recognise the serial port */
- goto not_found;
- }
- }
- }
-#endif /* CONFIG_SERIAL_8250_CONSOLE */
-#ifdef CONFIG_PPC_PSERIES
- else if (strcmp(name, "vty") == 0) {
- u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL);
- char *compat = (char *)get_property(prom_stdout, "compatible", NULL);
-
- if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) {
- /* Host Virtual Serial Interface */
- switch (reg[0]) {
- case 0x30000000:
- offset = 0;
- break;
- case 0x30000001:
- offset = 1;
- break;
- default:
- goto not_found;
- }
- of_node_put(prom_stdout);
- DBG("Found hvsi console at offset %d\n", offset);
- return add_preferred_console("hvsi", offset, NULL);
- } else {
- /* pSeries LPAR virtual console */
- of_node_put(prom_stdout);
- DBG("Found hvc console\n");
- return add_preferred_console("hvc", 0, NULL);
- }
- }
-#endif /* CONFIG_PPC_PSERIES */
-#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
- else if (strcmp(name, "ch-a") == 0)
- offset = 0;
- else if (strcmp(name, "ch-b") == 0)
- offset = 1;
-#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
- else
- goto not_found;
- of_node_put(prom_stdout);
-
- DBG("Found serial console at ttyS%d\n", offset);
-
- if (spd) {
- static char __initdata opt[16];
- sprintf(opt, "%d", *spd);
- return add_preferred_console("ttyS", offset, opt);
- } else
- return add_preferred_console("ttyS", offset, NULL);
-
- not_found:
- DBG("No preferred console found !\n");
- of_node_put(prom_stdout);
- return -ENODEV;
-}
-console_initcall(set_preferred_console);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
void __init check_for_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
Index: linux-serialfix/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/setup_64.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/setup_64.c 2005-11-22 15:12:20.000000000 +1100
@@ -451,6 +451,15 @@
*/
ppc_md.init_early();
+ /*
+ * We can discover serial ports now since the above did setup the
+ * hash table management for us, thus ioremap works. We do that early
+ * so that further code can be debugged
+ */
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ find_legacy_serial_ports();
+#endif
+
/*
* "Finish" the device-tree, that is do the actual parsing of
* some of the properties like the interrupt map
@@ -649,187 +658,6 @@
printk("[terminate]%04x %s\n", src, msg);
}
-#ifndef CONFIG_PPC_ISERIES
-/*
- * This function can be used by platforms to "find" legacy serial ports.
- * It works for "serial" nodes under an "isa" node, and will try to
- * respect the "ibm,aix-loc" property if any. It works with up to 8
- * ports.
- */
-
-#define MAX_LEGACY_SERIAL_PORTS 8
-static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
-static unsigned int old_serial_count;
-
-void __init generic_find_legacy_serial_ports(u64 *physport,
- unsigned int *default_speed)
-{
- struct device_node *np;
- u32 *sizeprop;
-
- struct isa_reg_property {
- u32 space;
- u32 address;
- u32 size;
- };
- struct pci_reg_property {
- struct pci_address addr;
- u32 size_hi;
- u32 size_lo;
- };
-
- DBG(" -> generic_find_legacy_serial_port()\n");
-
- *physport = 0;
- if (default_speed)
- *default_speed = 0;
-
- np = of_find_node_by_path("/");
- if (!np)
- return;
-
- /* First fill our array */
- for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
- struct device_node *isa, *pci;
- struct isa_reg_property *reg;
- unsigned long phys_size, addr_size, io_base;
- u32 *rangesp;
- u32 *interrupts, *clk, *spd;
- char *typep;
- int index, rlen, rentsize;
-
- /* Ok, first check if it's under an "isa" parent */
- isa = of_get_parent(np);
- if (!isa || strcmp(isa->name, "isa")) {
- DBG("%s: no isa parent found\n", np->full_name);
- continue;
- }
-
- /* Now look for an "ibm,aix-loc" property that gives us ordering
- * if any...
- */
- typep = (char *)get_property(np, "ibm,aix-loc", NULL);
-
- /* Get the ISA port number */
- reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
- if (reg == NULL)
- goto next_port;
- /* We assume the interrupt number isn't translated ... */
- interrupts = (u32 *)get_property(np, "interrupts", NULL);
- /* get clock freq. if present */
- clk = (u32 *)get_property(np, "clock-frequency", NULL);
- /* get default speed if present */
- spd = (u32 *)get_property(np, "current-speed", NULL);
- /* Default to locate at end of array */
- index = old_serial_count; /* end of the array by default */
-
- /* If we have a location index, then use it */
- if (typep && *typep == 'S') {
- index = simple_strtol(typep+1, NULL, 0) - 1;
- /* if index is out of range, use end of array instead */
- if (index >= MAX_LEGACY_SERIAL_PORTS)
- index = old_serial_count;
- /* if our index is still out of range, that mean that
- * array is full, we could scan for a free slot but that
- * make little sense to bother, just skip the port
- */
- if (index >= MAX_LEGACY_SERIAL_PORTS)
- goto next_port;
- if (index >= old_serial_count)
- old_serial_count = index + 1;
- /* Check if there is a port who already claimed our slot */
- if (serial_ports[index].iobase != 0) {
- /* if we still have some room, move it, else override */
- if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
- DBG("Moved legacy port %d -> %d\n", index,
- old_serial_count);
- serial_ports[old_serial_count++] =
- serial_ports[index];
- } else {
- DBG("Replacing legacy port %d\n", index);
- }
- }
- }
- if (index >= MAX_LEGACY_SERIAL_PORTS)
- goto next_port;
- if (index >= old_serial_count)
- old_serial_count = index + 1;
-
- /* Now fill the entry */
- memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port));
- serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16;
- serial_ports[index].iobase = reg->address;
- serial_ports[index].irq = interrupts ? interrupts[0] : 0;
- serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
-
- DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
- index,
- serial_ports[index].iobase,
- serial_ports[index].irq,
- serial_ports[index].uartclk);
-
- /* Get phys address of IO reg for port 1 */
- if (index != 0)
- goto next_port;
-
- pci = of_get_parent(isa);
- if (!pci) {
- DBG("%s: no pci parent found\n", np->full_name);
- goto next_port;
- }
-
- rangesp = (u32 *)get_property(pci, "ranges", &rlen);
- if (rangesp == NULL) {
- of_node_put(pci);
- goto next_port;
- }
- rlen /= 4;
-
- /* we need the #size-cells of the PCI bridge node itself */
- phys_size = 1;
- sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
- if (sizeprop != NULL)
- phys_size = *sizeprop;
- /* we need the parent #addr-cells */
- addr_size = prom_n_addr_cells(pci);
- rentsize = 3 + addr_size + phys_size;
- io_base = 0;
- for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
- if (((rangesp[0] >> 24) & 0x3) != 1)
- continue; /* not IO space */
- io_base = rangesp[3];
- if (addr_size == 2)
- io_base = (io_base << 32) | rangesp[4];
- }
- if (io_base != 0) {
- *physport = io_base + reg->address;
- if (default_speed && spd)
- *default_speed = *spd;
- }
- of_node_put(pci);
- next_port:
- of_node_put(isa);
- }
-
- DBG(" <- generic_find_legacy_serial_port()\n");
-}
-
-static struct platform_device serial_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = serial_ports,
- },
-};
-
-static int __init serial_dev_init(void)
-{
- return platform_device_register(&serial_device);
-}
-arch_initcall(serial_dev_init);
-
-#endif /* CONFIG_PPC_ISERIES */
-
int check_legacy_ioport(unsigned long base_port)
{
if (ppc_md.check_legacy_ioport == NULL)
Index: linux-serialfix/arch/powerpc/kernel/udbg_16550.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/udbg_16550.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/udbg_16550.c 2005-11-22 15:12:20.000000000 +1100
@@ -43,6 +43,8 @@
#define LSR_TEMT 0x40 /* Xmitter empty */
#define LSR_ERR 0x80 /* Error */
+#define LCR_DLAB 0x80
+
static volatile struct NS16550 __iomem *udbg_comport;
static void udbg_550_putc(unsigned char c)
@@ -77,29 +79,70 @@
return 0;
}
-void udbg_init_uart(void __iomem *comport, unsigned int speed)
+void udbg_init_uart(void __iomem *comport, unsigned int speed,
+ unsigned int clock)
{
- u16 dll = speed ? (115200 / speed) : 12;
+ unsigned int dll, base_bauds = clock / 16;
+
+ if (speed == 0)
+ speed = 9600;
+ dll = base_bauds / speed;
if (comport) {
udbg_comport = (struct NS16550 __iomem *)comport;
out_8(&udbg_comport->lcr, 0x00);
out_8(&udbg_comport->ier, 0xff);
out_8(&udbg_comport->ier, 0x00);
- out_8(&udbg_comport->lcr, 0x80); /* Access baud rate */
- out_8(&udbg_comport->dll, dll & 0xff); /* 1 = 115200, 2 = 57600,
- 3 = 38400, 12 = 9600 baud */
- out_8(&udbg_comport->dlm, dll >> 8); /* dll >> 8 which should be zero
- for fast rates; */
- out_8(&udbg_comport->lcr, 0x03); /* 8 data, 1 stop, no parity */
- out_8(&udbg_comport->mcr, 0x03); /* RTS/DTR */
- out_8(&udbg_comport->fcr ,0x07); /* Clear & enable FIFOs */
+ out_8(&udbg_comport->lcr, LCR_DLAB);
+ out_8(&udbg_comport->dll, dll & 0xff);
+ out_8(&udbg_comport->dlm, dll >> 8);
+ /* 8 data, 1 stop, no parity */
+ out_8(&udbg_comport->lcr, 0x03);
+ /* RTS/DTR */
+ out_8(&udbg_comport->mcr, 0x03);
+ /* Clear & enable FIFOs */
+ out_8(&udbg_comport->fcr ,0x07);
udbg_putc = udbg_550_putc;
udbg_getc = udbg_550_getc;
udbg_getc_poll = udbg_550_getc_poll;
}
}
+unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
+{
+ unsigned int dll, dlm, divisor, prescaler, speed;
+ u8 old_lcr;
+ volatile struct NS16550 __iomem *port = comport;
+
+ old_lcr = in_8(&port->lcr);
+
+ /* select divisor latch registers. */
+ out_8(&port->lcr, LCR_DLAB);
+
+ /* now, read the divisor */
+ dll = in_8(&port->dll);
+ dlm = in_8(&port->dlm);
+ divisor = dlm << 8 | dll;
+
+ /* check prescaling */
+ if (in_8(&port->mcr) & 0x80)
+ prescaler = 4;
+ else
+ prescaler = 1;
+
+ /* restore the LCR */
+ out_8(&port->lcr, old_lcr);
+
+ /* calculate speed */
+ speed = (clock / prescaler) / (divisor * 16);
+
+ /* sanity check */
+ if (speed < 9600 || speed > 115200)
+ speed = 9600;
+
+ return speed;
+}
+
#ifdef CONFIG_PPC_MAPLE
void udbg_maple_real_putc(unsigned char c)
{
Index: linux-serialfix/arch/powerpc/platforms/maple/setup.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/platforms/maple/setup.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/platforms/maple/setup.c 2005-11-22 15:12:20.000000000 +1100
@@ -191,20 +191,6 @@
*/
hpte_init_native();
- /* Find the serial port */
- generic_find_legacy_serial_ports(&physport, &default_speed);
-
- DBG("phys port addr: %lx\n", (long)physport);
-
- if (physport) {
- void *comport;
- /* Map the uart for udbg. */
- comport = (void *)ioremap(physport, 16);
- udbg_init_uart(comport, default_speed);
-
- DBG("Hello World !\n");
- }
-
/* Setup interrupt mapping options */
ppc64_interrupt_controller = IC_OPEN_PIC;
Index: linux-serialfix/arch/powerpc/platforms/pseries/lpar.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/platforms/pseries/lpar.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/platforms/pseries/lpar.c 2005-11-22 15:12:20.000000000 +1100
@@ -24,6 +24,7 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/dma-mapping.h>
+#include <linux/console.h>
#include <asm/processor.h>
#include <asm/mmu.h>
#include <asm/page.h>
@@ -191,7 +192,7 @@
/* call this from early_init() for a working debug console on
* vterm capable LPAR machines
*/
-void udbg_init_debug_lpar(void)
+void __init udbg_init_debug_lpar(void)
{
vtermno = 0;
udbg_putc = udbg_putcLP;
@@ -200,63 +201,54 @@
}
/* returns 0 if couldn't find or use /chosen/stdout as console */
-int find_udbg_vterm(void)
+void __init find_udbg_vterm(void)
{
struct device_node *stdout_node;
u32 *termno;
char *name;
- int found = 0;
+ int add_console;
/* find the boot console from /chosen/stdout */
if (!of_chosen)
- return 0;
+ return;
name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
if (name == NULL)
- return 0;
+ return;
stdout_node = of_find_node_by_path(name);
if (!stdout_node)
- return 0;
-
- /* now we have the stdout node; figure out what type of device it is. */
+ return;
name = (char *)get_property(stdout_node, "name", NULL);
if (!name) {
printk(KERN_WARNING "stdout node missing 'name' property!\n");
goto out;
}
+ /* The user has requested a console so this is already set up. */
+ add_console = !strstr(saved_command_line, "console=");
- if (strncmp(name, "vty", 3) == 0) {
- if (device_is_compatible(stdout_node, "hvterm1")) {
- termno = (u32 *)get_property(stdout_node, "reg", NULL);
- if (termno) {
- vtermno = termno[0];
- udbg_putc = udbg_putcLP;
- udbg_getc = udbg_getcLP;
- udbg_getc_poll = udbg_getc_pollLP;
- found = 1;
- }
- } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
- termno = (u32 *)get_property(stdout_node, "reg", NULL);
- if (termno) {
- vtermno = termno[0];
- udbg_putc = udbg_hvsi_putc;
- udbg_getc = udbg_hvsi_getc;
- udbg_getc_poll = udbg_hvsi_getc_poll;
- found = 1;
- }
- }
- } else if (strncmp(name, "serial", 6)) {
- /* XXX fix ISA serial console */
- printk(KERN_WARNING "serial stdout on LPAR ('%s')! "
- "can't print udbg messages\n",
- stdout_node->full_name);
- } else {
- printk(KERN_WARNING "don't know how to print to stdout '%s'\n",
- stdout_node->full_name);
- }
+ /* Check if it's a virtual terminal */
+ if (strncmp(name, "vty", 3) != 0)
+ goto out;
+ termno = (u32 *)get_property(stdout_node, "reg", NULL);
+ if (termno == NULL)
+ goto out;
+ vtermno = termno[0];
+ if (device_is_compatible(stdout_node, "hvterm1")) {
+ udbg_putc = udbg_putcLP;
+ udbg_getc = udbg_getcLP;
+ udbg_getc_poll = udbg_getc_pollLP;
+ if (add_console)
+ add_preferred_console("hvc", termno[0] & 0xff, NULL);
+ } else if (device_is_compatible(stdout_node, "hvterm-protocol")) {
+ vtermno = termno[0];
+ udbg_putc = udbg_hvsi_putc;
+ udbg_getc = udbg_hvsi_getc;
+ udbg_getc_poll = udbg_hvsi_getc_poll;
+ if (add_console)
+ add_preferred_console("hvsi", termno[0] & 0xff, NULL);
+ }
out:
of_node_put(stdout_node);
- return found;
}
void vpa_init(int cpu)
Index: linux-serialfix/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/platforms/pseries/setup.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/platforms/pseries/setup.c 2005-11-22 15:12:20.000000000 +1100
@@ -78,8 +78,6 @@
extern void find_udbg_vterm(void);
extern void system_reset_fwnmi(void); /* from head.S */
extern void machine_check_fwnmi(void); /* from head.S */
-extern void generic_find_legacy_serial_ports(u64 *physport,
- unsigned int *default_speed);
int fwnmi_active; /* TRUE if an FWNMI handler is present */
@@ -365,10 +363,7 @@
*/
static void __init pSeries_init_early(void)
{
- void *comport;
int iommu_off = 0;
- unsigned int default_speed;
- u64 physport;
DBG(" -> pSeries_init_early()\n");
@@ -382,17 +377,8 @@
get_property(of_chosen, "linux,iommu-off", NULL));
}
- generic_find_legacy_serial_ports(&physport, &default_speed);
-
if (platform_is_lpar())
find_udbg_vterm();
- else if (physport) {
- /* Map the uart for udbg. */
- comport = (void *)ioremap(physport, 16);
- udbg_init_uart(comport, default_speed);
-
- DBG("Hello World !\n");
- }
if (firmware_has_feature(FW_FEATURE_DABR))
ppc_md.set_dabr = pseries_set_dabr;
Index: linux-serialfix/include/asm-powerpc/serial.h
===================================================================
--- linux-serialfix.orig/include/asm-powerpc/serial.h 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/include/asm-powerpc/serial.h 2005-11-22 15:12:20.000000000 +1100
@@ -15,4 +15,6 @@
/* Default baud base if not found in device-tree */
#define BASE_BAUD ( 1843200 / 16 )
+extern void find_legacy_serial_ports(void);
+
#endif /* _PPC64_SERIAL_H */
Index: linux-serialfix/include/asm-powerpc/udbg.h
===================================================================
--- linux-serialfix.orig/include/asm-powerpc/udbg.h 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/include/asm-powerpc/udbg.h 2005-11-22 15:12:20.000000000 +1100
@@ -24,7 +24,10 @@
extern void register_early_udbg_console(void);
extern void udbg_printf(const char *fmt, ...);
-extern void udbg_init_uart(void __iomem *comport, unsigned int speed);
+extern void udbg_init_uart(void __iomem *comport, unsigned int speed,
+ unsigned int clock);
+extern unsigned int udbg_probe_uart_speed(void __iomem *comport,
+ unsigned int clock);
struct device_node;
extern void udbg_init_scc(struct device_node *np);
Index: linux-serialfix/arch/powerpc/kernel/setup_32.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/setup_32.c 2005-11-22 15:12:17.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/setup_32.c 2005-11-22 15:12:20.000000000 +1100
@@ -39,6 +39,7 @@
#include <asm/nvram.h>
#include <asm/xmon.h>
#include <asm/time.h>
+#include <asm/serial.h>
#include "setup.h"
@@ -282,6 +283,13 @@
unflatten_device_tree();
check_for_initrd();
+
+ if (ppc_md.init_early)
+ ppc_md.init_early();
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ find_legacy_serial_ports();
+#endif
finish_device_tree();
smp_setup_cpu_maps();
Index: linux-serialfix/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-serialfix.orig/arch/powerpc/kernel/pci_64.c 2005-11-21 11:53:14.000000000 +1100
+++ linux-serialfix/arch/powerpc/kernel/pci_64.c 2005-11-22 15:34:40.000000000 +1100
@@ -1223,6 +1223,7 @@
}
EXPORT_SYMBOL(pcibios_fixup_device_resources);
+
static void __devinit do_bus_setup(struct pci_bus *bus)
{
struct pci_dev *dev;
@@ -1306,6 +1307,20 @@
*end = rsrc->end + offset;
}
+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
+{
+ if (!have_of)
+ return NULL;
+ while(node) {
+ struct pci_controller *hose, *tmp;
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+ if (hose->arch_data == node)
+ return hose;
+ node = node->parent;
+ }
+ return NULL;
+}
+
#endif /* CONFIG_PPC_MULTIPLATFORM */
Index: linux-serialfix/arch/ppc/kernel/pci.c
===================================================================
--- linux-serialfix.orig/arch/ppc/kernel/pci.c 2005-11-21 11:53:14.000000000 +1100
+++ linux-serialfix/arch/ppc/kernel/pci.c 2005-11-22 15:25:03.000000000 +1100
@@ -815,8 +815,7 @@
* to set pci_assign_all_buses to 1 and still use RTAS for PCI
* config cycles.
*/
-struct pci_controller*
-pci_find_hose_for_OF_device(struct device_node* node)
+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
{
if (!have_of)
return NULL;
Index: linux-serialfix/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-serialfix.orig/include/asm-powerpc/pci-bridge.h 2005-11-21 11:53:15.000000000 +1100
+++ linux-serialfix/include/asm-powerpc/pci-bridge.h 2005-11-22 15:28:24.000000000 +1100
@@ -140,6 +140,9 @@
return PCI_DN(busdn)->phb;
}
+extern struct pci_controller*
+pci_find_hose_for_OF_device(struct device_node* node);
+
extern struct pci_controller *
pcibios_alloc_controller(struct device_node *dev);
extern void pcibios_free_controller(struct pci_controller *phb);
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox