Auto merge with /home/aegl/GIT/linus
authorTony Luck <tony.luck@intel.com>
Tue, 21 Jun 2005 23:21:20 +0000 (16:21 -0700)
committerTony Luck <tony.luck@intel.com>
Tue, 21 Jun 2005 23:21:20 +0000 (16:21 -0700)
399 files changed:
Documentation/DocBook/kernel-api.tmpl
Documentation/driver-model/device.txt
Documentation/driver-model/driver.txt
Documentation/filesystems/sysfs.txt
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/common/amba.c
arch/arm/common/dmabounce.c
arch/arm/common/sharpsl_param.c
arch/arm/configs/enp2611_defconfig
arch/arm/configs/ixdp2400_defconfig
arch/arm/configs/ixdp2401_defconfig
arch/arm/configs/ixdp2800_defconfig
arch/arm/configs/ixdp2801_defconfig
arch/arm/kernel/Makefile
arch/arm/kernel/arch.c [deleted file]
arch/arm/kernel/ecard.c
arch/arm/kernel/smp.c
arch/arm/lib/ashldi3.c
arch/arm/lib/ashrdi3.c
arch/arm/lib/gcclib.h
arch/arm/lib/longlong.h
arch/arm/lib/lshrdi3.c
arch/arm/lib/muldi3.c
arch/arm/lib/ucmpdi2.c
arch/arm/lib/udivdi3.c
arch/arm/mach-aaec2000/Kconfig [new file with mode: 0644]
arch/arm/mach-aaec2000/Makefile [new file with mode: 0644]
arch/arm/mach-aaec2000/aaed2000.c [new file with mode: 0644]
arch/arm/mach-aaec2000/core.c [new file with mode: 0644]
arch/arm/mach-aaec2000/core.h [new file with mode: 0644]
arch/arm/mach-integrator/core.c
arch/arm/mach-ixp2000/core.c
arch/arm/mach-versatile/Makefile
arch/arm/mach-versatile/core.c
arch/arm/mach-versatile/pci.c [new file with mode: 0644]
arch/arm/mm/Kconfig
arch/arm/mm/copypage-v6.c
arch/arm/mm/fault-armv.c
arch/arm/mm/flush.c
arch/arm/mm/ioremap.c
arch/arm26/kernel/ecard.c
arch/i386/kernel/cpuid.c
arch/i386/kernel/msr.c
arch/ia64/sn/kernel/tiocx.c
arch/parisc/kernel/drivers.c
arch/ppc/kernel/pci.c
arch/ppc/syslib/ocp.c
arch/ppc/syslib/of_device.c
arch/ppc64/kernel/iommu.c
arch/ppc64/kernel/of_device.c
arch/ppc64/kernel/pSeries_smp.c
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/rtasd.c
arch/ppc64/kernel/vio.c
drivers/acpi/scan.c
drivers/base/Makefile
drivers/base/base.h
drivers/base/bus.c
drivers/base/class.c
drivers/base/class_simple.c [deleted file]
drivers/base/core.c
drivers/base/dd.c [new file with mode: 0644]
drivers/base/dmapool.c
drivers/base/driver.c
drivers/base/node.c
drivers/base/power/resume.c
drivers/base/power/suspend.c
drivers/base/power/sysfs.c
drivers/base/sys.c
drivers/block/aoe/aoechr.c
drivers/block/as-iosched.c
drivers/block/cfq-iosched.c
drivers/block/deadline-iosched.c
drivers/block/genhd.c
drivers/block/ll_rw_blk.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/ub.c
drivers/char/dsp56k.c
drivers/char/ftape/zftape/zftape-init.c
drivers/char/hvcs.c
drivers/char/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/istallion.c
drivers/char/lp.c
drivers/char/mbcs.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/mwave/mwavedd.c
drivers/char/ppdev.c
drivers/char/raw.c
drivers/char/snsc.c
drivers/char/stallion.c
drivers/char/tipar.c
drivers/char/tpm/tpm.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/watchdog/ixp2000_wdt.c
drivers/cpufreq/cpufreq.c
drivers/dio/dio-sysfs.c
drivers/eisa/eisa-bus.c
drivers/fc4/fc.c
drivers/firmware/edd.c
drivers/firmware/efivars.c
drivers/i2c/chips/adm1021.c
drivers/i2c/chips/adm1025.c
drivers/i2c/chips/adm1026.c
drivers/i2c/chips/adm1031.c
drivers/i2c/chips/asb100.c
drivers/i2c/chips/ds1621.c
drivers/i2c/chips/fscher.c
drivers/i2c/chips/fscpos.c
drivers/i2c/chips/gl518sm.c
drivers/i2c/chips/gl520sm.c
drivers/i2c/chips/it87.c
drivers/i2c/chips/lm63.c
drivers/i2c/chips/lm75.c
drivers/i2c/chips/lm77.c
drivers/i2c/chips/lm78.c
drivers/i2c/chips/lm80.c
drivers/i2c/chips/lm83.c
drivers/i2c/chips/lm85.c
drivers/i2c/chips/lm87.c
drivers/i2c/chips/lm90.c
drivers/i2c/chips/lm92.c
drivers/i2c/chips/max1619.c
drivers/i2c/chips/pc87360.c
drivers/i2c/chips/pcf8574.c
drivers/i2c/chips/pcf8591.c
drivers/i2c/chips/sis5595.c
drivers/i2c/chips/smsc47b397.c
drivers/i2c/chips/smsc47m1.c
drivers/i2c/chips/via686a.c
drivers/i2c/chips/w83627hf.c
drivers/i2c/chips/w83781d.c
drivers/i2c/chips/w83l785ts.c
drivers/i2c/i2c-core.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.h
drivers/ieee1394/nodemgr.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/sbp2.c
drivers/ieee1394/video1394.c
drivers/infiniband/core/sysfs.c
drivers/input/evdev.c
drivers/input/gameport/gameport.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/keyboard/atkbd.c
drivers/input/mouse/psmouse.h
drivers/input/mousedev.c
drivers/input/serio/serio.c
drivers/input/tsdev.c
drivers/isdn/capi/capi.c
drivers/macintosh/adb.c
drivers/macintosh/therm_adt746x.c
drivers/macintosh/therm_pm72.c
drivers/macintosh/therm_windtunnel.c
drivers/mca/mca-bus.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/message/fusion/mptscsih.c
drivers/message/fusion/mptscsih.h
drivers/mmc/mmc_sysfs.c
drivers/net/ppp_generic.c
drivers/net/wan/cosa.c
drivers/pci/hotplug/cpqphp_sysfs.c
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/rpadlpar_sysfs.c
drivers/pci/hotplug/shpchp_sysfs.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pcie/portdrv_core.c
drivers/pcmcia/ds.c
drivers/pnp/card.c
drivers/pnp/driver.c
drivers/pnp/interface.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dcssblk.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_class.c
drivers/s390/char/tape_core.c
drivers/s390/char/vmlogrdr.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/chsc.c
drivers/s390/cio/cmf.c
drivers/s390/cio/device.c
drivers/s390/net/claw.c
drivers/s390/net/ctcmain.c
drivers/s390/net/lcs.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth_sys.c
drivers/s390/scsi/zfcp_scsi.c
drivers/s390/scsi/zfcp_sysfs_adapter.c
drivers/s390/scsi/zfcp_sysfs_port.c
drivers/s390/scsi/zfcp_sysfs_unit.c
drivers/scsi/53c700.c
drivers/scsi/aic7xxx/aic79xx_osm.c
drivers/scsi/arm/eesox.c
drivers/scsi/arm/powertec.c
drivers/scsi/ipr.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/osst.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_spi.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/sh/superhyway/superhyway-sysfs.c
drivers/usb/core/devices.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/sysfs.c
drivers/usb/core/usb.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/net2280.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ohci-dbg.c
drivers/usb/input/aiptek.c
drivers/usb/misc/cytherm.c
drivers/usb/misc/phidgetkit.c
drivers/usb/misc/phidgetservo.c
drivers/usb/misc/usbled.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/storage/scsiglue.c
drivers/video/fbmem.c
drivers/video/gbefb.c
drivers/video/w100fb.c
drivers/w1/w1.c
drivers/w1/w1_family.h
drivers/w1/w1_smem.c
drivers/w1/w1_therm.c
drivers/zorro/zorro-sysfs.c
fs/Kconfig
fs/coda/psdev.c
fs/debugfs/file.c
fs/jfs/acl.c
fs/jfs/file.c
fs/jfs/inode.c
fs/jfs/jfs_debug.c
fs/jfs/jfs_debug.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dtree.c
fs/jfs/jfs_extent.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_metapage.c
fs/jfs/jfs_metapage.h
fs/jfs/jfs_superblock.h
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.h
fs/jfs/namei.c
fs/jfs/super.c
fs/jfs/symlink.c
fs/jfs/xattr.c
fs/libfs.c
fs/sysfs/bin.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/inode.c
fs/sysfs/mount.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/asm-arm/arch-aaec2000/aaec2000.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/debug-macro.S [new file with mode: 0644]
include/asm-arm/arch-aaec2000/dma.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/entry-macro.S [new file with mode: 0644]
include/asm-arm/arch-aaec2000/hardware.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/io.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/irqs.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/memory.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/param.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/system.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/timex.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/uncompress.h [new file with mode: 0644]
include/asm-arm/arch-aaec2000/vmalloc.h [new file with mode: 0644]
include/asm-arm/arch-ixp2000/ixp2000-regs.h
include/asm-arm/arch-versatile/hardware.h
include/asm-arm/arch-versatile/io.h
include/asm-arm/arch-versatile/platform.h
include/asm-arm/cacheflush.h
include/asm-arm/io.h
include/asm-ppc/ocp.h
include/linux/atalk.h
include/linux/device.h
include/linux/fs.h
include/linux/i2c-sysfs.h [new file with mode: 0644]
include/linux/input.h
include/linux/klist.h [new file with mode: 0644]
include/linux/kobject.h
include/linux/netfilter_ipv4.h
include/linux/netfilter_ipv4/ip_conntrack_core.h
include/linux/netfilter_ipv4/ip_nat.h
include/linux/netfilter_ipv4/listhelp.h
include/linux/netfilter_ipv4/lockhelp.h [deleted file]
include/linux/netlink.h
include/linux/node.h
include/linux/pfkeyv2.h
include/linux/skbuff.h
include/linux/sysfs.h
include/linux/usb.h
include/linux/xfrm.h
include/net/ax25.h
include/net/ip6_fib.h
include/net/ip6_route.h
include/net/ip_fib.h
include/net/sctp/command.h
include/net/sctp/constants.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/sctp/user.h
include/net/xfrm.h
kernel/params.c
lib/Makefile
lib/klist.c [new file with mode: 0644]
lib/kobject.c
lib/kobject_uevent.c
net/appletalk/aarp.c
net/appletalk/ddp.c
net/bridge/br_forward.c
net/bridge/br_input.c
net/bridge/br_netfilter.c
net/core/netfilter.c
net/core/skbuff.c
net/ipv4/Kconfig
net/ipv4/Makefile
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/fib_trie.c [new file with mode: 0644]
net/ipv4/ip_input.c
net/ipv4/ip_output.c
net/ipv4/ipcomp.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_proto_sctp.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_conntrack_proto_udp.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_nat_core.c
net/ipv4/netfilter/ip_nat_helper.c
net/ipv4/netfilter/ip_nat_rule.c
net/ipv4/netfilter/ip_nat_standalone.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_hashlimit.c
net/ipv4/netfilter/ipt_helper.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_state.c
net/ipv4/xfrm4_tunnel.c
net/ipv6/addrconf.c
net/ipv6/ah6.c
net/ipv6/anycast.c
net/ipv6/esp6.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/route.c
net/ipv6/xfrm6_tunnel.c
net/key/af_key.c
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/outqueue.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/socket.c
net/sctp/transport.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/seclvl.c
sound/core/sound.c
sound/oss/soundcard.c
sound/sound_core.c

index 757cef8f84918165b68a8ee67a763fb21fd342b3..bb6a0106be1100951a7b99696f9e8176bd862e7e 100644 (file)
@@ -338,7 +338,6 @@ X!Earch/i386/kernel/mca.c
 X!Iinclude/linux/device.h
 -->
 !Edrivers/base/driver.c
-!Edrivers/base/class_simple.c
 !Edrivers/base/core.c
 !Edrivers/base/firmware_class.c
 !Edrivers/base/transport_class.c
index 58cc5dc8fd3eac2f8851674db7909d0f56c32f79..a05ec50f8004dd65f29c87579612389f93660187 100644 (file)
@@ -76,6 +76,14 @@ driver_data:   Driver-specific data.
 
 platform_data: Platform data specific to the device.
 
+              Example:  for devices on custom boards, as typical of embedded
+              and SOC based hardware, Linux often uses platform_data to point
+              to board-specific structures describing devices and how they
+              are wired.  That can include what ports are available, chip
+              variants, which GPIO pins act in what additional roles, and so
+              on.  This shrinks the "Board Support Packages" (BSPs) and
+              minimizes board-specific #ifdefs in drivers.
+
 current_state: Current power state of the device.
 
 saved_state:   Pointer to saved state of the device. This is usable by
index 6031a68dd3f5c249ea5daf391948d058fda44fef..fabaca1ab1b0b0f56980a4802b81b7a11e1aa241 100644 (file)
@@ -5,21 +5,17 @@ struct device_driver {
         char                    * name;
         struct bus_type         * bus;
 
-        rwlock_t                lock;
-        atomic_t                refcount;
-
-        list_t                  bus_list;
+        struct completion      unloaded;
+        struct kobject         kobj;
         list_t                  devices;
 
-        struct driver_dir_entry dir;
+        struct module          *owner;
 
         int     (*probe)        (struct device * dev);
         int     (*remove)       (struct device * dev);
 
         int     (*suspend)      (struct device * dev, pm_message_t state, u32 level);
         int     (*resume)       (struct device * dev, u32 level);
-
-        void    (*release)      (struct device_driver * drv);
 };
 
 
@@ -51,7 +47,6 @@ being converted completely to the new model.
 static struct device_driver eepro100_driver = {
        .name           = "eepro100",
        .bus            = &pci_bus_type,
-       .devclass       = &ethernet_devclass,   /* when it's implemented */
        
        .probe          = eepro100_probe,
        .remove         = eepro100_remove,
@@ -85,7 +80,6 @@ static struct pci_driver eepro100_driver = {
        .driver        = {
                .name           = "eepro100",
                .bus            = &pci_bus_type,
-               .devclass       = &ethernet_devclass,   /* when it's implemented */
                .probe          = eepro100_probe,
                .remove         = eepro100_remove,
                .suspend        = eepro100_suspend,
@@ -166,27 +160,32 @@ Callbacks
 
        int     (*probe)        (struct device * dev);
 
-probe is called to verify the existence of a certain type of
-hardware. This is called during the driver binding process, after the
-bus has verified that the device ID of a device matches one of the
-device IDs supported by the driver. 
-
-This callback only verifies that there actually is supported hardware
-present. It may allocate a driver-specific structure, but it should
-not do any initialization of the hardware itself. The device-specific
-structure may be stored in the device's driver_data field. 
-
-       int     (*init)         (struct device * dev);
-
-init is called during the binding stage. It is called after probe has
-successfully returned and the device has been registered with its
-class. It is responsible for initializing the hardware.
+The probe() entry is called in task context, with the bus's rwsem locked
+and the driver partially bound to the device.  Drivers commonly use
+container_of() to convert "dev" to a bus-specific type, both in probe()
+and other routines.  That type often provides device resource data, such
+as pci_dev.resource[] or platform_device.resources, which is used in
+addition to dev->platform_data to initialize the driver.
+
+This callback holds the driver-specific logic to bind the driver to a
+given device.  That includes verifying that the device is present, that
+it's a version the driver can handle, that driver data structures can
+be allocated and initialized, and that any hardware can be initialized.
+Drivers often store a pointer to their state with dev_set_drvdata().
+When the driver has successfully bound itself to that device, then probe()
+returns zero and the driver model code will finish its part of binding
+the driver to that device.
+
+A driver's probe() may return a negative errno value to indicate that
+the driver did not bind to this device, in which case it should have
+released all reasources it allocated.
 
        int     (*remove)       (struct device * dev);
 
-remove is called to dissociate a driver with a device. This may be
+remove is called to unbind a driver from a device. This may be
 called if a device is physically removed from the system, if the
-driver module is being unloaded, or during a reboot sequence. 
+driver module is being unloaded, during a reboot sequence, or
+in other cases.
 
 It is up to the driver to determine if the device is present or
 not. It should free any resources allocated specifically for the
index 60f6c2c4d477968e2966eb152183fe1c71bc689b..dc276598a65a3784c4dd7d41470c41f288db9529 100644 (file)
@@ -214,7 +214,7 @@ Other notes:
 
 A very simple (and naive) implementation of a device attribute is:
 
-static ssize_t show_name(struct device * dev, char * buf)
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
         return sprintf(buf,"%s\n",dev->name);
 }
index 475950c8a8317ec435f441137e4357d35efc93c1..ee8a9ad7bbd95343f46cd20e9467e062eaf848f2 100644 (file)
@@ -67,10 +67,6 @@ config GENERIC_BUST_SPINLOCK
 config GENERIC_ISA_DMA
        bool
 
-config GENERIC_IOMAP
-       bool
-       default y
-
 config FIQ
        bool
 
@@ -202,6 +198,11 @@ config ARCH_H720X
        help
          This enables support for systems based on the Hynix HMS720x
 
+config ARCH_AAEC2000
+       bool "Agilent AAEC-2000 based"
+       help
+         This enables support for systems based on the Agilent AAEC-2000
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -234,6 +235,8 @@ source "arch/arm/mach-h720x/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
+source "arch/arm/mach-aaec2000/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
        bool
@@ -277,7 +280,7 @@ config ISA_DMA_API
        default y
 
 config PCI
-       bool "PCI support" if ARCH_INTEGRATOR_AP
+       bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
        help
          Find out whether you have a PCI motherboard. PCI is the name of a
          bus system, i.e. the way the CPU talks to the other stuff inside
index 2277e3d179cc79ea84e12fc72e0676cbb9e6f46d..8330495e2448bc33f2ad7236b4fb5e4a45ebb2a1 100644 (file)
@@ -97,6 +97,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET)   := 0xc0008000
  machine-$(CONFIG_ARCH_VERSATILE)  := versatile
  machine-$(CONFIG_ARCH_IMX)       := imx
  machine-$(CONFIG_ARCH_H720X)     := h720x
+ machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
index a0507f8c33fe815838a825a6abf069e035eeaef1..c6beb751f2a93b4057a49df188d8522e1809dcdc 100644 (file)
@@ -169,7 +169,7 @@ static void amba_device_release(struct device *dev)
 }
 
 #define amba_attr(name,fmt,arg...)                             \
-static ssize_t show_##name(struct device *_dev, char *buf)     \
+static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf)      \
 {                                                              \
        struct amba_device *dev = to_amba_device(_dev);         \
        return sprintf(buf, fmt, arg);                          \
index 5797b1b100a1bc707031a3d7f169658261f4fe36..9d63a01214ebce2941a7033f41d49a059825a0fc 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/dmapool.h>
 #include <linux/list.h>
 
+#include <asm/cacheflush.h>
+
 #undef DEBUG
 
 #undef STATS
@@ -302,12 +304,24 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 
                DO_STATS ( device_info->bounce_count++ );
 
-               if ((dir == DMA_FROM_DEVICE) ||
-                   (dir == DMA_BIDIRECTIONAL)) {
+               if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
+                       unsigned long ptr;
+
                        dev_dbg(dev,
                                "%s: copy back safe %p to unsafe %p size %d\n",
                                __func__, buf->safe, buf->ptr, size);
                        memcpy(buf->ptr, buf->safe, size);
+
+                       /*
+                        * DMA buffers must have the same cache properties
+                        * as if they were really used for DMA - which means
+                        * data must be written back to RAM.  Note that
+                        * we don't use dmac_flush_range() here for the
+                        * bidirectional case because we know the cache
+                        * lines will be coherent with the data written.
+                        */
+                       ptr = (unsigned long)buf->ptr;
+                       dmac_clean_range(ptr, ptr + size);
                }
                free_safe_buffer(device_info, buf);
        }
index c2c557a224c2af0b7c558263e920f42868795cf0..c94864c5b1af568ae3fb796f6790d4f4850de283 100644 (file)
@@ -22,7 +22,7 @@
  * them early in the boot process, then pass them to the appropriate drivers.
  * Not all devices use all paramaters but the format is common to all.
  */
-#ifdef ARCH_SA1100
+#ifdef CONFIG_ARCH_SA1100
 #define PARAM_BASE     0xe8ffc000
 #else
 #define PARAM_BASE     0xa0000a00
index e8f9fccffe84a02809fd5f40306ac712d4da09bf..06fae4b62774659a1b6389db4a1a5d56f5a088c2 100644 (file)
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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
 
 #
 # System Type
index 4fd663ecbe39085376bfdefeea608723cee85e5d..810a450a55d22a4c1dbcc139688f937aafab9db8 100644 (file)
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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
 
 #
 # System Type
index 6f51c98084a3500727de6283825cbf7c58a7efbe..72e1b940e975b858769ac25ce0556dee0b0d0c62 100644 (file)
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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
 
 #
 # System Type
index 7be3521f91fc85e27053fd4fb922021dc058e45d..1592e45f027839e7967ef26c17e79bdc44bd1f64 100644 (file)
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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
 
 #
 # System Type
index cd84a20f30f1e79b327466410d9b75b77802e551..f1afe3d09ec66c5797ed553f1de4d1c1138396ed 100644 (file)
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+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
 
 #
 # System Type
index 4a2af55e134bcdc2cb07f01fc45d85458c673d94..3e1b0327e4d7a3a9bc25920eb98f6c5ab43c4b81 100644 (file)
@@ -6,7 +6,7 @@ AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
 
 # Object file lists.
 
-obj-y          := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o   \
+obj-y          := compat.o dma.o entry-armv.o entry-common.o irq.o \
                   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
                   time.o traps.o
 
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
deleted file mode 100644 (file)
index 4e02fbe..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  linux/arch/arm/kernel/arch.c
- *
- *  Architecture specific fixups.
- */
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-
-#include <asm/elf.h>
-#include <asm/page.h>
-#include <asm/setup.h>
-#include <asm/mach/arch.h>
-
-unsigned int vram_size;
-
-#ifdef CONFIG_ARCH_ACORN
-
-unsigned int memc_ctrl_reg;
-unsigned int number_mfm_drives;
-
-static int __init parse_tag_acorn(const struct tag *tag)
-{
-       memc_ctrl_reg = tag->u.acorn.memc_control_reg;
-       number_mfm_drives = tag->u.acorn.adfsdrives;
-
-       switch (tag->u.acorn.vram_pages) {
-       case 512:
-               vram_size += PAGE_SIZE * 256;
-       case 256:
-               vram_size += PAGE_SIZE * 256;
-       default:
-               break;
-       }
-#if 0
-       if (vram_size) {
-               desc->video_start = 0x02000000;
-               desc->video_end   = 0x02000000 + vram_size;
-       }
-#endif
-       return 0;
-}
-
-__tagtable(ATAG_ACORN, parse_tag_acorn);
-
-#endif
index 3dc15b131f532e4494e0dffa5ba4ed99fa703688..6540db6913381f4474d12594c6a84376d53724dd 100644 (file)
@@ -866,19 +866,19 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
        return ec;
 }
 
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->irq);
 }
 
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->dma);
 }
 
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        char *str = buf;
@@ -893,19 +893,19 @@ static ssize_t ecard_show_resources(struct device *dev, char *buf)
        return str - buf;
 }
 
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->cid.manufacturer);
 }
 
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->cid.product);
 }
 
-static ssize_t ecard_show_type(struct device *dev, char *buf)
+static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
index 45ed036336e0534eb8b9bb9ecf57fe4861fd6875..34892758f098c485f0b47e97083daf699a399878 100644 (file)
@@ -145,7 +145,8 @@ int __init __cpu_up(unsigned int cpu)
        pgd_free(pgd);
 
        if (ret) {
-               printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu);
+               printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
+
                /*
                 * FIXME: We need to clean up the new idle thread. --rmk
                 */
index 130f5a8396695b758180c0856b336a0d7814ac18..b62875cfd8f842fdc85c4e32ee9769b93fef920c 100644 (file)
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__ashldi3 (DItype u, word_type b)
+s64 __ashldi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      w.s.low = 0;
-      w.s.high = (USItype)uu.s.low << -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.low >> bm;
-      w.s.low = (USItype)uu.s.low << b;
-      w.s.high = ((USItype)uu.s.high << b) | carries;
-    }
-
-  return w.ll;
+       DIunion w;
+       int bm;
+       DIunion uu;
+
+       if (b == 0)
+               return u;
+
+       uu.ll = u;
+
+       bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+       if (bm <= 0) {
+               w.s.low = 0;
+               w.s.high = (u32) uu.s.low << -bm;
+       } else {
+               u32 carries = (u32) uu.s.low >> bm;
+               w.s.low = (u32) uu.s.low << b;
+               w.s.high = ((u32) uu.s.high << b) | carries;
+       }
+
+       return w.ll;
 }
-
index 71625d218f8d391266c2fd8b421e87838f2c6f33..9a8600a7543faf8159d029bf5b2dce40c8802852 100644 (file)
@@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__ashrdi3 (DItype u, word_type b)
+s64 __ashrdi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      /* w.s.high = 1..1 or 0..0 */
-      w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
-      w.s.low = uu.s.high >> -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.high << bm;
-      w.s.high = uu.s.high >> b;
-      w.s.low = ((USItype)uu.s.low >> b) | carries;
-    }
-
-  return w.ll;
+       DIunion w;
+       int bm;
+       DIunion uu;
+
+       if (b == 0)
+               return u;
+
+       uu.ll = u;
+
+       bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+       if (bm <= 0) {
+               /* w.s.high = 1..1 or 0..0 */
+               w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
+               w.s.low = uu.s.high >> -bm;
+       } else {
+               u32 carries = (u32) uu.s.high << bm;
+               w.s.high = uu.s.high >> b;
+               w.s.low = ((u32) uu.s.low >> b) | carries;
+       }
+
+       return w.ll;
 }
index 65314a3d9e273e932be1e1a3316b25f278d9f05f..8b6dcc656de779c3b2d030f0577238fe59e41954 100644 (file)
@@ -1,25 +1,22 @@
 /* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
 /* I Molton     29/07/01 */
 
-#define BITS_PER_UNIT  8
-#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#include <linux/types.h>
 
-typedef unsigned int UQItype    __attribute__ ((mode (QI)));
-typedef          int SItype     __attribute__ ((mode (SI)));
-typedef unsigned int USItype    __attribute__ ((mode (SI)));
-typedef          int DItype     __attribute__ ((mode (DI)));
-typedef          int word_type         __attribute__ ((mode (__word__)));
-typedef unsigned int UDItype    __attribute__ ((mode (DI)));
+#define BITS_PER_UNIT  8
+#define SI_TYPE_SIZE   (sizeof(s32) * BITS_PER_UNIT)
 
 #ifdef __ARMEB__
-  struct DIstruct {SItype high, low;};
+struct DIstruct {
+       s32 high, low;
+};
 #else
-  struct DIstruct {SItype low, high;};
+struct DIstruct {
+       s32 low, high;
+};
 #endif
 
-typedef union
-{
-  struct DIstruct s;
-  DItype ll;
+typedef union {
+       struct DIstruct s;
+       s64 ll;
 } DIunion;
-
index 179eea4edc35cc3a1180214cad63ca7e2ef807de..90ae647e4d76dadf575c4395e87affce807f0e19 100644 (file)
 
 #define __BITS4 (SI_TYPE_SIZE / 4)
 #define __ll_B (1L << (SI_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
-#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+#define __ll_lowpart(t) ((u32) (t) % __ll_B)
+#define __ll_highpart(t) ((u32) (t) / __ll_B)
 
 /* Define auxiliary asm macros.
 
    1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
-   multiplies two USItype integers MULTIPLER and MULTIPLICAND,
-   and generates a two-part USItype product in HIGH_PROD and
+   multiplies two u32 integers MULTIPLER and MULTIPLICAND,
+   and generates a two-part u32 product in HIGH_PROD and
    LOW_PROD.
 
-   2) __umulsidi3(a,b) multiplies two USItype integers A and B,
-   and returns a UDItype product.  This is just a variant of umul_ppmm.
+   2) __umulsidi3(a,b) multiplies two u32 integers A and B,
+   and returns a u64 product.  This is just a variant of umul_ppmm.
 
    3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
    denominator) divides a two-word unsigned integer, composed by the
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("adds       %1, %4, %5                                      \n\
        adc     %0, %2, %3"                                             \
-          : "=r" ((USItype) (sh)),                                     \
-            "=&r" ((USItype) (sl))                                     \
-          : "%r" ((USItype) (ah)),                                     \
-            "rI" ((USItype) (bh)),                                     \
-            "%r" ((USItype) (al)),                                     \
-            "rI" ((USItype) (bl)))
+          : "=r" ((u32) (sh)),                                 \
+            "=&r" ((u32) (sl))                                 \
+          : "%r" ((u32) (ah)),                                 \
+            "rI" ((u32) (bh)),                                 \
+            "%r" ((u32) (al)),                                 \
+            "rI" ((u32) (bl)))
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
   __asm__ ("subs       %1, %4, %5                                      \n\
        sbc     %0, %2, %3"                                             \
-          : "=r" ((USItype) (sh)),                                     \
-            "=&r" ((USItype) (sl))                                     \
-          : "r" ((USItype) (ah)),                                      \
-            "rI" ((USItype) (bh)),                                     \
-            "r" ((USItype) (al)),                                      \
-            "rI" ((USItype) (bl)))
+          : "=r" ((u32) (sh)),                                 \
+            "=&r" ((u32) (sl))                                 \
+          : "r" ((u32) (ah)),                                  \
+            "rI" ((u32) (bh)),                                 \
+            "r" ((u32) (al)),                                  \
+            "rI" ((u32) (bl)))
 #define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2;                                    \
+{register u32 __t0, __t1, __t2;                                        \
   __asm__ ("%@ Inlined umul_ppmm                                       \n\
        mov     %2, %5, lsr #16                                         \n\
        mov     %0, %6, lsr #16                                         \n\
        addcs   %0, %0, #65536                                          \n\
        adds    %1, %1, %3, lsl #16                                     \n\
        adc     %0, %0, %3, lsr #16"                                    \
-          : "=&r" ((USItype) (xh)),                                    \
-            "=r" ((USItype) (xl)),                                     \
+          : "=&r" ((u32) (xh)),                                        \
+            "=r" ((u32) (xl)),                                 \
             "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
-          : "r" ((USItype) (a)),                                       \
-            "r" ((USItype) (b)));}
+          : "r" ((u32) (a)),                                   \
+            "r" ((u32) (b)));}
 #define UMUL_TIME 20
 #define UDIV_TIME 100
-#endif /* __arm__ */
+#endif                         /* __arm__ */
 
 #define __umulsidi3(u, v) \
   ({DIunion __w;                                                       \
 
 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
   do {                                                                 \
-    USItype __d1, __d0, __q1, __q0;                                    \
-    USItype __r1, __r0, __m;                                           \
+    u32 __d1, __d0, __q1, __q0;                                        \
+    u32 __r1, __r0, __m;                                               \
     __d1 = __ll_highpart (d);                                          \
     __d0 = __ll_lowpart (d);                                           \
                                                                        \
     __r1 = (n1) % __d1;                                                        \
     __q1 = (n1) / __d1;                                                        \
-    __m = (USItype) __q1 * __d0;                                       \
+    __m = (u32) __q1 * __d0;                                   \
     __r1 = __r1 * __ll_B | __ll_highpart (n0);                         \
     if (__r1 < __m)                                                    \
       {                                                                        \
                                                                        \
     __r0 = __r1 % __d1;                                                        \
     __q0 = __r1 / __d1;                                                        \
-    __m = (USItype) __q0 * __d0;                                       \
+    __m = (u32) __q0 * __d0;                                   \
     __r0 = __r0 * __ll_B | __ll_lowpart (n0);                          \
     if (__r0 < __m)                                                    \
       {                                                                        \
       }                                                                        \
     __r0 -= __m;                                                       \
                                                                        \
-    (q) = (USItype) __q1 * __ll_B | __q0;                              \
+    (q) = (u32) __q1 * __ll_B | __q0;                          \
     (r) = __r0;                                                                \
   } while (0)
 
 
 #define count_leading_zeros(count, x) \
   do {                                                                 \
-    USItype __xr = (x);                                                        \
-    USItype __a;                                                       \
+    u32 __xr = (x);                                                    \
+    u32 __a;                                                   \
                                                                        \
     if (SI_TYPE_SIZE <= 32)                                            \
       {                                                                        \
-       __a = __xr < ((USItype)1<<2*__BITS4)                            \
-         ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4)                \
-         : (__xr < ((USItype)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);  \
+       __a = __xr < ((u32)1<<2*__BITS4)                                \
+         ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4)            \
+         : (__xr < ((u32)1<<3*__BITS4) ?  2*__BITS4 : 3*__BITS4);      \
       }                                                                        \
     else                                                               \
       {                                                                        \
index b666f1bad451047adcdf348ab2fd105d482b496f..3681f49d2b6e24c43c3d4b1670e57f2f50ebb1dd 100644 (file)
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-DItype
-__lshrdi3 (DItype u, word_type b)
+s64 __lshrdi3(s64 u, int b)
 {
-  DIunion w;
-  word_type bm;
-  DIunion uu;
-
-  if (b == 0)
-    return u;
-
-  uu.ll = u;
-
-  bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
-  if (bm <= 0)
-    {
-      w.s.high = 0;
-      w.s.low = (USItype)uu.s.high >> -bm;
-    }
-  else
-    {
-      USItype carries = (USItype)uu.s.high << bm;
-      w.s.high = (USItype)uu.s.high >> b;
-      w.s.low = ((USItype)uu.s.low >> b) | carries;
-    }
-
-  return w.ll;
+       DIunion w;
+       int bm;
+       DIunion uu;
+
+       if (b == 0)
+               return u;
+
+       uu.ll = u;
+
+       bm = (sizeof(s32) * BITS_PER_UNIT) - b;
+       if (bm <= 0) {
+               w.s.high = 0;
+               w.s.low = (u32) uu.s.high >> -bm;
+       } else {
+               u32 carries = (u32) uu.s.high << bm;
+               w.s.high = (u32) uu.s.high >> b;
+               w.s.low = ((u32) uu.s.low >> b) | carries;
+       }
+
+       return w.ll;
 }
-
index 44d611b1cfdbda4fcfdd5b17d0586109b249bb4a..0a3b93313f1831b24ef778f595a9d9bca0571a93 100644 (file)
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA.  */
 #include "gcclib.h"
 
 #define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2;                                     \
+{register u32 __t0, __t1, __t2;                                     \
   __asm__ ("%@ Inlined umul_ppmm                                       \n\
         mov     %2, %5, lsr #16                                                \n\
         mov     %0, %6, lsr #16                                                \n\
@@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA.  */
         addcs   %0, %0, #65536                                         \n\
         adds    %1, %1, %3, lsl #16                                    \n\
         adc     %0, %0, %3, lsr #16"                                    \
-           : "=&r" ((USItype) (xh)),                                    \
-             "=r" ((USItype) (xl)),                                     \
+           : "=&r" ((u32) (xh)),                                    \
+             "=r" ((u32) (xl)),                                     \
              "=&r" (__t0), "=&r" (__t1), "=r" (__t2)                    \
-           : "r" ((USItype) (a)),                                       \
-             "r" ((USItype) (b)));}
-
+           : "r" ((u32) (a)),                                       \
+             "r" ((u32) (b)));}
 
 #define __umulsidi3(u, v) \
   ({DIunion __w;                                                        \
     umul_ppmm (__w.s.high, __w.s.low, u, v);                            \
     __w.ll; })
 
-
-DItype
-__muldi3 (DItype u, DItype v)
+s64 __muldi3(s64 u, s64 v)
 {
-  DIunion w;
-  DIunion uu, vv;
+       DIunion w;
+       DIunion uu, vv;
 
-  uu.ll = u,
-  vv.ll = v;
+       uu.ll = u, vv.ll = v;
 
-  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
-  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
-               + (USItype) uu.s.high * (USItype) vv.s.low);
+       w.ll = __umulsidi3(uu.s.low, vv.s.low);
+       w.s.high += ((u32) uu.s.low * (u32) vv.s.high
+                    + (u32) uu.s.high * (u32) vv.s.low);
 
-  return w.ll;
+       return w.ll;
 }
-
index 6c6ae63efa0254cb75476231d83cffc0ad34d7ef..57f3f2df3850147286d89f870912cf40486d2d66 100644 (file)
@@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA.  */
 
 #include "gcclib.h"
 
-word_type
-__ucmpdi2 (DItype a, DItype b)
+int __ucmpdi2(s64 a, s64 b)
 {
-  DIunion au, bu;
-
-  au.ll = a, bu.ll = b;
-
-  if ((USItype) au.s.high < (USItype) bu.s.high)
-    return 0;
-  else if ((USItype) au.s.high > (USItype) bu.s.high)
-    return 2;
-  if ((USItype) au.s.low < (USItype) bu.s.low)
-    return 0;
-  else if ((USItype) au.s.low > (USItype) bu.s.low)
-    return 2;
-  return 1;
+       DIunion au, bu;
+
+       au.ll = a, bu.ll = b;
+
+       if ((u32) au.s.high < (u32) bu.s.high)
+               return 0;
+       else if ((u32) au.s.high > (u32) bu.s.high)
+               return 2;
+       if ((u32) au.s.low < (u32) bu.s.low)
+               return 0;
+       else if ((u32) au.s.low > (u32) bu.s.low)
+               return 2;
+       return 1;
 }
-
index d25195f673f465074a96cbb1ec30f1af6f65d1b3..e343be4c66421c9b6d2524f11e7858b02db369f9 100644 (file)
@@ -32,211 +32,191 @@ Boston, MA 02111-1307, USA.  */
 #include "gcclib.h"
 #include "longlong.h"
 
-static const UQItype __clz_tab[] =
-{
-  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
-  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+static const u8 __clz_tab[] = {
+       0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
+           5, 5, 5, 5, 5, 5, 5, 5,
+       6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+           6, 6, 6, 6, 6, 6, 6, 6,
+       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+           7, 7, 7, 7, 7, 7, 7, 7,
+       7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+           7, 7, 7, 7, 7, 7, 7, 7,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
+       8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+           8, 8, 8, 8, 8, 8, 8, 8,
 };
 
-UDItype
-__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
+u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
 {
-  DIunion ww;
-  DIunion nn, dd;
-  DIunion rr;
-  USItype d0, d1, n0, n1, n2;
-  USItype q0, q1;
-  USItype b, bm;
-
-  nn.ll = n;
-  dd.ll = d;
-
-  d0 = dd.s.low;
-  d1 = dd.s.high;
-  n0 = nn.s.low;
-  n1 = nn.s.high;
-
-  if (d1 == 0)
-    {
-      if (d0 > n1)
-        {
-          /* 0q = nn / 0D */
-
-          count_leading_zeros (bm, d0);
-
-          if (bm != 0)
-            {
-              /* Normalize, i.e. make the most significant bit of the
-                 denominator set.  */
-
-              d0 = d0 << bm;
-              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
-              n0 = n0 << bm;
-            }
-
-          udiv_qrnnd (q0, n0, n1, n0, d0);
-          q1 = 0;
-
-          /* Remainder in n0 >> bm.  */
-        }
-      else
-        {
-          /* qq = NN / 0d */
-
-          if (d0 == 0)
-            d0 = 1 / d0;        /* Divide intentionally by zero.  */
-
-          count_leading_zeros (bm, d0);
-
-          if (bm == 0)
-            {
-              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
-                 conclude (the most significant bit of n1 is set) /\ (the
-                 leading quotient digit q1 = 1).
-
-                 This special case is necessary, not an optimization.
-                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
-
-              n1 -= d0;
-              q1 = 1;
-            }
-          else
-            {
-              /* Normalize.  */
-
-              b = SI_TYPE_SIZE - bm;
-
-              d0 = d0 << bm;
-              n2 = n1 >> b;
-              n1 = (n1 << bm) | (n0 >> b);
-              n0 = n0 << bm;
-
-              udiv_qrnnd (q1, n1, n2, n1, d0);
-            }
-
-          /* n1 != d0...  */
-
-          udiv_qrnnd (q0, n0, n1, n0, d0);
-
-          /* Remainder in n0 >> bm.  */
-        }
-
-      if (rp != 0)
-        {
-          rr.s.low = n0 >> bm;
-          rr.s.high = 0;
-          *rp = rr.ll;
-        }
-    }
-  else
-    {
-      if (d1 > n1)
-        {
-          /* 00 = nn / DD */
-
-          q0 = 0;
-          q1 = 0;
-
-          /* Remainder in n1n0.  */
-          if (rp != 0)
-            {
-              rr.s.low = n0;
-              rr.s.high = n1;
-              *rp = rr.ll;
-            }
-        }
-      else
-        {
-          /* 0q = NN / dd */
-
-          count_leading_zeros (bm, d1);
-          if (bm == 0)
-            {
-              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
-                 conclude (the most significant bit of n1 is set) /\ (the
-                 quotient digit q0 = 0 or 1).
-
-                 This special case is necessary, not an optimization.  */
-
-              /* The condition on the next line takes advantage of that
-                 n1 >= d1 (true due to program flow).  */
-              if (n1 > d1 || n0 >= d0)
-                {
-                  q0 = 1;
-                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
-                }
-              else
-                q0 = 0;
-
-              q1 = 0;
-
-              if (rp != 0)
-                {
-                  rr.s.low = n0;
-                  rr.s.high = n1;
-                  *rp = rr.ll;
-                }
-            }
-          else
-            {
-              USItype m1, m0;
-              /* Normalize.  */
-
-              b = SI_TYPE_SIZE - bm;
-
-              d1 = (d1 << bm) | (d0 >> b);
-              d0 = d0 << bm;
-              n2 = n1 >> b;
-              n1 = (n1 << bm) | (n0 >> b);
-              n0 = n0 << bm;
-
-              udiv_qrnnd (q0, n1, n2, n1, d1);
-              umul_ppmm (m1, m0, q0, d0);
-
-              if (m1 > n1 || (m1 == n1 && m0 > n0))
-                {
-                  q0--;
-                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
-                }
-
-              q1 = 0;
-
-              /* Remainder in (n1n0 - m1m0) >> bm.  */
-              if (rp != 0)
-                {
-                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
-                  rr.s.low = (n1 << b) | (n0 >> bm);
-                  rr.s.high = n1 >> bm;
-                  *rp = rr.ll;
-                }
-            }
-        }
-    }
-
-  ww.s.low = q0;
-  ww.s.high = q1;
-  return ww.ll;
+       DIunion ww;
+       DIunion nn, dd;
+       DIunion rr;
+       u32 d0, d1, n0, n1, n2;
+       u32 q0, q1;
+       u32 b, bm;
+
+       nn.ll = n;
+       dd.ll = d;
+
+       d0 = dd.s.low;
+       d1 = dd.s.high;
+       n0 = nn.s.low;
+       n1 = nn.s.high;
+
+       if (d1 == 0) {
+               if (d0 > n1) {
+                       /* 0q = nn / 0D */
+
+                       count_leading_zeros(bm, d0);
+
+                       if (bm != 0) {
+                               /* Normalize, i.e. make the most significant bit of the
+                                  denominator set.  */
+
+                               d0 = d0 << bm;
+                               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+                               n0 = n0 << bm;
+                       }
+
+                       udiv_qrnnd(q0, n0, n1, n0, d0);
+                       q1 = 0;
+
+                       /* Remainder in n0 >> bm.  */
+               } else {
+                       /* qq = NN / 0d */
+
+                       if (d0 == 0)
+                               d0 = 1 / d0;    /* Divide intentionally by zero.  */
+
+                       count_leading_zeros(bm, d0);
+
+                       if (bm == 0) {
+                               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+                                  conclude (the most significant bit of n1 is set) /\ (the
+                                  leading quotient digit q1 = 1).
+
+                                  This special case is necessary, not an optimization.
+                                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
+
+                               n1 -= d0;
+                               q1 = 1;
+                       } else {
+                               /* Normalize.  */
+
+                               b = SI_TYPE_SIZE - bm;
+
+                               d0 = d0 << bm;
+                               n2 = n1 >> b;
+                               n1 = (n1 << bm) | (n0 >> b);
+                               n0 = n0 << bm;
+
+                               udiv_qrnnd(q1, n1, n2, n1, d0);
+                       }
+
+                       /* n1 != d0...  */
+
+                       udiv_qrnnd(q0, n0, n1, n0, d0);
+
+                       /* Remainder in n0 >> bm.  */
+               }
+
+               if (rp != 0) {
+                       rr.s.low = n0 >> bm;
+                       rr.s.high = 0;
+                       *rp = rr.ll;
+               }
+       } else {
+               if (d1 > n1) {
+                       /* 00 = nn / DD */
+
+                       q0 = 0;
+                       q1 = 0;
+
+                       /* Remainder in n1n0.  */
+                       if (rp != 0) {
+                               rr.s.low = n0;
+                               rr.s.high = n1;
+                               *rp = rr.ll;
+                       }
+               } else {
+                       /* 0q = NN / dd */
+
+                       count_leading_zeros(bm, d1);
+                       if (bm == 0) {
+                               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+                                  conclude (the most significant bit of n1 is set) /\ (the
+                                  quotient digit q0 = 0 or 1).
+
+                                  This special case is necessary, not an optimization.  */
+
+                               /* The condition on the next line takes advantage of that
+                                  n1 >= d1 (true due to program flow).  */
+                               if (n1 > d1 || n0 >= d0) {
+                                       q0 = 1;
+                                       sub_ddmmss(n1, n0, n1, n0, d1, d0);
+                               } else
+                                       q0 = 0;
+
+                               q1 = 0;
+
+                               if (rp != 0) {
+                                       rr.s.low = n0;
+                                       rr.s.high = n1;
+                                       *rp = rr.ll;
+                               }
+                       } else {
+                               u32 m1, m0;
+                               /* Normalize.  */
+
+                               b = SI_TYPE_SIZE - bm;
+
+                               d1 = (d1 << bm) | (d0 >> b);
+                               d0 = d0 << bm;
+                               n2 = n1 >> b;
+                               n1 = (n1 << bm) | (n0 >> b);
+                               n0 = n0 << bm;
+
+                               udiv_qrnnd(q0, n1, n2, n1, d1);
+                               umul_ppmm(m1, m0, q0, d0);
+
+                               if (m1 > n1 || (m1 == n1 && m0 > n0)) {
+                                       q0--;
+                                       sub_ddmmss(m1, m0, m1, m0, d1, d0);
+                               }
+
+                               q1 = 0;
+
+                               /* Remainder in (n1n0 - m1m0) >> bm.  */
+                               if (rp != 0) {
+                                       sub_ddmmss(n1, n0, n1, n0, m1, m0);
+                                       rr.s.low = (n1 << b) | (n0 >> bm);
+                                       rr.s.high = n1 >> bm;
+                                       *rp = rr.ll;
+                               }
+                       }
+               }
+       }
+
+       ww.s.low = q0;
+       ww.s.high = q1;
+       return ww.ll;
 }
 
-UDItype
-__udivdi3 (UDItype n, UDItype d)
+u64 __udivdi3(u64 n, u64 d)
 {
-  return __udivmoddi4 (n, d, (UDItype *) 0);
+       return __udivmoddi4(n, d, (u64 *) 0);
 }
 
-UDItype
-__umoddi3 (UDItype u, UDItype v)
+u64 __umoddi3(u64 u, u64 v)
 {
-  UDItype w;
+       u64 w;
 
-  (void) __udivmoddi4 (u ,v, &w);
+       (void)__udivmoddi4(u, v, &w);
 
-  return w;
+       return w;
 }
-
diff --git a/arch/arm/mach-aaec2000/Kconfig b/arch/arm/mach-aaec2000/Kconfig
new file mode 100644 (file)
index 0000000..5e4bef9
--- /dev/null
@@ -0,0 +1,11 @@
+if ARCH_AAEC2000
+
+menu "Agilent AAEC-2000 Implementations"
+
+config MACH_AAED2000
+       bool "Agilent AAED-2000 Development Platform"
+       select CPU_ARM920T
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
new file mode 100644 (file)
index 0000000..20ec838
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support (must be linked before board specific support)
+obj-y += core.o
+
+# Specific board support
+obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
new file mode 100644 (file)
index 0000000..5417ca3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/aaed2000.c
+ *
+ *  Support for the Agilent AAED-2000 Development Platform.
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/major.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/memory.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "core.h"
+
+static void __init aaed2000_init_irq(void)
+{
+       aaec2000_init_irq();
+}
+
+static void __init aaed2000_map_io(void)
+{
+       aaec2000_map_io();
+}
+
+MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
+       MAINTAINER("Nicolas Bellido Y Ortega")
+       BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE)
+       MAPIO(aaed2000_map_io)
+       INITIRQ(aaed2000_init_irq)
+       .timer          = &aaec2000_timer,
+MACHINE_END
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
new file mode 100644 (file)
index 0000000..fc145b3
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/core.c
+ *
+ *  Code common to all AAEC-2000 machines
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/signal.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+/*
+ * Common I/O mapping:
+ *
+ * Static virtual address mappings are as follow:
+ *
+ * 0xf8000000-0xf8001ffff: Devices connected to APB bus
+ * 0xf8002000-0xf8003ffff: Devices connected to AHB bus
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ *
+ * The machine specific code must provide the extra mapping beside the
+ * default mapping provided here.
+ */
+static struct map_desc standard_io_desc[] __initdata = {
+ /* virtual         physical       length           type */
+  { VIO_APB_BASE,   PIO_APB_BASE,  IO_APB_LENGTH,   MT_DEVICE },
+  { VIO_AHB_BASE,   PIO_AHB_BASE,  IO_AHB_LENGTH,   MT_DEVICE }
+};
+
+void __init aaec2000_map_io(void)
+{
+       iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+/*
+ * Interrupt handling routines
+ */
+static void aaec2000_int_ack(unsigned int irq)
+{
+       IRQ_INTSR = 1 << irq;
+}
+
+static void aaec2000_int_mask(unsigned int irq)
+{
+       IRQ_INTENC |= (1 << irq);
+}
+
+static void aaec2000_int_unmask(unsigned int irq)
+{
+       IRQ_INTENS |= (1 << irq);
+}
+
+static struct irqchip aaec2000_irq_chip = {
+       .ack    = aaec2000_int_ack,
+       .mask   = aaec2000_int_mask,
+       .unmask = aaec2000_int_unmask,
+};
+
+void __init aaec2000_init_irq(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < NR_IRQS; i++) {
+               set_irq_handler(i, do_level_IRQ);
+               set_irq_chip(i, &aaec2000_irq_chip);
+               set_irq_flags(i, IRQF_VALID);
+       }
+
+       /* Disable all interrupts */
+       IRQ_INTENC = 0xffffffff;
+
+       /* Clear any pending interrupts */
+       IRQ_INTSR = IRQ_INTSR;
+}
+
+/*
+ * Time keeping
+ */
+/* IRQs are disabled before entering here from do_gettimeofday() */
+static unsigned long aaec2000_gettimeoffset(void)
+{
+       unsigned long ticks_to_match, elapsed, usec;
+
+       /* Get ticks before next timer match */
+       ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
+
+       /* We need elapsed ticks since last match */
+       elapsed = LATCH - ticks_to_match;
+
+       /* Now, convert them to usec */
+       usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
+
+       return usec;
+}
+
+/* We enter here with IRQs enabled */
+static irqreturn_t
+aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       /* TODO: Check timer accuracy */
+       write_seqlock(&xtime_lock);
+
+       timer_tick(regs);
+       TIMER1_CLEAR = 1;
+
+       write_sequnlock(&xtime_lock);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction aaec2000_timer_irq = {
+       .name           = "AAEC-2000 Timer Tick",
+       .flags          = SA_INTERRUPT,
+       .handler        = aaec2000_timer_interrupt
+};
+
+static void __init aaec2000_timer_init(void)
+{
+       /* Disable timer 1 */
+       TIMER1_CTRL = 0;
+
+       /* We have somehow to generate a 100Hz clock.
+        * We then use the 508KHz timer in periodic mode.
+        */
+       TIMER1_LOAD = LATCH;
+       TIMER1_CLEAR = 1; /* Clear interrupt */
+
+       setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
+
+       TIMER1_CTRL = TIMER_CTRL_ENABLE |
+                       TIMER_CTRL_PERIODIC |
+                       TIMER_CTRL_CLKSEL_508K;
+}
+
+struct sys_timer aaec2000_timer = {
+       .init           = aaec2000_timer_init,
+       .offset         = aaec2000_gettimeoffset,
+};
+
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
new file mode 100644 (file)
index 0000000..91893d8
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ *  linux/arch/arm/mach-aaec2000/core.h
+ *
+ *  Copyright (c) 2005 Nicolas Bellido Y Ortega
+ *
+ *  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.
+ *
+ */
+
+struct sys_timer;
+
+extern struct sys_timer aaec2000_timer;
+extern void __init aaec2000_map_io(void);
+extern void __init aaec2000_init_irq(void);
index d302f0405fd2fa3be49a4692fcc9af4a354946e1..bd1e5e3c9d34b2e055f6d12763e2735b3994daf4 100644 (file)
@@ -227,7 +227,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         * primary CPU
         */
        if (hard_smp_processor_id() == 0) {
-               nmi_tick();
                timer_tick(regs);
 #ifdef CONFIG_SMP
                smp_send_timer();
index 4f3c3d5c781cae9790bdede88e260853f10d7f90..fc0555596d6d70c82a0c3cefb603efc9e574d2e7 100644 (file)
@@ -162,12 +162,13 @@ void __init ixp2000_map_io(void)
 static unsigned ticks_per_jiffy;
 static unsigned ticks_per_usec;
 static unsigned next_jiffy_time;
+static volatile unsigned long *missing_jiffy_timer_csr;
 
 unsigned long ixp2000_gettimeoffset (void)
 {
        unsigned long offset;
 
-       offset = next_jiffy_time - *IXP2000_T4_CSR;
+       offset = next_jiffy_time - *missing_jiffy_timer_csr;
 
        return offset / ticks_per_usec;
 }
@@ -179,7 +180,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /* clear timer 1 */
        ixp2000_reg_write(IXP2000_T1_CLR, 1);
        
-       while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) {
+       while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
                timer_tick(regs);
                next_jiffy_time -= ticks_per_jiffy;
        }
@@ -197,20 +198,37 @@ static struct irqaction ixp2000_timer_irq = {
 
 void __init ixp2000_init_time(unsigned long tick_rate)
 {
-       ixp2000_reg_write(IXP2000_T1_CLR, 0);
-       ixp2000_reg_write(IXP2000_T4_CLR, 0);
-
        ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
        ticks_per_usec = tick_rate / 1000000;
 
+       /*
+        * We use timer 1 as our timer interrupt.
+        */
+       ixp2000_reg_write(IXP2000_T1_CLR, 0);
        ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
        ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
 
        /*
-        * We use T4 as a monotonic counter to track missed jiffies
+        * We use a second timer as a monotonic counter for tracking
+        * missed jiffies.  The IXP2000 has four timers, but if we're
+        * on an A-step IXP2800, timer 2 and 3 don't work, so on those
+        * chips we use timer 4.  Timer 4 is the only timer that can
+        * be used for the watchdog, so we use timer 2 if we're on a
+        * non-buggy chip.
         */
-       ixp2000_reg_write(IXP2000_T4_CLD, -1);
-       ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+       if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
+               printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
+
+               ixp2000_reg_write(IXP2000_T4_CLR, 0);
+               ixp2000_reg_write(IXP2000_T4_CLD, -1);
+               ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
+               missing_jiffy_timer_csr = IXP2000_T4_CSR;
+       } else {
+               ixp2000_reg_write(IXP2000_T2_CLR, 0);
+               ixp2000_reg_write(IXP2000_T2_CLD, -1);
+               ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
+               missing_jiffy_timer_csr = IXP2000_T2_CSR;
+       }
        next_jiffy_time = 0xffffffff;
 
        /* register for interrupt */
index 5d608837757a8247a9cbb11ed781102b8e166b5a..ba81e70ed813ac633ab18fb305cfde4680ed2848 100644 (file)
@@ -5,3 +5,4 @@
 obj-y                                  := core.o clock.o
 obj-$(CONFIG_ARCH_VERSATILE_PB)                += versatile_pb.o
 obj-$(CONFIG_MACH_VERSATILE_AB)                += versatile_ab.o
+obj-$(CONFIG_PCI)                      += pci.o
index 302c2a7b9b63745bbeae0f59cd49fad31c259435..6a7cbea5e098d4acf62a3966217a643656848a3b 100644 (file)
@@ -196,11 +196,15 @@ static struct map_desc versatile_io_desc[] __initdata = {
 #ifdef CONFIG_DEBUG_LL
  { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K,      MT_DEVICE },
 #endif
-#ifdef FIXME
- { PCI_MEMORY_VADDR,                PHYS_PCI_MEM_BASE,    SZ_16M,     MT_DEVICE },
- { PCI_CONFIG_VADDR,                PHYS_PCI_CONFIG_BASE, SZ_16M,     MT_DEVICE },
- { PCI_V3_VADDR,                    PHYS_PCI_V3_BASE,     SZ_512K,    MT_DEVICE },
- { PCI_IO_VADDR,                    PHYS_PCI_IO_BASE,     SZ_64K,     MT_DEVICE },
+#ifdef CONFIG_PCI
+ { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
+ { VERSATILE_PCI_VIRT_BASE,          VERSATILE_PCI_BASE,   VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
+ { VERSATILE_PCI_CFG_VIRT_BASE,      VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
+#if 0
+ { VERSATILE_PCI_VIRT_MEM_BASE0,     VERSATILE_PCI_MEM_BASE0, SZ_16M,  MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE1,     VERSATILE_PCI_MEM_BASE1, SZ_16M,  MT_DEVICE },
+ { VERSATILE_PCI_VIRT_MEM_BASE2,     VERSATILE_PCI_MEM_BASE2, SZ_16M,  MT_DEVICE },
+#endif
 #endif
 };
 
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644 (file)
index 0000000..d1565e8
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ *  linux/arch/arm/mach-versatile/pci.c
+ *
+ * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
+ * You can redistribute and/or modify this software under the terms of version 2
+ * of the GNU General Public License as published by the Free Software Foundation.
+ * THIS SOFTWARE IS PROVIDED "AS IS" 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.
+ * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
+ *
+ * ARM Versatile PCI driver.
+ *
+ * 14/04/2005 Initial version, colin.king@philips.com
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+/*
+ * these spaces are mapped using the following base registers:
+ *
+ * Usage Local Bus Memory         Base/Map registers used
+ *
+ * Mem   50000000 - 5FFFFFFF      LB_BASE0/LB_MAP0,  non prefetch
+ * Mem   60000000 - 6FFFFFFF      LB_BASE1/LB_MAP1,  prefetch
+ * IO    44000000 - 4FFFFFFF      LB_BASE2/LB_MAP2,  IO
+ * Cfg   42000000 - 42FFFFFF     PCI config
+ *
+ */
+#define SYS_PCICTL                     IO_ADDRESS(VERSATILE_SYS_PCICTL)
+#define PCI_IMAP0                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
+#define PCI_IMAP1                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
+#define PCI_IMAP2                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
+#define PCI_SMAP0                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
+#define PCI_SMAP1                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
+#define PCI_SMAP2                      IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
+#define PCI_SELFID                     IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
+
+#define DEVICE_ID_OFFSET               0x00
+#define CSR_OFFSET                     0x04
+#define CLASS_ID_OFFSET                        0x08
+
+#define VP_PCI_DEVICE_ID               0x030010ee
+#define VP_PCI_CLASS_ID                        0x0b400000
+
+static unsigned long pci_slot_ignore = 0;
+
+static int __init versatile_pci_slot_ignore(char *str)
+{
+       int retval;
+       int slot;
+
+       while ((retval = get_option(&str,&slot))) {
+               if ((slot < 0) || (slot > 31)) {
+                       printk("Illegal slot value: %d\n",slot);
+               } else {
+                       pci_slot_ignore |= (1 << slot);
+               }
+       }
+       return 1;
+}
+
+__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
+
+
+static unsigned long __pci_addr(struct pci_bus *bus,
+                               unsigned int devfn, int offset)
+{
+       unsigned int busnr = bus->number;
+
+       /*
+        * Trap out illegal values
+        */
+       if (offset > 255)
+               BUG();
+       if (busnr > 255)
+               BUG();
+       if (devfn > 255)
+               BUG();
+
+       return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
+               (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
+}
+
+static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+                                int size, u32 *val)
+{
+       unsigned long addr = __pci_addr(bus, devfn, where);
+       u32 v;
+       int slot = PCI_SLOT(devfn);
+
+       if (pci_slot_ignore & (1 << slot)) {
+               /* Ignore this slot */
+               switch (size) {
+               case 1:
+                       v = 0xff;
+                       break;
+               case 2:
+                       v = 0xffff;
+                       break;
+               default:
+                       v = 0xffffffff;
+               }
+       } else {
+               switch (size) {
+               case 1:
+                       addr &= ~3;
+                       v = __raw_readb(addr);
+                       break;
+
+               case 2:
+                       v = __raw_readl(addr & ~3);
+                       if (addr & 2) v >>= 16;
+                       v &= 0xffff;
+                       break;
+
+               default:
+                       addr &= ~3;
+                       v = __raw_readl(addr);
+                       break;
+               }
+       }
+
+       *val = v;
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+                                 int size, u32 val)
+{
+       unsigned long addr = __pci_addr(bus, devfn, where);
+       int slot = PCI_SLOT(devfn);
+
+       if (pci_slot_ignore & (1 << slot)) {
+               return PCIBIOS_SUCCESSFUL;
+       }
+
+       switch (size) {
+       case 1:
+               __raw_writeb((u8)val, addr);
+               break;
+
+       case 2:
+               __raw_writew((u16)val, addr);
+               break;
+
+       case 4:
+               __raw_writel(val, addr);
+               break;
+       }
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pci_versatile_ops = {
+       .read   = versatile_read_config,
+       .write  = versatile_write_config,
+};
+
+static struct resource io_mem = {
+       .name   = "PCI I/O space",
+       .start  = VERSATILE_PCI_MEM_BASE0,
+       .end    = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
+       .flags  = IORESOURCE_IO,
+};
+
+static struct resource non_mem = {
+       .name   = "PCI non-prefetchable",
+       .start  = VERSATILE_PCI_MEM_BASE1,
+       .end    = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct resource pre_mem = {
+       .name   = "PCI prefetchable",
+       .start  = VERSATILE_PCI_MEM_BASE2,
+       .end    = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
+       .flags  = IORESOURCE_MEM | IORESOURCE_PREFETCH,
+};
+
+static int __init pci_versatile_setup_resources(struct resource **resource)
+{
+       int ret = 0;
+
+       ret = request_resource(&iomem_resource, &io_mem);
+       if (ret) {
+               printk(KERN_ERR "PCI: unable to allocate I/O "
+                      "memory region (%d)\n", ret);
+               goto out;
+       }
+       ret = request_resource(&iomem_resource, &non_mem);
+       if (ret) {
+               printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+                      "memory region (%d)\n", ret);
+               goto release_io_mem;
+       }
+       ret = request_resource(&iomem_resource, &pre_mem);
+       if (ret) {
+               printk(KERN_ERR "PCI: unable to allocate prefetchable "
+                      "memory region (%d)\n", ret);
+               goto release_non_mem;
+       }
+
+       /*
+        * bus->resource[0] is the IO resource for this bus
+        * bus->resource[1] is the mem resource for this bus
+        * bus->resource[2] is the prefetch mem resource for this bus
+        */
+       resource[0] = &io_mem;
+       resource[1] = &non_mem;
+       resource[2] = &pre_mem;
+
+       goto out;
+
+ release_non_mem:
+       release_resource(&non_mem);
+ release_io_mem:
+       release_resource(&io_mem);
+ out:
+       return ret;
+}
+
+int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
+{
+       int ret = 0;
+        int i;
+        int myslot = -1;
+       unsigned long val;
+
+       if (nr == 0) {
+               sys->mem_offset = 0;
+               ret = pci_versatile_setup_resources(sys->resource);
+               if (ret < 0) {
+                       printk("pci_versatile_setup: resources... oops?\n");
+                       goto out;
+               }
+       } else {
+               printk("pci_versatile_setup: resources... nr == 0??\n");
+               goto out;
+       }
+
+       __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0);
+       __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1);
+       __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2);
+
+       __raw_writel(1, SYS_PCICTL);
+
+       val = __raw_readl(SYS_PCICTL);
+       if (!(val & 1)) {
+               printk("Not plugged into PCI backplane!\n");
+               ret = -EIO;
+               goto out;
+       }
+
+       /*
+        *  We need to discover the PCI core first to configure itself
+        *  before the main PCI probing is performed
+        */
+       for (i=0; i<32; i++) {
+               if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
+                   (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
+                       myslot = i;
+
+                       __raw_writel(myslot, PCI_SELFID);
+                       val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+                       val |= (1<<2);
+                       __raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
+                       break;
+               }
+       }
+
+       if (myslot == -1) {
+               printk("Cannot find PCI core!\n");
+               ret = -EIO;
+       } else {
+               printk("PCI core found (slot %d)\n",myslot);
+               /* Do not to map Versatile FPGA PCI device
+                  into memory space as we are short of
+                  mappable memory */
+               pci_slot_ignore |= (1 << myslot);
+               ret = 1;
+       }
+
+ out:
+       return ret;
+}
+
+
+struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
+{
+       return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
+}
+
+/*
+ * V3_LB_BASE? - local bus address
+ * V3_LB_MAP?  - pci bus address
+ */
+void __init pci_versatile_preinit(void)
+{
+}
+
+void __init pci_versatile_postinit(void)
+{
+}
+
+
+/*
+ * map the specified device/slot/pin to an IRQ.   Different backplanes may need to modify this.
+ */
+static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int irq;
+       int devslot = PCI_SLOT(dev->devfn);
+
+       /* slot,  pin,  irq
+           24    1     27
+           25    1     28      untested
+           26    1     29
+           27    1     30      untested
+       */
+
+       irq = 27 + ((slot + pin + 2) % 3);      /* Fudged */
+
+       printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
+
+       return irq;
+}
+
+static struct hw_pci versatile_pci __initdata = {
+       .swizzle                = NULL,
+       .map_irq                = versatile_map_irq,
+       .nr_controllers         = 1,
+       .setup                  = pci_versatile_setup,
+       .scan                   = pci_versatile_scan_bus,
+       .preinit                = pci_versatile_preinit,
+       .postinit               = pci_versatile_postinit,
+};
+
+static int __init versatile_pci_init(void)
+{
+       pci_common_init(&versatile_pci);
+       return 0;
+}
+
+subsys_initcall(versatile_pci_init);
index 3fefb43c67f7c8cc851285e83e21d3648902027a..95606b4a3ba67942ae16563a21c783d35cc9753b 100644 (file)
@@ -62,7 +62,7 @@ config CPU_ARM720T
 # ARM920T
 config CPU_ARM920T
        bool "Support ARM920T processor" if !ARCH_S3C2410
-       depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX
+       depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
        default y if ARCH_S3C2410
        select CPU_32v4
        select CPU_ABRT_EV4T
index a8c00236bd3d54283da26f1fe36d3a0cc3d6c636..27d041574ea7891ab91bd9c1917ba1ee7e2be58f 100644 (file)
@@ -30,8 +30,6 @@
 
 static DEFINE_SPINLOCK(v6_lock);
 
-#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
-
 /*
  * Copy the user page.  No aliasing to deal with so we can just
  * attack the kernel's existing mapping of these pages.
@@ -55,7 +53,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
  */
 void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
 {
-       unsigned int offset = DCACHE_COLOUR(vaddr);
+       unsigned int offset = CACHE_COLOUR(vaddr);
        unsigned long from, to;
 
        /*
@@ -95,7 +93,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
  */
 void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
 {
-       unsigned int offset = DCACHE_COLOUR(vaddr);
+       unsigned int offset = CACHE_COLOUR(vaddr);
        unsigned long to = to_address + (offset << PAGE_SHIFT);
 
        /*
index 01967ddeef53df2cb72bda5d600419e63c392f82..be4ab3d73c91965448f064448136f7c078d9fb30 100644 (file)
@@ -77,9 +77,8 @@ no_pmd:
 }
 
 static void
-make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
+make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
 {
-       struct address_space *mapping = page_mapping(page);
        struct mm_struct *mm = vma->vm_mm;
        struct vm_area_struct *mpnt;
        struct prio_tree_iter iter;
@@ -87,9 +86,6 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
        pgoff_t pgoff;
        int aliases = 0;
 
-       if (!mapping)
-               return;
-
        pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
 
        /*
@@ -115,9 +111,11 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
        if (aliases)
                adjust_pte(vma, addr);
        else
-               flush_cache_page(vma, addr, page_to_pfn(page));
+               flush_cache_page(vma, addr, pfn);
 }
 
+void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
 /*
  * Take care of architecture specific things when placing a new PTE into
  * a page table, or changing an existing PTE.  Basically, there are two
@@ -134,29 +132,22 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
 {
        unsigned long pfn = pte_pfn(pte);
+       struct address_space *mapping;
        struct page *page;
 
        if (!pfn_valid(pfn))
                return;
+
        page = pfn_to_page(pfn);
-       if (page_mapping(page)) {
+       mapping = page_mapping(page);
+       if (mapping) {
                int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
 
-               if (dirty) {
-                       /*
-                        * This is our first userspace mapping of this page.
-                        * Ensure that the physical page is coherent with
-                        * the kernel mapping.
-                        *
-                        * FIXME: only need to do this on VIVT and aliasing
-                        *        VIPT cache architectures.  We can do that
-                        *        by choosing whether to set this bit...
-                        */
-                       __cpuc_flush_dcache_page(page_address(page));
-               }
+               if (dirty)
+                       __flush_dcache_page(mapping, page);
 
                if (cache_is_vivt())
-                       make_coherent(vma, addr, page, dirty);
+                       make_coherent(mapping, vma, addr, pfn);
        }
 }
 
index 4085ed983e46e07c3ac62ba31f8b0e605ee2594c..191788fb18d13a4f3adad73afd92a649c0c7ff21 100644 (file)
@@ -37,13 +37,8 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
 #define flush_pfn_alias(pfn,vaddr)     do { } while (0)
 #endif
 
-static void __flush_dcache_page(struct address_space *mapping, struct page *page)
+void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-       struct mm_struct *mm = current->active_mm;
-       struct vm_area_struct *mpnt;
-       struct prio_tree_iter iter;
-       pgoff_t pgoff;
-
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
@@ -52,24 +47,21 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
        __cpuc_flush_dcache_page(page_address(page));
 
        /*
-        * If there's no mapping pointer here, then this page isn't
-        * visible to userspace yet, so there are no cache lines
-        * associated with any other aliases.
-        */
-       if (!mapping)
-               return;
-
-       /*
-        * This is a page cache page.  If we have a VIPT cache, we
-        * only need to do one flush - which would be at the relevant
+        * If this is a page cache page, and we have an aliasing VIPT cache,
+        * we only need to do one flush - which would be at the relevant
         * userspace colour, which is congruent with page->index.
         */
-       if (cache_is_vipt()) {
-               if (cache_is_vipt_aliasing())
-                       flush_pfn_alias(page_to_pfn(page),
-                                       page->index << PAGE_CACHE_SHIFT);
-               return;
-       }
+       if (mapping && cache_is_vipt_aliasing())
+               flush_pfn_alias(page_to_pfn(page),
+                               page->index << PAGE_CACHE_SHIFT);
+}
+
+static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
+{
+       struct mm_struct *mm = current->active_mm;
+       struct vm_area_struct *mpnt;
+       struct prio_tree_iter iter;
+       pgoff_t pgoff;
 
        /*
         * There are possible user space mappings of this page:
@@ -116,12 +108,12 @@ void flush_dcache_page(struct page *page)
 {
        struct address_space *mapping = page_mapping(page);
 
-       if (cache_is_vipt_nonaliasing())
-               return;
-
        if (mapping && !mapping_mapped(mapping))
                set_bit(PG_dcache_dirty, &page->flags);
-       else
+       else {
                __flush_dcache_page(mapping, page);
+               if (mapping && cache_is_vivt())
+                       __flush_dcache_aliases(mapping, page);
+       }
 }
 EXPORT_SYMBOL(flush_dcache_page);
index 00bb8fd37a59f1bcfdb92c0f60bb314c9b710f8a..7110e54182b1e146ce6d26254965436cb971d6d4 100644 (file)
@@ -170,3 +170,50 @@ void __iounmap(void __iomem *addr)
        vfree((void *) (PAGE_MASK & (unsigned long) addr));
 }
 EXPORT_SYMBOL(__iounmap);
+
+#ifdef __io
+void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+       return __io(port);
+}
+EXPORT_SYMBOL(ioport_map);
+
+void ioport_unmap(void __iomem *addr)
+{
+}
+EXPORT_SYMBOL(ioport_unmap);
+#endif
+
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#include <linux/ioport.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+       unsigned long start = pci_resource_start(dev, bar);
+       unsigned long len   = pci_resource_len(dev, bar);
+       unsigned long flags = pci_resource_flags(dev, bar);
+
+       if (!len || !start)
+               return NULL;
+       if (maxlen && len > maxlen)
+               len = maxlen;
+       if (flags & IORESOURCE_IO)
+               return ioport_map(start, len);
+       if (flags & IORESOURCE_MEM) {
+               if (flags & IORESOURCE_CACHEABLE)
+                       return ioremap(start, len);
+               return ioremap_nocache(start, len);
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(pci_iomap);
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+       if ((unsigned long)addr >= VMALLOC_START &&
+           (unsigned long)addr < VMALLOC_END)
+               iounmap(addr);
+}
+EXPORT_SYMBOL(pci_iounmap);
+#endif
index 824c6b571ad933614ab04a41ad4ad3bac446307a..f2278aadac8a28638312039ff3f6cd05cd4db640 100644 (file)
@@ -562,31 +562,31 @@ static void __init ecard_init_resources(struct expansion_card *ec)
        }
 }
 
-static ssize_t ecard_show_irq(struct device *dev, char *buf)
+static ssize_t ecard_show_irq(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->irq);
 }
 
-static ssize_t ecard_show_vendor(struct device *dev, char *buf)
+static ssize_t ecard_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->cid.manufacturer);
 }
 
-static ssize_t ecard_show_device(struct device *dev, char *buf)
+static ssize_t ecard_show_device(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->cid.product);
 }
 
-static ssize_t ecard_show_dma(struct device *dev, char *buf)
+static ssize_t ecard_show_dma(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        return sprintf(buf, "%u\n", ec->dma);
 }
 
-static ssize_t ecard_show_resources(struct device *dev, char *buf)
+static ssize_t ecard_show_resources(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct expansion_card *ec = ECARD_DEV(dev);
        char *str = buf;
index 2e2756345bb23964f763ff747e284c7e89050678..4647db4ad6de9a8bd7bc9ab9bb32a4f3d594dd5c 100644 (file)
@@ -45,7 +45,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct class_simple *cpuid_class;
+static struct class *cpuid_class;
 
 #ifdef CONFIG_SMP
 
@@ -158,12 +158,12 @@ static struct file_operations cpuid_fops = {
        .open = cpuid_open,
 };
 
-static int cpuid_class_simple_device_add(int i) 
+static int cpuid_class_device_create(int i)
 {
        int err = 0;
        struct class_device *class_err;
 
-       class_err = class_simple_device_add(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+       class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
        if (IS_ERR(class_err))
                err = PTR_ERR(class_err);
        return err;
@@ -175,10 +175,10 @@ static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsign
 
        switch (action) {
        case CPU_ONLINE:
-               cpuid_class_simple_device_add(cpu);
+               cpuid_class_device_create(cpu);
                break;
        case CPU_DEAD:
-               class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
+               class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
                break;
        }
        return NOTIFY_OK;
@@ -200,13 +200,13 @@ static int __init cpuid_init(void)
                err = -EBUSY;
                goto out;
        }
-       cpuid_class = class_simple_create(THIS_MODULE, "cpuid");
+       cpuid_class = class_create(THIS_MODULE, "cpuid");
        if (IS_ERR(cpuid_class)) {
                err = PTR_ERR(cpuid_class);
                goto out_chrdev;
        }
        for_each_online_cpu(i) {
-               err = cpuid_class_simple_device_add(i);
+               err = cpuid_class_device_create(i);
                if (err != 0) 
                        goto out_class;
        }
@@ -218,9 +218,9 @@ static int __init cpuid_init(void)
 out_class:
        i = 0;
        for_each_online_cpu(i) {
-               class_simple_device_remove(MKDEV(CPUID_MAJOR, i));
+               class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
        }
-       class_simple_destroy(cpuid_class);
+       class_destroy(cpuid_class);
 out_chrdev:
        unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");    
 out:
@@ -232,8 +232,8 @@ static void __exit cpuid_exit(void)
        int cpu = 0;
 
        for_each_online_cpu(cpu)
-               class_simple_device_remove(MKDEV(CPUID_MAJOR, cpu));
-       class_simple_destroy(cpuid_class);
+               class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+       class_destroy(cpuid_class);
        unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
        unregister_cpu_notifier(&cpuid_class_cpu_notifier);
 }
index 05d9f8f363a695dc330f69d5550de0f43e774fff..b2f03c39a6fed5eebcd381776ae0948e3f280d4a 100644 (file)
@@ -44,7 +44,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct class_simple *msr_class;
+static struct class *msr_class;
 
 /* Note: "err" is handled in a funny way below.  Otherwise one version
    of gcc or another breaks. */
@@ -260,12 +260,12 @@ static struct file_operations msr_fops = {
        .open = msr_open,
 };
 
-static int msr_class_simple_device_add(int i)
+static int msr_class_device_create(int i)
 {
        int err = 0;
        struct class_device *class_err;
 
-       class_err = class_simple_device_add(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+       class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
        if (IS_ERR(class_err)) 
                err = PTR_ERR(class_err);
        return err;
@@ -277,10 +277,10 @@ static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned
 
        switch (action) {
        case CPU_ONLINE:
-               msr_class_simple_device_add(cpu);
+               msr_class_device_create(cpu);
                break;
        case CPU_DEAD:
-               class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));      
+               class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
                break;
        }
        return NOTIFY_OK;
@@ -302,13 +302,13 @@ static int __init msr_init(void)
                err = -EBUSY;
                goto out;
        }
-       msr_class = class_simple_create(THIS_MODULE, "msr");
+       msr_class = class_create(THIS_MODULE, "msr");
        if (IS_ERR(msr_class)) {
                err = PTR_ERR(msr_class);
                goto out_chrdev;
        }
        for_each_online_cpu(i) {
-               err = msr_class_simple_device_add(i);
+               err = msr_class_device_create(i);
                if (err != 0)
                        goto out_class;
        }
@@ -320,8 +320,8 @@ static int __init msr_init(void)
 out_class:
        i = 0;
        for_each_online_cpu(i)
-               class_simple_device_remove(MKDEV(MSR_MAJOR, i));
-       class_simple_destroy(msr_class);
+               class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
+       class_destroy(msr_class);
 out_chrdev:
        unregister_chrdev(MSR_MAJOR, "cpu/msr");
 out:
@@ -332,8 +332,8 @@ static void __exit msr_exit(void)
 {
        int cpu = 0;
        for_each_online_cpu(cpu)
-               class_simple_device_remove(MKDEV(MSR_MAJOR, cpu));
-       class_simple_destroy(msr_class);
+               class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
+       class_destroy(msr_class);
        unregister_chrdev(MSR_MAJOR, "cpu/msr");
        unregister_cpu_notifier(&msr_class_cpu_notifier);
 }
index ab9b5f35c2a72ba9bf6a398029e888dbeed3d129..a087b274847e52a265f94f473d707baa6d26fc89 100644 (file)
@@ -432,7 +432,7 @@ static int tiocx_reload(struct cx_dev *cx_dev)
        return cx_device_reload(cx_dev);
 }
 
-static ssize_t show_cxdev_control(struct device *dev, char *buf)
+static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct cx_dev *cx_dev = to_cx_dev(dev);
 
@@ -442,7 +442,7 @@ static ssize_t show_cxdev_control(struct device *dev, char *buf)
                       tiocx_btchar_get(cx_dev->cx_id.nasid));
 }
 
-static ssize_t store_cxdev_control(struct device *dev, const char *buf,
+static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
                                   size_t count)
 {
        int n;
@@ -518,25 +518,22 @@ static int __init tiocx_init(void)
        return 0;
 }
 
-static void __exit tiocx_exit(void)
+static int cx_remove_device(struct device * dev, void * data)
 {
-       struct device *dev;
-       struct device *tdev;
+       struct cx_dev *cx_dev = to_cx_dev(dev);
+       device_remove_file(dev, &dev_attr_cxdev_control);
+       cx_device_unregister(cx_dev);
+       return 0;
+}
 
+static void __exit tiocx_exit(void)
+{
        DBG("tiocx_exit\n");
 
        /*
         * Unregister devices.
         */
-       list_for_each_entry_safe(dev, tdev, &tiocx_bus_type.devices.list,
-                                bus_list) {
-               if (dev) {
-                       struct cx_dev *cx_dev = to_cx_dev(dev);
-                       device_remove_file(dev, &dev_attr_cxdev_control);
-                       cx_device_unregister(cx_dev);
-               }
-       }
-
+       bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device);
        bus_unregister(&tiocx_bus_type);
 }
 
index ebf186656afbd16bc2a0040990388462228704d6..d34bbe7ae0e3e9d192e73fe774702891bae98a6a 100644 (file)
@@ -466,7 +466,7 @@ static int parisc_generic_match(struct device *dev, struct device_driver *drv)
 }
 
 #define pa_dev_attr(name, field, format_string)                                \
-static ssize_t name##_show(struct device *dev, char *buf)              \
+static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf)               \
 {                                                                      \
        struct parisc_device *padev = to_parisc_device(dev);            \
        return sprintf(buf, format_string, padev->field);               \
index 47a15306823ae4d603a262e6dfa1dffbd9b55740..6d7b92d724582c87b9bd23b7e54752191c269666 100644 (file)
@@ -1003,7 +1003,7 @@ pci_create_OF_bus_map(void)
        }
 }
 
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev;
        struct device_node *np;
index a5156c5179a617ac0ef4baeb109c30170d1d401c..e5fd2ae503ea7c2240c373f022ffa0c989ad52e3 100644 (file)
@@ -68,7 +68,7 @@ static int ocp_inited;
 /* Sysfs support */
 #define OCP_DEF_ATTR(field, format_string)                             \
 static ssize_t                                                         \
-show_##field(struct device *dev, char *buf)                            \
+show_##field(struct device *dev, struct device_attribute *attr, char *buf)                             \
 {                                                                      \
        struct ocp_device *odev = to_ocp_dev(dev);                      \
                                                                        \
index 46269ed21aee77eaab1d784ec4e57910c3b6adc1..49c0e34e2d6bf2abf8c37522337e122e007c71ce 100644 (file)
@@ -161,7 +161,7 @@ void of_unregister_driver(struct of_platform_driver *drv)
 }
 
 
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct of_device *ofdev;
 
index 344164681d2ce5a4f4373ed9637140e42d17fcee..8316426ccaf60036c59d3cd45e18835d8e19c88a 100644 (file)
@@ -423,6 +423,9 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
        tbl->it_largehint = tbl->it_halfpoint;
        spin_lock_init(&tbl->it_lock);
 
+       /* Clear the hardware table in case firmware left allocations in it */
+       ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+
        if (!welcomed) {
                printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
                       novmerge ? "disabled" : "enabled");
index f4c825a69fa0ce700065f51ed48a71cfa5d5985b..66bd5ab7c25a4f17a3d95430fcc790c68e2c6360 100644 (file)
@@ -161,7 +161,7 @@ void of_unregister_driver(struct of_platform_driver *drv)
 }
 
 
-static ssize_t dev_show_devspec(struct device *dev, char *buf)
+static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct of_device *ofdev;
 
index fbad349ec58c2179fce3731d9ead5b8739cbc8c8..4203bd020c828364a42279ea48ef9ac1c85f6f03 100644 (file)
@@ -375,7 +375,7 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
         * cpus are assumed to be secondary threads.
         */
        if (system_state < SYSTEM_RUNNING &&
-           cur_cpu_spec->cpu_features & CPU_FTR_SMT &&
+           cpu_has_feature(CPU_FTR_SMT) &&
            !smt_enabled_at_boot && nr % 2 != 0)
                return 0;
 
@@ -419,8 +419,8 @@ void __init smp_init_pSeries(void)
 #endif
 
        /* Mark threads which are still spinning in hold loops. */
-       if (cur_cpu_spec->cpu_features & CPU_FTR_SMT)
-               for_each_present_cpu(i) {
+       if (cpu_has_feature(CPU_FTR_SMT)) {
+               for_each_present_cpu(i) { 
                        if (i % 2 == 0)
                                /*
                                 * Even-numbered logical cpus correspond to
@@ -428,8 +428,9 @@ void __init smp_init_pSeries(void)
                                 */
                                cpu_set(i, of_spin_map);
                }
-       else
+       } else {
                of_spin_map = cpu_present_map;
+       }
 
        cpu_clear(boot_cpuid, of_spin_map);
 
index d786d4b6af0b2a78403d4bb1325b9f2c2be414fe..2bf0513f3eca0a0fa2c53f50640ef312def4cc71 100644 (file)
@@ -507,7 +507,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 }
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
-static ssize_t pci_show_devspec(struct device *dev, char *buf)
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev;
        struct device_node *np;
index ff65dc33320ee779bf89b4b602d64da4d22a003b..b0c3b829fe47c43eac16b7d5ff9d885f0fd1b5c4 100644 (file)
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
                goto error;
        }
 
-       printk(KERN_ERR "RTAS daemon started\n");
+       printk(KERN_INFO "RTAS daemon started\n");
 
        DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
 
@@ -485,7 +485,7 @@ static int __init rtas_init(void)
        /* No RTAS, only warn if we are on a pSeries box  */
        if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
                if (systemcfg->platform & PLATFORM_PSERIES)
-                       printk(KERN_ERR "rtasd: no event-scan on system\n");
+                       printk(KERN_INFO "rtasd: no event-scan on system\n");
                return 1;
        }
 
index cdd830cb2768b6de5e2642022b383a78941935eb..79f2dc7a9833c481e91c8e3981d9db7b38335f23 100644 (file)
@@ -300,7 +300,7 @@ static void __devinit vio_dev_release(struct device *dev)
 }
 
 #ifdef CONFIG_PPC_PSERIES
-static ssize_t viodev_show_devspec(struct device *dev, char *buf)
+static ssize_t viodev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct device_node *of_node = dev->platform_data;
 
@@ -309,7 +309,7 @@ static ssize_t viodev_show_devspec(struct device *dev, char *buf)
 DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
 #endif
 
-static ssize_t viodev_show_name(struct device *dev, char *buf)
+static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
 }
index 119c94093a136a4704f0422b25cf30e2e26fccbe..e85885593280dde6313df7ac701785c23511ecb0 100644 (file)
@@ -65,14 +65,14 @@ static ssize_t acpi_device_attr_show(struct kobject *kobj,
 {
        struct acpi_device *device = to_acpi_device(kobj);
        struct acpi_device_attribute *attribute = to_handle_attr(attr);
-       return attribute->show ? attribute->show(device, buf) : 0;
+       return attribute->show ? attribute->show(device, buf) : -EIO;
 }
 static ssize_t acpi_device_attr_store(struct kobject *kobj,
                struct attribute *attr, const char *buf, size_t len)
 {
        struct acpi_device *device = to_acpi_device(kobj);
        struct acpi_device_attribute *attribute = to_handle_attr(attr);
-       return attribute->store ? attribute->store(device, buf, len) : len;
+       return attribute->store ? attribute->store(device, buf, len) : -EIO;
 }
 
 static struct sysfs_ops acpi_device_sysfs_ops = {
index a47928a2e57508a30bb527143d3c503201592f00..66d9c4643fc1d0857cbaac240a2cc7a9f6dbfff6 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile for the Linux device tree
 
-obj-y                  := core.o sys.o bus.o \
-                          driver.o class.o class_simple.o platform.o \
+obj-y                  := core.o sys.o bus.o dd.o \
+                          driver.o class.o platform.o \
                           cpu.o firmware.o init.o map.o dmapool.o \
                           attribute_container.o transport_class.o
 obj-y                  += power/
index 8d1e8bd48632e68b001755d673c3f90bfad47b03..645f626929209dd9e59cef9cd3070de9f0181a71 100644 (file)
@@ -4,6 +4,8 @@ extern void bus_remove_device(struct device * dev);
 extern int bus_add_driver(struct device_driver *);
 extern void bus_remove_driver(struct device_driver *);
 
+extern void driver_detach(struct device_driver * drv);
+
 static inline struct class_device *to_class_dev(struct kobject *obj)
 {
        return container_of(obj, struct class_device, kobj);
index 3cb04bb04c2b8e0d80ad910f8b6e94935be1c089..43722af90bddf2e01343bc24de33e25668952237 100644 (file)
@@ -17,9 +17,6 @@
 #include "base.h"
 #include "power/power.h"
 
-#define to_dev(node) container_of(node, struct device, bus_list)
-#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
-
 #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr)
 #define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj)
 
@@ -36,7 +33,7 @@ drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
        struct driver_attribute * drv_attr = to_drv_attr(attr);
        struct device_driver * drv = to_driver(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (drv_attr->show)
                ret = drv_attr->show(drv, buf);
@@ -49,7 +46,7 @@ drv_attr_store(struct kobject * kobj, struct attribute * attr,
 {
        struct driver_attribute * drv_attr = to_drv_attr(attr);
        struct device_driver * drv = to_driver(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (drv_attr->store)
                ret = drv_attr->store(drv, buf, count);
@@ -135,50 +132,11 @@ static struct kobj_type ktype_bus = {
 
 decl_subsys(bus, &ktype_bus, NULL);
 
-static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
-                             void *data, int (*fn)(struct device *, void *))
-{
-       struct list_head *head;
-       struct device *dev;
-       int error = 0;
-
-       if (!(bus = get_bus(bus)))
-               return -EINVAL;
-
-       head = &bus->devices.list;
-       dev = list_prepare_entry(start, head, bus_list);
-       list_for_each_entry_continue(dev, head, bus_list) {
-               get_device(dev);
-               error = fn(dev, data);
-               put_device(dev);
-               if (error)
-                       break;
-       }
-       put_bus(bus);
-       return error;
-}
 
-static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
-                             void * data, int (*fn)(struct device_driver *, void *))
+static struct device * next_device(struct klist_iter * i)
 {
-       struct list_head *head;
-       struct device_driver *drv;
-       int error = 0;
-
-       if (!(bus = get_bus(bus)))
-               return -EINVAL;
-
-       head = &bus->drivers.list;
-       drv = list_prepare_entry(start, head, kobj.entry);
-       list_for_each_entry_continue(drv, head, kobj.entry) {
-               get_driver(drv);
-               error = fn(drv, data);
-               put_driver(drv);
-               if (error)
-                       break;
-       }
-       put_bus(bus);
-       return error;
+       struct klist_node * n = klist_next(i);
+       return n ? container_of(n, struct device, knode_bus) : NULL;
 }
 
 /**
@@ -204,12 +162,27 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
 int bus_for_each_dev(struct bus_type * bus, struct device * start,
                     void * data, int (*fn)(struct device *, void *))
 {
-       int ret;
+       struct klist_iter i;
+       struct device * dev;
+       int error = 0;
 
-       down_read(&bus->subsys.rwsem);
-       ret = __bus_for_each_dev(bus, start, data, fn);
-       up_read(&bus->subsys.rwsem);
-       return ret;
+       if (!bus)
+               return -EINVAL;
+
+       klist_iter_init_node(&bus->klist_devices, &i,
+                            (start ? &start->knode_bus : NULL));
+       while ((dev = next_device(&i)) && !error)
+               error = fn(dev, data);
+       klist_iter_exit(&i);
+       return error;
+}
+
+
+
+static struct device_driver * next_driver(struct klist_iter * i)
+{
+       struct klist_node * n = klist_next(i);
+       return n ? container_of(n, struct device_driver, knode_bus) : NULL;
 }
 
 /**
@@ -235,179 +208,19 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
                     void * data, int (*fn)(struct device_driver *, void *))
 {
-       int ret;
-
-       down_read(&bus->subsys.rwsem);
-       ret = __bus_for_each_drv(bus, start, data, fn);
-       up_read(&bus->subsys.rwsem);
-       return ret;
-}
-
-/**
- *     device_bind_driver - bind a driver to one device.
- *     @dev:   device.
- *
- *     Allow manual attachment of a driver to a device.
- *     Caller must have already set @dev->driver.
- *
- *     Note that this does not modify the bus reference count
- *     nor take the bus's rwsem. Please verify those are accounted
- *     for before calling this. (It is ok to call with no other effort
- *     from a driver's probe() method.)
- */
-
-void device_bind_driver(struct device * dev)
-{
-       pr_debug("bound device '%s' to driver '%s'\n",
-                dev->bus_id, dev->driver->name);
-       list_add_tail(&dev->driver_list, &dev->driver->devices);
-       sysfs_create_link(&dev->driver->kobj, &dev->kobj,
-                         kobject_name(&dev->kobj));
-       sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
-}
-
-
-/**
- *     driver_probe_device - attempt to bind device & driver.
- *     @drv:   driver.
- *     @dev:   device.
- *
- *     First, we call the bus's match function, if one present, which
- *     should compare the device IDs the driver supports with the
- *     device IDs of the device. Note we don't do this ourselves
- *     because we don't know the format of the ID structures, nor what
- *     is to be considered a match and what is not.
- *
- *     If we find a match, we call @drv->probe(@dev) if it exists, and
- *     call device_bind_driver() above.
- */
-int driver_probe_device(struct device_driver * drv, struct device * dev)
-{
-       if (drv->bus->match && !drv->bus->match(dev, drv))
-               return -ENODEV;
-
-       dev->driver = drv;
-       if (drv->probe) {
-               int error = drv->probe(dev);
-               if (error) {
-                       dev->driver = NULL;
-                       return error;
-               }
-       }
-
-       device_bind_driver(dev);
-       return 0;
-}
-
-
-/**
- *     device_attach - try to attach device to a driver.
- *     @dev:   device.
- *
- *     Walk the list of drivers that the bus has and call
- *     driver_probe_device() for each pair. If a compatible
- *     pair is found, break out and return.
- */
-int device_attach(struct device * dev)
-{
-       struct bus_type * bus = dev->bus;
-       struct list_head * entry;
-       int error;
-
-       if (dev->driver) {
-               device_bind_driver(dev);
-               return 1;
-       }
-
-       if (bus->match) {
-               list_for_each(entry, &bus->drivers.list) {
-                       struct device_driver * drv = to_drv(entry);
-                       error = driver_probe_device(drv, dev);
-                       if (!error)
-                               /* success, driver matched */
-                               return 1;
-                       if (error != -ENODEV && error != -ENXIO)
-                               /* driver matched but the probe failed */
-                               printk(KERN_WARNING
-                                   "%s: probe of %s failed with error %d\n",
-                                   drv->name, dev->bus_id, error);
-               }
-       }
-
-       return 0;
-}
-
-
-/**
- *     driver_attach - try to bind driver to devices.
- *     @drv:   driver.
- *
- *     Walk the list of devices that the bus has on it and try to
- *     match the driver with each one.  If driver_probe_device()
- *     returns 0 and the @dev->driver is set, we've found a
- *     compatible pair.
- *
- *     Note that we ignore the -ENODEV error from driver_probe_device(),
- *     since it's perfectly valid for a driver not to bind to any devices.
- */
-void driver_attach(struct device_driver * drv)
-{
-       struct bus_type * bus = drv->bus;
-       struct list_head * entry;
-       int error;
-
-       if (!bus->match)
-               return;
-
-       list_for_each(entry, &bus->devices.list) {
-               struct device * dev = container_of(entry, struct device, bus_list);
-               if (!dev->driver) {
-                       error = driver_probe_device(drv, dev);
-                       if (error && (error != -ENODEV))
-                               /* driver matched but the probe failed */
-                               printk(KERN_WARNING
-                                   "%s: probe of %s failed with error %d\n",
-                                   drv->name, dev->bus_id, error);
-               }
-       }
-}
-
-
-/**
- *     device_release_driver - manually detach device from driver.
- *     @dev:   device.
- *
- *     Manually detach device from driver.
- *     Note that this is called without incrementing the bus
- *     reference count nor taking the bus's rwsem. Be sure that
- *     those are accounted for before calling this function.
- */
-
-void device_release_driver(struct device * dev)
-{
-       struct device_driver * drv = dev->driver;
-       if (drv) {
-               sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
-               sysfs_remove_link(&dev->kobj, "driver");
-               list_del_init(&dev->driver_list);
-               if (drv->remove)
-                       drv->remove(dev);
-               dev->driver = NULL;
-       }
-}
-
+       struct klist_iter i;
+       struct device_driver * drv;
+       int error = 0;
 
-/**
- *     driver_detach - detach driver from all devices it controls.
- *     @drv:   driver.
- */
+       if (!bus)
+               return -EINVAL;
 
-static void driver_detach(struct device_driver * drv)
-{
-       while (!list_empty(&drv->devices)) {
-               struct device * dev = container_of(drv->devices.next, struct device, driver_list);
-               device_release_driver(dev);
-       }
+       klist_iter_init_node(&bus->klist_drivers, &i,
+                            start ? &start->knode_bus : NULL);
+       while ((drv = next_driver(&i)) && !error)
+               error = fn(drv, data);
+       klist_iter_exit(&i);
+       return error;
 }
 
 static int device_add_attrs(struct bus_type * bus, struct device * dev)
@@ -456,14 +269,15 @@ int bus_add_device(struct device * dev)
        int error = 0;
 
        if (bus) {
-               down_write(&dev->bus->subsys.rwsem);
                pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
-               list_add_tail(&dev->bus_list, &dev->bus->devices.list);
-               device_attach(dev);
-               up_write(&dev->bus->subsys.rwsem);
-               device_add_attrs(bus, dev);
-               sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
-               sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+               error = device_attach(dev);
+               klist_add_tail(&bus->klist_devices, &dev->knode_bus);
+               if (error >= 0)
+                       error = device_add_attrs(bus, dev);
+               if (!error) {
+                       sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
+                       sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
+               }
        }
        return error;
 }
@@ -483,11 +297,9 @@ void bus_remove_device(struct device * dev)
                sysfs_remove_link(&dev->kobj, "bus");
                sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
                device_remove_attrs(dev->bus, dev);
-               down_write(&dev->bus->subsys.rwsem);
+               klist_remove(&dev->knode_bus);
                pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
                device_release_driver(dev);
-               list_del_init(&dev->bus_list);
-               up_write(&dev->bus->subsys.rwsem);
                put_bus(dev->bus);
        }
 }
@@ -547,9 +359,8 @@ int bus_add_driver(struct device_driver * drv)
                        return error;
                }
 
-               down_write(&bus->subsys.rwsem);
                driver_attach(drv);
-               up_write(&bus->subsys.rwsem);
+               klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
                module_add_driver(drv->owner, drv);
 
                driver_add_attrs(bus, drv);
@@ -571,10 +382,9 @@ void bus_remove_driver(struct device_driver * drv)
 {
        if (drv->bus) {
                driver_remove_attrs(drv->bus, drv);
-               down_write(&drv->bus->subsys.rwsem);
+               klist_remove(&drv->knode_bus);
                pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
                driver_detach(drv);
-               up_write(&drv->bus->subsys.rwsem);
                module_remove_driver(drv);
                kobject_unregister(&drv->kobj);
                put_bus(drv->bus);
@@ -587,7 +397,7 @@ static int bus_rescan_devices_helper(struct device *dev, void *data)
 {
        int *count = data;
 
-       if (!dev->driver && device_attach(dev))
+       if (!dev->driver && (device_attach(dev) > 0))
                (*count)++;
 
        return 0;
@@ -607,9 +417,7 @@ int bus_rescan_devices(struct bus_type * bus)
 {
        int count = 0;
 
-       down_write(&bus->subsys.rwsem);
-       __bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
-       up_write(&bus->subsys.rwsem);
+       bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
 
        return count;
 }
@@ -710,6 +518,9 @@ int bus_register(struct bus_type * bus)
        retval = kset_register(&bus->drivers);
        if (retval)
                goto bus_drivers_fail;
+
+       klist_init(&bus->klist_devices);
+       klist_init(&bus->klist_drivers);
        bus_add_attrs(bus);
 
        pr_debug("bus type '%s' registered\n", bus->name);
@@ -749,12 +560,6 @@ int __init buses_init(void)
 EXPORT_SYMBOL_GPL(bus_for_each_dev);
 EXPORT_SYMBOL_GPL(bus_for_each_drv);
 
-EXPORT_SYMBOL_GPL(driver_probe_device);
-EXPORT_SYMBOL_GPL(device_bind_driver);
-EXPORT_SYMBOL_GPL(device_release_driver);
-EXPORT_SYMBOL_GPL(device_attach);
-EXPORT_SYMBOL_GPL(driver_attach);
-
 EXPORT_SYMBOL_GPL(bus_add_device);
 EXPORT_SYMBOL_GPL(bus_remove_device);
 EXPORT_SYMBOL_GPL(bus_register);
index d2a2f8f2b4ed49d7c9e60e4c3a768f7ce53065e4..479c12570881374f9bdb6fafb172879b583b20bc 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/kdev_t.h>
+#include <linux/err.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -26,7 +27,7 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
        struct class_attribute * class_attr = to_class_attr(attr);
        struct class * dc = to_class(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (class_attr->show)
                ret = class_attr->show(dc, buf);
@@ -39,7 +40,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr,
 {
        struct class_attribute * class_attr = to_class_attr(attr);
        struct class * dc = to_class(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (class_attr->store)
                ret = class_attr->store(dc, buf, count);
@@ -162,6 +163,69 @@ void class_unregister(struct class * cls)
        subsystem_unregister(&cls->subsys);
 }
 
+static void class_create_release(struct class *cls)
+{
+       kfree(cls);
+}
+
+static void class_device_create_release(struct class_device *class_dev)
+{
+       kfree(class_dev);
+}
+
+/**
+ * class_create - create a struct class structure
+ * @owner: pointer to the module that is to "own" this struct class
+ * @name: pointer to a string for the name of this class.
+ *
+ * This is used to create a struct class pointer that can then be used
+ * in calls to class_device_create().
+ *
+ * Note, the pointer created here is to be destroyed when finished by
+ * making a call to class_destroy().
+ */
+struct class *class_create(struct module *owner, char *name)
+{
+       struct class *cls;
+       int retval;
+
+       cls = kmalloc(sizeof(struct class), GFP_KERNEL);
+       if (!cls) {
+               retval = -ENOMEM;
+               goto error;
+       }
+       memset(cls, 0x00, sizeof(struct class));
+
+       cls->name = name;
+       cls->owner = owner;
+       cls->class_release = class_create_release;
+       cls->release = class_device_create_release;
+
+       retval = class_register(cls);
+       if (retval)
+               goto error;
+
+       return cls;
+
+error:
+       kfree(cls);
+       return ERR_PTR(retval);
+}
+
+/**
+ * class_destroy - destroys a struct class structure
+ * @cs: pointer to the struct class that is to be destroyed
+ *
+ * Note, the pointer to be destroyed must have been created with a call
+ * to class_create().
+ */
+void class_destroy(struct class *cls)
+{
+       if ((cls == NULL) || (IS_ERR(cls)))
+               return;
+
+       class_unregister(cls);
+}
 
 /* Class Device Stuff */
 
@@ -262,7 +326,7 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
        return 0;
 }
 
-static char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
 {
        struct class_device *class_dev = to_class_dev(kobj);
 
@@ -375,7 +439,6 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
 {
        return print_dev_t(buf, class_dev->devt);
 }
-static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
 
 void class_device_initialize(struct class_device *class_dev)
 {
@@ -412,7 +475,31 @@ int class_device_add(struct class_device *class_dev)
        if ((error = kobject_add(&class_dev->kobj)))
                goto register_done;
 
-       /* now take care of our own registration */
+       /* add the needed attributes to this device */
+       if (MAJOR(class_dev->devt)) {
+               struct class_device_attribute *attr;
+               attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+               if (!attr) {
+                       error = -ENOMEM;
+                       kobject_del(&class_dev->kobj);
+                       goto register_done;
+               }
+               memset(attr, sizeof(*attr), 0x00);
+               attr->attr.name = "dev";
+               attr->attr.mode = S_IRUGO;
+               attr->attr.owner = parent->owner;
+               attr->show = show_dev;
+               attr->store = NULL;
+               class_device_create_file(class_dev, attr);
+               class_dev->devt_attr = attr;
+       }
+
+       class_device_add_attrs(class_dev);
+       if (class_dev->dev)
+               sysfs_create_link(&class_dev->kobj,
+                                 &class_dev->dev->kobj, "device");
+
+       /* notify any interfaces this device is now here */
        if (parent) {
                down(&parent->sem);
                list_add_tail(&class_dev->node, &parent->children);
@@ -421,16 +508,8 @@ int class_device_add(struct class_device *class_dev)
                                class_intf->add(class_dev);
                up(&parent->sem);
        }
-
-       if (MAJOR(class_dev->devt))
-               class_device_create_file(class_dev, &class_device_attr_dev);
-
-       class_device_add_attrs(class_dev);
-       if (class_dev->dev)
-               sysfs_create_link(&class_dev->kobj,
-                                 &class_dev->dev->kobj, "device");
-
        kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+
  register_done:
        if (error && parent)
                class_put(parent);
@@ -444,6 +523,58 @@ int class_device_register(struct class_device *class_dev)
        return class_device_add(class_dev);
 }
 
+/**
+ * class_device_create - creates a class device and registers it with sysfs
+ * @cs: pointer to the struct class that this device should be registered to.
+ * @dev: the dev_t for the char device to be added.
+ * @device: a pointer to a struct device that is assiociated with this class device.
+ * @fmt: string for the class device's name
+ *
+ * This function can be used by char device classes.  A struct
+ * class_device will be created in sysfs, registered to the specified
+ * class.  A "dev" file will be created, showing the dev_t for the
+ * device.  The pointer to the struct class_device will be returned from
+ * the call.  Any further sysfs files that might be required can be
+ * created using this pointer.
+ *
+ * Note: the struct class passed to this function must have previously
+ * been created with a call to class_create().
+ */
+struct class_device *class_device_create(struct class *cls, dev_t devt,
+                                        struct device *device, char *fmt, ...)
+{
+       va_list args;
+       struct class_device *class_dev = NULL;
+       int retval = -ENODEV;
+
+       if (cls == NULL || IS_ERR(cls))
+               goto error;
+
+       class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
+       if (!class_dev) {
+               retval = -ENOMEM;
+               goto error;
+       }
+       memset(class_dev, 0x00, sizeof(struct class_device));
+
+       class_dev->devt = devt;
+       class_dev->dev = device;
+       class_dev->class = cls;
+
+       va_start(args, fmt);
+       vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
+       va_end(args);
+       retval = class_device_register(class_dev);
+       if (retval)
+               goto error;
+
+       return class_dev;
+
+error:
+       kfree(class_dev);
+       return ERR_PTR(retval);
+}
+
 void class_device_del(struct class_device *class_dev)
 {
        struct class * parent = class_dev->class;
@@ -460,6 +591,11 @@ void class_device_del(struct class_device *class_dev)
 
        if (class_dev->dev)
                sysfs_remove_link(&class_dev->kobj, "device");
+       if (class_dev->devt_attr) {
+               class_device_remove_file(class_dev, class_dev->devt_attr);
+               kfree(class_dev->devt_attr);
+               class_dev->devt_attr = NULL;
+       }
        class_device_remove_attrs(class_dev);
 
        kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
@@ -477,6 +613,32 @@ void class_device_unregister(struct class_device *class_dev)
        class_device_put(class_dev);
 }
 
+/**
+ * class_device_destroy - removes a class device that was created with class_device_create()
+ * @cls: the pointer to the struct class that this device was registered * with.
+ * @dev: the dev_t of the device that was previously registered.
+ *
+ * This call unregisters and cleans up a class device that was created with a
+ * call to class_device_create()
+ */
+void class_device_destroy(struct class *cls, dev_t devt)
+{
+       struct class_device *class_dev = NULL;
+       struct class_device *class_dev_tmp;
+
+       down(&cls->sem);
+       list_for_each_entry(class_dev_tmp, &cls->children, node) {
+               if (class_dev_tmp->devt == devt) {
+                       class_dev = class_dev_tmp;
+                       break;
+               }
+       }
+       up(&cls->sem);
+
+       if (class_dev)
+               class_device_unregister(class_dev);
+}
+
 int class_device_rename(struct class_device *class_dev, char *new_name)
 {
        int error = 0;
@@ -576,6 +738,8 @@ EXPORT_SYMBOL_GPL(class_register);
 EXPORT_SYMBOL_GPL(class_unregister);
 EXPORT_SYMBOL_GPL(class_get);
 EXPORT_SYMBOL_GPL(class_put);
+EXPORT_SYMBOL_GPL(class_create);
+EXPORT_SYMBOL_GPL(class_destroy);
 
 EXPORT_SYMBOL_GPL(class_device_register);
 EXPORT_SYMBOL_GPL(class_device_unregister);
@@ -584,6 +748,8 @@ EXPORT_SYMBOL_GPL(class_device_add);
 EXPORT_SYMBOL_GPL(class_device_del);
 EXPORT_SYMBOL_GPL(class_device_get);
 EXPORT_SYMBOL_GPL(class_device_put);
+EXPORT_SYMBOL_GPL(class_device_create);
+EXPORT_SYMBOL_GPL(class_device_destroy);
 EXPORT_SYMBOL_GPL(class_device_create_file);
 EXPORT_SYMBOL_GPL(class_device_remove_file);
 EXPORT_SYMBOL_GPL(class_device_create_bin_file);
diff --git a/drivers/base/class_simple.c b/drivers/base/class_simple.c
deleted file mode 100644 (file)
index 27699eb..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * class_simple.c - a "simple" interface for classes for simple char devices.
- *
- * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2003-2004 IBM Corp.
- *
- * This file is released under the GPLv2
- *
- */
-
-#include <linux/config.h>
-#include <linux/device.h>
-#include <linux/err.h>
-
-struct class_simple {
-       struct class class;
-};
-#define to_class_simple(d) container_of(d, struct class_simple, class)
-
-struct simple_dev {
-       struct list_head node;
-       struct class_device class_dev;
-};
-#define to_simple_dev(d) container_of(d, struct simple_dev, class_dev)
-
-static LIST_HEAD(simple_dev_list);
-static DEFINE_SPINLOCK(simple_dev_list_lock);
-
-static void release_simple_dev(struct class_device *class_dev)
-{
-       struct simple_dev *s_dev = to_simple_dev(class_dev);
-       kfree(s_dev);
-}
-
-static void class_simple_release(struct class *class)
-{
-       struct class_simple *cs = to_class_simple(class);
-       kfree(cs);
-}
-
-/**
- * class_simple_create - create a struct class_simple structure
- * @owner: pointer to the module that is to "own" this struct class_simple
- * @name: pointer to a string for the name of this class.
- *
- * This is used to create a struct class_simple pointer that can then be used
- * in calls to class_simple_device_add().  This is used when you do not wish to
- * create a full blown class support for a type of char devices.
- *
- * Note, the pointer created here is to be destroyed when finished by making a
- * call to class_simple_destroy().
- */
-struct class_simple *class_simple_create(struct module *owner, char *name)
-{
-       struct class_simple *cs;
-       int retval;
-
-       cs = kmalloc(sizeof(*cs), GFP_KERNEL);
-       if (!cs) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(cs, 0x00, sizeof(*cs));
-
-       cs->class.name = name;
-       cs->class.class_release = class_simple_release;
-       cs->class.release = release_simple_dev;
-
-       retval = class_register(&cs->class);
-       if (retval)
-               goto error;
-
-       return cs;
-
-error:
-       kfree(cs);
-       return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_create);
-
-/**
- * class_simple_destroy - destroys a struct class_simple structure
- * @cs: pointer to the struct class_simple that is to be destroyed
- *
- * Note, the pointer to be destroyed must have been created with a call to
- * class_simple_create().
- */
-void class_simple_destroy(struct class_simple *cs)
-{
-       if ((cs == NULL) || (IS_ERR(cs)))
-               return;
-
-       class_unregister(&cs->class);
-}
-EXPORT_SYMBOL(class_simple_destroy);
-
-/**
- * class_simple_device_add - adds a class device to sysfs for a character driver
- * @cs: pointer to the struct class_simple that this device should be registered to.
- * @dev: the dev_t for the device to be added.
- * @device: a pointer to a struct device that is assiociated with this class device.
- * @fmt: string for the class device's name
- *
- * This function can be used by simple char device classes that do not
- * implement their own class device registration.  A struct class_device will
- * be created in sysfs, registered to the specified class.  A "dev" file will
- * be created, showing the dev_t for the device.  The pointer to the struct
- * class_device will be returned from the call.  Any further sysfs files that
- * might be required can be created using this pointer.
- * Note: the struct class_simple passed to this function must have previously been
- * created with a call to class_simple_create().
- */
-struct class_device *class_simple_device_add(struct class_simple *cs, dev_t dev, struct device *device, const char *fmt, ...)
-{
-       va_list args;
-       struct simple_dev *s_dev = NULL;
-       int retval;
-
-       if ((cs == NULL) || (IS_ERR(cs))) {
-               retval = -ENODEV;
-               goto error;
-       }
-
-       s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
-       if (!s_dev) {
-               retval = -ENOMEM;
-               goto error;
-       }
-       memset(s_dev, 0x00, sizeof(*s_dev));
-
-       s_dev->class_dev.devt = dev;
-       s_dev->class_dev.dev = device;
-       s_dev->class_dev.class = &cs->class;
-
-       va_start(args, fmt);
-       vsnprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, fmt, args);
-       va_end(args);
-       retval = class_device_register(&s_dev->class_dev);
-       if (retval)
-               goto error;
-
-       spin_lock(&simple_dev_list_lock);
-       list_add(&s_dev->node, &simple_dev_list);
-       spin_unlock(&simple_dev_list_lock);
-
-       return &s_dev->class_dev;
-
-error:
-       kfree(s_dev);
-       return ERR_PTR(retval);
-}
-EXPORT_SYMBOL(class_simple_device_add);
-
-/**
- * class_simple_set_hotplug - set the hotplug callback in the embedded struct class
- * @cs: pointer to the struct class_simple to hold the pointer
- * @hotplug: function pointer to the hotplug function
- *
- * Implement and set a hotplug function to add environment variables specific to this
- * class on the hotplug event.
- */
-int class_simple_set_hotplug(struct class_simple *cs,
-       int (*hotplug)(struct class_device *dev, char **envp, int num_envp, char *buffer, int buffer_size))
-{
-       if ((cs == NULL) || (IS_ERR(cs)))
-               return -ENODEV;
-       cs->class.hotplug = hotplug;
-       return 0;
-}
-EXPORT_SYMBOL(class_simple_set_hotplug);
-
-/**
- * class_simple_device_remove - removes a class device that was created with class_simple_device_add()
- * @dev: the dev_t of the device that was previously registered.
- *
- * This call unregisters and cleans up a class device that was created with a
- * call to class_device_simple_add()
- */
-void class_simple_device_remove(dev_t dev)
-{
-       struct simple_dev *s_dev = NULL;
-       int found = 0;
-
-       spin_lock(&simple_dev_list_lock);
-       list_for_each_entry(s_dev, &simple_dev_list, node) {
-               if (s_dev->class_dev.devt == dev) {
-                       found = 1;
-                       break;
-               }
-       }
-       if (found) {
-               list_del(&s_dev->node);
-               spin_unlock(&simple_dev_list_lock);
-               class_device_unregister(&s_dev->class_dev);
-       } else {
-               spin_unlock(&simple_dev_list_lock);
-       }
-}
-EXPORT_SYMBOL(class_simple_device_remove);
index fbc223486f81b2b8380b0e157a81e429986ff73c..86d79755fbfb9d4c62c572df8d0585200d1064bf 100644 (file)
@@ -36,10 +36,10 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
 {
        struct device_attribute * dev_attr = to_dev_attr(attr);
        struct device * dev = to_dev(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (dev_attr->show)
-               ret = dev_attr->show(dev, buf);
+               ret = dev_attr->show(dev, dev_attr, buf);
        return ret;
 }
 
@@ -49,10 +49,10 @@ dev_attr_store(struct kobject * kobj, struct attribute * attr,
 {
        struct device_attribute * dev_attr = to_dev_attr(attr);
        struct device * dev = to_dev(kobj);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (dev_attr->store)
-               ret = dev_attr->store(dev, buf, count);
+               ret = dev_attr->store(dev, dev_attr, buf, count);
        return ret;
 }
 
@@ -102,7 +102,7 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
        return 0;
 }
 
-static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
 {
        struct device *dev = to_dev(kobj);
 
@@ -207,11 +207,9 @@ void device_initialize(struct device *dev)
 {
        kobj_set_kset_s(dev, devices_subsys);
        kobject_init(&dev->kobj);
-       INIT_LIST_HEAD(&dev->node);
-       INIT_LIST_HEAD(&dev->children);
-       INIT_LIST_HEAD(&dev->driver_list);
-       INIT_LIST_HEAD(&dev->bus_list);
+       klist_init(&dev->klist_children);
        INIT_LIST_HEAD(&dev->dma_pools);
+       init_MUTEX(&dev->sem);
 }
 
 /**
@@ -250,10 +248,8 @@ int device_add(struct device *dev)
                goto PMError;
        if ((error = bus_add_device(dev)))
                goto BusError;
-       down_write(&devices_subsys.rwsem);
        if (parent)
-               list_add_tail(&dev->node, &parent->children);
-       up_write(&devices_subsys.rwsem);
+               klist_add_tail(&parent->klist_children, &dev->knode_parent);
 
        /* notify platform of device entry */
        if (platform_notify)
@@ -336,10 +332,8 @@ void device_del(struct device * dev)
 {
        struct device * parent = dev->parent;
 
-       down_write(&devices_subsys.rwsem);
        if (parent)
-               list_del_init(&dev->node);
-       up_write(&devices_subsys.rwsem);
+               klist_remove(&dev->knode_parent);
 
        /* Notify the platform of the removal, in case they
         * need to do anything...
@@ -373,6 +367,12 @@ void device_unregister(struct device * dev)
 }
 
 
+static struct device * next_device(struct klist_iter * i)
+{
+       struct klist_node * n = klist_next(i);
+       return n ? container_of(n, struct device, knode_parent) : NULL;
+}
+
 /**
  *     device_for_each_child - device child iterator.
  *     @dev:   parent struct device.
@@ -385,39 +385,20 @@ void device_unregister(struct device * dev)
  *     We check the return of @fn each time. If it returns anything
  *     other than 0, we break out and return that value.
  */
-int device_for_each_child(struct device * dev, void * data,
+int device_for_each_child(struct device * parent, void * data,
                     int (*fn)(struct device *, void *))
 {
+       struct klist_iter i;
        struct device * child;
        int error = 0;
 
-       down_read(&devices_subsys.rwsem);
-       list_for_each_entry(child, &dev->children, node) {
-               if((error = fn(child, data)))
-                       break;
-       }
-       up_read(&devices_subsys.rwsem);
+       klist_iter_init(&parent->klist_children, &i);
+       while ((child = next_device(&i)) && !error)
+               error = fn(child, data);
+       klist_iter_exit(&i);
        return error;
 }
 
-/**
- *     device_find - locate device on a bus by name.
- *     @name:  name of the device.
- *     @bus:   bus to scan for the device.
- *
- *     Call kset_find_obj() to iterate over list of devices on
- *     a bus to find device by name. Return device if found.
- *
- *     Note that kset_find_obj increments device's reference count.
- */
-struct device *device_find(const char *name, struct bus_type *bus)
-{
-       struct kobject *k = kset_find_obj(&bus->devices, name);
-       if (k)
-               return to_dev(k);
-       return NULL;
-}
-
 int __init devices_init(void)
 {
        return subsystem_register(&devices_subsys);
@@ -433,7 +414,6 @@ EXPORT_SYMBOL_GPL(device_del);
 EXPORT_SYMBOL_GPL(device_unregister);
 EXPORT_SYMBOL_GPL(get_device);
 EXPORT_SYMBOL_GPL(put_device);
-EXPORT_SYMBOL_GPL(device_find);
 
 EXPORT_SYMBOL_GPL(device_create_file);
 EXPORT_SYMBOL_GPL(device_remove_file);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
new file mode 100644 (file)
index 0000000..6db3a78
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ *     drivers/base/dd.c - The core device/driver interactions.
+ *
+ *     This file contains the (sometimes tricky) code that controls the
+ *     interactions between devices and drivers, which primarily includes
+ *     driver binding and unbinding.
+ *
+ *     All of this code used to exist in drivers/base/bus.c, but was
+ *     relocated to here in the name of compartmentalization (since it wasn't
+ *     strictly code just for the 'struct bus_type'.
+ *
+ *     Copyright (c) 2002-5 Patrick Mochel
+ *     Copyright (c) 2002-3 Open Source Development Labs
+ *
+ *     This file is released under the GPLv2
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+#include "base.h"
+#include "power/power.h"
+
+#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
+
+
+/**
+ *     device_bind_driver - bind a driver to one device.
+ *     @dev:   device.
+ *
+ *     Allow manual attachment of a driver to a device.
+ *     Caller must have already set @dev->driver.
+ *
+ *     Note that this does not modify the bus reference count
+ *     nor take the bus's rwsem. Please verify those are accounted
+ *     for before calling this. (It is ok to call with no other effort
+ *     from a driver's probe() method.)
+ *
+ *     This function must be called with @dev->sem held.
+ */
+void device_bind_driver(struct device * dev)
+{
+       pr_debug("bound device '%s' to driver '%s'\n",
+                dev->bus_id, dev->driver->name);
+       klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
+       sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+                         kobject_name(&dev->kobj));
+       sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+}
+
+/**
+ *     driver_probe_device - attempt to bind device & driver.
+ *     @drv:   driver.
+ *     @dev:   device.
+ *
+ *     First, we call the bus's match function, if one present, which
+ *     should compare the device IDs the driver supports with the
+ *     device IDs of the device. Note we don't do this ourselves
+ *     because we don't know the format of the ID structures, nor what
+ *     is to be considered a match and what is not.
+ *
+ *
+ *     This function returns 1 if a match is found, an error if one
+ *     occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
+ *
+ *     This function must be called with @dev->sem held.
+ */
+static int driver_probe_device(struct device_driver * drv, struct device * dev)
+{
+       int ret = 0;
+
+       if (drv->bus->match && !drv->bus->match(dev, drv))
+               goto Done;
+
+       pr_debug("%s: Matched Device %s with Driver %s\n",
+                drv->bus->name, dev->bus_id, drv->name);
+       dev->driver = drv;
+       if (drv->probe) {
+               ret = drv->probe(dev);
+               if (ret) {
+                       dev->driver = NULL;
+                       goto ProbeFailed;
+               }
+       }
+       device_bind_driver(dev);
+       ret = 1;
+       pr_debug("%s: Bound Device %s to Driver %s\n",
+                drv->bus->name, dev->bus_id, drv->name);
+       goto Done;
+
+ ProbeFailed:
+       if (ret == -ENODEV || ret == -ENXIO) {
+               /* Driver matched, but didn't support device
+                * or device not found.
+                * Not an error; keep going.
+                */
+               ret = 0;
+       } else {
+               /* driver matched but the probe failed */
+               printk(KERN_WARNING
+                      "%s: probe of %s failed with error %d\n",
+                      drv->name, dev->bus_id, ret);
+       }
+ Done:
+       return ret;
+}
+
+static int __device_attach(struct device_driver * drv, void * data)
+{
+       struct device * dev = data;
+       return driver_probe_device(drv, dev);
+}
+
+/**
+ *     device_attach - try to attach device to a driver.
+ *     @dev:   device.
+ *
+ *     Walk the list of drivers that the bus has and call
+ *     driver_probe_device() for each pair. If a compatible
+ *     pair is found, break out and return.
+ *
+ *     Returns 1 if the device was bound to a driver;
+ *     0 if no matching device was found; error code otherwise.
+ */
+int device_attach(struct device * dev)
+{
+       int ret = 0;
+
+       down(&dev->sem);
+       if (dev->driver) {
+               device_bind_driver(dev);
+               ret = 1;
+       } else
+               ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
+       up(&dev->sem);
+       return ret;
+}
+
+static int __driver_attach(struct device * dev, void * data)
+{
+       struct device_driver * drv = data;
+
+       /*
+        * Lock device and try to bind to it. We drop the error
+        * here and always return 0, because we need to keep trying
+        * to bind to devices and some drivers will return an error
+        * simply if it didn't support the device.
+        *
+        * driver_probe_device() will spit a warning if there
+        * is an error.
+        */
+
+       down(&dev->sem);
+       if (!dev->driver)
+               driver_probe_device(drv, dev);
+       up(&dev->sem);
+
+
+       return 0;
+}
+
+/**
+ *     driver_attach - try to bind driver to devices.
+ *     @drv:   driver.
+ *
+ *     Walk the list of devices that the bus has on it and try to
+ *     match the driver with each one.  If driver_probe_device()
+ *     returns 0 and the @dev->driver is set, we've found a
+ *     compatible pair.
+ */
+void driver_attach(struct device_driver * drv)
+{
+       bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
+}
+
+/**
+ *     device_release_driver - manually detach device from driver.
+ *     @dev:   device.
+ *
+ *     Manually detach device from driver.
+ *
+ *     __device_release_driver() must be called with @dev->sem held.
+ */
+
+static void __device_release_driver(struct device * dev)
+{
+       struct device_driver * drv;
+
+       drv = dev->driver;
+       if (drv) {
+               get_driver(drv);
+               sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj));
+               sysfs_remove_link(&dev->kobj, "driver");
+               klist_remove(&dev->knode_driver);
+
+               if (drv->remove)
+                       drv->remove(dev);
+               dev->driver = NULL;
+               put_driver(drv);
+       }
+}
+
+void device_release_driver(struct device * dev)
+{
+       /*
+        * If anyone calls device_release_driver() recursively from
+        * within their ->remove callback for the same device, they
+        * will deadlock right here.
+        */
+       down(&dev->sem);
+       __device_release_driver(dev);
+       up(&dev->sem);
+}
+
+
+/**
+ * driver_detach - detach driver from all devices it controls.
+ * @drv: driver.
+ */
+void driver_detach(struct device_driver * drv)
+{
+       struct device * dev;
+
+       for (;;) {
+               spin_lock_irq(&drv->klist_devices.k_lock);
+               if (list_empty(&drv->klist_devices.k_list)) {
+                       spin_unlock_irq(&drv->klist_devices.k_lock);
+                       break;
+               }
+               dev = list_entry(drv->klist_devices.k_list.prev,
+                               struct device, knode_driver.n_node);
+               get_device(dev);
+               spin_unlock_irq(&drv->klist_devices.k_lock);
+
+               down(&dev->sem);
+               if (dev->driver == drv)
+                       __device_release_driver(dev);
+               up(&dev->sem);
+               put_device(dev);
+       }
+}
+
+
+EXPORT_SYMBOL_GPL(device_bind_driver);
+EXPORT_SYMBOL_GPL(device_release_driver);
+EXPORT_SYMBOL_GPL(device_attach);
+EXPORT_SYMBOL_GPL(driver_attach);
+
index f48833df61a29dfba2c469abba7bc4ed6516aa77..c4aebf2f522d724abfbb8e1c5538ac8441322bbd 100644 (file)
@@ -41,7 +41,7 @@ struct dma_page {     /* cacheable header for 'allocation' bytes */
 static DECLARE_MUTEX (pools_lock);
 
 static ssize_t
-show_pools (struct device *dev, char *buf)
+show_pools (struct device *dev, struct device_attribute *attr, char *buf)
 {
        unsigned temp;
        unsigned size;
index 3b269f7e52135472c70b6102e17ca31a5b24c050..1b645886e9eba14046fbb0d62fd7051477ff43a5 100644 (file)
 #define to_dev(node) container_of(node, struct device, driver_list)
 #define to_drv(obj) container_of(obj, struct device_driver, kobj)
 
+
+static struct device * next_device(struct klist_iter * i)
+{
+       struct klist_node * n = klist_next(i);
+       return n ? container_of(n, struct device, knode_driver) : NULL;
+}
+
+/**
+ *     driver_for_each_device - Iterator for devices bound to a driver.
+ *     @drv:   Driver we're iterating.
+ *     @data:  Data to pass to the callback.
+ *     @fn:    Function to call for each device.
+ *
+ *     Iterate over the @drv's list of devices calling @fn for each one.
+ */
+
+int driver_for_each_device(struct device_driver * drv, struct device * start, 
+                          void * data, int (*fn)(struct device *, void *))
+{
+       struct klist_iter i;
+       struct device * dev;
+       int error = 0;
+
+       if (!drv)
+               return -EINVAL;
+
+       klist_iter_init_node(&drv->klist_devices, &i,
+                            start ? &start->knode_driver : NULL);
+       while ((dev = next_device(&i)) && !error)
+               error = fn(dev, data);
+       klist_iter_exit(&i);
+       return error;
+}
+
+EXPORT_SYMBOL_GPL(driver_for_each_device);
+
+
 /**
  *     driver_create_file - create sysfs file for driver.
  *     @drv:   driver.
@@ -85,7 +122,7 @@ void put_driver(struct device_driver * drv)
  */
 int driver_register(struct device_driver * drv)
 {
-       INIT_LIST_HEAD(&drv->devices);
+       klist_init(&drv->klist_devices);
        init_completion(&drv->unloaded);
        return bus_add_driver(drv);
 }
index 583d57ec49a822f0f30305526d456141662bec38..5d4517ccc422c392e308b83376b2d537fce67485 100644 (file)
@@ -136,7 +136,7 @@ static SYSDEV_ATTR(distance, S_IRUGO, node_read_distance, NULL);
  *
  * Initialize and register the node device.
  */
-int __init register_node(struct node *node, int num, struct node *parent)
+int register_node(struct node *node, int num, struct node *parent)
 {
        int error;
 
@@ -153,8 +153,24 @@ int __init register_node(struct node *node, int num, struct node *parent)
        return error;
 }
 
+/**
+ * unregister_node - unregister a node device
+ * @node: node going away
+ *
+ * Unregisters a node device @node.  All the devices on the node must be
+ * unregistered before calling this function.
+ */
+void unregister_node(struct node *node)
+{
+       sysdev_remove_file(&node->sysdev, &attr_cpumap);
+       sysdev_remove_file(&node->sysdev, &attr_meminfo);
+       sysdev_remove_file(&node->sysdev, &attr_numastat);
+       sysdev_remove_file(&node->sysdev, &attr_distance);
+
+       sysdev_unregister(&node->sysdev);
+}
 
-int __init register_node_type(void)
+static int __init register_node_type(void)
 {
        return sysdev_class_register(&node_class);
 }
index 26468971ef5a7711179e87f0d500cdc680888157..bdd96b03b8857a14367535bf408224b1eb939503 100644 (file)
@@ -22,6 +22,9 @@ extern int sysdev_resume(void);
 
 int resume_device(struct device * dev)
 {
+       int error = 0;
+
+       down(&dev->sem);
        if (dev->power.pm_parent
                        && dev->power.pm_parent->power.power_state) {
                dev_err(dev, "PM: resume from %d, parent %s still %d\n",
@@ -31,9 +34,10 @@ int resume_device(struct device * dev)
        }
        if (dev->bus && dev->bus->resume) {
                dev_dbg(dev,"resuming\n");
-               return dev->bus->resume(dev);
+               error = dev->bus->resume(dev);
        }
-       return 0;
+       up(&dev->sem);
+       return error;
 }
 
 
index 0ec44ef840beaf42c89d2fdb897be5f60685a369..2ccee3763acfae23a3d1de899179dd5ac0ca9419 100644 (file)
@@ -39,6 +39,7 @@ int suspend_device(struct device * dev, pm_message_t state)
 {
        int error = 0;
 
+       down(&dev->sem);
        if (dev->power.power_state) {
                dev_dbg(dev, "PM: suspend %d-->%d\n",
                        dev->power.power_state, state);
@@ -58,7 +59,7 @@ int suspend_device(struct device * dev, pm_message_t state)
                dev_dbg(dev, "suspending\n");
                error = dev->bus->suspend(dev, state);
        }
-
+       up(&dev->sem);
        return error;
 }
 
@@ -113,8 +114,19 @@ int device_suspend(pm_message_t state)
                put_device(dev);
        }
        up(&dpm_list_sem);
-       if (error)
+       if (error) {
+               /* we failed... before resuming, bring back devices from
+                * dpm_off_irq list back to main dpm_off list, we do want
+                * to call resume() on them, in case they partially suspended
+                * despite returning -EAGAIN
+                */
+               while (!list_empty(&dpm_off_irq)) {
+                       struct list_head * entry = dpm_off_irq.next;
+                       list_del(entry);
+                       list_add(entry, &dpm_off);
+               }
                dpm_resume();
+       }
        up(&dpm_sem);
        return error;
 }
index 6ac96349a8e8688b3e557608742b9d866ddb99f7..f82b3df9545f68b66cd1866862bc665a1f7e00c5 100644 (file)
  *     low-power state.
  */
 
-static ssize_t state_show(struct device * dev, char * buf)
+static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
        return sprintf(buf, "%u\n", dev->power.power_state);
 }
 
-static ssize_t state_store(struct device * dev, const char * buf, size_t n)
+static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
 {
        u32 state;
        char * rest;
index 9102e3756f953cfc8bd0303f1add2948ee07a8bc..f37a13de804a9905c131f59d75c07ada35f9dd9d 100644 (file)
@@ -37,7 +37,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
 
        if (sysdev_attr->show)
                return sysdev_attr->show(sysdev, buffer);
-       return 0;
+       return -EIO;
 }
 
 
@@ -50,7 +50,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr,
 
        if (sysdev_attr->store)
                return sysdev_attr->store(sysdev, buffer, count);
-       return 0;
+       return -EIO;
 }
 
 static struct sysfs_ops sysfs_ops = {
index 14aeca3e2e8c58ab178ba489b6e32f230ebec29d..45a243096187afed4746ca58b84584841b2373eb 100644 (file)
@@ -36,7 +36,7 @@ static int emsgs_head_idx, emsgs_tail_idx;
 static struct semaphore emsgs_sema;
 static spinlock_t emsgs_lock;
 static int nblocked_emsgs_readers;
-static struct class_simple *aoe_class;
+static struct class *aoe_class;
 static struct aoe_chardev chardevs[] = {
        { MINOR_ERR, "err" },
        { MINOR_DISCOVER, "discover" },
@@ -218,13 +218,13 @@ aoechr_init(void)
        }
        sema_init(&emsgs_sema, 0);
        spin_lock_init(&emsgs_lock);
-       aoe_class = class_simple_create(THIS_MODULE, "aoe");
+       aoe_class = class_create(THIS_MODULE, "aoe");
        if (IS_ERR(aoe_class)) {
                unregister_chrdev(AOE_MAJOR, "aoechr");
                return PTR_ERR(aoe_class);
        }
        for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-               class_simple_device_add(aoe_class,
+               class_device_create(aoe_class,
                                        MKDEV(AOE_MAJOR, chardevs[i].minor),
                                        NULL, chardevs[i].name);
 
@@ -237,8 +237,8 @@ aoechr_exit(void)
        int i;
 
        for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-               class_simple_device_remove(MKDEV(AOE_MAJOR, chardevs[i].minor));
-       class_simple_destroy(aoe_class);
+               class_device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor));
+       class_destroy(aoe_class);
        unregister_chrdev(AOE_MAJOR, "aoechr");
 }
 
index a9575bb58a5e14630c507734bb35288c32da8338..638db06de2bea5414a55b0dfa8522a5db238c8bf 100644 (file)
@@ -2044,7 +2044,7 @@ as_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
        struct as_fs_entry *entry = to_as(attr);
 
        if (!entry->show)
-               return 0;
+               return -EIO;
 
        return entry->show(e->elevator_data, page);
 }
@@ -2057,7 +2057,7 @@ as_attr_store(struct kobject *kobj, struct attribute *attr,
        struct as_fs_entry *entry = to_as(attr);
 
        if (!entry->store)
-               return -EINVAL;
+               return -EIO;
 
        return entry->store(e->elevator_data, page, length);
 }
index 2210bacad56a34c4023a85036681c51657d19f8b..3ac47dde64da3be93b5e4bed65cee827f16db952 100644 (file)
@@ -1775,7 +1775,7 @@ cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
        struct cfq_fs_entry *entry = to_cfq(attr);
 
        if (!entry->show)
-               return 0;
+               return -EIO;
 
        return entry->show(e->elevator_data, page);
 }
@@ -1788,7 +1788,7 @@ cfq_attr_store(struct kobject *kobj, struct attribute *attr,
        struct cfq_fs_entry *entry = to_cfq(attr);
 
        if (!entry->store)
-               return -EINVAL;
+               return -EIO;
 
        return entry->store(e->elevator_data, page, length);
 }
index d63d34c671f7a7fcbc9007ca009a04f125303cd1..7f79f3dd01655f111d88701bb48df642c72046a5 100644 (file)
@@ -886,7 +886,7 @@ deadline_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
        struct deadline_fs_entry *entry = to_deadline(attr);
 
        if (!entry->show)
-               return 0;
+               return -EIO;
 
        return entry->show(e->elevator_data, page);
 }
@@ -899,7 +899,7 @@ deadline_attr_store(struct kobject *kobj, struct attribute *attr,
        struct deadline_fs_entry *entry = to_deadline(attr);
 
        if (!entry->store)
-               return -EINVAL;
+               return -EIO;
 
        return entry->store(e->elevator_data, page, length);
 }
index 8bbe01d4b487cf5c9a03b474e8ffd2e57bbf1e8f..53f7d846b747f35692f782e0bc84f1fa8639a42e 100644 (file)
@@ -322,7 +322,7 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
        struct gendisk *disk = to_disk(kobj);
        struct disk_attribute *disk_attr =
                container_of(attr,struct disk_attribute,attr);
-       ssize_t ret = 0;
+       ssize_t ret = -EIO;
 
        if (disk_attr->show)
                ret = disk_attr->show(disk,page);
index f20eba22b14b254553933848e94f3f4192552603..81fe3a0c1fe730f0cfea7661b65c44602aca5844 100644 (file)
@@ -3574,7 +3574,7 @@ queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
        q = container_of(kobj, struct request_queue, kobj);
        if (!entry->show)
-               return 0;
+               return -EIO;
 
        return entry->show(q, page);
 }
@@ -3588,7 +3588,7 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
 
        q = container_of(kobj, struct request_queue, kobj);
        if (!entry->store)
-               return -EINVAL;
+               return -EIO;
 
        return entry->store(q, page, length);
 }
index dbeb107bb97107c42af8abffa049d56bb888f9e4..84d8e291ed964aaafb537790dc2fd00f1b781263 100644 (file)
@@ -222,7 +222,7 @@ static int pg_identify(struct pg *dev, int log);
 
 static char pg_scratch[512];   /* scratch block buffer */
 
-static struct class_simple *pg_class;
+static struct class *pg_class;
 
 /* kernel glue structures */
 
@@ -666,7 +666,7 @@ static int __init pg_init(void)
                err = -1;
                goto out;
        }
-       pg_class = class_simple_create(THIS_MODULE, "pg");
+       pg_class = class_create(THIS_MODULE, "pg");
        if (IS_ERR(pg_class)) {
                err = PTR_ERR(pg_class);
                goto out_chrdev;
@@ -675,7 +675,7 @@ static int __init pg_init(void)
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
                if (dev->present) {
-                       class_simple_device_add(pg_class, MKDEV(major, unit), 
+                       class_device_create(pg_class, MKDEV(major, unit),
                                        NULL, "pg%u", unit);
                        err = devfs_mk_cdev(MKDEV(major, unit),
                                      S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
@@ -688,8 +688,8 @@ static int __init pg_init(void)
        goto out;
 
 out_class:
-       class_simple_device_remove(MKDEV(major, unit));
-       class_simple_destroy(pg_class);
+       class_device_destroy(pg_class, MKDEV(major, unit));
+       class_destroy(pg_class);
 out_chrdev:
        unregister_chrdev(major, "pg");
 out:
@@ -703,11 +703,11 @@ static void __exit pg_exit(void)
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
                if (dev->present) {
-                       class_simple_device_remove(MKDEV(major, unit));
+                       class_device_destroy(pg_class, MKDEV(major, unit));
                        devfs_remove("pg/%u", unit);
                }
        }
-       class_simple_destroy(pg_class);
+       class_destroy(pg_class);
        devfs_remove("pg");
        unregister_chrdev(major, name);
 
index 8fbd6922fe0d461a0b3cd5b885756fc882d0535d..5fe8ee86f095bb82a9691fd5792f8411a4797555 100644 (file)
@@ -242,7 +242,7 @@ static struct file_operations pt_fops = {
 };
 
 /* sysfs class support */
-static struct class_simple *pt_class;
+static struct class *pt_class;
 
 static inline int status_reg(struct pi_adapter *pi)
 {
@@ -963,7 +963,7 @@ static int __init pt_init(void)
                err = -1;
                goto out;
        }
-       pt_class = class_simple_create(THIS_MODULE, "pt");
+       pt_class = class_create(THIS_MODULE, "pt");
        if (IS_ERR(pt_class)) {
                err = PTR_ERR(pt_class);
                goto out_chrdev;
@@ -972,29 +972,29 @@ static int __init pt_init(void)
        devfs_mk_dir("pt");
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
-                       class_simple_device_add(pt_class, MKDEV(major, unit), 
+                       class_device_create(pt_class, MKDEV(major, unit),
                                        NULL, "pt%d", unit);
                        err = devfs_mk_cdev(MKDEV(major, unit),
                                      S_IFCHR | S_IRUSR | S_IWUSR,
                                      "pt/%d", unit);
                        if (err) {
-                               class_simple_device_remove(MKDEV(major, unit));
+                               class_device_destroy(pt_class, MKDEV(major, unit));
                                goto out_class;
                        }
-                       class_simple_device_add(pt_class, MKDEV(major, unit + 128),
+                       class_device_create(pt_class, MKDEV(major, unit + 128),
                                        NULL, "pt%dn", unit);
                        err = devfs_mk_cdev(MKDEV(major, unit + 128),
                                      S_IFCHR | S_IRUSR | S_IWUSR,
                                      "pt/%dn", unit);
                        if (err) {
-                               class_simple_device_remove(MKDEV(major, unit + 128));
+                               class_device_destroy(pt_class, MKDEV(major, unit + 128));
                                goto out_class;
                        }
                }
        goto out;
 
 out_class:
-       class_simple_destroy(pt_class);
+       class_destroy(pt_class);
 out_chrdev:
        unregister_chrdev(major, "pt");
 out:
@@ -1006,12 +1006,12 @@ static void __exit pt_exit(void)
        int unit;
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
-                       class_simple_device_remove(MKDEV(major, unit));
+                       class_device_destroy(pt_class, MKDEV(major, unit));
                        devfs_remove("pt/%d", unit);
-                       class_simple_device_remove(MKDEV(major, unit + 128));
+                       class_device_destroy(pt_class, MKDEV(major, unit + 128));
                        devfs_remove("pt/%dn", unit);
                }
-       class_simple_destroy(pt_class);
+       class_destroy(pt_class);
        devfs_remove("pt");
        unregister_chrdev(major, name);
        for (unit = 0; unit < PT_UNITS; unit++)
index 19c5e59bcfa826966d433c2edd6f921592a7f40f..685f061e69b2971484a9546de5f3e32cc7b32801 100644 (file)
@@ -430,7 +430,7 @@ static void ub_cmdtr_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
        }
 }
 
-static ssize_t ub_diag_show(struct device *dev, char *page)
+static ssize_t ub_diag_show(struct device *dev, struct device_attribute *attr, char *page)
 {
        struct usb_interface *intf;
        struct ub_dev *sc;
index 37d6649011ad29900d11d6a2483db08d6bae768d..26271e3ca82371542b9395fea1815e0b71f43290 100644 (file)
@@ -144,7 +144,7 @@ static struct dsp56k_device {
        int tx_wsize, rx_wsize;
 } dsp56k;
 
-static struct class_simple *dsp56k_class;
+static struct class *dsp56k_class;
 
 static int dsp56k_reset(void)
 {
@@ -510,12 +510,12 @@ static int __init dsp56k_init_driver(void)
                printk("DSP56k driver: Unable to register driver\n");
                return -ENODEV;
        }
-       dsp56k_class = class_simple_create(THIS_MODULE, "dsp56k");
+       dsp56k_class = class_create(THIS_MODULE, "dsp56k");
        if (IS_ERR(dsp56k_class)) {
                err = PTR_ERR(dsp56k_class);
                goto out_chrdev;
        }
-       class_simple_device_add(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+       class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
 
        err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
                      S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
@@ -526,8 +526,8 @@ static int __init dsp56k_init_driver(void)
        goto out;
 
 out_class:
-       class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
-       class_simple_destroy(dsp56k_class);
+       class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+       class_destroy(dsp56k_class);
 out_chrdev:
        unregister_chrdev(DSP56K_MAJOR, "dsp56k");
 out:
@@ -537,8 +537,8 @@ module_init(dsp56k_init_driver);
 
 static void __exit dsp56k_cleanup_driver(void)
 {
-       class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0));
-       class_simple_destroy(dsp56k_class);
+       class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
+       class_destroy(dsp56k_class);
        unregister_chrdev(DSP56K_MAJOR, "dsp56k");
        devfs_remove("dsp56k");
 }
index dbac7e54e8e069911517c99f153b9c8650475b06..5745b74044ec1b1a583a606b2ef7346b7df5bfad 100644 (file)
@@ -99,7 +99,7 @@ static struct file_operations zft_cdev =
        .release        = zft_close,
 };
 
-static struct class_simple *zft_class;
+static struct class *zft_class;
 
 /*      Open floppy tape device
  */
@@ -329,29 +329,29 @@ KERN_INFO
              "installing zftape VFS interface for ftape driver ...");
        TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),);
 
-       zft_class = class_simple_create(THIS_MODULE, "zft");
+       zft_class = class_create(THIS_MODULE, "zft");
        for (i = 0; i < 4; i++) {
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "qft%i", i);
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "nqft%i", i);
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "zqft%i", i);
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "nzqft%i", i);
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "rawqft%i", i);
-               class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+               class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
                devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
                                S_IFCHR | S_IRUSR | S_IWUSR,
                                "nrawqft%i", i);
@@ -381,19 +381,19 @@ static void zft_exit(void)
        }
         for (i = 0; i < 4; i++) {
                devfs_remove("qft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
                devfs_remove("nqft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 4));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
                devfs_remove("zqft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 16));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
                devfs_remove("nzqft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 20));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
                devfs_remove("rawqft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 32));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
                devfs_remove("nrawqft%i", i);
-               class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 36));
+               class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
        }
-       class_simple_destroy(zft_class);
+       class_destroy(zft_class);
        zft_uninit_mem(); /* release remaining memory, if any */
         printk(KERN_INFO "zftape successfully unloaded.\n");
        TRACE_EXIT;
index abfbdcfd4e725a397f23121144d5a308c1a429e7..3236d2404905003ad92ce5b2ef82cc96f28a3906 100644 (file)
@@ -1466,7 +1466,7 @@ static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod)
 }
 /* The sysfs interface for the driver and devices */
 
-static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct vio_dev *viod = to_vio_dev(dev);
        struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1480,7 +1480,7 @@ static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf)
 }
 static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL);
 
-static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf)
+static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct vio_dev *viod = to_vio_dev(dev);
        struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1494,7 +1494,7 @@ static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf)
 }
 static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL);
 
-static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf,
+static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf,
                size_t count)
 {
        /*
@@ -1505,7 +1505,7 @@ static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf,
        return -EPERM;
 }
 
-static ssize_t hvcs_current_vty_show(struct device *dev, char *buf)
+static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct vio_dev *viod = to_vio_dev(dev);
        struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1521,7 +1521,7 @@ static ssize_t hvcs_current_vty_show(struct device *dev, char *buf)
 static DEVICE_ATTR(current_vty,
        S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
 
-static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf,
+static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf,
                size_t count)
 {
        struct vio_dev *viod = to_vio_dev(dev);
@@ -1559,7 +1559,7 @@ static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf,
        return count;
 }
 
-static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf)
+static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct vio_dev *viod = to_vio_dev(dev);
        struct hvcs_struct *hvcsd = from_vio_dev(viod);
@@ -1574,7 +1574,7 @@ static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf)
 static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR,
                hvcs_vterm_state_show, hvcs_vterm_state_store);
 
-static ssize_t hvcs_index_show(struct device *dev, char *buf)
+static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct vio_dev *viod = to_vio_dev(dev);
        struct hvcs_struct *hvcsd = from_vio_dev(viod);
index fca9a978fb73fc2662daea26caa6f0744e0a5764..3b8314b4249ac902b5da172c20a781191956afa2 100644 (file)
@@ -302,7 +302,7 @@ static char rirqs[IP2_MAX_BOARDS];
 static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
 
 /* for sysfs class support */
-static struct class_simple *ip2_class;
+static struct class *ip2_class;
 
 // Some functions to keep track of what irq's we have
 
@@ -414,9 +414,9 @@ cleanup_module(void)
                        iiResetDelay( i2BoardPtrTable[i] );
                        /* free io addresses and Tibet */
                        release_region( ip2config.addr[i], 8 );
-                       class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i)); 
+                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
                        devfs_remove("ip2/ipl%d", i);
-                       class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
+                       class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
                        devfs_remove("ip2/stat%d", i);
                }
                /* Disable and remove interrupt handler. */
@@ -425,7 +425,7 @@ cleanup_module(void)
                        clear_requested_irq( ip2config.irq[i]);
                }
        }
-       class_simple_destroy(ip2_class);
+       class_destroy(ip2_class);
        devfs_remove("ip2");
        if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
                printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
@@ -700,7 +700,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
                printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err );
        } else {
                /* create the sysfs class */
-               ip2_class = class_simple_create(THIS_MODULE, "ip2");
+               ip2_class = class_create(THIS_MODULE, "ip2");
                if (IS_ERR(ip2_class)) {
                        err = PTR_ERR(ip2_class);
                        goto out_chrdev;        
@@ -722,25 +722,25 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
                        }
 
                        if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-                               class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+                               class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
                                                4 * i), NULL, "ipl%d", i);
                                err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
                                                S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
                                                "ip2/ipl%d", i);
                                if (err) {
-                                       class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
-                                               4 * i));
+                                       class_device_destroy(ip2_class,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i));
                                        goto out_class;
                                }
 
-                               class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, 
+                               class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
                                                4 * i + 1), NULL, "stat%d", i);
                                err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
                                                S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
                                                "ip2/stat%d", i);
                                if (err) {
-                                       class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 
-                                               4 * i + 1));
+                                       class_device_destroy(ip2_class,
+                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
                                        goto out_class;
                                }
 
@@ -798,7 +798,7 @@ retry:
        goto out;
 
 out_class:
-       class_simple_destroy(ip2_class);
+       class_destroy(ip2_class);
 out_chrdev:
        unregister_chrdev(IP2_IPL_MAJOR, "ip2");
 out:
index 6dc765dc5413dfe1f0ba58ead7d921899be22194..88d1ad656e99a2df138122225992d7cb91f3d728 100644 (file)
@@ -520,7 +520,7 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device.  By"
                 " interface.  Other values will set the major device number"
                 " to that value.");
 
-static struct class_simple *ipmi_class;
+static struct class *ipmi_class;
 
 static void ipmi_new_smi(int if_num)
 {
@@ -529,12 +529,12 @@ static void ipmi_new_smi(int if_num)
        devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
                      "ipmidev/%d", if_num);
 
-       class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num);
+       class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
 }
 
 static void ipmi_smi_gone(int if_num)
 {
-       class_simple_device_remove(MKDEV(ipmi_major, if_num));
+       class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num));
        devfs_remove("ipmidev/%d", if_num);
 }
 
@@ -555,7 +555,7 @@ static __init int init_ipmi_devintf(void)
        printk(KERN_INFO "ipmi device interface version "
               IPMI_DEVINTF_VERSION "\n");
 
-       ipmi_class = class_simple_create(THIS_MODULE, "ipmi");
+       ipmi_class = class_create(THIS_MODULE, "ipmi");
        if (IS_ERR(ipmi_class)) {
                printk(KERN_ERR "ipmi: can't register device class\n");
                return PTR_ERR(ipmi_class);
@@ -563,7 +563,7 @@ static __init int init_ipmi_devintf(void)
 
        rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
        if (rv < 0) {
-               class_simple_destroy(ipmi_class);
+               class_destroy(ipmi_class);
                printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
                return rv;
        }
@@ -577,7 +577,7 @@ static __init int init_ipmi_devintf(void)
        rv = ipmi_smi_watcher_register(&smi_watcher);
        if (rv) {
                unregister_chrdev(ipmi_major, DEVICE_NAME);
-               class_simple_destroy(ipmi_class);
+               class_destroy(ipmi_class);
                printk(KERN_WARNING "ipmi: can't register smi watcher\n");
                return rv;
        }
@@ -588,7 +588,7 @@ module_init(init_ipmi_devintf);
 
 static __exit void cleanup_ipmi(void)
 {
-       class_simple_destroy(ipmi_class);
+       class_destroy(ipmi_class);
        ipmi_smi_watcher_unregister(&smi_watcher);
        devfs_remove(DEVICE_NAME);
        unregister_chrdev(ipmi_major, DEVICE_NAME);
index 21aed0e8779de8e934b0bedebd8c4306ea9abe34..c02a21dbad5d516b400f28fa0f2c601aaa8b7136 100644 (file)
@@ -792,7 +792,7 @@ static int  stli_timeron;
 
 /*****************************************************************************/
 
-static struct class_simple *istallion_class;
+static struct class *istallion_class;
 
 #ifdef MODULE
 
@@ -854,10 +854,10 @@ static void __exit istallion_module_exit(void)
        put_tty_driver(stli_serial);
        for (i = 0; i < 4; i++) {
                devfs_remove("staliomem/%d", i);
-               class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i));
+               class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i));
        }
        devfs_remove("staliomem");
-       class_simple_destroy(istallion_class);
+       class_destroy(istallion_class);
        if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
                printk("STALLION: failed to un-register serial memory device, "
                        "errno=%d\n", -i);
@@ -5242,12 +5242,12 @@ int __init stli_init(void)
                                "device\n");
 
        devfs_mk_dir("staliomem");
-       istallion_class = class_simple_create(THIS_MODULE, "staliomem");
+       istallion_class = class_create(THIS_MODULE, "staliomem");
        for (i = 0; i < 4; i++) {
                devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
                               S_IFCHR | S_IRUSR | S_IWUSR,
                               "staliomem/%d", i);
-               class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), 
+               class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
                                NULL, "staliomem%d", i);
        }
 
index 4dee945031d45cf46d61b604bcbfffe58f1ac895..59eebe5a035f1c7691656f389c75af261769c0eb 100644 (file)
 static struct lp_struct lp_table[LP_NO];
 
 static unsigned int lp_count = 0;
-static struct class_simple *lp_class;
+static struct class *lp_class;
 
 #ifdef CONFIG_LP_CONSOLE
 static struct parport *console_registered; // initially NULL
@@ -804,7 +804,7 @@ static int lp_register(int nr, struct parport *port)
        if (reset)
                lp_reset(nr);
 
-       class_simple_device_add(lp_class, MKDEV(LP_MAJOR, nr), NULL,
+       class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
                                "lp%d", nr);
        devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
                        "printers/%d", nr);
@@ -907,7 +907,7 @@ static int __init lp_init (void)
        }
 
        devfs_mk_dir("printers");
-       lp_class = class_simple_create(THIS_MODULE, "printer");
+       lp_class = class_create(THIS_MODULE, "printer");
        if (IS_ERR(lp_class)) {
                err = PTR_ERR(lp_class);
                goto out_devfs;
@@ -930,7 +930,7 @@ static int __init lp_init (void)
        return 0;
 
 out_class:
-       class_simple_destroy(lp_class);
+       class_destroy(lp_class);
 out_devfs:
        devfs_remove("printers");
        unregister_chrdev(LP_MAJOR, "lp");
@@ -981,10 +981,10 @@ static void lp_cleanup_module (void)
                        continue;
                parport_unregister_device(lp_table[offset].dev);
                devfs_remove("printers/%d", offset);
-               class_simple_device_remove(MKDEV(LP_MAJOR, offset));
+               class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
        }
        devfs_remove("printers");
-       class_simple_destroy(lp_class);
+       class_destroy(lp_class);
 }
 
 __setup("lp=", lp_setup);
index ac9cfa9701ea9003d0f440ec572e0eecaec7a1a3..115dbb35334b031e71acaedff084402499a449a2 100644 (file)
@@ -699,7 +699,7 @@ static inline int mbcs_hw_init(struct mbcs_soft *soft)
        return 0;
 }
 
-static ssize_t show_algo(struct device *dev, char *buf)
+static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct cx_dev *cx_dev = to_cx_dev(dev);
        struct mbcs_soft *soft = cx_dev->soft;
@@ -715,7 +715,7 @@ static ssize_t show_algo(struct device *dev, char *buf)
                       (debug0 >> 32), (debug0 & 0xffffffff));
 }
 
-static ssize_t store_algo(struct device *dev, const char *buf, size_t count)
+static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        int n;
        struct cx_dev *cx_dev = to_cx_dev(dev);
index 947cb3cef816715dafe2c6a48e092d9dbf30d0a7..257b8ee605e555d14dc5da5495d14e609b891bbe 100644 (file)
@@ -856,7 +856,7 @@ static const struct {
        {11,"kmsg",    S_IRUGO | S_IWUSR,           &kmsg_fops},
 };
 
-static struct class_simple *mem_class;
+static struct class *mem_class;
 
 static int __init chr_dev_init(void)
 {
@@ -865,10 +865,9 @@ static int __init chr_dev_init(void)
        if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
                printk("unable to get major %d for memory devs\n", MEM_MAJOR);
 
-       mem_class = class_simple_create(THIS_MODULE, "mem");
+       mem_class = class_create(THIS_MODULE, "mem");
        for (i = 0; i < ARRAY_SIZE(devlist); i++) {
-               class_simple_device_add(mem_class,
-                                       MKDEV(MEM_MAJOR, devlist[i].minor),
+               class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
                                        NULL, devlist[i].name);
                devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
                                S_IFCHR | devlist[i].mode, devlist[i].name);
index 0937544762da76d0a8627a9fe96b35c394a5d768..3115d318b9978618784a4ee4f8173070cfcbe023 100644 (file)
@@ -177,10 +177,10 @@ fail:
 
 /* 
  * TODO for 2.7:
- *  - add a struct class_device to struct miscdevice and make all usages of
+ *  - add a struct kref to struct miscdevice and make all usages of
  *    them dynamic.
  */
-static struct class_simple *misc_class;
+static struct class *misc_class;
 
 static struct file_operations misc_fops = {
        .owner          = THIS_MODULE,
@@ -238,8 +238,8 @@ int misc_register(struct miscdevice * misc)
        }
        dev = MKDEV(MISC_MAJOR, misc->minor);
 
-       misc->class = class_simple_device_add(misc_class, dev,
-                                             misc->dev, misc->name);
+       misc->class = class_device_create(misc_class, dev, misc->dev,
+                                         "%s", misc->name);
        if (IS_ERR(misc->class)) {
                err = PTR_ERR(misc->class);
                goto out;
@@ -248,7 +248,7 @@ int misc_register(struct miscdevice * misc)
        err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, 
                            misc->devfs_name);
        if (err) {
-               class_simple_device_remove(dev);
+         &nbs