From 0c81e6739f7a68994fdf2105e4d8ce1143237513 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 2 Jan 2012 10:04:14 +0100 Subject: [PATCH] --- yaml --- r: 288670 b: refs/heads/master c: ac483c446b67870444c9eeaf8325d3d2af9b91bc h: refs/heads/master v: v3 --- [refs] | 2 +- .../Documentation/DocBook/device-drivers.tmpl | 12 +- trunk/Documentation/driver-model/devres.txt | 4 - .../feature-removal-schedule.txt | 14 - trunk/Documentation/lockup-watchdogs.txt | 63 - trunk/Documentation/nmi_watchdog.txt | 83 + trunk/Documentation/pinctrl.txt | 17 +- trunk/Documentation/stable_kernel_rules.txt | 3 +- trunk/Documentation/virtual/00-INDEX | 2 + trunk/MAINTAINERS | 43 +- trunk/Makefile | 2 +- trunk/arch/arm/Kconfig | 4 +- trunk/arch/arm/common/gic.c | 7 +- trunk/arch/arm/include/asm/assembler.h | 4 +- trunk/arch/arm/include/asm/domain.h | 8 +- trunk/arch/arm/include/asm/futex.h | 8 +- trunk/arch/arm/include/asm/smp.h | 6 + trunk/arch/arm/include/asm/smp_plat.h | 6 - trunk/arch/arm/include/asm/uaccess.h | 16 +- trunk/arch/arm/kernel/entry-common.S | 15 +- trunk/arch/arm/kernel/setup.c | 17 +- trunk/arch/arm/kernel/smp.c | 24 +- trunk/arch/arm/kernel/smp_twd.c | 2 - trunk/arch/arm/kernel/vmlinux.lds.S | 9 +- trunk/arch/arm/lib/getuser.S | 12 +- trunk/arch/arm/lib/putuser.S | 28 +- trunk/arch/arm/lib/uaccess.S | 82 +- trunk/arch/arm/mach-at91/Kconfig | 14 - trunk/arch/arm/mach-at91/Makefile | 14 +- trunk/arch/arm/mach-at91/at91cap9.c | 9 +- trunk/arch/arm/mach-at91/at91sam9260.c | 1 - trunk/arch/arm/mach-at91/at91sam9261.c | 1 - trunk/arch/arm/mach-at91/at91sam9263.c | 1 - trunk/arch/arm/mach-at91/at91sam9_alt_reset.S | 7 +- trunk/arch/arm/mach-at91/at91sam9g45.c | 7 +- trunk/arch/arm/mach-at91/at91sam9g45_reset.S | 40 - trunk/arch/arm/mach-at91/at91sam9rl.c | 1 - trunk/arch/arm/mach-at91/generic.h | 2 - .../arm/mach-at91/include/mach/at91_rstc.h | 18 +- .../arm/mach-at91/include/mach/at91cap9.h | 2 +- .../mach-at91/include/mach/at91cap9_ddrsdr.h | 108 + .../arm/mach-at91/include/mach/at91sam9260.h | 2 +- .../arm/mach-at91/include/mach/at91sam9261.h | 2 +- .../arm/mach-at91/include/mach/at91sam9263.h | 2 +- .../mach-at91/include/mach/at91sam9_ddrsdr.h | 30 +- .../arm/mach-at91/include/mach/at91sam9g45.h | 2 +- .../arm/mach-at91/include/mach/at91sam9rl.h | 2 +- trunk/arch/arm/mach-at91/include/mach/board.h | 2 +- trunk/arch/arm/mach-at91/pm.c | 9 +- trunk/arch/arm/mach-at91/pm.h | 8 +- trunk/arch/arm/mach-at91/pm_slowclock.S | 5 +- trunk/arch/arm/mach-at91/setup.c | 16 +- trunk/arch/arm/mach-exynos/hotplug.c | 1 - trunk/arch/arm/mach-exynos/platsmp.c | 1 - trunk/arch/arm/mach-highbank/highbank.c | 3 +- trunk/arch/arm/mach-imx/Kconfig | 1 + trunk/arch/arm/mach-imx/clock-imx6q.c | 11 - trunk/arch/arm/mach-imx/mach-mx53_ard.c | 4 +- trunk/arch/arm/mach-imx/src.c | 5 +- trunk/arch/arm/mach-msm/hotplug.c | 1 - trunk/arch/arm/mach-msm/platsmp.c | 1 - trunk/arch/arm/mach-omap2/Kconfig | 1 + trunk/arch/arm/mach-pxa/devices.c | 20 + trunk/arch/arm/mach-pxa/pxa25x.c | 2 + trunk/arch/arm/mach-pxa/pxa27x.c | 2 + trunk/arch/arm/mach-pxa/pxa300.c | 1 + trunk/arch/arm/mach-pxa/pxa320.c | 1 + trunk/arch/arm/mach-pxa/pxa3xx.c | 1 + trunk/arch/arm/mach-pxa/pxa95x.c | 1 + trunk/arch/arm/mach-realview/hotplug.c | 1 - .../arm/mach-realview/include/mach/board-eb.h | 18 +- .../mach-realview/include/mach/board-pb11mp.h | 2 - trunk/arch/arm/mach-realview/realview_eb.c | 11 +- .../arch/arm/mach-realview/realview_pb11mp.c | 13 +- trunk/arch/arm/mach-sa1100/assabet.c | 12 + trunk/arch/arm/mach-sa1100/cerf.c | 11 + trunk/arch/arm/mach-sa1100/clock.c | 91 +- trunk/arch/arm/mach-sa1100/collie.c | 23 +- trunk/arch/arm/mach-sa1100/cpu-sa1100.c | 2 +- trunk/arch/arm/mach-sa1100/generic.c | 27 +- trunk/arch/arm/mach-sa1100/include/mach/mcp.h | 2 + trunk/arch/arm/mach-sa1100/jornada720_ssp.c | 2 - trunk/arch/arm/mach-sa1100/lart.c | 10 + trunk/arch/arm/mach-sa1100/shannon.c | 11 + trunk/arch/arm/mach-sa1100/simpad.c | 18 +- trunk/arch/arm/mach-shmobile/smp-r8a7779.c | 1 - trunk/arch/arm/mach-shmobile/smp-sh73a0.c | 1 - trunk/arch/arm/mach-ux500/Kconfig | 1 - trunk/arch/arm/mach-ux500/board-mop500-sdi.c | 2 - trunk/arch/arm/mach-ux500/cache-l2x0.c | 48 +- trunk/arch/arm/mach-ux500/hotplug.c | 1 - trunk/arch/arm/mach-ux500/platsmp.c | 1 - trunk/arch/arm/mach-ux500/usb.c | 6 + trunk/arch/arm/mach-vexpress/ct-ca9x4.c | 4 +- trunk/arch/arm/mach-vexpress/hotplug.c | 1 - trunk/arch/arm/mm/Kconfig | 1 - trunk/arch/arm/mm/init.c | 2 +- trunk/arch/arm/mm/ioremap.c | 3 +- trunk/arch/arm/mm/proc-v7.S | 26 +- .../arch/arm/plat-mxc/include/mach/iomux-v1.h | 2 +- trunk/arch/arm/plat-versatile/platsmp.c | 1 - trunk/arch/microblaze/Kconfig | 1 - trunk/arch/microblaze/include/asm/atomic.h | 1 - trunk/arch/microblaze/kernel/setup.c | 21 +- trunk/arch/s390/Makefile | 1 + trunk/arch/s390/kernel/vmlinux.lds.S | 4 +- trunk/arch/sparc/Kconfig | 1 - trunk/arch/sparc/lib/divdi3.S | 16 +- trunk/arch/x86/include/asm/cmpxchg.h | 6 +- trunk/arch/x86/include/asm/inat.h | 5 +- trunk/arch/x86/include/asm/insn.h | 18 +- trunk/arch/x86/kernel/cpu/amd.c | 3 - trunk/arch/x86/kernel/cpu/perf_event.c | 3 + .../arch/x86/kernel/cpu/perf_event_intel_ds.c | 1 + .../x86/kernel/cpu/perf_event_intel_lbr.c | 2 + trunk/arch/x86/kernel/dumpstack.c | 3 +- trunk/arch/x86/kernel/dumpstack_64.c | 6 +- trunk/arch/x86/kernel/reboot.c | 36 +- trunk/arch/x86/lib/inat.c | 36 +- trunk/arch/x86/lib/insn.c | 13 +- trunk/arch/x86/mm/fault.c | 4 +- trunk/arch/x86/xen/spinlock.c | 27 +- trunk/drivers/base/Makefile | 2 +- trunk/drivers/base/core.c | 17 +- trunk/drivers/base/sys.c | 383 +++ trunk/drivers/block/rbd.c | 7 +- trunk/drivers/char/agp/backend.c | 12 +- trunk/drivers/firewire/ohci.c | 6 +- trunk/drivers/gpu/drm/drm_gem.c | 2 +- trunk/drivers/gpu/drm/exynos/Kconfig | 4 +- .../drivers/gpu/drm/exynos/exynos_drm_fimd.c | 109 +- trunk/drivers/gpu/drm/exynos/exynos_hdmi.c | 8 +- trunk/drivers/gpu/drm/gma500/framebuffer.c | 8 +- trunk/drivers/gpu/drm/i810/i810_dma.c | 17 +- trunk/drivers/gpu/drm/i810/i810_drv.c | 1 - trunk/drivers/gpu/drm/i810/i810_drv.h | 6 +- trunk/drivers/gpu/drm/i915/i915_debugfs.c | 31 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 1 - trunk/drivers/gpu/drm/i915/i915_drv.c | 56 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 10 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 3 +- trunk/drivers/gpu/drm/i915/i915_suspend.c | 11 +- trunk/drivers/gpu/drm/i915/intel_bios.h | 6 +- trunk/drivers/gpu/drm/i915/intel_crt.c | 23 - trunk/drivers/gpu/drm/i915/intel_display.c | 22 +- trunk/drivers/gpu/drm/i915/intel_lvds.c | 8 - trunk/drivers/gpu/drm/i915/intel_ringbuffer.c | 41 +- trunk/drivers/gpu/drm/i915/intel_sdvo.c | 8 +- trunk/drivers/gpu/drm/i915/intel_sprite.c | 8 +- trunk/drivers/gpu/drm/i915/intel_tv.c | 138 +- trunk/drivers/gpu/drm/nouveau/nouveau_bios.h | 5 +- .../drivers/gpu/drm/nouveau/nouveau_display.c | 10 - trunk/drivers/gpu/drm/nouveau/nouveau_drv.c | 2 +- trunk/drivers/gpu/drm/nouveau/nouveau_gem.c | 23 +- trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c | 9 - trunk/drivers/gpu/drm/nouveau/nv50_pm.c | 4 +- trunk/drivers/gpu/drm/radeon/atombios_crtc.c | 4 +- trunk/drivers/gpu/drm/radeon/atombios_dp.c | 18 +- trunk/drivers/gpu/drm/radeon/r600_blit_kms.c | 35 +- .../gpu/drm/radeon/radeon_atpx_handler.c | 3 +- trunk/drivers/gpu/drm/radeon/radeon_device.c | 4 - trunk/drivers/gpu/drm/radeon/radeon_i2c.c | 2 - trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- trunk/drivers/hwmon/f71805f.c | 10 +- trunk/drivers/hwmon/sht15.c | 3 +- trunk/drivers/hwmon/w83627ehf.c | 6 - trunk/drivers/infiniband/core/ucma.c | 5 +- trunk/drivers/infiniband/core/uverbs_cmd.c | 1 - trunk/drivers/infiniband/core/verbs.c | 2 +- trunk/drivers/infiniband/hw/ipath/ipath_fs.c | 2 +- trunk/drivers/infiniband/hw/mlx4/mad.c | 7 +- trunk/drivers/infiniband/hw/nes/nes.c | 2 +- trunk/drivers/infiniband/hw/nes/nes.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_cm.c | 10 +- trunk/drivers/infiniband/hw/nes/nes_cm.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_context.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_hw.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_hw.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_mgt.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_mgt.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_nic.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_user.h | 2 +- trunk/drivers/infiniband/hw/nes/nes_utils.c | 2 +- trunk/drivers/infiniband/hw/nes/nes_verbs.c | 6 +- trunk/drivers/infiniband/hw/nes/nes_verbs.h | 2 +- trunk/drivers/infiniband/hw/qib/qib_iba6120.c | 2 +- trunk/drivers/infiniband/hw/qib/qib_pcie.c | 2 +- trunk/drivers/mfd/mcp-core.c | 61 +- trunk/drivers/mfd/mcp-sa11x0.c | 169 +- trunk/drivers/mfd/ucb1x00-core.c | 67 +- trunk/drivers/mfd/ucb1x00-ts.c | 34 +- .../net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 +- trunk/drivers/net/xen-netfront.c | 2 +- trunk/drivers/pcmcia/sa1111_generic.c | 3 +- trunk/drivers/pinctrl/core.c | 50 +- trunk/drivers/pinctrl/core.h | 3 - trunk/drivers/pinctrl/pinconf.c | 6 +- trunk/drivers/pinctrl/pinconf.h | 4 +- trunk/drivers/pinctrl/pinmux.c | 81 +- trunk/drivers/pinctrl/pinmux.h | 4 +- trunk/drivers/regulator/of_regulator.c | 2 +- trunk/drivers/rtc/Kconfig | 2 +- trunk/drivers/rtc/rtc-sa1100.c | 295 ++- trunk/drivers/s390/block/dasd.c | 6 - trunk/drivers/s390/block/dasd_alias.c | 64 +- trunk/drivers/s390/block/dasd_eckd.c | 63 +- trunk/drivers/s390/block/dasd_int.h | 2 - .../drivers/staging/media/go7007/go7007-usb.c | 1 - trunk/drivers/tty/serial/{8250 => }/8250.c | 0 trunk/drivers/tty/serial/{8250 => }/8250.h | 0 trunk/drivers/tty/serial/8250/Kconfig | 280 -- trunk/drivers/tty/serial/8250/Makefile | 20 - .../tty/serial/{8250 => }/8250_accent.c | 0 .../tty/serial/{8250 => }/8250_acorn.c | 0 .../drivers/tty/serial/{8250 => }/8250_boca.c | 0 trunk/drivers/tty/serial/{8250 => }/8250_dw.c | 0 .../tty/serial/{8250 => }/8250_early.c | 0 .../serial/{8250 => }/8250_exar_st16c554.c | 0 .../tty/serial/{8250 => }/8250_fourport.c | 0 .../drivers/tty/serial/{8250 => }/8250_fsl.c | 0 .../drivers/tty/serial/{8250 => }/8250_gsc.c | 0 .../tty/serial/{8250 => }/8250_hp300.c | 0 .../drivers/tty/serial/{8250 => }/8250_hub6.c | 0 .../drivers/tty/serial/{8250 => }/8250_mca.c | 0 .../drivers/tty/serial/{8250 => }/8250_pci.c | 0 .../drivers/tty/serial/{8250 => }/8250_pnp.c | 0 trunk/drivers/tty/serial/Kconfig | 283 +- trunk/drivers/tty/serial/Makefile | 20 +- trunk/drivers/tty/serial/amba-pl011.c | 30 +- trunk/drivers/tty/serial/jsm/jsm_driver.c | 1 - .../drivers/tty/serial/{8250 => }/m32r_sio.c | 0 .../drivers/tty/serial/{8250 => }/m32r_sio.h | 0 .../tty/serial/{8250 => }/m32r_sio_reg.h | 0 trunk/drivers/tty/serial/max3107-aava.c | 344 +++ trunk/drivers/tty/serial/omap-serial.c | 4 +- trunk/drivers/tty/serial/serial_core.c | 6 +- .../drivers/tty/serial/{8250 => }/serial_cs.c | 0 trunk/drivers/tty/tty_port.c | 12 +- trunk/drivers/usb/class/cdc-wdm.c | 59 +- trunk/drivers/usb/dwc3/ep0.c | 15 +- trunk/drivers/usb/dwc3/gadget.c | 2 +- trunk/drivers/usb/gadget/composite.c | 7 +- trunk/drivers/usb/gadget/epautoconf.c | 2 +- trunk/drivers/usb/gadget/f_mass_storage.c | 10 +- trunk/drivers/usb/gadget/fsl_udc_core.c | 4 +- trunk/drivers/usb/gadget/langwell_udc.c | 107 +- trunk/drivers/usb/gadget/langwell_udc.h | 1 + trunk/drivers/usb/gadget/storage_common.c | 6 +- trunk/drivers/usb/host/ehci-fsl.c | 2 +- trunk/drivers/usb/host/ehci-pci.c | 6 - trunk/drivers/usb/host/ohci-at91.c | 24 +- trunk/drivers/usb/host/ohci-dbg.c | 12 +- trunk/drivers/usb/host/ohci-pci.c | 4 - trunk/drivers/usb/host/xhci-ring.c | 6 +- trunk/drivers/usb/misc/emi26.c | 3 + trunk/drivers/usb/misc/emi62.c | 3 + trunk/drivers/usb/misc/usbsevseg.c | 2 +- trunk/drivers/usb/musb/davinci.c | 3 + trunk/drivers/usb/musb/musb_core.c | 5 +- trunk/drivers/usb/musb/omap2430.c | 4 +- trunk/drivers/usb/otg/Kconfig | 18 +- trunk/drivers/usb/otg/Makefile | 1 + trunk/drivers/usb/otg/langwell_otg.c | 2347 +++++++++++++++++ trunk/drivers/usb/otg/mv_otg.c | 2 - trunk/drivers/usb/renesas_usbhs/mod_gadget.c | 2 +- trunk/drivers/usb/serial/cp210x.c | 105 +- trunk/drivers/usb/serial/ftdi_sio.c | 14 +- trunk/drivers/usb/serial/ftdi_sio_ids.h | 19 - trunk/drivers/usb/serial/io_ti.c | 10 +- trunk/drivers/usb/serial/kobil_sct.c | 2 +- trunk/drivers/usb/serial/option.c | 5 - trunk/drivers/usb/serial/qcaux.c | 7 +- trunk/drivers/usb/storage/realtek_cr.c | 2 +- trunk/drivers/usb/usb-skeleton.c | 18 +- trunk/drivers/usb/wusbcore/Kconfig | 2 +- trunk/drivers/virtio/virtio_ring.c | 8 +- trunk/drivers/watchdog/dw_wdt.c | 6 +- trunk/drivers/watchdog/iTCO_wdt.c | 35 - trunk/drivers/watchdog/imx2_wdt.c | 11 +- trunk/drivers/watchdog/nuc900_wdt.c | 5 +- trunk/drivers/watchdog/omap_wdt.c | 2 - trunk/drivers/watchdog/pnx4008_wdt.c | 2 +- trunk/drivers/watchdog/stmp3xxx_wdt.c | 2 +- trunk/drivers/watchdog/via_wdt.c | 6 +- trunk/drivers/watchdog/wafer5823wdt.c | 4 +- trunk/drivers/watchdog/wm8350_wdt.c | 4 +- trunk/drivers/xen/grant-table.c | 7 +- trunk/fs/btrfs/backref.c | 4 +- trunk/fs/btrfs/check-integrity.c | 11 +- trunk/fs/btrfs/disk-io.c | 7 - trunk/fs/btrfs/extent-tree.c | 49 +- trunk/fs/btrfs/extent_io.c | 2 - trunk/fs/btrfs/free-space-cache.c | 5 +- trunk/fs/btrfs/inode.c | 10 +- trunk/fs/btrfs/ioctl.c | 2 +- trunk/fs/btrfs/tree-log.c | 6 +- trunk/fs/ceph/caps.c | 4 +- trunk/fs/ceph/dir.c | 4 +- trunk/fs/ceph/mds_client.c | 10 +- trunk/fs/ceph/mds_client.h | 7 +- trunk/fs/ceph/xattr.c | 4 +- trunk/fs/logfs/dev_mtd.c | 6 + trunk/fs/logfs/dir.c | 2 +- trunk/fs/logfs/file.c | 2 - trunk/fs/logfs/gc.c | 2 +- trunk/fs/logfs/inode.c | 4 +- trunk/fs/logfs/journal.c | 1 + trunk/fs/logfs/logfs.h | 5 +- trunk/fs/logfs/readwrite.c | 51 +- trunk/fs/logfs/segment.c | 51 +- trunk/fs/logfs/super.c | 3 +- trunk/fs/proc/base.c | 126 +- trunk/fs/sysfs/file.c | 6 - trunk/fs/sysfs/inode.c | 5 +- trunk/include/linux/freezer.h | 2 - trunk/include/linux/ftrace.h | 4 +- trunk/include/linux/lp8727.h | 0 trunk/include/linux/mfd/mcp.h | 12 +- trunk/include/linux/mfd/ucb1x00.h | 5 +- trunk/include/linux/mod_devicetable.h | 11 + trunk/include/linux/mpi.h | 2 + trunk/include/linux/mtd/mtd.h | 2 +- trunk/include/linux/sched.h | 6 - trunk/include/linux/sysdev.h | 164 ++ trunk/include/linux/usb/langwell_otg.h | 139 + trunk/include/net/netns/generic.h | 1 - trunk/include/net/sock.h | 1 - trunk/include/net/tcp.h | 2 - trunk/kernel/exit.c | 16 - trunk/kernel/fork.c | 20 - trunk/kernel/power/process.c | 19 - trunk/kernel/power/user.c | 9 - trunk/kernel/sched/core.c | 19 +- trunk/kernel/sched/fair.c | 34 +- trunk/kernel/sched/rt.c | 5 - trunk/kernel/trace/ftrace.c | 15 +- trunk/kernel/watchdog.c | 26 +- trunk/lib/Kconfig | 4 - trunk/lib/Kconfig.debug | 18 +- trunk/lib/Makefile | 2 - trunk/lib/bug.c | 2 +- trunk/lib/clz_tab.c | 18 - trunk/lib/digsig.c | 52 +- trunk/lib/mpi/longlong.h | 44 +- trunk/lib/mpi/mpi-bit.c | 19 + trunk/lib/mpi/mpi-div.c | 5 - trunk/lib/mpi/mpi-pow.c | 2 +- trunk/lib/mpi/mpicoder.c | 91 +- trunk/lib/mpi/mpih-div.c | 4 - trunk/lib/mpi/mpiutil.c | 5 +- trunk/mm/process_vm_access.c | 23 +- trunk/net/caif/caif_dev.c | 22 +- trunk/net/caif/cfcnfg.c | 1 + trunk/net/ceph/ceph_common.c | 2 + trunk/net/ceph/mon_client.c | 13 +- trunk/net/core/net_namespace.c | 31 +- trunk/net/core/rtnetlink.c | 3 - trunk/net/ipv4/inet_connection_sock.c | 7 +- trunk/net/ipv4/ip_gre.c | 4 - trunk/net/ipv4/sysctl_net_ipv4.c | 1 - trunk/net/ipv4/tcp.c | 16 +- trunk/net/ipv4/tcp_output.c | 6 +- trunk/net/l2tp/l2tp_ip.c | 5 + trunk/net/mac80211/ibss.c | 1 - trunk/net/mac80211/iface.c | 1 - trunk/net/sunrpc/auth_generic.c | 17 +- trunk/net/unix/af_unix.c | 19 +- trunk/scripts/mod/file2alias.c | 10 + trunk/sound/core/compress_offload.c | 13 +- trunk/sound/pci/hda/patch_realtek.c | 11 - trunk/sound/pci/hda/patch_sigmatel.c | 9 +- trunk/sound/pci/ymfpci/ymfpci.c | 21 +- trunk/sound/pci/ymfpci/ymfpci_main.c | 21 +- trunk/tools/perf/Documentation/Makefile | 86 +- .../tools/perf/Documentation/perf-record.txt | 4 +- trunk/tools/perf/Documentation/perf-stat.txt | 4 +- trunk/tools/perf/Documentation/perf-top.txt | 4 +- trunk/tools/perf/MANIFEST | 1 - trunk/tools/perf/Makefile | 8 +- .../tools/perf/bench/mem-memcpy-x86-64-asm.S | 6 - .../tools/perf/bench/mem-memset-x86-64-asm.S | 7 - trunk/tools/perf/builtin-probe.c | 12 +- trunk/tools/perf/builtin-record.c | 74 +- trunk/tools/perf/builtin-stat.c | 41 +- trunk/tools/perf/builtin-test.c | 3 + trunk/tools/perf/builtin-top.c | 44 +- trunk/tools/perf/perf.h | 8 +- trunk/tools/perf/util/bitmap.c | 10 - trunk/tools/perf/util/ctype.c | 2 +- trunk/tools/perf/util/debugfs.c | 141 + trunk/tools/perf/util/debugfs.h | 6 + trunk/tools/perf/util/event.c | 2 +- trunk/tools/perf/util/evlist.c | 16 +- trunk/tools/perf/util/evlist.h | 9 +- trunk/tools/perf/util/evsel.c | 7 +- trunk/tools/perf/util/header.c | 421 ++- trunk/tools/perf/util/header.h | 1 - trunk/tools/perf/util/hist.h | 1 - trunk/tools/perf/util/include/linux/bitmap.h | 11 - trunk/tools/perf/util/probe-event.c | 26 +- trunk/tools/perf/util/python-ext-sources | 19 - trunk/tools/perf/util/session.c | 10 - trunk/tools/perf/util/setup.py | 8 +- trunk/tools/perf/util/symbol.c | 2 +- trunk/tools/perf/util/sysfs.c | 60 - trunk/tools/perf/util/sysfs.h | 6 - trunk/tools/perf/util/thread_map.c | 128 - trunk/tools/perf/util/thread_map.h | 4 - trunk/tools/perf/util/top.c | 10 +- trunk/tools/perf/util/top.h | 5 +- trunk/tools/perf/util/usage.c | 6 +- trunk/tools/perf/util/util.c | 4 +- trunk/tools/perf/util/util.h | 6 +- 413 files changed, 6698 insertions(+), 3374 deletions(-) delete mode 100644 trunk/Documentation/lockup-watchdogs.txt create mode 100644 trunk/Documentation/nmi_watchdog.txt delete mode 100644 trunk/arch/arm/mach-at91/at91sam9g45_reset.S create mode 100644 trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h create mode 100644 trunk/drivers/base/sys.c rename trunk/drivers/tty/serial/{8250 => }/8250.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250.h (100%) delete mode 100644 trunk/drivers/tty/serial/8250/Kconfig delete mode 100644 trunk/drivers/tty/serial/8250/Makefile rename trunk/drivers/tty/serial/{8250 => }/8250_accent.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_acorn.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_boca.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_dw.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_early.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_exar_st16c554.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_fourport.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_fsl.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_gsc.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_hp300.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_hub6.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_mca.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_pci.c (100%) rename trunk/drivers/tty/serial/{8250 => }/8250_pnp.c (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio.c (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio.h (100%) rename trunk/drivers/tty/serial/{8250 => }/m32r_sio_reg.h (100%) create mode 100644 trunk/drivers/tty/serial/max3107-aava.c rename trunk/drivers/tty/serial/{8250 => }/serial_cs.c (100%) create mode 100644 trunk/drivers/usb/otg/langwell_otg.c mode change 100644 => 100755 trunk/include/linux/lp8727.h create mode 100644 trunk/include/linux/sysdev.h create mode 100644 trunk/include/linux/usb/langwell_otg.h delete mode 100644 trunk/lib/clz_tab.c delete mode 100644 trunk/tools/perf/util/python-ext-sources delete mode 100644 trunk/tools/perf/util/sysfs.c delete mode 100644 trunk/tools/perf/util/sysfs.h diff --git a/[refs] b/[refs] index c68d72db3866..ae61c7001bbe 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d1e169da9e20efc0762da6ec160dd7740d0103f5 +refs/heads/master: ac483c446b67870444c9eeaf8325d3d2af9b91bc diff --git a/trunk/Documentation/DocBook/device-drivers.tmpl b/trunk/Documentation/DocBook/device-drivers.tmpl index 9c27e5125dd2..2f7fd4360848 100644 --- a/trunk/Documentation/DocBook/device-drivers.tmpl +++ b/trunk/Documentation/DocBook/device-drivers.tmpl @@ -102,12 +102,9 @@ X!Iinclude/linux/kobject.h !Iinclude/linux/device.h Device Drivers Base -!Idrivers/base/init.c !Edrivers/base/driver.c !Edrivers/base/core.c -!Edrivers/base/syscore.c !Edrivers/base/class.c -!Idrivers/base/node.c !Edrivers/base/firmware_class.c !Edrivers/base/transport_class.c -!Edrivers/base/dd.c +!Edrivers/base/sys.c !Iinclude/linux/platform_device.h !Edrivers/base/platform.c !Edrivers/base/bus.c - - Device Drivers DMA Management -!Edrivers/base/dma-buf.c -!Edrivers/base/dma-coherent.c -!Edrivers/base/dma-mapping.c Device Drivers Power Management !Edrivers/base/power/main.c @@ -227,7 +219,7 @@ X!Isound/sound_firmware.c 16x50 UART Driver !Edrivers/tty/serial/serial_core.c -!Edrivers/tty/serial/8250/8250.c +!Edrivers/tty/serial/8250.c diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt index 41c0c5d1ba14..10c64c8a13d4 100644 --- a/trunk/Documentation/driver-model/devres.txt +++ b/trunk/Documentation/driver-model/devres.txt @@ -233,10 +233,6 @@ certainly invest a bit more effort into libata core layer). 6. List of managed interfaces ----------------------------- -MEM - devm_kzalloc() - devm_kfree() - IO region devm_request_region() devm_request_mem_region() diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index a0ffac029a0d..1bea46a54b1c 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -510,17 +510,3 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The convert to using pci_scan_root_bus() so they can supply a list of bus resources when the bus is created. Who: Bjorn Helgaas - ----------------------------- - -What: The CAP9 SoC family will be removed -When: 3.4 -Files: arch/arm/mach-at91/at91cap9.c - arch/arm/mach-at91/at91cap9_devices.c - arch/arm/mach-at91/include/mach/at91cap9.h - arch/arm/mach-at91/include/mach/at91cap9_matrix.h - arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h - arch/arm/mach-at91/board-cap9adk.c -Why: The code is not actively maintained and platforms are now hard to find. -Who: Nicolas Ferre - Jean-Christophe PLAGNIOL-VILLARD diff --git a/trunk/Documentation/lockup-watchdogs.txt b/trunk/Documentation/lockup-watchdogs.txt deleted file mode 100644 index d2a36602ca8d..000000000000 --- a/trunk/Documentation/lockup-watchdogs.txt +++ /dev/null @@ -1,63 +0,0 @@ -=============================================================== -Softlockup detector and hardlockup detector (aka nmi_watchdog) -=============================================================== - -The Linux kernel can act as a watchdog to detect both soft and hard -lockups. - -A 'softlockup' is defined as a bug that causes the kernel to loop in -kernel mode for more than 20 seconds (see "Implementation" below for -details), without giving other tasks a chance to run. The current -stack trace is displayed upon detection and, by default, the system -will stay locked up. Alternatively, the kernel can be configured to -panic; a sysctl, "kernel.softlockup_panic", a kernel parameter, -"softlockup_panic" (see "Documentation/kernel-parameters.txt" for -details), and a compile option, "BOOTPARAM_HARDLOCKUP_PANIC", are -provided for this. - -A 'hardlockup' is defined as a bug that causes the CPU to loop in -kernel mode for more than 10 seconds (see "Implementation" below for -details), without letting other interrupts have a chance to run. -Similarly to the softlockup case, the current stack trace is displayed -upon detection and the system will stay locked up unless the default -behavior is changed, which can be done through a compile time knob, -"BOOTPARAM_HARDLOCKUP_PANIC", and a kernel parameter, "nmi_watchdog" -(see "Documentation/kernel-parameters.txt" for details). - -The panic option can be used in combination with panic_timeout (this -timeout is set through the confusingly named "kernel.panic" sysctl), -to cause the system to reboot automatically after a specified amount -of time. - -=== Implementation === - -The soft and hard lockup detectors are built on top of the hrtimer and -perf subsystems, respectively. A direct consequence of this is that, -in principle, they should work in any architecture where these -subsystems are present. - -A periodic hrtimer runs to generate interrupts and kick the watchdog -task. An NMI perf event is generated every "watchdog_thresh" -(compile-time initialized to 10 and configurable through sysctl of the -same name) seconds to check for hardlockups. If any CPU in the system -does not receive any hrtimer interrupt during that time the -'hardlockup detector' (the handler for the NMI perf event) will -generate a kernel warning or call panic, depending on the -configuration. - -The watchdog task is a high priority kernel thread that updates a -timestamp every time it is scheduled. If that timestamp is not updated -for 2*watchdog_thresh seconds (the softlockup threshold) the -'softlockup detector' (coded inside the hrtimer callback function) -will dump useful debug information to the system log, after which it -will call panic if it was instructed to do so or resume execution of -other kernel code. - -The period of the hrtimer is 2*watchdog_thresh/5, which means it has -two or three chances to generate an interrupt before the hardlockup -detector kicks in. - -As explained above, a kernel knob is provided that allows -administrators to configure the period of the hrtimer and the perf -event. The right value for a particular environment is a trade-off -between fast response to lockups and detection overhead. diff --git a/trunk/Documentation/nmi_watchdog.txt b/trunk/Documentation/nmi_watchdog.txt new file mode 100644 index 000000000000..bf9f80a98282 --- /dev/null +++ b/trunk/Documentation/nmi_watchdog.txt @@ -0,0 +1,83 @@ + +[NMI watchdog is available for x86 and x86-64 architectures] + +Is your system locking up unpredictably? No keyboard activity, just +a frustrating complete hard lockup? Do you want to help us debugging +such lockups? If all yes then this document is definitely for you. + +On many x86/x86-64 type hardware there is a feature that enables +us to generate 'watchdog NMI interrupts'. (NMI: Non Maskable Interrupt +which get executed even if the system is otherwise locked up hard). +This can be used to debug hard kernel lockups. By executing periodic +NMI interrupts, the kernel can monitor whether any CPU has locked up, +and print out debugging messages if so. + +In order to use the NMI watchdog, you need to have APIC support in your +kernel. For SMP kernels, APIC support gets compiled in automatically. For +UP, enable either CONFIG_X86_UP_APIC (Processor type and features -> Local +APIC support on uniprocessors) or CONFIG_X86_UP_IOAPIC (Processor type and +features -> IO-APIC support on uniprocessors) in your kernel config. +CONFIG_X86_UP_APIC is for uniprocessor machines without an IO-APIC. +CONFIG_X86_UP_IOAPIC is for uniprocessor with an IO-APIC. [Note: certain +kernel debugging options, such as Kernel Stack Meter or Kernel Tracer, +may implicitly disable the NMI watchdog.] + +For x86-64, the needed APIC is always compiled in. + +Using local APIC (nmi_watchdog=2) needs the first performance register, so +you can't use it for other purposes (such as high precision performance +profiling.) However, at least oprofile and the perfctr driver disable the +local APIC NMI watchdog automatically. + +To actually enable the NMI watchdog, use the 'nmi_watchdog=N' boot +parameter. Eg. the relevant lilo.conf entry: + + append="nmi_watchdog=1" + +For SMP machines and UP machines with an IO-APIC use nmi_watchdog=1. +For UP machines without an IO-APIC use nmi_watchdog=2, this only works +for some processor types. If in doubt, boot with nmi_watchdog=1 and +check the NMI count in /proc/interrupts; if the count is zero then +reboot with nmi_watchdog=2 and check the NMI count. If it is still +zero then log a problem, you probably have a processor that needs to be +added to the nmi code. + +A 'lockup' is the following scenario: if any CPU in the system does not +execute the period local timer interrupt for more than 5 seconds, then +the NMI handler generates an oops and kills the process. This +'controlled crash' (and the resulting kernel messages) can be used to +debug the lockup. Thus whenever the lockup happens, wait 5 seconds and +the oops will show up automatically. If the kernel produces no messages +then the system has crashed so hard (eg. hardware-wise) that either it +cannot even accept NMI interrupts, or the crash has made the kernel +unable to print messages. + +Be aware that when using local APIC, the frequency of NMI interrupts +it generates, depends on the system load. The local APIC NMI watchdog, +lacking a better source, uses the "cycles unhalted" event. As you may +guess it doesn't tick when the CPU is in the halted state (which happens +when the system is idle), but if your system locks up on anything but the +"hlt" processor instruction, the watchdog will trigger very soon as the +"cycles unhalted" event will happen every clock tick. If it locks up on +"hlt", then you are out of luck -- the event will not happen at all and the +watchdog won't trigger. This is a shortcoming of the local APIC watchdog +-- unfortunately there is no "clock ticks" event that would work all the +time. The I/O APIC watchdog is driven externally and has no such shortcoming. +But its NMI frequency is much higher, resulting in a more significant hit +to the overall system performance. + +On x86 nmi_watchdog is disabled by default so you have to enable it with +a boot time parameter. + +It's possible to disable the NMI watchdog in run-time by writing "0" to +/proc/sys/kernel/nmi_watchdog. Writing "1" to the same file will re-enable +the NMI watchdog. Notice that you still need to use "nmi_watchdog=" parameter +at boot time. + +NOTE: In kernels prior to 2.4.2-ac18 the NMI-oopser is enabled unconditionally +on x86 SMP boxes. + +[ feel free to send bug reports, suggestions and patches to + Ingo Molnar or the Linux SMP mailing + list at ] + diff --git a/trunk/Documentation/pinctrl.txt b/trunk/Documentation/pinctrl.txt index 150fd3833d0b..6727b92bc2fb 100644 --- a/trunk/Documentation/pinctrl.txt +++ b/trunk/Documentation/pinctrl.txt @@ -857,41 +857,42 @@ case), we define a mapping like this: ... { - .name = "2bit" + .name "2bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "4bit" + .name "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "4bit" + .name "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", .group = "mmc0_1_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", .dev_name = "foo-mmc.0", }, { - .name = "8bit" + .name "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_3_grp", @@ -994,7 +995,7 @@ This is enabled by simply setting the .hog_on_boot field in the map to true, like this: { - .name = "POWERMAP" + .name "POWERMAP" .ctrl_dev_name = "pinctrl-foo", .function = "power_func", .hog_on_boot = true, @@ -1024,7 +1025,7 @@ it, disables and releases it, and muxes it in on the pins defined by group B: foo_switch() { - struct pinmux *pmx; + struct pinmux pmx; /* Enable on position A */ pmx = pinmux_get(&device, "spi0-pos-A"); diff --git a/trunk/Documentation/stable_kernel_rules.txt b/trunk/Documentation/stable_kernel_rules.txt index f0ab5cf28fca..21fd05c28e73 100644 --- a/trunk/Documentation/stable_kernel_rules.txt +++ b/trunk/Documentation/stable_kernel_rules.txt @@ -25,8 +25,7 @@ Procedure for submitting patches to the -stable tree: - Send the patch, after verifying that it follows the above rules, to stable@vger.kernel.org. You must note the upstream commit ID in the - changelog of your submission, as well as the kernel version you wish - it to be applied to. + changelog of your submission. - To have the patch automatically included in the stable tree, add the tag Cc: stable@vger.kernel.org in the sign-off area. Once the patch is merged it will be applied to diff --git a/trunk/Documentation/virtual/00-INDEX b/trunk/Documentation/virtual/00-INDEX index 924bd462675e..8e601991d91c 100644 --- a/trunk/Documentation/virtual/00-INDEX +++ b/trunk/Documentation/virtual/00-INDEX @@ -4,6 +4,8 @@ Virtualization support in the Linux kernel. - this file. kvm/ - Kernel Virtual Machine. See also http://linux-kvm.org +lguest/ + - Extremely simple hypervisor for experimental/educational use. uml/ - User Mode Linux, builds/runs Linux kernel as a userspace program. virtio.txt diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 252972b6c4a0..260d9c1785d0 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -159,7 +159,7 @@ S: Maintained F: drivers/net/ethernet/realtek/r8169.c 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-serial@vger.kernel.org W: http://serial.sourceforge.net S: Maintained @@ -1783,9 +1783,9 @@ X: net/wireless/wext* CHAR and MISC DRIVERS M: Arnd Bergmann -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git -S: Supported +S: Maintained F: drivers/char/* F: drivers/misc/* @@ -2320,7 +2320,7 @@ F: lib/lru_cache.c F: Documentation/blockdev/drbd/ DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git S: Supported F: Documentation/kobject.txt @@ -2350,9 +2350,6 @@ F: include/drm/i915* DRM DRIVERS FOR EXYNOS M: Inki Dae -M: Joonyoung Shim -M: Seung-Woo Kim -M: Kyungmin Park L: dri-devel@lists.freedesktop.org S: Supported F: drivers/gpu/drm/exynos @@ -4140,7 +4137,6 @@ F: fs/partitions/ldm.* LogFS M: Joern Engel -M: Prasad Joshi L: logfs@logfs.org W: logfs.org S: Maintained @@ -4282,6 +4278,13 @@ S: Orphan F: drivers/video/matrox/matroxfb_* F: include/linux/matroxfb.h +MAX1668 TEMPERATURE SENSOR DRIVER +M: "David George" +L: lm-sensors@lm-sensors.org +S: Maintained +F: Documentation/hwmon/max1668 +F: drivers/hwmon/max1668.c + MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" L: lm-sensors@lm-sensors.org @@ -6276,15 +6279,15 @@ S: Maintained F: arch/alpha/kernel/srm_env.c STABLE BRANCH -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: stable@vger.kernel.org -S: Supported +S: Maintained STAGING SUBSYSTEM -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git L: devel@driverdev.osuosl.org -S: Supported +S: Maintained F: drivers/staging/ STAGING - AGERE HERMES II and II.5 WIRELESS DRIVERS @@ -6669,10 +6672,10 @@ S: Maintained K: ^Subject:.*(?i)trivial TTY LAYER -M: Greg Kroah-Hartman -S: Supported +M: Greg Kroah-Hartman +S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6.git -F: drivers/tty/ +F: drivers/tty/* F: drivers/tty/serial/serial_core.c F: include/linux/serial_core.h F: include/linux/serial.h @@ -6958,7 +6961,7 @@ S: Maintained F: drivers/usb/serial/digi_acceleport.c USB SERIAL DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org S: Supported F: Documentation/usb/usb-serial.txt @@ -6973,8 +6976,9 @@ S: Maintained F: drivers/usb/serial/empeg.c USB SERIAL KEYSPAN DRIVER -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org +W: http://www.kroah.com/linux/ S: Maintained F: drivers/usb/serial/*keyspan* @@ -7002,7 +7006,7 @@ F: Documentation/video4linux/sn9c102.txt F: drivers/media/video/sn9c102/ USB SUBSYSTEM -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman L: linux-usb@vger.kernel.org W: http://www.linux-usb.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6.git @@ -7089,7 +7093,7 @@ F: fs/hppfs/ USERSPACE I/O (UIO) M: "Hans J. Koch" -M: Greg Kroah-Hartman +M: Greg Kroah-Hartman S: Maintained F: Documentation/DocBook/uio-howto.tmpl F: drivers/uio/ @@ -7364,7 +7368,6 @@ S: Supported F: Documentation/hwmon/wm83?? F: arch/arm/mach-s3c64xx/mach-crag6410* F: drivers/leds/leds-wm83*.c -F: drivers/hwmon/wm83??-hwmon.c F: drivers/input/misc/wm831x-on.c F: drivers/input/touchscreen/wm831x-ts.c F: drivers/input/touchscreen/wm97*.c diff --git a/trunk/Makefile b/trunk/Makefile index e3b23e864a53..71e6ed21dd15 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 3 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc1 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index a48aecc17eac..24626b0419ee 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -754,7 +754,7 @@ config ARCH_SA1100 select ARCH_HAS_CPUFREQ select CPU_FREQ select GENERIC_CLOCKEVENTS - select HAVE_CLK + select CLKDEV_LOOKUP select HAVE_SCHED_CLOCK select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB @@ -825,6 +825,7 @@ config ARCH_S5PC100 select HAVE_CLK select CLKDEV_LOOKUP select CPU_V7 + select ARM_L1_CACHE_SHIFT_6 select ARCH_USES_GETTIMEOFFSET select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS @@ -841,6 +842,7 @@ config ARCH_S5PV210 select HAVE_CLK select CLKDEV_LOOKUP select CLKSRC_MMIO + select ARM_L1_CACHE_SHIFT_6 select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS select HAVE_SCHED_CLOCK diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index c47d6199b784..b2dc2dd7f1df 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -41,7 +41,6 @@ #include #include -#include #include #include @@ -353,7 +352,11 @@ static void __init gic_dist_init(struct gic_chip_data *gic) unsigned int gic_irqs = gic->gic_irqs; struct irq_domain *domain = &gic->domain; void __iomem *base = gic_data_dist_base(gic); - u32 cpu = cpu_logical_map(smp_processor_id()); + u32 cpu = 0; + +#ifdef CONFIG_SMP + cpu = cpu_logical_map(smp_processor_id()); +#endif cpumask = 1 << cpu; cpumask |= cpumask << 8; diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h index 62f8095d46de..b6e65dedfd71 100644 --- a/trunk/arch/arm/include/asm/assembler.h +++ b/trunk/arch/arm/include/asm/assembler.h @@ -237,7 +237,7 @@ */ #ifdef CONFIG_THUMB2_KERNEL - .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER() + .macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=T() 9999: .if \inc == 1 \instr\cond\()b\()\t\().w \reg, [\ptr, #\off] @@ -277,7 +277,7 @@ #else /* !CONFIG_THUMB2_KERNEL */ - .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER() + .macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=T() .rept \rept 9999: .if \inc == 1 diff --git a/trunk/arch/arm/include/asm/domain.h b/trunk/arch/arm/include/asm/domain.h index b5dc173d336f..af18ceaacf5d 100644 --- a/trunk/arch/arm/include/asm/domain.h +++ b/trunk/arch/arm/include/asm/domain.h @@ -83,9 +83,9 @@ * instructions (inline assembly) */ #ifdef CONFIG_CPU_USE_DOMAINS -#define TUSER(instr) #instr "t" +#define T(instr) #instr "t" #else -#define TUSER(instr) #instr +#define T(instr) #instr #endif #else /* __ASSEMBLY__ */ @@ -95,9 +95,9 @@ * instructions */ #ifdef CONFIG_CPU_USE_DOMAINS -#define TUSER(instr) instr ## t +#define T(instr) instr ## t #else -#define TUSER(instr) instr +#define T(instr) instr #endif #endif /* __ASSEMBLY__ */ diff --git a/trunk/arch/arm/include/asm/futex.h b/trunk/arch/arm/include/asm/futex.h index 7be54690aeec..253cc86318bf 100644 --- a/trunk/arch/arm/include/asm/futex.h +++ b/trunk/arch/arm/include/asm/futex.h @@ -75,9 +75,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \ __asm__ __volatile__( \ - "1: " TUSER(ldr) " %1, [%3]\n" \ + "1: " T(ldr) " %1, [%3]\n" \ " " insn "\n" \ - "2: " TUSER(str) " %0, [%3]\n" \ + "2: " T(str) " %0, [%3]\n" \ " mov %0, #0\n" \ __futex_atomic_ex_table("%5") \ : "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \ @@ -95,10 +95,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" - "1: " TUSER(ldr) " %1, [%4]\n" + "1: " T(ldr) " %1, [%4]\n" " teq %1, %2\n" " it eq @ explicit IT needed for the 2b label\n" - "2: " TUSER(streq) " %3, [%4]\n" + "2: " T(streq) " %3, [%4]\n" __futex_atomic_ex_table("%5") : "+r" (ret), "=&r" (val) : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) diff --git a/trunk/arch/arm/include/asm/smp.h b/trunk/arch/arm/include/asm/smp.h index ae29293270a3..1e5717afc4ac 100644 --- a/trunk/arch/arm/include/asm/smp.h +++ b/trunk/arch/arm/include/asm/smp.h @@ -70,6 +70,12 @@ extern void platform_secondary_init(unsigned int cpu); */ extern void platform_smp_prepare_cpus(unsigned int); +/* + * Logical CPU mapping. + */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] + /* * Initial data for bringing up a secondary CPU. */ diff --git a/trunk/arch/arm/include/asm/smp_plat.h b/trunk/arch/arm/include/asm/smp_plat.h index 558d6c80aca9..f24c1b9e211d 100644 --- a/trunk/arch/arm/include/asm/smp_plat.h +++ b/trunk/arch/arm/include/asm/smp_plat.h @@ -43,10 +43,4 @@ static inline int cache_ops_need_broadcast(void) } #endif -/* - * Logical CPU mapping. - */ -extern int __cpu_logical_map[]; -#define cpu_logical_map(cpu) __cpu_logical_map[cpu] - #endif diff --git a/trunk/arch/arm/include/asm/uaccess.h b/trunk/arch/arm/include/asm/uaccess.h index 2958976d867b..b293616a1a1a 100644 --- a/trunk/arch/arm/include/asm/uaccess.h +++ b/trunk/arch/arm/include/asm/uaccess.h @@ -227,7 +227,7 @@ do { \ #define __get_user_asm_byte(x,addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(ldrb) " %1,[%2],#0\n" \ + "1: " T(ldrb) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -263,7 +263,7 @@ do { \ #define __get_user_asm_word(x,addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(ldr) " %1,[%2],#0\n" \ + "1: " T(ldr) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -308,7 +308,7 @@ do { \ #define __put_user_asm_byte(x,__pu_addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(strb) " %1,[%2],#0\n" \ + "1: " T(strb) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -341,7 +341,7 @@ do { \ #define __put_user_asm_word(x,__pu_addr,err) \ __asm__ __volatile__( \ - "1: " TUSER(str) " %1,[%2],#0\n" \ + "1: " T(str) " %1,[%2],#0\n" \ "2:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ @@ -366,10 +366,10 @@ do { \ #define __put_user_asm_dword(x,__pu_addr,err) \ __asm__ __volatile__( \ - ARM( "1: " TUSER(str) " " __reg_oper1 ", [%1], #4\n" ) \ - ARM( "2: " TUSER(str) " " __reg_oper0 ", [%1]\n" ) \ - THUMB( "1: " TUSER(str) " " __reg_oper1 ", [%1]\n" ) \ - THUMB( "2: " TUSER(str) " " __reg_oper0 ", [%1, #4]\n" ) \ + ARM( "1: " T(str) " " __reg_oper1 ", [%1], #4\n" ) \ + ARM( "2: " T(str) " " __reg_oper0 ", [%1]\n" ) \ + THUMB( "1: " T(str) " " __reg_oper1 ", [%1]\n" ) \ + THUMB( "2: " T(str) " " __reg_oper0 ", [%1, #4]\n" ) \ "3:\n" \ " .pushsection .fixup,\"ax\"\n" \ " .align 2\n" \ diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 9fd0ba90c1d2..520889cf1b5b 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -149,11 +149,6 @@ ENDPROC(ret_from_fork) #endif #endif -.macro mcount_adjust_addr rd, rn - bic \rd, \rn, #1 @ clear the Thumb bit if present - sub \rd, \rd, #MCOUNT_INSN_SIZE -.endm - .macro __mcount suffix mcount_enter ldr r0, =ftrace_trace_function @@ -178,7 +173,8 @@ ENDPROC(ret_from_fork) mcount_exit 1: mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function + mov r0, lr @ instrumented function + sub r0, r0, #MCOUNT_INSN_SIZE adr lr, BSYM(2f) mov pc, r2 2: mcount_exit @@ -188,7 +184,8 @@ ENDPROC(ret_from_fork) mcount_enter mcount_get_lr r1 @ lr of instrumented func - mcount_adjust_addr r0, lr @ instrumented function + mov r0, lr @ instrumented function + sub r0, r0, #MCOUNT_INSN_SIZE .globl ftrace_call\suffix ftrace_call\suffix: @@ -208,11 +205,11 @@ ftrace_graph_call\suffix: #ifdef CONFIG_DYNAMIC_FTRACE @ called from __ftrace_caller, saved in mcount_enter ldr r1, [sp, #16] @ instrumented routine (func) - mcount_adjust_addr r1, r1 #else @ called from __mcount, untouched in lr - mcount_adjust_addr r1, lr @ instrumented routine (func) + mov r1, lr @ instrumented routine (func) #endif + sub r1, r1, #MCOUNT_INSN_SIZE mov r2, fp @ frame pointer bl prepare_ftrace_return mcount_exit diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index a255c39612ca..129fbd55bde8 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -159,7 +160,7 @@ static struct resource mem_res[] = { .flags = IORESOURCE_MEM }, { - .name = "Kernel code", + .name = "Kernel text", .start = 0, .end = 0, .flags = IORESOURCE_MEM @@ -426,20 +427,6 @@ void cpu_init(void) : "r14"); } -int __cpu_logical_map[NR_CPUS]; - -void __init smp_setup_processor_id(void) -{ - int i; - u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; - - cpu_logical_map(0) = cpu; - for (i = 1; i < NR_CPUS; ++i) - cpu_logical_map(i) = i == cpu ? 0 : i; - - printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); -} - static void __init setup_processor(void) { struct proc_info_list *list; diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index cdeb727527d3..57db122a4f62 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -233,6 +233,20 @@ void __ref cpu_die(void) } #endif /* CONFIG_HOTPLUG_CPU */ +int __cpu_logical_map[NR_CPUS]; + +void __init smp_setup_processor_id(void) +{ + int i; + u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; + + cpu_logical_map(0) = cpu; + for (i = 1; i < NR_CPUS; ++i) + cpu_logical_map(i) = i == cpu ? 0 : i; + + printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); +} + /* * Called by both boot and secondaries to move global data into * per-processor storage. @@ -429,7 +443,9 @@ static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent); static void ipi_timer(void) { struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent); + irq_enter(); evt->event_handler(evt); + irq_exit(); } #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST @@ -532,9 +548,7 @@ void handle_IPI(int ipinr, struct pt_regs *regs) switch (ipinr) { case IPI_TIMER: - irq_enter(); ipi_timer(); - irq_exit(); break; case IPI_RESCHEDULE: @@ -542,21 +556,15 @@ void handle_IPI(int ipinr, struct pt_regs *regs) break; case IPI_CALL_FUNC: - irq_enter(); generic_smp_call_function_interrupt(); - irq_exit(); break; case IPI_CALL_FUNC_SINGLE: - irq_enter(); generic_smp_call_function_single_interrupt(); - irq_exit(); break; case IPI_CPU_STOP: - irq_enter(); ipi_cpu_stop(cpu); - irq_exit(); break; default: diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index 4285daa077b0..c8e938553d47 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -252,8 +252,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk) else twd_calibrate_rate(); - __raw_writel(0, twd_base + TWD_TIMER_CONTROL); - clk->name = "local_timer"; clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 1e19691e0406..f76e75548670 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -182,7 +181,7 @@ SECTIONS } #endif - PERCPU_SECTION(L1_CACHE_BYTES) + PERCPU_SECTION(32) #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ @@ -213,13 +212,13 @@ SECTIONS #endif NOSAVE_DATA - CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) - READ_MOSTLY_DATA(L1_CACHE_BYTES) + CACHELINE_ALIGNED_DATA(32) + READ_MOSTLY_DATA(32) /* * The exception fixup table (might need resorting at runtime) */ - . = ALIGN(4); + . = ALIGN(32); __start___ex_table = .; #ifdef CONFIG_MMU *(__ex_table) diff --git a/trunk/arch/arm/lib/getuser.S b/trunk/arch/arm/lib/getuser.S index 11093a7c3e32..1b049cd7a49a 100644 --- a/trunk/arch/arm/lib/getuser.S +++ b/trunk/arch/arm/lib/getuser.S @@ -31,18 +31,18 @@ #include ENTRY(__get_user_1) -1: TUSER(ldrb) r2, [r0] +1: T(ldrb) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__get_user_1) ENTRY(__get_user_2) #ifdef CONFIG_THUMB2_KERNEL -2: TUSER(ldrb) r2, [r0] -3: TUSER(ldrb) r3, [r0, #1] +2: T(ldrb) r2, [r0] +3: T(ldrb) r3, [r0, #1] #else -2: TUSER(ldrb) r2, [r0], #1 -3: TUSER(ldrb) r3, [r0] +2: T(ldrb) r2, [r0], #1 +3: T(ldrb) r3, [r0] #endif #ifndef __ARMEB__ orr r2, r2, r3, lsl #8 @@ -54,7 +54,7 @@ ENTRY(__get_user_2) ENDPROC(__get_user_2) ENTRY(__get_user_4) -4: TUSER(ldr) r2, [r0] +4: T(ldr) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__get_user_4) diff --git a/trunk/arch/arm/lib/putuser.S b/trunk/arch/arm/lib/putuser.S index 7db25990c589..c023fc11e86c 100644 --- a/trunk/arch/arm/lib/putuser.S +++ b/trunk/arch/arm/lib/putuser.S @@ -31,7 +31,7 @@ #include ENTRY(__put_user_1) -1: TUSER(strb) r2, [r0] +1: T(strb) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__put_user_1) @@ -40,19 +40,19 @@ ENTRY(__put_user_2) mov ip, r2, lsr #8 #ifdef CONFIG_THUMB2_KERNEL #ifndef __ARMEB__ -2: TUSER(strb) r2, [r0] -3: TUSER(strb) ip, [r0, #1] +2: T(strb) r2, [r0] +3: T(strb) ip, [r0, #1] #else -2: TUSER(strb) ip, [r0] -3: TUSER(strb) r2, [r0, #1] +2: T(strb) ip, [r0] +3: T(strb) r2, [r0, #1] #endif #else /* !CONFIG_THUMB2_KERNEL */ #ifndef __ARMEB__ -2: TUSER(strb) r2, [r0], #1 -3: TUSER(strb) ip, [r0] +2: T(strb) r2, [r0], #1 +3: T(strb) ip, [r0] #else -2: TUSER(strb) ip, [r0], #1 -3: TUSER(strb) r2, [r0] +2: T(strb) ip, [r0], #1 +3: T(strb) r2, [r0] #endif #endif /* CONFIG_THUMB2_KERNEL */ mov r0, #0 @@ -60,18 +60,18 @@ ENTRY(__put_user_2) ENDPROC(__put_user_2) ENTRY(__put_user_4) -4: TUSER(str) r2, [r0] +4: T(str) r2, [r0] mov r0, #0 mov pc, lr ENDPROC(__put_user_4) ENTRY(__put_user_8) #ifdef CONFIG_THUMB2_KERNEL -5: TUSER(str) r2, [r0] -6: TUSER(str) r3, [r0, #4] +5: T(str) r2, [r0] +6: T(str) r3, [r0, #4] #else -5: TUSER(str) r2, [r0], #4 -6: TUSER(str) r3, [r0] +5: T(str) r2, [r0], #4 +6: T(str) r3, [r0] #endif mov r0, #0 mov pc, lr diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S index 5c908b1cb8ed..d0ece2aeb70d 100644 --- a/trunk/arch/arm/lib/uaccess.S +++ b/trunk/arch/arm/lib/uaccess.S @@ -32,11 +32,11 @@ rsb ip, ip, #4 cmp ip, #2 ldrb r3, [r1], #1 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #1 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault sub r2, r2, ip b .Lc2u_dest_aligned @@ -59,7 +59,7 @@ ENTRY(__copy_to_user) addmi ip, r2, #4 bmi .Lc2u_0nowords ldr r3, [r1], #4 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -88,18 +88,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault stmneia r0!, {r3 - r4} @ Shouldnt fault tst ip, #4 ldrne r3, [r1], #4 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_0fupi .Lc2u_0nowords: teq ip, #0 beq .Lc2u_finished .Lc2u_nowords: cmp ip, #2 ldrb r3, [r1], #1 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #1 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_not_enough: @@ -120,7 +120,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #8 ldr r7, [r1], #4 orr r3, r3, r7, push #24 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -155,18 +155,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #8 ldrne r7, [r1], #4 orrne r3, r3, r7, push #24 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_1fupi .Lc2u_1nowords: mov r3, r7, get_byte_1 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault movge r3, r7, get_byte_2 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault movgt r3, r7, get_byte_3 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_2fupi: subs r2, r2, #4 @@ -175,7 +175,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #16 ldr r7, [r1], #4 orr r3, r3, r7, push #16 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -210,18 +210,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #16 ldrne r7, [r1], #4 orrne r3, r3, r7, push #16 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_2fupi .Lc2u_2nowords: mov r3, r7, get_byte_2 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault movge r3, r7, get_byte_3 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #0 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished .Lc2u_3fupi: subs r2, r2, #4 @@ -230,7 +230,7 @@ USER( TUSER( strgtb) r3, [r0], #1) @ May fault mov r3, r7, pull #24 ldr r7, [r1], #4 orr r3, r3, r7, push #8 -USER( TUSER( str) r3, [r0], #4) @ May fault +USER( T(str) r3, [r0], #4) @ May fault mov ip, r0, lsl #32 - PAGE_SHIFT rsb ip, ip, #0 movs ip, ip, lsr #32 - PAGE_SHIFT @@ -265,18 +265,18 @@ USER( TUSER( str) r3, [r0], #4) @ May fault movne r3, r7, pull #24 ldrne r7, [r1], #4 orrne r3, r3, r7, push #8 - TUSER( strne) r3, [r0], #4 @ Shouldnt fault + T(strne) r3, [r0], #4 @ Shouldnt fault ands ip, ip, #3 beq .Lc2u_3fupi .Lc2u_3nowords: mov r3, r7, get_byte_3 teq ip, #0 beq .Lc2u_finished cmp ip, #2 -USER( TUSER( strb) r3, [r0], #1) @ May fault +USER( T(strb) r3, [r0], #1) @ May fault ldrgeb r3, [r1], #1 -USER( TUSER( strgeb) r3, [r0], #1) @ May fault +USER( T(strgeb) r3, [r0], #1) @ May fault ldrgtb r3, [r1], #0 -USER( TUSER( strgtb) r3, [r0], #1) @ May fault +USER( T(strgtb) r3, [r0], #1) @ May fault b .Lc2u_finished ENDPROC(__copy_to_user) @@ -295,11 +295,11 @@ ENDPROC(__copy_to_user) .Lcfu_dest_not_aligned: rsb ip, ip, #4 cmp ip, #2 -USER( TUSER( ldrb) r3, [r1], #1) @ May fault +USER( T(ldrb) r3, [r1], #1) @ May fault strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 sub r2, r2, ip b .Lcfu_dest_aligned @@ -322,7 +322,7 @@ ENTRY(__copy_from_user) .Lcfu_0fupi: subs r2, r2, #4 addmi ip, r2, #4 bmi .Lcfu_0nowords -USER( TUSER( ldr) r3, [r1], #4) +USER( T(ldr) r3, [r1], #4) str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction rsb ip, ip, #0 @@ -351,18 +351,18 @@ USER( TUSER( ldr) r3, [r1], #4) ldmneia r1!, {r3 - r4} @ Shouldnt fault stmneia r0!, {r3 - r4} tst ip, #4 - TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault + T(ldrne) r3, [r1], #4 @ Shouldnt fault strne r3, [r0], #4 ands ip, ip, #3 beq .Lcfu_0fupi .Lcfu_0nowords: teq ip, #0 beq .Lcfu_finished .Lcfu_nowords: cmp ip, #2 -USER( TUSER( ldrb) r3, [r1], #1) @ May fault +USER( T(ldrb) r3, [r1], #1) @ May fault strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished @@ -375,7 +375,7 @@ USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault .Lcfu_src_not_aligned: bic r1, r1, #3 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault cmp ip, #2 bgt .Lcfu_3fupi beq .Lcfu_2fupi @@ -383,7 +383,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault addmi ip, r2, #4 bmi .Lcfu_1nowords mov r3, r7, pull #8 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #24 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -418,7 +418,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #8 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #24 strne r3, [r0], #4 ands ip, ip, #3 @@ -438,7 +438,7 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault addmi ip, r2, #4 bmi .Lcfu_2nowords mov r3, r7, pull #16 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #16 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -474,7 +474,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #16 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #16 strne r3, [r0], #4 ands ip, ip, #3 @@ -486,7 +486,7 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault strb r3, [r0], #1 movge r3, r7, get_byte_3 strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault +USER( T(ldrgtb) r3, [r1], #0) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished @@ -494,7 +494,7 @@ USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault addmi ip, r2, #4 bmi .Lcfu_3nowords mov r3, r7, pull #24 -USER( TUSER( ldr) r7, [r1], #4) @ May fault +USER( T(ldr) r7, [r1], #4) @ May fault orr r3, r3, r7, push #8 str r3, [r0], #4 mov ip, r1, lsl #32 - PAGE_SHIFT @@ -529,7 +529,7 @@ USER( TUSER( ldr) r7, [r1], #4) @ May fault stmneia r0!, {r3 - r4} tst ip, #4 movne r3, r7, pull #24 -USER( TUSER( ldrne) r7, [r1], #4) @ May fault +USER( T(ldrne) r7, [r1], #4) @ May fault orrne r3, r3, r7, push #8 strne r3, [r0], #4 ands ip, ip, #3 @@ -539,9 +539,9 @@ USER( TUSER( ldrne) r7, [r1], #4) @ May fault beq .Lcfu_finished cmp ip, #2 strb r3, [r0], #1 -USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault +USER( T(ldrgeb) r3, [r1], #1) @ May fault strgeb r3, [r0], #1 -USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault +USER( T(ldrgtb) r3, [r1], #1) @ May fault strgtb r3, [r0], #1 b .Lcfu_finished ENDPROC(__copy_from_user) diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index 71feb00a1e99..4f991f295284 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -18,12 +18,6 @@ config HAVE_AT91_USART4 config HAVE_AT91_USART5 bool -config AT91_SAM9_ALT_RESET - bool - -config AT91_SAM9G45_RESET - bool - menu "Atmel AT91 System-on-Chip" choice @@ -45,7 +39,6 @@ config ARCH_AT91SAM9260 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9261 bool "AT91SAM9261" @@ -53,7 +46,6 @@ config ARCH_AT91SAM9261 select GENERIC_CLOCKEVENTS select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G10 bool "AT91SAM9G10" @@ -61,7 +53,6 @@ config ARCH_AT91SAM9G10 select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 select HAVE_FB_ATMEL - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9263 bool "AT91SAM9263" @@ -70,7 +61,6 @@ config ARCH_AT91SAM9263 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9RL bool "AT91SAM9RL" @@ -79,7 +69,6 @@ config ARCH_AT91SAM9RL select HAVE_AT91_USART3 select HAVE_FB_ATMEL select HAVE_AT91_DBGU0 - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G20 bool "AT91SAM9G20" @@ -90,7 +79,6 @@ config ARCH_AT91SAM9G20 select HAVE_AT91_USART4 select HAVE_AT91_USART5 select HAVE_NET_MACB - select AT91_SAM9_ALT_RESET config ARCH_AT91SAM9G45 bool "AT91SAM9G45" @@ -100,7 +88,6 @@ config ARCH_AT91SAM9G45 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET config ARCH_AT91CAP9 bool "AT91CAP9" @@ -109,7 +96,6 @@ config ARCH_AT91CAP9 select HAVE_FB_ATMEL select HAVE_NET_MACB select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET config ARCH_AT91X40 bool "AT91x40" diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index 705e1fbded39..242174f9f355 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -8,17 +8,15 @@ obj-n := obj- := obj-$(CONFIG_AT91_PMC_UNIT) += clock.o -obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o -obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o at91sam9_alt_reset.o +obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.o obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o diff --git a/trunk/arch/arm/mach-at91/at91cap9.c b/trunk/arch/arm/mach-at91/at91cap9.c index a42edc25a87e..edb879ac04c8 100644 --- a/trunk/arch/arm/mach-at91/at91cap9.c +++ b/trunk/arch/arm/mach-at91/at91cap9.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "soc.h" #include "generic.h" @@ -313,6 +314,11 @@ static struct at91_gpio_bank at91cap9_gpio[] __initdata = { } }; +static void at91cap9_restart(char mode, const char *cmd) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + /* -------------------------------------------------------------------- * AT91CAP9 processor initialization * -------------------------------------------------------------------- */ @@ -325,14 +331,13 @@ static void __init at91cap9_map_io(void) static void __init at91cap9_ioremap_registers(void) { at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); - at91_ioremap_rstc(AT91CAP9_BASE_RSTC); at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); } static void __init at91cap9_initialize(void) { - arm_pm_restart = at91sam9g45_restart; + arm_pm_restart = at91cap9_restart; at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); /* Register GPIO subsystem */ diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index d4036ba43612..5e46e4a96430 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -323,7 +323,6 @@ static void __init at91sam9260_map_io(void) static void __init at91sam9260_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9260_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9260_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index 023c2ff138df..b85b9ea60170 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -281,7 +281,6 @@ static void __init at91sam9261_map_io(void) static void __init at91sam9261_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9261_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9261_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9261_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 75e876c258af..79e3669b1117 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -301,7 +301,6 @@ static void __init at91sam9263_map_io(void) static void __init at91sam9263_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9263_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9263_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9263_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9263_BASE_SMC0); at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1); diff --git a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S index 518e42377171..d3f931c5942e 100644 --- a/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S +++ b/trunk/arch/arm/mach-at91/at91sam9_alt_reset.S @@ -23,8 +23,7 @@ .globl at91sam9_alt_restart at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] + ldr r1, .at91_va_base_rstc_cr mov r2, #1 mov r3, #AT91_SDRAMC_LPCB_POWER_DOWN @@ -34,9 +33,11 @@ at91sam9_alt_restart: ldr r0, .at91_va_base_sdramc @ preload constants str r2, [r0, #AT91_SDRAMC_TR] @ disable SDRAM access str r3, [r0, #AT91_SDRAMC_LPR] @ power down SDRAM - str r4, [r1, #AT91_RSTC_CR] @ reset processor + str r4, [r1] @ reset processor b . .at91_va_base_sdramc: .word AT91_VA_BASE_SYS + AT91_SDRAMC0 +.at91_va_base_rstc_cr: + .word AT91_VA_BASE_SYS + AT91_RSTC_CR diff --git a/trunk/arch/arm/mach-at91/at91sam9g45.c b/trunk/arch/arm/mach-at91/at91sam9g45.c index 1cb6a96b1c1e..7032dd32cdf0 100644 --- a/trunk/arch/arm/mach-at91/at91sam9g45.c +++ b/trunk/arch/arm/mach-at91/at91sam9g45.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "soc.h" @@ -317,6 +318,11 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = { } }; +static void at91sam9g45_restart(char mode, const char *cmd) +{ + at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); +} + /* -------------------------------------------------------------------- * AT91SAM9G45 processor initialization * -------------------------------------------------------------------- */ @@ -330,7 +336,6 @@ static void __init at91sam9g45_map_io(void) static void __init at91sam9g45_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9G45_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9G45_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9G45_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9G45_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/at91sam9g45_reset.S b/trunk/arch/arm/mach-at91/at91sam9g45_reset.S deleted file mode 100644 index 0468be10980b..000000000000 --- a/trunk/arch/arm/mach-at91/at91sam9g45_reset.S +++ /dev/null @@ -1,40 +0,0 @@ -/* - * reset AT91SAM9G45 as per errata - * - * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD - * - * unless the SDRAM is cleanly shutdown before we hit the - * reset register it can be left driving the data bus and - * killing the chance of a subsequent boot from NAND - * - * GPLv2 Only - */ - -#include -#include -#include -#include - - .arm - - .globl at91sam9g45_restart - -at91sam9g45_restart: - ldr r0, .at91_va_base_sdramc0 @ preload constants - ldr r1, =at91_rstc_base - ldr r1, [r1] - - mov r2, #1 - mov r3, #AT91_DDRSDRC_LPCB_POWER_DOWN - ldr r4, =AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST - - .balign 32 @ align to cache line - - str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access - str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0 - str r4, [r1, #AT91_RSTC_CR] @ reset processor - - b . - -.at91_va_base_sdramc0: - .word AT91_VA_BASE_SYS + AT91_DDRSDRC0 diff --git a/trunk/arch/arm/mach-at91/at91sam9rl.c b/trunk/arch/arm/mach-at91/at91sam9rl.c index d2c91a841cb8..d6bcb1da11df 100644 --- a/trunk/arch/arm/mach-at91/at91sam9rl.c +++ b/trunk/arch/arm/mach-at91/at91sam9rl.c @@ -286,7 +286,6 @@ static void __init at91sam9rl_map_io(void) static void __init at91sam9rl_ioremap_registers(void) { at91_ioremap_shdwc(AT91SAM9RL_BASE_SHDWC); - at91_ioremap_rstc(AT91SAM9RL_BASE_RSTC); at91sam926x_ioremap_pit(AT91SAM9RL_BASE_PIT); at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC); } diff --git a/trunk/arch/arm/mach-at91/generic.h b/trunk/arch/arm/mach-at91/generic.h index 594133451c0c..4866b8180d66 100644 --- a/trunk/arch/arm/mach-at91/generic.h +++ b/trunk/arch/arm/mach-at91/generic.h @@ -58,9 +58,7 @@ extern void at91_irq_suspend(void); extern void at91_irq_resume(void); /* reset */ -extern void at91_ioremap_rstc(u32 base_addr); extern void at91sam9_alt_restart(char, const char *); -extern void at91sam9g45_restart(char, const char *); /* shutdown */ extern void at91_ioremap_shdwc(u32 base_addr); diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h index 875fa336800b..cbd2bf052c1f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91_rstc.h @@ -16,25 +16,13 @@ #ifndef AT91_RSTC_H #define AT91_RSTC_H -#ifndef __ASSEMBLY__ -extern void __iomem *at91_rstc_base; - -#define at91_rstc_read(field) \ - __raw_readl(at91_rstc_base + field) - -#define at91_rstc_write(field, value) \ - __raw_writel(value, at91_rstc_base + field); -#else -.extern at91_rstc_base -#endif - -#define AT91_RSTC_CR 0x00 /* Reset Controller Control Register */ +#define AT91_RSTC_CR (AT91_RSTC + 0x00) /* Reset Controller Control Register */ #define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ #define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */ #define AT91_RSTC_EXTRST (1 << 3) /* External Reset */ #define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */ -#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */ +#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */ #define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */ #define AT91_RSTC_RSTTYP (7 << 8) /* Reset Type */ #define AT91_RSTC_RSTTYP_GENERAL (0 << 8) @@ -45,7 +33,7 @@ extern void __iomem *at91_rstc_base; #define AT91_RSTC_NRSTL (1 << 16) /* NRST Pin Level */ #define AT91_RSTC_SRCMP (1 << 17) /* Software Reset Command in Progress */ -#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */ +#define AT91_RSTC_MR (AT91_RSTC + 0x08) /* Reset Controller Mode Register */ #define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */ #define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */ #define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h index 61d952902f2b..4c0e2f6011d7 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91cap9.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91cap9.h @@ -83,6 +83,7 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (cpu_is_at91cap9_revB() ? \ (0xfffffd50 - AT91_BASE_SYS) : \ (0xfffffd60 - AT91_BASE_SYS)) @@ -95,7 +96,6 @@ #define AT91CAP9_BASE_PIOB 0xfffff400 #define AT91CAP9_BASE_PIOC 0xfffff600 #define AT91CAP9_BASE_PIOD 0xfffff800 -#define AT91CAP9_BASE_RSTC 0xfffffd00 #define AT91CAP9_BASE_SHDWC 0xfffffd10 #define AT91CAP9_BASE_RTT 0xfffffd20 #define AT91CAP9_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h new file mode 100644 index 000000000000..976f4a6c3353 --- /dev/null +++ b/trunk/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h + * + * (C) 2008 Andrew Victor + * + * DDR/SDR Controller (DDRSDRC) - System peripherals registers. + * Based on AT91CAP9 datasheet revision B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef AT91CAP9_DDRSDR_H +#define AT91CAP9_DDRSDR_H + +#define AT91_DDRSDRC_MR 0x00 /* Mode Register */ +#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */ +#define AT91_DDRSDRC_MODE_NORMAL 0 +#define AT91_DDRSDRC_MODE_NOP 1 +#define AT91_DDRSDRC_MODE_PRECHARGE 2 +#define AT91_DDRSDRC_MODE_LMR 3 +#define AT91_DDRSDRC_MODE_REFRESH 4 +#define AT91_DDRSDRC_MODE_EXT_LMR 5 +#define AT91_DDRSDRC_MODE_DEEP 6 + +#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */ +#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */ + +#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */ +#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */ +#define AT91_DDRSDRC_NC_SDR8 (0 << 0) +#define AT91_DDRSDRC_NC_SDR9 (1 << 0) +#define AT91_DDRSDRC_NC_SDR10 (2 << 0) +#define AT91_DDRSDRC_NC_SDR11 (3 << 0) +#define AT91_DDRSDRC_NC_DDR9 (0 << 0) +#define AT91_DDRSDRC_NC_DDR10 (1 << 0) +#define AT91_DDRSDRC_NC_DDR11 (2 << 0) +#define AT91_DDRSDRC_NC_DDR12 (3 << 0) +#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */ +#define AT91_DDRSDRC_NR_11 (0 << 2) +#define AT91_DDRSDRC_NR_12 (1 << 2) +#define AT91_DDRSDRC_NR_13 (2 << 2) +#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */ +#define AT91_DDRSDRC_CAS_2 (2 << 4) +#define AT91_DDRSDRC_CAS_3 (3 << 4) +#define AT91_DDRSDRC_CAS_25 (6 << 4) +#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */ +#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ + +#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ +#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ +#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */ +#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */ +#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */ +#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ +#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ +#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ +#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ + +#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ +#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */ +#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */ +#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ +#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ + +#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */ +#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ +#define AT91_DDRSDRC_LPCB_DISABLE 0 +#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 +#define AT91_DDRSDRC_LPCB_POWER_DOWN 2 +#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3 +#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */ +#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */ +#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */ +#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */ +#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */ +#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12) +#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12) +#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12) + +#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */ +#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ +#define AT91_DDRSDRC_MD_SDR 0 +#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 +#define AT91_DDRSDRC_MD_DDR 2 +#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 + +#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */ +#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ +#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ +#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ +#define AT91_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ +#define AT91_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ +#define AT91_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ +#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ +#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ +#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ + +/* Register access macros */ +#define at91_ramc_read(num, reg) \ + at91_sys_read(AT91_DDRSDRC##num + reg) +#define at91_ramc_write(num, reg, value) \ + at91_sys_write(AT91_DDRSDRC##num + reg, value) + + +#endif diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h index fa5ca278adeb..f937c476bb67 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -83,6 +83,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9260_BASE_ECC 0xffffe800 @@ -91,7 +92,6 @@ #define AT91SAM9260_BASE_PIOA 0xfffff400 #define AT91SAM9260_BASE_PIOB 0xfffff600 #define AT91SAM9260_BASE_PIOC 0xfffff800 -#define AT91SAM9260_BASE_RSTC 0xfffffd00 #define AT91SAM9260_BASE_SHDWC 0xfffffd10 #define AT91SAM9260_BASE_RTT 0xfffffd20 #define AT91SAM9260_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h index 7cde2d36570e..175604e261be 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9261.h @@ -68,6 +68,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd50 - AT91_BASE_SYS) #define AT91SAM9261_BASE_SMC 0xffffec00 @@ -75,7 +76,6 @@ #define AT91SAM9261_BASE_PIOA 0xfffff400 #define AT91SAM9261_BASE_PIOB 0xfffff600 #define AT91SAM9261_BASE_PIOC 0xfffff800 -#define AT91SAM9261_BASE_RSTC 0xfffffd00 #define AT91SAM9261_BASE_SHDWC 0xfffffd10 #define AT91SAM9261_BASE_RTT 0xfffffd20 #define AT91SAM9261_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h index 5949abda962b..80c915002d83 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9263.h @@ -78,6 +78,7 @@ #define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9263_BASE_ECC0 0xffffe000 @@ -90,7 +91,6 @@ #define AT91SAM9263_BASE_PIOC 0xfffff600 #define AT91SAM9263_BASE_PIOD 0xfffff800 #define AT91SAM9263_BASE_PIOE 0xfffffa00 -#define AT91SAM9263_BASE_RSTC 0xfffffd00 #define AT91SAM9263_BASE_SHDWC 0xfffffd10 #define AT91SAM9263_BASE_RTT0 0xfffffd20 #define AT91SAM9263_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h index e2f8da8ce5bc..d27b15ba8ebf 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h @@ -46,10 +46,10 @@ #define AT91_DDRSDRC_CAS_25 (6 << 4) #define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */ #define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */ -#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL [SAM9 Only] */ -#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver [SAM9 Only] */ -#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared [SAM9 Only] */ -#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y [SAM9 Only] */ +#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */ +#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */ +#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */ +#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */ #define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */ #define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */ @@ -59,8 +59,7 @@ #define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */ #define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */ #define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */ -#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */ -#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */ +#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */ #define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */ #define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */ @@ -69,14 +68,13 @@ #define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */ #define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */ -#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register [SAM9 Only] */ +#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */ #define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */ #define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */ #define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */ #define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */ #define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */ -#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */ #define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */ #define AT91_DDRSDRC_LPCB_DISABLE 0 #define AT91_DDRSDRC_LPCB_SELF_REFRESH 1 @@ -94,40 +92,32 @@ #define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */ #define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */ -#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */ #define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */ #define AT91_DDRSDRC_MD_SDR 0 #define AT91_DDRSDRC_MD_LOW_POWER_SDR 1 -#define AT91CAP9_DDRSDRC_MD_DDR 2 #define AT91_DDRSDRC_MD_LOW_POWER_DDR 3 -#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */ +#define AT91_DDRSDRC_MD_DDR2 6 #define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */ #define AT91_DDRSDRC_DBW_32BITS (0 << 4) #define AT91_DDRSDRC_DBW_16BITS (1 << 4) #define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */ -#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */ #define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */ #define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */ #define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */ -#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */ -#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */ -#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */ #define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */ -#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */ -#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */ -#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */ +#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */ #define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */ #define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */ -#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register [SAM9 Only] */ +#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */ #define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */ #define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */ #define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */ -#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register [SAM9 Only] */ +#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */ #define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */ #define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */ diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h index dd9c95ea0862..f0c23c960dec 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9g45.h @@ -90,6 +90,7 @@ #define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) #define AT91SAM9G45_BASE_ECC 0xffffe200 @@ -101,7 +102,6 @@ #define AT91SAM9G45_BASE_PIOC 0xfffff600 #define AT91SAM9G45_BASE_PIOD 0xfffff800 #define AT91SAM9G45_BASE_PIOE 0xfffffa00 -#define AT91SAM9G45_BASE_RSTC 0xfffffd00 #define AT91SAM9G45_BASE_SHDWC 0xfffffd10 #define AT91SAM9G45_BASE_RTT 0xfffffd20 #define AT91SAM9G45_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h index d7bead7118da..2bb359e60b97 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91sam9rl.h @@ -72,6 +72,7 @@ #define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS) #define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS) #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) +#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS) #define AT91_SCKCR (0xfffffd50 - AT91_BASE_SYS) #define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS) @@ -83,7 +84,6 @@ #define AT91SAM9RL_BASE_PIOB 0xfffff600 #define AT91SAM9RL_BASE_PIOC 0xfffff800 #define AT91SAM9RL_BASE_PIOD 0xfffffa00 -#define AT91SAM9RL_BASE_RSTC 0xfffffd00 #define AT91SAM9RL_BASE_SHDWC 0xfffffd10 #define AT91SAM9RL_BASE_RTT 0xfffffd20 #define AT91SAM9RL_BASE_PIT 0xfffffd30 diff --git a/trunk/arch/arm/mach-at91/include/mach/board.h b/trunk/arch/arm/mach-at91/include/mach/board.h index 3b33f07b1e11..d0b377b21bd7 100644 --- a/trunk/arch/arm/mach-at91/include/mach/board.h +++ b/trunk/arch/arm/mach-at91/include/mach/board.h @@ -88,7 +88,7 @@ extern void __init at91_add_device_eth(struct macb_platform_data *data); struct at91_usbh_data { u8 ports; /* number of ports on root hub */ int vbus_pin[2]; /* port power-control pin */ - u8 vbus_pin_active_low[2]; + u8 vbus_pin_inverted; u8 overcurrent_supported; int overcurrent_pin[2]; u8 overcurrent_status[2]; diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 1606379ac284..62ad95556c36 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -34,6 +34,7 @@ /* * Show the reason for the previous system reset. */ +#if defined(AT91_RSTC) #include #include @@ -57,10 +58,10 @@ static void __init show_reset_status(void) char *reason, *r2 = reset; u32 reset_type, wake_type; - if (!at91_shdwc_base || !at91_rstc_base) + if (!at91_shdwc_base) return; - reset_type = at91_rstc_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; + reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; wake_type = at91_shdwc_read(AT91_SHDW_SR); switch (reset_type) { @@ -101,6 +102,10 @@ static void __init show_reset_status(void) } pr_info("AT91: Starting after %s %s\n", reason, r2); } +#else +static void __init show_reset_status(void) {} +#endif + static int at91_pm_valid_state(suspend_state_t state) { diff --git a/trunk/arch/arm/mach-at91/pm.h b/trunk/arch/arm/mach-at91/pm.h index 7eb40d24242f..ce9a20699111 100644 --- a/trunk/arch/arm/mach-at91/pm.h +++ b/trunk/arch/arm/mach-at91/pm.h @@ -25,21 +25,21 @@ static inline u32 sdram_selfrefresh_enable(void) : : "r" (0)) #elif defined(CONFIG_ARCH_AT91CAP9) -#include +#include static inline u32 sdram_selfrefresh_enable(void) { u32 saved_lpr, lpr; - saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR); + saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR); lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; - at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); + at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); return saved_lpr; } -#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr) +#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr) #define wait_for_interrupt_enable() cpu_do_idle() #elif defined(CONFIG_ARCH_AT91SAM9G45) diff --git a/trunk/arch/arm/mach-at91/pm_slowclock.S b/trunk/arch/arm/mach-at91/pm_slowclock.S index 92dfb8461392..f7922a436172 100644 --- a/trunk/arch/arm/mach-at91/pm_slowclock.S +++ b/trunk/arch/arm/mach-at91/pm_slowclock.S @@ -18,8 +18,9 @@ #if defined(CONFIG_ARCH_AT91RM9200) #include -#elif defined(CONFIG_ARCH_AT91CAP9) \ - || defined(CONFIG_ARCH_AT91SAM9G45) +#elif defined(CONFIG_ARCH_AT91CAP9) +#include +#elif defined(CONFIG_ARCH_AT91SAM9G45) #include #else #include diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index 69d3fc4c46f3..8bdcc3cb6012 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -29,12 +29,9 @@ EXPORT_SYMBOL(at91_soc_initdata); void __init at91rm9200_set_type(int type) { if (type == ARCH_REVISON_9200_PQFP) - at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; - else at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA; - - pr_info("AT91: filled in soc subtype: %s\n", - at91_get_soc_subtype(&at91_soc_initdata)); + else + at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP; } void __init at91_init_irq_default(void) @@ -284,15 +281,6 @@ void __init at91_ioremap_shdwc(u32 base_addr) pm_power_off = at91sam9_poweroff; } -void __iomem *at91_rstc_base; - -void __init at91_ioremap_rstc(u32 base_addr) -{ - at91_rstc_base = ioremap(base_addr, 16); - if (!at91_rstc_base) - panic("Impossible to ioremap at91_rstc_base\n"); -} - void __init at91_initialize(unsigned long main_clock) { at91_boot_soc.ioremap_registers(); diff --git a/trunk/arch/arm/mach-exynos/hotplug.c b/trunk/arch/arm/mach-exynos/hotplug.c index dd1ad55524c9..da70e7e39937 100644 --- a/trunk/arch/arm/mach-exynos/hotplug.c +++ b/trunk/arch/arm/mach-exynos/hotplug.c @@ -16,7 +16,6 @@ #include #include -#include #include diff --git a/trunk/arch/arm/mach-exynos/platsmp.c b/trunk/arch/arm/mach-exynos/platsmp.c index 0f2035a1eb6e..683aec786b78 100644 --- a/trunk/arch/arm/mach-exynos/platsmp.c +++ b/trunk/arch/arm/mach-exynos/platsmp.c @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-highbank/highbank.c b/trunk/arch/arm/mach-highbank/highbank.c index 8394d512a402..7afbe1e55beb 100644 --- a/trunk/arch/arm/mach-highbank/highbank.c +++ b/trunk/arch/arm/mach-highbank/highbank.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -73,7 +72,9 @@ static void __init highbank_map_io(void) void highbank_set_cpu_jump(int cpu, void *jump_addr) { +#ifdef CONFIG_SMP cpu = cpu_logical_map(cpu); +#endif writel(virt_to_phys(jump_addr), HB_JUMP_TABLE_VIRT(cpu)); __cpuc_flush_dcache_area(HB_JUMP_TABLE_VIRT(cpu), 16); outer_clean_range(HB_JUMP_TABLE_PHYS(cpu), diff --git a/trunk/arch/arm/mach-imx/Kconfig b/trunk/arch/arm/mach-imx/Kconfig index 4defb97bbfc8..09f357bcecde 100644 --- a/trunk/arch/arm/mach-imx/Kconfig +++ b/trunk/arch/arm/mach-imx/Kconfig @@ -87,6 +87,7 @@ config SOC_IMX35 config SOC_IMX5 select CPU_V7 + select ARM_L1_CACHE_SHIFT_6 select MXC_TZIC select ARCH_MXC_IOMUX_V3 select ARCH_MXC_AUDMUX_V2 diff --git a/trunk/arch/arm/mach-imx/clock-imx6q.c b/trunk/arch/arm/mach-imx/clock-imx6q.c index 2d88f8b9a454..9273c2a24b54 100644 --- a/trunk/arch/arm/mach-imx/clock-imx6q.c +++ b/trunk/arch/arm/mach-imx/clock-imx6q.c @@ -814,16 +814,6 @@ DEF_PFD(pll3_pfd_540m, PFD_480, PFD1, &pll3_usb_otg); DEF_PFD(pll3_pfd_508m, PFD_480, PFD2, &pll3_usb_otg); DEF_PFD(pll3_pfd_454m, PFD_480, PFD3, &pll3_usb_otg); -static unsigned long twd_clk_get_rate(struct clk *clk) -{ - return clk_get_rate(clk->parent) / 2; -} - -static struct clk twd_clk = { - .parent = &arm_clk, - .get_rate = twd_clk_get_rate, -}; - static unsigned long pll2_200m_get_rate(struct clk *clk) { return clk_get_rate(clk->parent) / 2; @@ -1904,7 +1894,6 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("20ec000.sdma", NULL, sdma_clk), _REGISTER_CLOCK("20bc000.wdog", NULL, dummy_clk), _REGISTER_CLOCK("20c0000.wdog", NULL, dummy_clk), - _REGISTER_CLOCK("smp_twd", NULL, twd_clk), _REGISTER_CLOCK(NULL, "ckih", ckih_clk), _REGISTER_CLOCK(NULL, "ckil_clk", ckil_clk), _REGISTER_CLOCK(NULL, "aips_tz1_clk", aips_tz1_clk), diff --git a/trunk/arch/arm/mach-imx/mach-mx53_ard.c b/trunk/arch/arm/mach-imx/mach-mx53_ard.c index 753f4fc9ec04..08dfb7628d2d 100644 --- a/trunk/arch/arm/mach-imx/mach-mx53_ard.c +++ b/trunk/arch/arm/mach-imx/mach-mx53_ard.c @@ -188,10 +188,8 @@ static int weim_cs_config(void) return -ENOMEM; iomuxc_base = ioremap(MX53_IOMUXC_BASE_ADDR, SZ_4K); - if (!iomuxc_base) { - iounmap(weim_base); + if (!iomuxc_base) return -ENOMEM; - } /* CS1 timings for LAN9220 */ writel(0x20001, (weim_base + 0x18)); diff --git a/trunk/arch/arm/mach-imx/src.c b/trunk/arch/arm/mach-imx/src.c index e15f1555c59b..29bd1243781e 100644 --- a/trunk/arch/arm/mach-imx/src.c +++ b/trunk/arch/arm/mach-imx/src.c @@ -15,7 +15,6 @@ #include #include #include -#include #define SRC_SCR 0x000 #define SRC_GPR1 0x020 @@ -25,6 +24,10 @@ static void __iomem *src_base; +#ifndef CONFIG_SMP +#define cpu_logical_map(cpu) 0 +#endif + void imx_enable_cpu(int cpu, bool enable) { u32 mask, val; diff --git a/trunk/arch/arm/mach-msm/hotplug.c b/trunk/arch/arm/mach-msm/hotplug.c index a446fc14221f..41c252de0215 100644 --- a/trunk/arch/arm/mach-msm/hotplug.c +++ b/trunk/arch/arm/mach-msm/hotplug.c @@ -11,7 +11,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-msm/platsmp.c b/trunk/arch/arm/mach-msm/platsmp.c index db0117ec55f4..0b3e357c4c8c 100644 --- a/trunk/arch/arm/mach-msm/platsmp.c +++ b/trunk/arch/arm/mach-msm/platsmp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index 41e6612ecbaf..a8ba7b96dcd1 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -33,6 +33,7 @@ config ARCH_OMAP3 default y select CPU_V7 select USB_ARCH_HAS_EHCI + select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4 select ARCH_HAS_OPP select PM_OPP if PM select ARM_CPU_SUSPEND if PM diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c index 5bc13121eac5..18fd177073f4 100644 --- a/trunk/arch/arm/mach-pxa/devices.c +++ b/trunk/arch/arm/mach-pxa/devices.c @@ -415,9 +415,29 @@ static struct resource pxa_rtc_resources[] = { }, }; +static struct resource sa1100_rtc_resources[] = { + [0] = { + .start = 0x40900000, + .end = 0x409000ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + struct platform_device sa1100_device_rtc = { .name = "sa1100-rtc", .id = -1, + .num_resources = ARRAY_SIZE(sa1100_rtc_resources), + .resource = sa1100_rtc_resources, }; struct platform_device pxa_device_rtc = { diff --git a/trunk/arch/arm/mach-pxa/pxa25x.c b/trunk/arch/arm/mach-pxa/pxa25x.c index 91e4f6c03766..adf058fa97ee 100644 --- a/trunk/arch/arm/mach-pxa/pxa25x.c +++ b/trunk/arch/arm/mach-pxa/pxa25x.c @@ -209,6 +209,8 @@ static struct clk_lookup pxa25x_clkregs[] = { INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"), INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"), INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static struct clk_lookup pxa25x_hwuart_clkreg = diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index aed6cbcf3866..180bd8675d4b 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -230,6 +230,8 @@ static struct clk_lookup pxa27x_clkregs[] = { INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"), INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"), INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL), + INIT_CLKREG(&clk_dummy, "pxa-gpio", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; #ifdef CONFIG_PM diff --git a/trunk/arch/arm/mach-pxa/pxa300.c b/trunk/arch/arm/mach-pxa/pxa300.c index 40bb16501d86..0388eda7878a 100644 --- a/trunk/arch/arm/mach-pxa/pxa300.c +++ b/trunk/arch/arm/mach-pxa/pxa300.c @@ -89,6 +89,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA300_GCU, 0, 0); static struct clk_lookup common_clkregs[] = { INIT_CLKREG(&clk_common_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static DEFINE_PXA3_CKEN(pxa310_mmc3, MMC3, 19500000, 0); diff --git a/trunk/arch/arm/mach-pxa/pxa320.c b/trunk/arch/arm/mach-pxa/pxa320.c index 8d614ecd8e99..d487e1ff4c9a 100644 --- a/trunk/arch/arm/mach-pxa/pxa320.c +++ b/trunk/arch/arm/mach-pxa/pxa320.c @@ -83,6 +83,7 @@ static DEFINE_PXA3_CKEN(gcu, PXA320_GCU, 0, 0); static struct clk_lookup pxa320_clkregs[] = { INIT_CLKREG(&clk_pxa320_nand, "pxa3xx-nand", NULL), INIT_CLKREG(&clk_gcu, "pxa3xx-gcu", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), }; static int __init pxa320_init(void) diff --git a/trunk/arch/arm/mach-pxa/pxa3xx.c b/trunk/arch/arm/mach-pxa/pxa3xx.c index 4f402afa6609..f107c71c7589 100644 --- a/trunk/arch/arm/mach-pxa/pxa3xx.c +++ b/trunk/arch/arm/mach-pxa/pxa3xx.c @@ -67,6 +67,7 @@ static struct clk_lookup pxa3xx_clkregs[] = { INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), diff --git a/trunk/arch/arm/mach-pxa/pxa95x.c b/trunk/arch/arm/mach-pxa/pxa95x.c index d082a583df78..fccc644702e6 100644 --- a/trunk/arch/arm/mach-pxa/pxa95x.c +++ b/trunk/arch/arm/mach-pxa/pxa95x.c @@ -217,6 +217,7 @@ static struct clk_lookup pxa95x_clkregs[] = { INIT_CLKREG(&clk_pxa95x_pout, NULL, "CLK_POUT"), /* Power I2C clock is always on */ INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), INIT_CLKREG(&clk_pxa95x_lcd, "pxa2xx-fb", NULL), INIT_CLKREG(&clk_pxa95x_ffuart, "pxa2xx-uart.0", NULL), INIT_CLKREG(&clk_pxa95x_btuart, "pxa2xx-uart.1", NULL), diff --git a/trunk/arch/arm/mach-realview/hotplug.c b/trunk/arch/arm/mach-realview/hotplug.c index eb55f05bef3a..ac1aed2a8da4 100644 --- a/trunk/arch/arm/mach-realview/hotplug.c +++ b/trunk/arch/arm/mach-realview/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-realview/include/mach/board-eb.h b/trunk/arch/arm/mach-realview/include/mach/board-eb.h index 124bce6b4d7b..794a8d91a6a6 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-eb.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-eb.h @@ -47,23 +47,21 @@ #define REALVIEW_EB_USB_BASE 0x4F000000 /* USB */ #ifdef CONFIG_REALVIEW_EB_ARM11MP_REVB -#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 +#define REALVIEW_EB11MP_SCU_BASE 0x10100000 /* SCU registers */ +#define REALVIEW_EB11MP_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_EB11MP_TWD_BASE 0x10100600 +#define REALVIEW_EB11MP_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_L220_BASE 0x10102000 /* L220 registers */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */ #else -#define REALVIEW_EB11MP_PRIV_MEM_BASE 0x1F000000 +#define REALVIEW_EB11MP_SCU_BASE 0x1F000000 /* SCU registers */ +#define REALVIEW_EB11MP_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */ +#define REALVIEW_EB11MP_TWD_BASE 0x1F000600 +#define REALVIEW_EB11MP_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */ #define REALVIEW_EB11MP_L220_BASE 0x1F002000 /* L220 registers */ #define REALVIEW_EB11MP_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */ #endif -#define REALVIEW_EB11MP_PRIV_MEM_SIZE SZ_8K -#define REALVIEW_EB11MP_PRIV_MEM_OFF(x) (REALVIEW_EB11MP_PRIV_MEM_BASE + (x)) - -#define REALVIEW_EB11MP_SCU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0) /* SCU registers */ -#define REALVIEW_EB11MP_GIC_CPU_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0100) /* Generic interrupt controller CPU interface */ -#define REALVIEW_EB11MP_TWD_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x0600) -#define REALVIEW_EB11MP_GIC_DIST_BASE REALVIEW_EB11MP_PRIV_MEM_OFF(0x1000) /* Generic interrupt controller distributor */ - /* * Core tile identification (REALVIEW_SYS_PROCID) */ diff --git a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h index aa2d4e02ea2c..7abf918b77e9 100644 --- a/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h +++ b/trunk/arch/arm/mach-realview/include/mach/board-pb11mp.h @@ -75,8 +75,6 @@ /* * Testchip peripheral and fpga gic regions */ -#define REALVIEW_TC11MP_PRIV_MEM_BASE 0x1F000000 -#define REALVIEW_TC11MP_PRIV_MEM_SIZE SZ_8K #define REALVIEW_TC11MP_SCU_BASE 0x1F000000 /* IRQ, Test chip */ #define REALVIEW_TC11MP_GIC_CPU_BASE 0x1F000100 /* Test chip interrupt controller CPU interface */ #define REALVIEW_TC11MP_TWD_BASE 0x1F000600 diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 9578145f2df0..e62962117763 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -91,9 +91,14 @@ static struct map_desc realview_eb_io_desc[] __initdata = { static struct map_desc realview_eb11mp_io_desc[] __initdata = { { - .virtual = IO_ADDRESS(REALVIEW_EB11MP_PRIV_MEM_BASE), - .pfn = __phys_to_pfn(REALVIEW_EB11MP_PRIV_MEM_BASE), - .length = REALVIEW_EB11MP_PRIV_MEM_SIZE, + .virtual = IO_ADDRESS(REALVIEW_EB11MP_SCU_BASE), + .pfn = __phys_to_pfn(REALVIEW_EB11MP_SCU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = IO_ADDRESS(REALVIEW_EB11MP_GIC_DIST_BASE), + .pfn = __phys_to_pfn(REALVIEW_EB11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = IO_ADDRESS(REALVIEW_EB11MP_L220_BASE), diff --git a/trunk/arch/arm/mach-realview/realview_pb11mp.c b/trunk/arch/arm/mach-realview/realview_pb11mp.c index 2147335f66f5..127a3fd42ab1 100644 --- a/trunk/arch/arm/mach-realview/realview_pb11mp.c +++ b/trunk/arch/arm/mach-realview/realview_pb11mp.c @@ -64,10 +64,15 @@ static struct map_desc realview_pb11mp_io_desc[] __initdata = { .pfn = __phys_to_pfn(REALVIEW_PB11MP_GIC_DIST_BASE), .length = SZ_4K, .type = MT_DEVICE, - }, { /* Maps the SCU, GIC CPU interface, TWD, GIC DIST */ - .virtual = IO_ADDRESS(REALVIEW_TC11MP_PRIV_MEM_BASE), - .pfn = __phys_to_pfn(REALVIEW_TC11MP_PRIV_MEM_BASE), - .length = REALVIEW_TC11MP_PRIV_MEM_SIZE, + }, { + .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_CPU_BASE), + .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_CPU_BASE), + .length = SZ_4K, + .type = MT_DEVICE, + }, { + .virtual = IO_ADDRESS(REALVIEW_TC11MP_GIC_DIST_BASE), + .pfn = __phys_to_pfn(REALVIEW_TC11MP_GIC_DIST_BASE), + .length = SZ_4K, .type = MT_DEVICE, }, { .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE), diff --git a/trunk/arch/arm/mach-sa1100/assabet.c b/trunk/arch/arm/mach-sa1100/assabet.c index 0c4b76ab4d8e..ebafe8aa8956 100644 --- a/trunk/arch/arm/mach-sa1100/assabet.c +++ b/trunk/arch/arm/mach-sa1100/assabet.c @@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = { static struct mcp_plat_data assabet_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init assabet_init(void) @@ -252,6 +253,17 @@ static void __init assabet_init(void) sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources, ARRAY_SIZE(assabet_flash_resources)); sa11x0_register_irda(&assabet_irda_data); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); sa11x0_register_mcp(&assabet_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/cerf.c b/trunk/arch/arm/mach-sa1100/cerf.c index 11bb6d0b9be3..d12d0f48b1dc 100644 --- a/trunk/arch/arm/mach-sa1100/cerf.c +++ b/trunk/arch/arm/mach-sa1100/cerf.c @@ -124,12 +124,23 @@ static void __init cerf_map_io(void) static struct mcp_plat_data cerf_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init cerf_init(void) { platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices)); sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&cerf_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/clock.c b/trunk/arch/arm/mach-sa1100/clock.c index dab3c6347a8f..d6df9f6c9f7e 100644 --- a/trunk/arch/arm/mach-sa1100/clock.c +++ b/trunk/arch/arm/mach-sa1100/clock.c @@ -11,17 +11,39 @@ #include #include #include +#include +#include #include -/* - * Very simple clock implementation - we only have one clock to deal with. - */ +struct clkops { + void (*enable)(struct clk *); + void (*disable)(struct clk *); + unsigned long (*getrate)(struct clk *); +}; + struct clk { + const struct clkops *ops; + unsigned long rate; unsigned int enabled; }; -static void clk_gpio27_enable(void) +#define INIT_CLKREG(_clk, _devname, _conname) \ + { \ + .clk = _clk, \ + .dev_id = _devname, \ + .con_id = _conname, \ + } + +#define DEFINE_CLK(_name, _ops, _rate) \ +struct clk clk_##_name = { \ + .ops = _ops, \ + .rate = _rate, \ + } + +static DEFINE_SPINLOCK(clocks_lock); + +static void clk_gpio27_enable(struct clk *clk) { /* * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111: @@ -32,38 +54,22 @@ static void clk_gpio27_enable(void) TUCR = TUCR_3_6864MHz; } -static void clk_gpio27_disable(void) +static void clk_gpio27_disable(struct clk *clk) { TUCR = 0; GPDR &= ~GPIO_32_768kHz; GAFR &= ~GPIO_32_768kHz; } -static struct clk clk_gpio27; - -static DEFINE_SPINLOCK(clocks_lock); - -struct clk *clk_get(struct device *dev, const char *id) -{ - const char *devname = dev_name(dev); - - return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27; -} -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - int clk_enable(struct clk *clk) { unsigned long flags; spin_lock_irqsave(&clocks_lock, flags); if (clk->enabled++ == 0) - clk_gpio27_enable(); + clk->ops->enable(clk); spin_unlock_irqrestore(&clocks_lock, flags); + return 0; } EXPORT_SYMBOL(clk_enable); @@ -76,13 +82,48 @@ void clk_disable(struct clk *clk) spin_lock_irqsave(&clocks_lock, flags); if (--clk->enabled == 0) - clk_gpio27_disable(); + clk->ops->disable(clk); spin_unlock_irqrestore(&clocks_lock, flags); } EXPORT_SYMBOL(clk_disable); unsigned long clk_get_rate(struct clk *clk) { - return 3686400; + unsigned long rate; + + rate = clk->rate; + if (clk->ops->getrate) + rate = clk->ops->getrate(clk); + + return rate; } EXPORT_SYMBOL(clk_get_rate); + +const struct clkops clk_gpio27_ops = { + .enable = clk_gpio27_enable, + .disable = clk_gpio27_disable, +}; + +static void clk_dummy_enable(struct clk *clk) { } +static void clk_dummy_disable(struct clk *clk) { } + +const struct clkops clk_dummy_ops = { + .enable = clk_dummy_enable, + .disable = clk_dummy_disable, +}; + +static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400); +static DEFINE_CLK(dummy, &clk_dummy_ops, 0); + +static struct clk_lookup sa11xx_clkregs[] = { + INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL), + INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL), +}; + +static int __init sa11xx_clk_init(void) +{ + clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs)); + return 0; +} + +postcore_initcall(sa11xx_clk_init); diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index fd5652118ed1..c483912d08af 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { .num_devs = 1, }; +static struct ucb1x00_plat_data collie_ucb1x00_data = { + .gpio_base = COLLIE_TC35143_GPIO_BASE, +}; + static struct mcp_plat_data collie_mcp_data = { .mccr0 = MCCR0_ADM | MCCR0_ExtClk, .sclk_rate = 9216000, - .gpio_base = COLLIE_TC35143_GPIO_BASE, + .codec = "ucb1x00", + .codec_pdata = &collie_ucb1x00_data, }; /* @@ -138,6 +144,8 @@ static struct pda_power_pdata collie_power_data = { static struct resource collie_power_resource[] = { { .name = "ac", + .start = gpio_to_irq(COLLIE_GPIO_AC_IN), + .end = gpio_to_irq(COLLIE_GPIO_AC_IN), .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE, @@ -339,8 +347,7 @@ static void __init collie_init(void) GPSR |= _COLLIE_GPIO_UCB1x00_RESET; - collie_power_resource[0].start = gpio_to_irq(COLLIE_GPIO_AC_IN); - collie_power_resource[0].end = gpio_to_irq(COLLIE_GPIO_AC_IN); + platform_scoop_config = &collie_pcmcia_config; ret = platform_add_devices(devices, ARRAY_SIZE(devices)); @@ -350,6 +357,16 @@ static void __init collie_init(void) sa11x0_register_mtd(&collie_flash_data, collie_flash_resources, ARRAY_SIZE(collie_flash_resources)); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&collie_mcp_data); sharpsl_save_param(); diff --git a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c index 19b2053f5af4..aaa8acf76b7b 100644 --- a/trunk/arch/arm/mach-sa1100/cpu-sa1100.c +++ b/trunk/arch/arm/mach-sa1100/cpu-sa1100.c @@ -228,7 +228,7 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy) return 0; } -static struct cpufreq_driver sa1100_driver __refdata = { +static struct cpufreq_driver sa1100_driver = { .flags = CPUFREQ_STICKY, .verify = sa11x0_verify_speed, .target = sa1100_target, diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index bb10ee2cb89f..e3a28ca2a7b7 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -217,10 +217,15 @@ static struct platform_device sa11x0uart3_device = { static struct resource sa11x0mcp_resources[] = { [0] = { .start = __PREG(Ser4MCCR0), - .end = __PREG(Ser4MCCR0) + 0xffff, + .end = __PREG(Ser4MCCR0) + 0x1C - 1, .flags = IORESOURCE_MEM, }, [1] = { + .start = __PREG(Ser4MCCR1), + .end = __PREG(Ser4MCCR1) + 0x4 - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { .start = IRQ_Ser4MCP, .end = IRQ_Ser4MCP, .flags = IORESOURCE_IRQ, @@ -345,9 +350,29 @@ void sa11x0_register_irda(struct irda_platform_data *irda) sa11x0_register_device(&sa11x0ir_device, irda); } +static struct resource sa11x0rtc_resources[] = { + [0] = { + .start = 0x90010000, + .end = 0x900100ff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device sa11x0rtc_device = { .name = "sa1100-rtc", .id = -1, + .resource = sa11x0rtc_resources, + .num_resources = ARRAY_SIZE(sa11x0rtc_resources), }; static struct platform_device *sa11x0_devices[] __initdata = { diff --git a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h index ed1a331508a7..586cec898b35 100644 --- a/trunk/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/trunk/arch/arm/mach-sa1100/include/mach/mcp.h @@ -17,6 +17,8 @@ struct mcp_plat_data { u32 mccr1; unsigned int sclk_rate; int gpio_base; + const char *codec; + void *codec_pdata; }; #endif diff --git a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c index b412fc09c80c..f50b00bd18a0 100644 --- a/trunk/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/trunk/arch/arm/mach-sa1100/jornada720_ssp.c @@ -198,5 +198,3 @@ static int __init jornada_ssp_init(void) { return platform_driver_register(&jornadassp_driver); } - -module_init(jornada_ssp_init); diff --git a/trunk/arch/arm/mach-sa1100/lart.c b/trunk/arch/arm/mach-sa1100/lart.c index af4e2761f3db..d117ceab6215 100644 --- a/trunk/arch/arm/mach-sa1100/lart.c +++ b/trunk/arch/arm/mach-sa1100/lart.c @@ -24,10 +24,20 @@ static struct mcp_plat_data lart_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init lart_init(void) { + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&lart_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/shannon.c b/trunk/arch/arm/mach-sa1100/shannon.c index 318b2b766a0b..748d34435b3f 100644 --- a/trunk/arch/arm/mach-sa1100/shannon.c +++ b/trunk/arch/arm/mach-sa1100/shannon.c @@ -55,11 +55,22 @@ static struct resource shannon_flash_resource = { static struct mcp_plat_data shannon_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, + .codec = "ucb1x00", }; static void __init shannon_init(void) { sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&shannon_mcp_data); } diff --git a/trunk/arch/arm/mach-sa1100/simpad.c b/trunk/arch/arm/mach-sa1100/simpad.c index e17c04d6e324..458ececefa58 100644 --- a/trunk/arch/arm/mach-sa1100/simpad.c +++ b/trunk/arch/arm/mach-sa1100/simpad.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = { } }; +static struct ucb1x00_plat_data simpad_ucb1x00_data = { + .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, +}; + static struct mcp_plat_data simpad_mcp_data = { .mccr0 = MCCR0_ADM, .sclk_rate = 11981000, - .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, + .codec = "ucb1300", + .codec_pdata = &simpad_ucb1x00_data, }; @@ -378,6 +384,16 @@ static int __init simpad_init(void) sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources, ARRAY_SIZE(simpad_flash_resources)); + + /* + * Setup the PPC unit correctly. + */ + PPDR &= ~PPC_RXD4; + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; + PSDR |= PPC_RXD4; + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); + sa11x0_register_mcp(&simpad_mcp_data); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); diff --git a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c index 4fe2e9eaf501..cc97ef892d1b 100644 --- a/trunk/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/trunk/arch/arm/mach-shmobile/smp-r8a7779.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c index 0d159d64a345..be1ade76ccc8 100644 --- a/trunk/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/trunk/arch/arm/mach-shmobile/smp-sh73a0.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index 52af00446a63..a3e0c8692f0d 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -7,7 +7,6 @@ config UX500_SOC_COMMON select HAS_MTU select ARM_ERRATA_753970 select ARM_ERRATA_754322 - select ARM_ERRATA_764369 menu "Ux500 SoC" diff --git a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c index 5dde4d4ebe88..23be34b3bb6e 100644 --- a/trunk/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/trunk/arch/arm/mach-ux500/board-mop500-sdi.c @@ -261,8 +261,6 @@ void __init mop500_sdi_init(void) void __init snowball_sdi_init(void) { - /* On Snowball MMC_CAP_SD_HIGHSPEED isn't supported (Hardware issue?) */ - mop500_sdi0_data.capabilities &= ~MMC_CAP_SD_HIGHSPEED; /* On-board eMMC */ db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ diff --git a/trunk/arch/arm/mach-ux500/cache-l2x0.c b/trunk/arch/arm/mach-ux500/cache-l2x0.c index da5569d83d58..122ddde00ba7 100644 --- a/trunk/arch/arm/mach-ux500/cache-l2x0.c +++ b/trunk/arch/arm/mach-ux500/cache-l2x0.c @@ -12,6 +12,44 @@ static void __iomem *l2x0_base; +static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask) +{ + /* wait for the operation to complete */ + while (readl_relaxed(reg) & mask) + cpu_relax(); +} + +static inline void ux500_cache_sync(void) +{ + writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC); + ux500_cache_wait(l2x0_base + L2X0_CACHE_SYNC, 1); +} + +/* + * The L2 cache cannot be turned off in the non-secure world. + * Dummy until a secure service is in place. + */ +static void ux500_l2x0_disable(void) +{ +} + +/* + * This is only called when doing a kexec, just after turning off the L2 + * and L1 cache, and it is surrounded by a spinlock in the generic version. + * However, we're not really turning off the L2 cache right now and the + * PL310 does not support exclusive accesses (used to implement the spinlock). + * So, the invalidation needs to be done without the spinlock. + */ +static void ux500_l2x0_inv_all(void) +{ + uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */ + + /* invalidate all ways */ + writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY); + ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask); + ux500_cache_sync(); +} + static int __init ux500_l2x0_unlock(void) { int i; @@ -47,13 +85,9 @@ static int __init ux500_l2x0_init(void) /* 64KB way size, 8 way associativity, force WA */ l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff); - /* - * We can't disable l2 as we are in non secure mode, currently - * this seems be called only during kexec path. So let's - * override outer.disable with nasty assignment until we have - * some SMI service available. - */ - outer_cache.disable = NULL; + /* Override invalidate function */ + outer_cache.disable = ux500_l2x0_disable; + outer_cache.inv_all = ux500_l2x0_inv_all; return 0; } diff --git a/trunk/arch/arm/mach-ux500/hotplug.c b/trunk/arch/arm/mach-ux500/hotplug.c index c76f0f456f04..572015e57cd9 100644 --- a/trunk/arch/arm/mach-ux500/hotplug.c +++ b/trunk/arch/arm/mach-ux500/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include extern volatile int pen_release; diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index d2058ef8345f..a19e398dade3 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/mach-ux500/usb.c b/trunk/arch/arm/mach-ux500/usb.c index 9f9e1c203061..0a01cbdfe063 100644 --- a/trunk/arch/arm/mach-ux500/usb.c +++ b/trunk/arch/arm/mach-ux500/usb.c @@ -95,7 +95,13 @@ static struct musb_hdrc_config musb_hdrc_config = { }; static struct musb_hdrc_platform_data musb_platform_data = { +#if defined(CONFIG_USB_MUSB_OTG) .mode = MUSB_OTG, +#elif defined(CONFIG_USB_MUSB_PERIPHERAL) + .mode = MUSB_PERIPHERAL, +#else /* defined(CONFIG_USB_MUSB_HOST) */ + .mode = MUSB_HOST, +#endif .config = &musb_hdrc_config, .board_data = &musb_board_data, }; diff --git a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c index b1e87c184e54..2b1e836a76ed 100644 --- a/trunk/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/trunk/arch/arm/mach-vexpress/ct-ca9x4.c @@ -217,7 +217,7 @@ static void __init ct_ca9x4_init(void) } #ifdef CONFIG_SMP -static void __init ct_ca9x4_init_cpu_map(void) +static void ct_ca9x4_init_cpu_map(void) { int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); @@ -233,7 +233,7 @@ static void __init ct_ca9x4_init_cpu_map(void) set_smp_cross_call(gic_raise_softirq); } -static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) +static void ct_ca9x4_smp_enable(unsigned int max_cpus) { scu_enable(MMIO_P2V(A9_MPCORE_SCU)); } diff --git a/trunk/arch/arm/mach-vexpress/hotplug.c b/trunk/arch/arm/mach-vexpress/hotplug.c index 3034a4dab4a1..813ee08f96e6 100644 --- a/trunk/arch/arm/mach-vexpress/hotplug.c +++ b/trunk/arch/arm/mach-vexpress/hotplug.c @@ -13,7 +13,6 @@ #include #include -#include #include extern volatile int pen_release; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 1a3ca2488164..4cefb57d9ed2 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -882,7 +882,6 @@ config CACHE_XSC3L2 config ARM_L1_CACHE_SHIFT_6 bool - default y if CPU_V7 help Setting ARM L1 cache line size to 64 Bytes. diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 5dc7d127a40f..6ec1226fc62d 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -310,7 +310,7 @@ static void arm_memory_present(void) static bool arm_memblock_steal_permitted = true; -phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align) +phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align) { phys_addr_t phys; diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index ba159370fa5f..80632e8d7538 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -225,8 +225,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype)) continue; if (__phys_to_pfn(area->phys_addr) > pfn || - __pfn_to_phys(pfn) + offset + size-1 > - area->phys_addr + area->size-1) + __pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1) continue; /* we can drop the lock here as we know *area is static */ read_unlock(&vmlist_lock); diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index 0404ccbb8aa3..7e9b5bf910c1 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -148,6 +148,10 @@ ENDPROC(cpu_v7_do_resume) * Initialise TLB, Caches, and MMU state ready to switch the MMU * on. Return in r0 the new CP15 C1 control register setting. * + * We automatically detect if we have a Harvard cache, and use the + * Harvard cache control instructions insead of the unified cache + * control instructions. + * * This should be able to cover all ARMv7 cores. * * It is assumed that: @@ -247,7 +251,9 @@ __v7_setup: #endif 3: mov r10, #0 +#ifdef HARVARD_CACHE mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate +#endif dsb #ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs @@ -323,6 +329,16 @@ __v7_ca5mp_proc_info: __v7_proc __v7_ca5mp_setup .size __v7_ca5mp_proc_info, . - __v7_ca5mp_proc_info + /* + * ARM Ltd. Cortex A7 processor. + */ + .type __v7_ca7mp_proc_info, #object +__v7_ca7mp_proc_info: + .long 0x410fc070 + .long 0xff0ffff0 + __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV + .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info + /* * ARM Ltd. Cortex A9 processor. */ @@ -334,16 +350,6 @@ __v7_ca9mp_proc_info: .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info #endif /* CONFIG_ARM_LPAE */ - /* - * ARM Ltd. Cortex A7 processor. - */ - .type __v7_ca7mp_proc_info, #object -__v7_ca7mp_proc_info: - .long 0x410fc070 - .long 0xff0ffff0 - __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV - .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info - /* * ARM Ltd. Cortex A15 processor. */ diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h index f7d18046c04f..6fa8a707b9a0 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-v1.h @@ -96,6 +96,6 @@ extern int mxc_gpio_mode(int gpio_mode); extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, const char *label); -extern int imx_iomuxv1_init(void __iomem *base, int numports); +extern int __init imx_iomuxv1_init(void __iomem *base, int numports); #endif /* __MACH_IOMUX_V1_H__ */ diff --git a/trunk/arch/arm/plat-versatile/platsmp.c b/trunk/arch/arm/plat-versatile/platsmp.c index 49c7db48c7f1..92f18d372b69 100644 --- a/trunk/arch/arm/plat-versatile/platsmp.c +++ b/trunk/arch/arm/plat-versatile/platsmp.c @@ -16,7 +16,6 @@ #include #include -#include #include /* diff --git a/trunk/arch/microblaze/Kconfig b/trunk/arch/microblaze/Kconfig index c8d6efb99dbf..74f23a460ba2 100644 --- a/trunk/arch/microblaze/Kconfig +++ b/trunk/arch/microblaze/Kconfig @@ -19,7 +19,6 @@ config MICROBLAZE select GENERIC_IRQ_SHOW select GENERIC_PCI_IOMAP select GENERIC_CPU_DEVICES - select GENERIC_ATOMIC64 config SWAP def_bool n diff --git a/trunk/arch/microblaze/include/asm/atomic.h b/trunk/arch/microblaze/include/asm/atomic.h index 615f53992c65..6d2e1d418be7 100644 --- a/trunk/arch/microblaze/include/asm/atomic.h +++ b/trunk/arch/microblaze/include/asm/atomic.h @@ -2,7 +2,6 @@ #define _ASM_MICROBLAZE_ATOMIC_H #include -#include /* * Atomically test *v and decrement if it is greater than 0. diff --git a/trunk/arch/microblaze/kernel/setup.c b/trunk/arch/microblaze/kernel/setup.c index 604cd9dd1333..d4fc1a971779 100644 --- a/trunk/arch/microblaze/kernel/setup.c +++ b/trunk/arch/microblaze/kernel/setup.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -226,5 +227,23 @@ static int __init setup_bus_notifier(void) return 0; } - arch_initcall(setup_bus_notifier); + +static DEFINE_PER_CPU(struct cpu, cpu_devices); + +static int __init topology_init(void) +{ + int i, ret; + + for_each_present_cpu(i) { + struct cpu *c = &per_cpu(cpu_devices, i); + + ret = register_cpu(c, i); + if (ret) + printk(KERN_WARNING "topology_init: register_cpu %d " + "failed (%d)\n", i, ret); + } + + return 0; +} +subsys_initcall(topology_init); diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index 0ad2f1e1ce9e..e9f353341693 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -88,6 +88,7 @@ KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare KBUILD_AFLAGS += $(aflags-y) OBJCOPYFLAGS := -O binary +LDFLAGS_vmlinux := -e start head-y := arch/s390/kernel/head.o head-y += arch/s390/kernel/$(if $(CONFIG_64BIT),head64.o,head31.o) diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S index 21109c63eb12..e4c79ebb40e6 100644 --- a/trunk/arch/s390/kernel/vmlinux.lds.S +++ b/trunk/arch/s390/kernel/vmlinux.lds.S @@ -9,12 +9,12 @@ #ifndef CONFIG_64BIT OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390") OUTPUT_ARCH(s390) -ENTRY(startup) +ENTRY(_start) jiffies = jiffies_64 + 4; #else OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_ARCH(s390:64-bit) -ENTRY(startup) +ENTRY(_start) jiffies = jiffies_64; #endif diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index ca5580e4d813..96657992a72e 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -33,7 +33,6 @@ config SPARC config SPARC32 def_bool !64BIT select GENERIC_ATOMIC64 - select CLZ_TAB config SPARC64 def_bool 64BIT diff --git a/trunk/arch/sparc/lib/divdi3.S b/trunk/arch/sparc/lib/divdi3.S index d74bc0925f2d..681b3683da9e 100644 --- a/trunk/arch/sparc/lib/divdi3.S +++ b/trunk/arch/sparc/lib/divdi3.S @@ -17,9 +17,23 @@ along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + .data + .align 8 + .globl __clz_tab +__clz_tab: + .byte 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 + .byte 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 + .byte 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 + .byte 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 + .byte 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 + .byte 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 + .byte 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 + .byte 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 + .size __clz_tab,256 + .global .udiv + .text .align 4 - .global .udiv .globl __divdi3 __divdi3: save %sp,-104,%sp diff --git a/trunk/arch/x86/include/asm/cmpxchg.h b/trunk/arch/x86/include/asm/cmpxchg.h index b3b733262909..0c9fa2745f13 100644 --- a/trunk/arch/x86/include/asm/cmpxchg.h +++ b/trunk/arch/x86/include/asm/cmpxchg.h @@ -145,13 +145,13 @@ extern void __add_wrong_size(void) #ifdef __HAVE_ARCH_CMPXCHG #define cmpxchg(ptr, old, new) \ - __cmpxchg(ptr, old, new, sizeof(*(ptr))) + __cmpxchg((ptr), (old), (new), sizeof(*ptr)) #define sync_cmpxchg(ptr, old, new) \ - __sync_cmpxchg(ptr, old, new, sizeof(*(ptr))) + __sync_cmpxchg((ptr), (old), (new), sizeof(*ptr)) #define cmpxchg_local(ptr, old, new) \ - __cmpxchg_local(ptr, old, new, sizeof(*(ptr))) + __cmpxchg_local((ptr), (old), (new), sizeof(*ptr)) #endif /* diff --git a/trunk/arch/x86/include/asm/inat.h b/trunk/arch/x86/include/asm/inat.h index 74a2e312e8a2..205b063e3e32 100644 --- a/trunk/arch/x86/include/asm/inat.h +++ b/trunk/arch/x86/include/asm/inat.h @@ -97,12 +97,11 @@ /* Attribute search APIs */ extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode); -extern int inat_get_last_prefix_id(insn_byte_t last_pfx); extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, - int lpfx_id, + insn_byte_t last_pfx, insn_attr_t esc_attr); extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm, - int lpfx_id, + insn_byte_t last_pfx, insn_attr_t esc_attr); extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode, insn_byte_t vex_m, diff --git a/trunk/arch/x86/include/asm/insn.h b/trunk/arch/x86/include/asm/insn.h index 48eb30a86062..74df3f1eddfd 100644 --- a/trunk/arch/x86/include/asm/insn.h +++ b/trunk/arch/x86/include/asm/insn.h @@ -96,6 +96,12 @@ struct insn { #define X86_VEX_P(vex) ((vex) & 0x03) /* VEX3 Byte2, VEX2 Byte1 */ #define X86_VEX_M_MAX 0x1f /* VEX3.M Maximum value */ +/* The last prefix is needed for two-byte and three-byte opcodes */ +static inline insn_byte_t insn_last_prefix(struct insn *insn) +{ + return insn->prefixes.bytes[3]; +} + extern void insn_init(struct insn *insn, const void *kaddr, int x86_64); extern void insn_get_prefixes(struct insn *insn); extern void insn_get_opcode(struct insn *insn); @@ -154,18 +160,6 @@ static inline insn_byte_t insn_vex_p_bits(struct insn *insn) return X86_VEX_P(insn->vex_prefix.bytes[2]); } -/* Get the last prefix id from last prefix or VEX prefix */ -static inline int insn_last_prefix_id(struct insn *insn) -{ - if (insn_is_avx(insn)) - return insn_vex_p_bits(insn); /* VEX_p is a SIMD prefix id */ - - if (insn->prefixes.bytes[3]) - return inat_get_last_prefix_id(insn->prefixes.bytes[3]); - - return 0; -} - /* Offset of each field from kaddr */ static inline int insn_offset_rex_prefix(struct insn *insn) { diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 0a44b90602b0..f4773f4aae35 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -457,8 +456,6 @@ static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) if (c->x86_power & (1 << 8)) { set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC); - if (!check_tsc_unstable()) - sched_clock_stable = 1; } #ifdef CONFIG_X86_64 diff --git a/trunk/arch/x86/kernel/cpu/perf_event.c b/trunk/arch/x86/kernel/cpu/perf_event.c index 3c44b712380c..f8bddb5b0600 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event.c +++ b/trunk/arch/x86/kernel/cpu/perf_event.c @@ -988,6 +988,9 @@ static void x86_pmu_start(struct perf_event *event, int flags) struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); int idx = event->hw.idx; + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + if (WARN_ON_ONCE(idx == -1)) return; diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c index d6bd49faa40c..73da6b64f5b7 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -439,6 +439,7 @@ void intel_pmu_pebs_enable(struct perf_event *event) hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; cpuc->pebs_enabled |= 1ULL << hwc->idx; + WARN_ON_ONCE(cpuc->enabled); if (x86_pmu.intel_cap.pebs_trap && event->attr.precise_ip > 1) intel_pmu_lbr_enable(event); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c index 47a7e63bfe54..3fab3de3ce96 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel_lbr.c @@ -72,6 +72,8 @@ void intel_pmu_lbr_enable(struct perf_event *event) if (!x86_pmu.lbr_nr) return; + WARN_ON_ONCE(cpuc->enabled); + /* * Reset the LBR stack if we changed task context to * avoid data leaks. diff --git a/trunk/arch/x86/kernel/dumpstack.c b/trunk/arch/x86/kernel/dumpstack.c index 4025fe4f928f..1aae78f775fc 100644 --- a/trunk/arch/x86/kernel/dumpstack.c +++ b/trunk/arch/x86/kernel/dumpstack.c @@ -252,8 +252,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err) unsigned short ss; unsigned long sp; #endif - printk(KERN_DEFAULT - "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); + printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); #endif diff --git a/trunk/arch/x86/kernel/dumpstack_64.c b/trunk/arch/x86/kernel/dumpstack_64.c index 17107bd6e1f0..af7785ff5aa0 100644 --- a/trunk/arch/x86/kernel/dumpstack_64.c +++ b/trunk/arch/x86/kernel/dumpstack_64.c @@ -269,11 +269,11 @@ void show_registers(struct pt_regs *regs) unsigned char c; u8 *ip; - printk(KERN_DEFAULT "Stack:\n"); + printk(KERN_EMERG "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, - 0, KERN_DEFAULT); + 0, KERN_EMERG); - printk(KERN_DEFAULT "Code: "); + printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { diff --git a/trunk/arch/x86/kernel/reboot.c b/trunk/arch/x86/kernel/reboot.c index d840e69a853c..37a458b521a6 100644 --- a/trunk/arch/x86/kernel/reboot.c +++ b/trunk/arch/x86/kernel/reboot.c @@ -39,14 +39,6 @@ static int reboot_mode; enum reboot_type reboot_type = BOOT_ACPI; int reboot_force; -/* This variable is used privately to keep track of whether or not - * reboot_type is still set to its default value (i.e., reboot= hasn't - * been set on the command line). This is needed so that we can - * suppress DMI scanning for reboot quirks. Without it, it's - * impossible to override a faulty reboot quirk without recompiling. - */ -static int reboot_default = 1; - #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) static int reboot_cpu = -1; #endif @@ -75,12 +67,6 @@ bool port_cf9_safe = false; static int __init reboot_setup(char *str) { for (;;) { - /* Having anything passed on the command line via - * reboot= will cause us to disable DMI checking - * below. - */ - reboot_default = 0; - switch (*str) { case 'w': reboot_mode = 0x1234; @@ -309,6 +295,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "P4S800"), }, }, + { /* Handle problems with rebooting on VersaLogic Menlow boards */ + .callback = set_bios_reboot, + .ident = "VersaLogic Menlow based board", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "VersaLogic Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"), + }, + }, { /* Handle reboot issue on Acer Aspire one */ .callback = set_kbd_reboot, .ident = "Acer Aspire One A110", @@ -322,12 +316,7 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { static int __init reboot_init(void) { - /* Only do the DMI check if reboot_type hasn't been overridden - * on the command line - */ - if (reboot_default) { - dmi_check_system(reboot_dmi_table); - } + dmi_check_system(reboot_dmi_table); return 0; } core_initcall(reboot_init); @@ -476,12 +465,7 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { static int __init pci_reboot_init(void) { - /* Only do the DMI check if reboot_type hasn't been overridden - * on the command line - */ - if (reboot_default) { - dmi_check_system(pci_reboot_dmi_table); - } + dmi_check_system(pci_reboot_dmi_table); return 0; } core_initcall(pci_reboot_init); diff --git a/trunk/arch/x86/lib/inat.c b/trunk/arch/x86/lib/inat.c index c1f01a8e9f65..88ad5fbda6e1 100644 --- a/trunk/arch/x86/lib/inat.c +++ b/trunk/arch/x86/lib/inat.c @@ -29,46 +29,46 @@ insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode) return inat_primary_table[opcode]; } -int inat_get_last_prefix_id(insn_byte_t last_pfx) -{ - insn_attr_t lpfx_attr; - - lpfx_attr = inat_get_opcode_attribute(last_pfx); - return inat_last_prefix_id(lpfx_attr); -} - -insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, int lpfx_id, +insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx, insn_attr_t esc_attr) { const insn_attr_t *table; - int n; + insn_attr_t lpfx_attr; + int n, m = 0; n = inat_escape_id(esc_attr); - + if (last_pfx) { + lpfx_attr = inat_get_opcode_attribute(last_pfx); + m = inat_last_prefix_id(lpfx_attr); + } table = inat_escape_tables[n][0]; if (!table) return 0; - if (inat_has_variant(table[opcode]) && lpfx_id) { - table = inat_escape_tables[n][lpfx_id]; + if (inat_has_variant(table[opcode]) && m) { + table = inat_escape_tables[n][m]; if (!table) return 0; } return table[opcode]; } -insn_attr_t inat_get_group_attribute(insn_byte_t modrm, int lpfx_id, +insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx, insn_attr_t grp_attr) { const insn_attr_t *table; - int n; + insn_attr_t lpfx_attr; + int n, m = 0; n = inat_group_id(grp_attr); - + if (last_pfx) { + lpfx_attr = inat_get_opcode_attribute(last_pfx); + m = inat_last_prefix_id(lpfx_attr); + } table = inat_group_tables[n][0]; if (!table) return inat_group_common_attribute(grp_attr); - if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && lpfx_id) { - table = inat_group_tables[n][lpfx_id]; + if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) { + table = inat_group_tables[n][m]; if (!table) return inat_group_common_attribute(grp_attr); } diff --git a/trunk/arch/x86/lib/insn.c b/trunk/arch/x86/lib/insn.c index 25feb1ae71c5..5a1f9f3e3fbb 100644 --- a/trunk/arch/x86/lib/insn.c +++ b/trunk/arch/x86/lib/insn.c @@ -185,8 +185,7 @@ void insn_get_prefixes(struct insn *insn) void insn_get_opcode(struct insn *insn) { struct insn_field *opcode = &insn->opcode; - insn_byte_t op; - int pfx_id; + insn_byte_t op, pfx; if (opcode->got) return; if (!insn->prefixes.got) @@ -213,8 +212,8 @@ void insn_get_opcode(struct insn *insn) /* Get escaped opcode */ op = get_next(insn_byte_t, insn); opcode->bytes[opcode->nbytes++] = op; - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_escape_attribute(op, pfx_id, insn->attr); + pfx = insn_last_prefix(insn); + insn->attr = inat_get_escape_attribute(op, pfx, insn->attr); } if (inat_must_vex(insn->attr)) insn->attr = 0; /* This instruction is bad */ @@ -236,7 +235,7 @@ void insn_get_opcode(struct insn *insn) void insn_get_modrm(struct insn *insn) { struct insn_field *modrm = &insn->modrm; - insn_byte_t pfx_id, mod; + insn_byte_t pfx, mod; if (modrm->got) return; if (!insn->opcode.got) @@ -247,8 +246,8 @@ void insn_get_modrm(struct insn *insn) modrm->value = mod; modrm->nbytes = 1; if (inat_is_group(insn->attr)) { - pfx_id = insn_last_prefix_id(insn); - insn->attr = inat_get_group_attribute(mod, pfx_id, + pfx = insn_last_prefix(insn); + insn->attr = inat_get_group_attribute(mod, pfx, insn->attr); if (insn_is_avx(insn) && !inat_accept_vex(insn->attr)) insn->attr = 0; /* This is bad */ diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index f0b4caf85c1a..9d74824a708d 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -673,7 +673,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, stackend = end_of_stack(tsk); if (tsk != &init_task && *stackend != STACK_END_MAGIC) - printk(KERN_EMERG "Thread overran stack, or stack corrupted\n"); + printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); tsk->thread.cr2 = address; tsk->thread.trap_no = 14; @@ -684,7 +684,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, sig = 0; /* Executive summary in case the body of the oops scrolled away */ - printk(KERN_DEFAULT "CR2: %016lx\n", address); + printk(KERN_EMERG "CR2: %016lx\n", address); oops_end(flags, regs, sig); } diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index d69cc6c3f808..cc9b1e182fcf 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -116,26 +116,9 @@ static inline void spin_time_accum_blocked(u64 start) } #endif /* CONFIG_XEN_DEBUG_FS */ -/* - * Size struct xen_spinlock so it's the same as arch_spinlock_t. - */ -#if NR_CPUS < 256 -typedef u8 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incb %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decb %0" : "+m" ((xl)->spinners) : : "memory"); -#else -typedef u16 xen_spinners_t; -# define inc_spinners(xl) \ - asm(LOCK_PREFIX " incw %0" : "+m" ((xl)->spinners) : : "memory"); -# define dec_spinners(xl) \ - asm(LOCK_PREFIX " decw %0" : "+m" ((xl)->spinners) : : "memory"); -#endif - struct xen_spinlock { unsigned char lock; /* 0 -> free; 1 -> locked */ - xen_spinners_t spinners; /* count of waiting cpus */ + unsigned short spinners; /* count of waiting cpus */ }; static int xen_spin_is_locked(struct arch_spinlock *lock) @@ -181,7 +164,8 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl) wmb(); /* set lock of interest before count */ - inc_spinners(xl); + asm(LOCK_PREFIX " incw %0" + : "+m" (xl->spinners) : : "memory"); return prev; } @@ -192,7 +176,8 @@ static inline struct xen_spinlock *spinning_lock(struct xen_spinlock *xl) */ static inline void unspinning_lock(struct xen_spinlock *xl, struct xen_spinlock *prev) { - dec_spinners(xl); + asm(LOCK_PREFIX " decw %0" + : "+m" (xl->spinners) : : "memory"); wmb(); /* decrement count before restoring lock */ __this_cpu_write(lock_spinners, prev); } @@ -388,8 +373,6 @@ void xen_uninit_lock_cpu(int cpu) void __init xen_init_spinlocks(void) { - BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); - pv_lock_ops.spin_is_locked = xen_spin_is_locked; pv_lock_ops.spin_is_contended = xen_spin_is_contended; pv_lock_ops.spin_lock = xen_spin_lock; diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index 610f9997a403..2c8272dd93c4 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o bus.o dd.o syscore.o \ +obj-y := core.o sys.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o \ diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 74dda4f697f9..4a67cc0c8b37 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -632,11 +632,6 @@ static void klist_children_put(struct klist_node *n) * may be used for reference counting of @dev after calling this * function. * - * All fields in @dev must be initialized by the caller to 0, except - * for those explicitly set to some other value. The simplest - * approach is to use kzalloc() to allocate the structure containing - * @dev. - * * NOTE: Use put_device() to give up your reference instead of freeing * @dev directly once you have called this function. */ @@ -935,13 +930,6 @@ int device_private_init(struct device *dev) * to the global and sibling lists for the device, then * adds it to the other relevant subsystems of the driver model. * - * Do not call this routine or device_register() more than once for - * any device structure. The driver model core is not designed to work - * with devices that get unregistered and then spring back to life. - * (Among other things, it's very hard to guarantee that all references - * to the previous incarnation of @dev have been dropped.) Allocate - * and register a fresh new struct device instead. - * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up your * reference instead. @@ -1034,7 +1022,7 @@ int device_add(struct device *dev) device_pm_add(dev); /* Notify clients of device addition. This call must come - * after dpm_sysfs_add() and before kobject_uevent(). + * after dpm_sysf_add() and before kobject_uevent(). */ if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, @@ -1102,9 +1090,6 @@ int device_add(struct device *dev) * have a clearly defined need to use and refcount the device * before it is added to the hierarchy. * - * For more information, see the kerneldoc for device_initialize() - * and device_add(). - * * NOTE: _Never_ directly free @dev after calling this function, even * if it returned an error! Always use put_device() to give up the * reference initialized in this function instead. diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c new file mode 100644 index 000000000000..409f5ce78829 --- /dev/null +++ b/trunk/drivers/base/sys.c @@ -0,0 +1,383 @@ +/* + * sys.c - pseudo-bus for system 'devices' (cpus, PICs, timers, etc) + * + * Copyright (c) 2002-3 Patrick Mochel + * 2002-3 Open Source Development Lab + * + * This file is released under the GPLv2 + * + * This exports a 'system' bus type. + * By default, a 'sys' bus gets added to the root of the system. There will + * always be core system devices. Devices can use sysdev_register() to + * add themselves as children of the system bus. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base.h" + +#define to_sysdev(k) container_of(k, struct sys_device, kobj) +#define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) + + +static ssize_t +sysdev_show(struct kobject *kobj, struct attribute *attr, char *buffer) +{ + struct sys_device *sysdev = to_sysdev(kobj); + struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); + + if (sysdev_attr->show) + return sysdev_attr->show(sysdev, sysdev_attr, buffer); + return -EIO; +} + + +static ssize_t +sysdev_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct sys_device *sysdev = to_sysdev(kobj); + struct sysdev_attribute *sysdev_attr = to_sysdev_attr(attr); + + if (sysdev_attr->store) + return sysdev_attr->store(sysdev, sysdev_attr, buffer, count); + return -EIO; +} + +static const struct sysfs_ops sysfs_ops = { + .show = sysdev_show, + .store = sysdev_store, +}; + +static struct kobj_type ktype_sysdev = { + .sysfs_ops = &sysfs_ops, +}; + + +int sysdev_create_file(struct sys_device *s, struct sysdev_attribute *a) +{ + return sysfs_create_file(&s->kobj, &a->attr); +} + + +void sysdev_remove_file(struct sys_device *s, struct sysdev_attribute *a) +{ + sysfs_remove_file(&s->kobj, &a->attr); +} + +EXPORT_SYMBOL_GPL(sysdev_create_file); +EXPORT_SYMBOL_GPL(sysdev_remove_file); + +#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj) +#define to_sysdev_class_attr(a) container_of(a, \ + struct sysdev_class_attribute, attr) + +static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr, + char *buffer) +{ + struct sysdev_class *class = to_sysdev_class(kobj); + struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); + + if (class_attr->show) + return class_attr->show(class, class_attr, buffer); + return -EIO; +} + +static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr, + const char *buffer, size_t count) +{ + struct sysdev_class *class = to_sysdev_class(kobj); + struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr); + + if (class_attr->store) + return class_attr->store(class, class_attr, buffer, count); + return -EIO; +} + +static const struct sysfs_ops sysfs_class_ops = { + .show = sysdev_class_show, + .store = sysdev_class_store, +}; + +static struct kobj_type ktype_sysdev_class = { + .sysfs_ops = &sysfs_class_ops, +}; + +int sysdev_class_create_file(struct sysdev_class *c, + struct sysdev_class_attribute *a) +{ + return sysfs_create_file(&c->kset.kobj, &a->attr); +} +EXPORT_SYMBOL_GPL(sysdev_class_create_file); + +void sysdev_class_remove_file(struct sysdev_class *c, + struct sysdev_class_attribute *a) +{ + sysfs_remove_file(&c->kset.kobj, &a->attr); +} +EXPORT_SYMBOL_GPL(sysdev_class_remove_file); + +extern struct kset *system_kset; + +int sysdev_class_register(struct sysdev_class *cls) +{ + int retval; + + pr_debug("Registering sysdev class '%s'\n", cls->name); + + INIT_LIST_HEAD(&cls->drivers); + memset(&cls->kset.kobj, 0x00, sizeof(struct kobject)); + cls->kset.kobj.parent = &system_kset->kobj; + cls->kset.kobj.ktype = &ktype_sysdev_class; + cls->kset.kobj.kset = system_kset; + + retval = kobject_set_name(&cls->kset.kobj, "%s", cls->name); + if (retval) + return retval; + + retval = kset_register(&cls->kset); + if (!retval && cls->attrs) + retval = sysfs_create_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); + return retval; +} + +void sysdev_class_unregister(struct sysdev_class *cls) +{ + pr_debug("Unregistering sysdev class '%s'\n", + kobject_name(&cls->kset.kobj)); + if (cls->attrs) + sysfs_remove_files(&cls->kset.kobj, + (const struct attribute **)cls->attrs); + kset_unregister(&cls->kset); +} + +EXPORT_SYMBOL_GPL(sysdev_class_register); +EXPORT_SYMBOL_GPL(sysdev_class_unregister); + +static DEFINE_MUTEX(sysdev_drivers_lock); + +/* + * @dev != NULL means that we're unwinding because some drv->add() + * failed for some reason. You need to grab sysdev_drivers_lock before + * calling this. + */ +static void __sysdev_driver_remove(struct sysdev_class *cls, + struct sysdev_driver *drv, + struct sys_device *from_dev) +{ + struct sys_device *dev = from_dev; + + list_del_init(&drv->entry); + if (!cls) + return; + + if (!drv->remove) + goto kset_put; + + if (dev) + list_for_each_entry_continue_reverse(dev, &cls->kset.list, + kobj.entry) + drv->remove(dev); + else + list_for_each_entry(dev, &cls->kset.list, kobj.entry) + drv->remove(dev); + +kset_put: + kset_put(&cls->kset); +} + +/** + * sysdev_driver_register - Register auxiliary driver + * @cls: Device class driver belongs to. + * @drv: Driver. + * + * @drv is inserted into @cls->drivers to be + * called on each operation on devices of that class. The refcount + * of @cls is incremented. + */ +int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv) +{ + struct sys_device *dev = NULL; + int err = 0; + + if (!cls) { + WARN(1, KERN_WARNING "sysdev: invalid class passed to %s!\n", + __func__); + return -EINVAL; + } + + /* Check whether this driver has already been added to a class. */ + if (drv->entry.next && !list_empty(&drv->entry)) + WARN(1, KERN_WARNING "sysdev: class %s: driver (%p) has already" + " been registered to a class, something is wrong, but " + "will forge on!\n", cls->name, drv); + + mutex_lock(&sysdev_drivers_lock); + if (cls && kset_get(&cls->kset)) { + list_add_tail(&drv->entry, &cls->drivers); + + /* If devices of this class already exist, tell the driver */ + if (drv->add) { + list_for_each_entry(dev, &cls->kset.list, kobj.entry) { + err = drv->add(dev); + if (err) + goto unwind; + } + } + } else { + err = -EINVAL; + WARN(1, KERN_ERR "%s: invalid device class\n", __func__); + } + + goto unlock; + +unwind: + __sysdev_driver_remove(cls, drv, dev); + +unlock: + mutex_unlock(&sysdev_drivers_lock); + return err; +} + +/** + * sysdev_driver_unregister - Remove an auxiliary driver. + * @cls: Class driver belongs to. + * @drv: Driver. + */ +void sysdev_driver_unregister(struct sysdev_class *cls, + struct sysdev_driver *drv) +{ + mutex_lock(&sysdev_drivers_lock); + __sysdev_driver_remove(cls, drv, NULL); + mutex_unlock(&sysdev_drivers_lock); +} +EXPORT_SYMBOL_GPL(sysdev_driver_register); +EXPORT_SYMBOL_GPL(sysdev_driver_unregister); + +/** + * sysdev_register - add a system device to the tree + * @sysdev: device in question + * + */ +int sysdev_register(struct sys_device *sysdev) +{ + int error; + struct sysdev_class *cls = sysdev->cls; + + if (!cls) + return -EINVAL; + + pr_debug("Registering sys device of class '%s'\n", + kobject_name(&cls->kset.kobj)); + + /* initialize the kobject to 0, in case it had previously been used */ + memset(&sysdev->kobj, 0x00, sizeof(struct kobject)); + + /* Make sure the kset is set */ + sysdev->kobj.kset = &cls->kset; + + /* Register the object */ + error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, + "%s%d", kobject_name(&cls->kset.kobj), + sysdev->id); + + if (!error) { + struct sysdev_driver *drv; + + pr_debug("Registering sys device '%s'\n", + kobject_name(&sysdev->kobj)); + + mutex_lock(&sysdev_drivers_lock); + /* Generic notification is implicit, because it's that + * code that should have called us. + */ + + /* Notify class auxiliary drivers */ + list_for_each_entry(drv, &cls->drivers, entry) { + if (drv->add) + drv->add(sysdev); + } + mutex_unlock(&sysdev_drivers_lock); + kobject_uevent(&sysdev->kobj, KOBJ_ADD); + } + + return error; +} + +void sysdev_unregister(struct sys_device *sysdev) +{ + struct sysdev_driver *drv; + + mutex_lock(&sysdev_drivers_lock); + list_for_each_entry(drv, &sysdev->cls->drivers, entry) { + if (drv->remove) + drv->remove(sysdev); + } + mutex_unlock(&sysdev_drivers_lock); + + kobject_put(&sysdev->kobj); +} + +EXPORT_SYMBOL_GPL(sysdev_register); +EXPORT_SYMBOL_GPL(sysdev_unregister); + +#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr) + +ssize_t sysdev_store_ulong(struct sys_device *sysdev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + char *end; + unsigned long new = simple_strtoul(buf, &end, 0); + if (end == buf) + return -EINVAL; + *(unsigned long *)(ea->var) = new; + /* Always return full write size even if we didn't consume all */ + return size; +} +EXPORT_SYMBOL_GPL(sysdev_store_ulong); + +ssize_t sysdev_show_ulong(struct sys_device *sysdev, + struct sysdev_attribute *attr, + char *buf) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); +} +EXPORT_SYMBOL_GPL(sysdev_show_ulong); + +ssize_t sysdev_store_int(struct sys_device *sysdev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + char *end; + long new = simple_strtol(buf, &end, 0); + if (end == buf || new > INT_MAX || new < INT_MIN) + return -EINVAL; + *(int *)(ea->var) = new; + /* Always return full write size even if we didn't consume all */ + return size; +} +EXPORT_SYMBOL_GPL(sysdev_store_int); + +ssize_t sysdev_show_int(struct sys_device *sysdev, + struct sysdev_attribute *attr, + char *buf) +{ + struct sysdev_ext_attribute *ea = to_ext_attr(attr); + return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); +} +EXPORT_SYMBOL_GPL(sysdev_show_int); + diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index a6278e7e61a0..3fd31dec8c9c 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -380,7 +380,6 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, rbdc = __rbd_client_find(opt); if (rbdc) { ceph_destroy_options(opt); - kfree(rbd_opts); /* using an existing client */ kref_get(&rbdc->kref); @@ -407,15 +406,15 @@ static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr, /* * Destroy ceph client - * - * Caller must hold node_lock. */ static void rbd_client_release(struct kref *kref) { struct rbd_client *rbdc = container_of(kref, struct rbd_client, kref); dout("rbd_release_client %p\n", rbdc); + spin_lock(&node_lock); list_del(&rbdc->node); + spin_unlock(&node_lock); ceph_destroy_client(rbdc->client); kfree(rbdc->rbd_opts); @@ -428,9 +427,7 @@ static void rbd_client_release(struct kref *kref) */ static void rbd_put_client(struct rbd_device *rbd_dev) { - spin_lock(&node_lock); kref_put(&rbd_dev->rbd_client->kref, rbd_client_release); - spin_unlock(&node_lock); rbd_dev->rbd_client = NULL; rbd_dev->client = NULL; } diff --git a/trunk/drivers/char/agp/backend.c b/trunk/drivers/char/agp/backend.c index 317c28ce8328..4b71647782d0 100644 --- a/trunk/drivers/char/agp/backend.c +++ b/trunk/drivers/char/agp/backend.c @@ -194,10 +194,10 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) { - struct page *page = bridge->scratch_page_page; + void *va = page_address(bridge->scratch_page_page); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); } if (got_gatt) bridge->driver->free_gatt_table(bridge); @@ -221,10 +221,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) { - struct page *page = bridge->scratch_page_page; + void *va = page_address(bridge->scratch_page_page); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_UNMAP); - bridge->driver->agp_destroy_page(page, AGP_PAGE_DESTROY_FREE); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); + bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); } } diff --git a/trunk/drivers/firewire/ohci.c b/trunk/drivers/firewire/ohci.c index 7f5f0da726da..6628feaa7622 100644 --- a/trunk/drivers/firewire/ohci.c +++ b/trunk/drivers/firewire/ohci.c @@ -263,7 +263,6 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) static char ohci_driver_name[] = KBUILD_MODNAME; #define PCI_DEVICE_ID_AGERE_FW643 0x5901 -#define PCI_DEVICE_ID_CREATIVE_SB1394 0x4001 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 #define PCI_DEVICE_ID_TI_TSB12LV26 0x8020 @@ -290,9 +289,6 @@ static const struct { {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, QUIRK_NO_MSI}, - {PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_SB1394, PCI_ANY_ID, - QUIRK_RESET_PACKET}, - {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, QUIRK_NO_MSI}, @@ -303,7 +299,7 @@ static const struct { QUIRK_NO_MSI}, {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, - QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, + QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index f8625e290728..396e60ce8114 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev, obj->dev = dev; obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); if (IS_ERR(obj->filp)) - return PTR_ERR(obj->filp); + return -ENOMEM; kref_init(&obj->refcount); atomic_set(&obj->handle_count, 0); diff --git a/trunk/drivers/gpu/drm/exynos/Kconfig b/trunk/drivers/gpu/drm/exynos/Kconfig index b9e5266c341b..f9aaa56eae07 100644 --- a/trunk/drivers/gpu/drm/exynos/Kconfig +++ b/trunk/drivers/gpu/drm/exynos/Kconfig @@ -13,7 +13,7 @@ config DRM_EXYNOS config DRM_EXYNOS_FIMD tristate "Exynos DRM FIMD" - depends on DRM_EXYNOS && !FB_S3C + depends on DRM_EXYNOS default n help Choose this option if you want to use Exynos FIMD for DRM. @@ -21,7 +21,7 @@ config DRM_EXYNOS_FIMD config DRM_EXYNOS_HDMI tristate "Exynos DRM HDMI" - depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV + depends on DRM_EXYNOS help Choose this option if you want to use Exynos HDMI for DRM. If M is selected, the module will be called exynos_drm_hdmi diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b6a737d196ae..ca83139cd309 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -158,8 +158,7 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (!ctx->suspended) - pm_runtime_put_sync(subdrv_dev); + pm_runtime_put_sync(subdrv_dev); break; default: DRM_DEBUG_KMS("unspecified mode %d\n", mode); @@ -735,46 +734,6 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) writel(val, ctx->regs + SHADOWCON); } -static int fimd_power_on(struct fimd_context *ctx, bool enable) -{ - struct exynos_drm_subdrv *subdrv = &ctx->subdrv; - struct device *dev = subdrv->manager.dev; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - int ret; - - ret = clk_enable(ctx->bus_clk); - if (ret < 0) - return ret; - - ret = clk_enable(ctx->lcd_clk); - if (ret < 0) { - clk_disable(ctx->bus_clk); - return ret; - } - - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - fimd_enable_vblank(dev); - - fimd_apply(dev); - } else { - clk_disable(ctx->lcd_clk); - clk_disable(ctx->bus_clk); - - ctx->suspended = true; - } - - return 0; -} - static int __devinit fimd_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -952,30 +911,39 @@ static int __devexit fimd_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int fimd_suspend(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + int ret; if (pm_runtime_suspended(dev)) return 0; - /* - * do not use pm_runtime_suspend(). if pm_runtime_suspend() is - * called here, an error would be returned by that interface - * because the usage_count of pm runtime is more than 1. - */ - return fimd_power_on(ctx, false); + ret = pm_runtime_suspend(dev); + if (ret < 0) + return ret; + + return 0; } static int fimd_resume(struct device *dev) { - struct fimd_context *ctx = get_fimd_context(dev); + int ret; - /* - * if entered to sleep when lcd panel was on, the usage_count - * of pm runtime would still be 1 so in this case, fimd driver - * should be on directly not drawing on pm runtime interface. - */ - if (!pm_runtime_suspended(dev)) - return fimd_power_on(ctx, true); + ret = pm_runtime_resume(dev); + if (ret < 0) { + DRM_ERROR("failed to resume runtime pm.\n"); + return ret; + } + + pm_runtime_disable(dev); + + ret = pm_runtime_set_active(dev); + if (ret < 0) { + DRM_ERROR("failed to active runtime pm.\n"); + pm_runtime_enable(dev); + pm_runtime_suspend(dev); + return ret; + } + + pm_runtime_enable(dev); return 0; } @@ -988,16 +956,39 @@ static int fimd_runtime_suspend(struct device *dev) DRM_DEBUG_KMS("%s\n", __FILE__); - return fimd_power_on(ctx, false); + clk_disable(ctx->lcd_clk); + clk_disable(ctx->bus_clk); + + ctx->suspended = true; + return 0; } static int fimd_runtime_resume(struct device *dev) { struct fimd_context *ctx = get_fimd_context(dev); + int ret; DRM_DEBUG_KMS("%s\n", __FILE__); - return fimd_power_on(ctx, true); + ret = clk_enable(ctx->bus_clk); + if (ret < 0) + return ret; + + ret = clk_enable(ctx->lcd_clk); + if (ret < 0) { + clk_disable(ctx->bus_clk); + return ret; + } + + ctx->suspended = false; + + /* if vblank was enabled status, enable it again. */ + if (test_and_clear_bit(0, &ctx->irq_flags)) + fimd_enable_vblank(dev); + + fimd_apply(dev); + + return 0; } #endif diff --git a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c index 3429d3fd93f3..f48f7ce92f5f 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1116,8 +1116,8 @@ static int __devinit hdmi_probe(struct platform_device *pdev) err_iomap: iounmap(hdata->regs); err_req_region: - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); + release_resource(hdata->regs_res); + kfree(hdata->regs_res); err_resource: hdmi_resources_cleanup(hdata); err_data: @@ -1145,8 +1145,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev) iounmap(hdata->regs); - release_mem_region(hdata->regs_res->start, - resource_size(hdata->regs_res)); + release_resource(hdata->regs_res); + kfree(hdata->regs_res); /* hdmiphy i2c driver */ i2c_del_driver(&hdmiphy_driver); diff --git a/trunk/drivers/gpu/drm/gma500/framebuffer.c b/trunk/drivers/gpu/drm/gma500/framebuffer.c index 830dfdd6bf15..791c0ef1a65b 100644 --- a/trunk/drivers/gpu/drm/gma500/framebuffer.c +++ b/trunk/drivers/gpu/drm/gma500/framebuffer.c @@ -113,12 +113,12 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) void psbfb_suspend(struct drm_device *dev) { - struct drm_framebuffer *fb; + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); console_lock(); mutex_lock(&dev->mode_config.mutex); list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct psb_framebuffer *psbfb = to_psb_fb(fb); struct fb_info *info = psbfb->fbdev; fb_set_suspend(info, 1); drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); @@ -129,12 +129,12 @@ void psbfb_suspend(struct drm_device *dev) void psbfb_resume(struct drm_device *dev) { - struct drm_framebuffer *fb; + struct drm_framebuffer *fb = 0; + struct psb_framebuffer *psbfb = to_psb_fb(fb); console_lock(); mutex_lock(&dev->mode_config.mutex); list_for_each_entry(fb, &dev->mode_config.fb_list, head) { - struct psb_framebuffer *psbfb = to_psb_fb(fb); struct fb_info *info = psbfb->fbdev; fb_set_suspend(info, 0); drm_fb_helper_blank(FB_BLANK_UNBLANK, info); diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c index 7f4b4e10246e..f7c17b239833 100644 --- a/trunk/drivers/gpu/drm/i810/i810_dma.c +++ b/trunk/drivers/gpu/drm/i810/i810_dma.c @@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev) } /* Must be called with the lock held */ -static void i810_reclaim_buffers(struct drm_device *dev, +void i810_driver_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) { struct drm_device_dma *dma = dev->dma; @@ -1223,12 +1223,17 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) if (dev_priv->page_flipping) i810_do_cleanup_pageflip(dev); } -} -void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv) -{ - i810_reclaim_buffers(dev, file_priv); + if (file_priv->master && file_priv->master->lock.hw_lock) { + drm_idlelock_take(&file_priv->master->lock); + i810_driver_reclaim_buffers(dev, file_priv); + drm_idlelock_release(&file_priv->master->lock); + } else { + /* master disappeared, clean up stuff anyway and hope nothing + * goes wrong */ + i810_driver_reclaim_buffers(dev, file_priv); + } + } int i810_driver_dma_quiescent(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.c b/trunk/drivers/gpu/drm/i810/i810_drv.c index ec12f7dc717a..053f1ee58393 100644 --- a/trunk/drivers/gpu/drm/i810/i810_drv.c +++ b/trunk/drivers/gpu/drm/i810/i810_drv.c @@ -63,7 +63,6 @@ static struct drm_driver driver = { .lastclose = i810_driver_lastclose, .preclose = i810_driver_preclose, .device_is_agp = i810_driver_device_is_agp, - .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, .dma_quiescent = i810_driver_dma_quiescent, .ioctls = i810_ioctls, .fops = &i810_driver_fops, diff --git a/trunk/drivers/gpu/drm/i810/i810_drv.h b/trunk/drivers/gpu/drm/i810/i810_drv.h index c9339f481795..6e0acad9e0f5 100644 --- a/trunk/drivers/gpu/drm/i810/i810_drv.h +++ b/trunk/drivers/gpu/drm/i810/i810_drv.h @@ -116,14 +116,12 @@ typedef struct drm_i810_private { /* i810_dma.c */ extern int i810_driver_dma_quiescent(struct drm_device *dev); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); +void i810_driver_reclaim_buffers(struct drm_device *dev, + struct drm_file *file_priv); extern int i810_driver_load(struct drm_device *, unsigned long flags); extern void i810_driver_lastclose(struct drm_device *dev); extern void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); -extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, - struct drm_file *file_priv); extern int i810_driver_device_is_agp(struct drm_device *dev); extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index deaa657292b4..11807989f918 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -121,11 +121,11 @@ static const char *cache_level_str(int type) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", + seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), - obj->base.size / 1024, + obj->base.size, obj->base.read_domains, obj->base.write_domain, obj->last_rendering_seqno, @@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, " Size : %08x\n", ring->size); seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); - if (IS_GEN6(dev) || IS_GEN7(dev)) { + if (IS_GEN6(dev)) { seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); } @@ -1075,7 +1075,6 @@ static int gen6_drpc_info(struct seq_file *m) struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; u32 rpmodectl1, gt_core_status, rcctl1; - unsigned forcewake_count; int count=0, ret; @@ -1083,13 +1082,9 @@ static int gen6_drpc_info(struct seq_file *m) if (ret) return ret; - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - - if (forcewake_count) { - seq_printf(m, "RC information inaccurate because somebody " - "holds a forcewake reference \n"); + if (atomic_read(&dev_priv->forcewake_count)) { + seq_printf(m, "RC information inaccurate because userspace " + "holds a reference \n"); } else { /* NB: we cannot use forcewake, else we read the wrong values */ while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) @@ -1111,7 +1106,7 @@ static int gen6_drpc_info(struct seq_file *m) seq_printf(m, "SW control enabled: %s\n", yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == GEN6_RP_MEDIA_SW_MODE)); - seq_printf(m, "RC1e Enabled: %s\n", + seq_printf(m, "RC6 Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); seq_printf(m, "RC6 Enabled: %s\n", yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); @@ -1403,13 +1398,9 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; - unsigned forcewake_count; - - spin_lock_irq(&dev_priv->gt_lock); - forcewake_count = dev_priv->forcewake_count; - spin_unlock_irq(&dev_priv->gt_lock); - seq_printf(m, "forcewake count = %u\n", forcewake_count); + seq_printf(m, "forcewake count = %d\n", + atomic_read(&dev_priv->forcewake_count)); return 0; } @@ -1674,7 +1665,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) struct drm_i915_private *dev_priv = dev->dev_private; int ret; - if (INTEL_INFO(dev)->gen < 6) + if (!IS_GEN6(dev)) return 0; ret = mutex_lock_interruptible(&dev->struct_mutex); @@ -1691,7 +1682,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file) struct drm_device *dev = inode->i_private; struct drm_i915_private *dev_priv = dev->dev_private; - if (INTEL_INFO(dev)->gen < 6) + if (!IS_GEN6(dev)) return 0; /* diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index ddfe3d902b2a..5f4d5893e983 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -2045,7 +2045,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!IS_I945G(dev) && !IS_I945GM(dev)) pci_enable_msi(dev->pdev); - spin_lock_init(&dev_priv->gt_lock); spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->error_lock); spin_lock_init(&dev_priv->rps_lock); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 308f81913562..8f7187915b0d 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -368,12 +368,11 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) { - unsigned long irqflags; + WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (dev_priv->forcewake_count++ == 0) + /* Forcewake is atomic in case we get in here without the lock */ + if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) dev_priv->display.force_wake_get(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) @@ -393,12 +392,10 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) */ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) { - unsigned long irqflags; + WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - if (--dev_priv->forcewake_count == 0) + if (atomic_dec_and_test(&dev_priv->forcewake_count)) dev_priv->display.force_wake_put(dev_priv); - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); } void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) @@ -600,36 +597,9 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) static int gen6_do_reset(struct drm_device *dev, u8 flags) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret; - unsigned long irqflags; - /* Hold gt_lock across reset to prevent any register access - * with forcewake not set correctly - */ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); - - /* Reset the chip */ - - /* GEN6_GDRST is not in the gt power well, no need to check - * for fifo space for the write or forcewake the chip for - * the read - */ - I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); - - /* Spin waiting for the device to ack the reset request */ - ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); - - /* If reset with a user forcewake, try to restore, otherwise turn it off */ - if (dev_priv->forcewake_count) - dev_priv->display.force_wake_get(dev_priv); - else - dev_priv->display.force_wake_put(dev_priv); - - /* Restore fifo count */ - dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); - - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); - return ret; + I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); + return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); } /** @@ -673,6 +643,9 @@ int i915_reset(struct drm_device *dev, u8 flags) case 7: case 6: ret = gen6_do_reset(dev, flags); + /* If reset with a user forcewake, try to restore */ + if (atomic_read(&dev_priv->forcewake_count)) + __gen6_gt_force_wake_get(dev_priv); break; case 5: ret = ironlake_do_reset(dev, flags); @@ -954,14 +927,9 @@ MODULE_LICENSE("GPL and additional rights"); u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ u##x val = 0; \ if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ - unsigned long irqflags; \ - spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_get(dev_priv); \ + gen6_gt_force_wake_get(dev_priv); \ val = read##y(dev_priv->regs + reg); \ - if (dev_priv->forcewake_count == 0) \ - dev_priv->display.force_wake_put(dev_priv); \ - spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ + gen6_gt_force_wake_put(dev_priv); \ } else { \ val = read##y(dev_priv->regs + reg); \ } \ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 9689ca38b2b3..602bc80baabb 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -288,13 +288,7 @@ typedef struct drm_i915_private { int relative_constants_mode; void __iomem *regs; - /** gt_fifo_count and the subsequent register write are synchronized - * with dev->struct_mutex. */ - unsigned gt_fifo_count; - /** forcewake_count is protected by gt_lock */ - unsigned forcewake_count; - /** gt_lock is also taken in irq contexts. */ - struct spinlock gt_lock; + u32 gt_fifo_count; struct intel_gmbus { struct i2c_adapter adapter; @@ -747,6 +741,8 @@ typedef struct drm_i915_private { struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; + + atomic_t forcewake_count; } drm_i915_private_t; enum i915_cache_level { diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 5bd4361ea84d..5d433fc11ace 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -1751,8 +1751,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev) INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); I915_WRITE(HWSTAM, 0xeffe); - - if (IS_GEN6(dev)) { + if (IS_GEN6(dev) || IS_GEN7(dev)) { /* Workaround stalls observed on Sandy Bridge GPUs by * making the blitter command streamer generate a * write to the Hardware Status Page for diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 2b5eb229ff2c..7886e4fb60e3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -28,19 +28,14 @@ #include "drm.h" #include "i915_drm.h" #include "intel_drv.h" -#include "i915_reg.h" static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; u32 dpll_reg; - /* On IVB, 3rd pipe shares PLL with another one */ - if (pipe > 1) - return false; - if (HAS_PCH_SPLIT(dev)) - dpll_reg = PCH_DPLL(pipe); + dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B; else dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; @@ -827,7 +822,7 @@ int i915_save_state(struct drm_device *dev) if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); - if (INTEL_INFO(dev)->gen >= 6) + if (IS_GEN6(dev)) gen6_disable_rps(dev); /* Cache mode state */ @@ -886,7 +881,7 @@ int i915_restore_state(struct drm_device *dev) intel_init_emon(dev); } - if (INTEL_INFO(dev)->gen >= 6) { + if (IS_GEN6(dev)) { gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } diff --git a/trunk/drivers/gpu/drm/i915/intel_bios.h b/trunk/drivers/gpu/drm/i915/intel_bios.h index dbda6e3bdf07..8af3735e27c6 100644 --- a/trunk/drivers/gpu/drm/i915/intel_bios.h +++ b/trunk/drivers/gpu/drm/i915/intel_bios.h @@ -467,12 +467,8 @@ struct edp_link_params { struct bdb_edp { struct edp_power_seq power_seqs[16]; u32 color_depth; - struct edp_link_params link_params[16]; u32 sdrrs_msa_timing_delay; - - /* ith bit indicates enabled/disabled for (i+1)th panel */ - u16 edp_s3d_feature; - u16 edp_t3_optimization; + struct edp_link_params link_params[16]; } __attribute__ ((packed)); void intel_setup_bios(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index dd729d46a61f..fee0ad02c6d0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -24,7 +24,6 @@ * Eric Anholt */ -#include #include #include #include "drmP.h" @@ -541,24 +540,6 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { .destroy = intel_encoder_destroy, }; -static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident); - return 1; -} - -static const struct dmi_system_id intel_no_crt[] = { - { - .callback = intel_no_crt_dmi_callback, - .ident = "ACER ZGB", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ACER"), - DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), - }, - }, - { } -}; - void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; @@ -566,10 +547,6 @@ void intel_crt_init(struct drm_device *dev) struct intel_connector *intel_connector; struct drm_i915_private *dev_priv = dev->dev_private; - /* Skip machines without VGA that falsely report hotplug events */ - if (dmi_check_system(intel_no_crt)) - return; - crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); if (!crt) return; diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index b3b51c43dad0..2a3f707caab8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -5808,15 +5808,12 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, if (is_lvds) { temp = I915_READ(PCH_LVDS); temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (HAS_PCH_CPT(dev)) { - temp &= ~PORT_TRANS_SEL_MASK; + if (HAS_PCH_CPT(dev)) temp |= PORT_TRANS_SEL_CPT(pipe); - } else { - if (pipe == 1) - temp |= LVDS_PIPEB_SELECT; - else - temp &= ~LVDS_PIPEB_SELECT; - } + else if (pipe == 1) + temp |= LVDS_PIPEB_SELECT; + else + temp &= ~LVDS_PIPEB_SELECT; /* set the corresponsding LVDS_BORDER bit */ temp |= dev_priv->lvds_border_bits; @@ -9028,9 +9025,12 @@ void intel_modeset_init(struct drm_device *dev) for (i = 0; i < dev_priv->num_pipe; i++) { intel_crtc_init(dev, i); - ret = intel_plane_init(dev, i); - if (ret) - DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); + if (HAS_PCH_SPLIT(dev)) { + ret = intel_plane_init(dev, i); + if (ret) + DRM_ERROR("plane %d init failed: %d\n", + i, ret); + } } /* Just disable it once at startup */ diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 798f6e1aa544..e44191132ac4 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -708,14 +708,6 @@ static const struct dmi_system_id intel_no_lvds[] = { }, }, { - .callback = intel_no_lvds_dmi_callback, - .ident = "Clientron E830", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), - DMI_MATCH(DMI_PRODUCT_NAME, "E830"), - }, - }, - { .callback = intel_no_lvds_dmi_callback, .ident = "Asus EeeBox PC EB1007", .matches = { diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 1ab842c6032e..77e729d4e4f0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -635,19 +635,6 @@ render_ring_add_request(struct intel_ring_buffer *ring, return 0; } -static u32 -gen6_ring_get_seqno(struct intel_ring_buffer *ring) -{ - struct drm_device *dev = ring->dev; - - /* Workaround to force correct ordering between irq and seqno writes on - * ivb (and maybe also on snb) by reading from a CS register (like - * ACTHD) before reading the status page. */ - if (IS_GEN7(dev)) - intel_ring_get_active_head(ring); - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); -} - static u32 ring_get_seqno(struct intel_ring_buffer *ring) { @@ -804,6 +791,17 @@ ring_add_request(struct intel_ring_buffer *ring, return 0; } +static bool +gen7_blt_ring_get_irq(struct intel_ring_buffer *ring) +{ + /* The BLT ring on IVB appears to have broken synchronization + * between the seqno write and the interrupt, so that the + * interrupt appears first. Returning false here makes + * i915_wait_request() do a polling loop, instead. + */ + return false; +} + static bool gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) { @@ -813,12 +811,6 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) if (!dev->irq_enabled) return false; - /* It looks like we need to prevent the gt from suspending while waiting - * for an notifiy irq, otherwise irqs seem to get lost on at least the - * blt/bsd rings on ivb. */ - if (IS_GEN7(dev)) - gen6_gt_force_wake_get(dev_priv); - spin_lock(&ring->irq_lock); if (ring->irq_refcount++ == 0) { ring->irq_mask &= ~rflag; @@ -843,9 +835,6 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) ironlake_disable_irq(dev_priv, gflag); } spin_unlock(&ring->irq_lock); - - if (IS_GEN7(dev)) - gen6_gt_force_wake_put(dev_priv); } static bool @@ -1352,7 +1341,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .write_tail = gen6_bsd_ring_write_tail, .flush = gen6_ring_flush, .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, + .get_seqno = ring_get_seqno, .irq_get = gen6_bsd_ring_get_irq, .irq_put = gen6_bsd_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, @@ -1487,7 +1476,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { .write_tail = ring_write_tail, .flush = blt_ring_flush, .add_request = gen6_add_request, - .get_seqno = gen6_ring_get_seqno, + .get_seqno = ring_get_seqno, .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, @@ -1510,7 +1499,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->flush = gen6_render_ring_flush; ring->irq_get = gen6_render_ring_get_irq; ring->irq_put = gen6_render_ring_put_irq; - ring->get_seqno = gen6_ring_get_seqno; } else if (IS_GEN5(dev)) { ring->add_request = pc_render_add_request; ring->get_seqno = pc_render_get_seqno; @@ -1589,5 +1577,8 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) *ring = gen6_blt_ring; + if (IS_GEN7(dev)) + ring->irq_get = gen7_blt_ring_get_irq; + return intel_init_ring_buffer(dev, ring); } diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index e334ec33a47d..f7b9268df266 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -1066,13 +1066,15 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the SDVO control regs. */ if (INTEL_INFO(dev)->gen >= 4) { - /* The real mode polarity is set by the SDVO commands, using - * struct intel_sdvo_dtd. */ - sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; + sdvox = 0; if (intel_sdvo->is_hdmi) sdvox |= intel_sdvo->color_range; if (INTEL_INFO(dev)->gen < 5) sdvox |= SDVO_BORDER_ENABLE; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + sdvox |= SDVO_VSYNC_ACTIVE_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + sdvox |= SDVO_HSYNC_ACTIVE_HIGH; } else { sdvox = I915_READ(intel_sdvo->sdvo_reg); switch (intel_sdvo->sdvo_reg) { diff --git a/trunk/drivers/gpu/drm/i915/intel_sprite.c b/trunk/drivers/gpu/drm/i915/intel_sprite.c index 2288abf88cce..d13989fda501 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sprite.c +++ b/trunk/drivers/gpu/drm/i915/intel_sprite.c @@ -466,8 +466,10 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); - if (ret) + if (ret) { + DRM_ERROR("failed to pin object\n"); goto out_unlock; + } intel_plane->obj = obj; @@ -630,8 +632,10 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) unsigned long possible_crtcs; int ret; - if (!(IS_GEN6(dev) || IS_GEN7(dev))) + if (!(IS_GEN6(dev) || IS_GEN7(dev))) { + DRM_ERROR("new plane code only for SNB+\n"); return -ENODEV; + } intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); if (!intel_plane) diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 1571be37ce3e..f3c6a9a8b081 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ @@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-443", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ @@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { { .name = "NTSC-J", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { { .name = "PAL-M", .clock = 108000, - .refresh = 59940, + .refresh = 29970, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL-N", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ .name = "PAL", .clock = 108000, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_8X, .component_only = 0, @@ -673,6 +673,78 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, + { + .name = "480p@59.94Hz", + .clock = 107520, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 857, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 479, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = "480p@60Hz", + .clock = 107520, + .refresh = 60000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 122, + .hblank_start = 842, .htotal = 856, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 12, .vsync_start_f2 = 12, + .vsync_len = 12, + + .veq_ena = false, + + .vi_end_f1 = 44, .vi_end_f2 = 44, + .nbr_end = 479, + + .burst_ena = false, + + .filter_table = filter_table, + }, + { + .name = "576p", + .clock = 107520, + .refresh = 50000, + .oversample = TV_OVERSAMPLE_4X, + .component_only = 1, + + .hsync_end = 64, .hblank_end = 139, + .hblank_start = 859, .htotal = 863, + + .progressive = true, .trilevel_sync = false, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = false, + + .vi_end_f1 = 48, .vi_end_f2 = 48, + .nbr_end = 575, + + .burst_ena = false, + + .filter_table = filter_table, + }, { .name = "720p@60Hz", .clock = 148800, @@ -697,6 +769,30 @@ static const struct tv_mode tv_modes[] = { .filter_table = filter_table, }, + { + .name = "720p@59.94Hz", + .clock = 148800, + .refresh = 59940, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 80, .hblank_end = 300, + .hblank_start = 1580, .htotal = 1651, + + .progressive = true, .trilevel_sync = true, + + .vsync_start_f1 = 10, .vsync_start_f2 = 10, + .vsync_len = 10, + + .veq_ena = false, + + .vi_end_f1 = 29, .vi_end_f2 = 29, + .nbr_end = 719, + + .burst_ena = false, + + .filter_table = filter_table, + }, { .name = "720p@50Hz", .clock = 148800, @@ -725,7 +821,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@50Hz", .clock = 148800, - .refresh = 50000, + .refresh = 25000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -751,7 +847,7 @@ static const struct tv_mode tv_modes[] = { { .name = "1080i@60Hz", .clock = 148800, - .refresh = 60000, + .refresh = 30000, .oversample = TV_OVERSAMPLE_2X, .component_only = 1, @@ -772,6 +868,32 @@ static const struct tv_mode tv_modes[] = { .burst_ena = false, + .filter_table = filter_table, + }, + { + .name = "1080i@59.94Hz", + .clock = 148800, + .refresh = 29970, + .oversample = TV_OVERSAMPLE_2X, + .component_only = 1, + + .hsync_end = 88, .hblank_end = 235, + .hblank_start = 2155, .htotal = 2201, + + .progressive = false, .trilevel_sync = true, + + .vsync_start_f1 = 4, .vsync_start_f2 = 5, + .vsync_len = 10, + + .veq_ena = true, .veq_start_f1 = 4, + .veq_start_f2 = 4, .veq_len = 10, + + + .vi_end_f1 = 21, .vi_end_f2 = 22, + .nbr_end = 539, + + .burst_ena = false, + .filter_table = filter_table, }, }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h index a37c31e358aa..1e382ad5a2b8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.h @@ -54,10 +54,9 @@ struct bit_entry { int bit_table(struct drm_device *, u8 id, struct bit_entry *); enum dcb_gpio_tag { - DCB_GPIO_PANEL_POWER = 0x01, - DCB_GPIO_TVDAC0 = 0x0c, + DCB_GPIO_TVDAC0 = 0xc, DCB_GPIO_TVDAC1 = 0x2d, - DCB_GPIO_PWM_FAN = 0x09, + DCB_GPIO_PWM_FAN = 0x9, DCB_GPIO_FAN_SENSE = 0x3d, DCB_GPIO_UNUSED = 0xff }; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c index 795a9e3c990a..3cb52bc52b21 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_display.c @@ -219,16 +219,6 @@ nouveau_display_init(struct drm_device *dev) if (ret) return ret; - /* power on internal panel if it's not already. the init tables of - * some vbios default this to off for some reason, causing the - * panel to not work after resume - */ - if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) { - nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true); - msleep(300); - } - - /* enable polling for external displays */ drm_kms_helper_poll_enable(dev); /* enable hotplug interrupts */ diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c index 81d7962e7252..e4a7cfe7898d 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n"); int nouveau_ctxfw; module_param_named(ctxfw, nouveau_ctxfw, int, 0400); -MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n"); +MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n"); int nouveau_mxmdcb = 1; module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c index 7ce3fde40743..5f0bc57fdaab 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -379,25 +379,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, return 0; } -static int -validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) -{ - struct nouveau_fence *fence = NULL; - int ret = 0; - - spin_lock(&nvbo->bo.bdev->fence_lock); - if (nvbo->bo.sync_obj) - fence = nouveau_fence_ref(nvbo->bo.sync_obj); - spin_unlock(&nvbo->bo.bdev->fence_lock); - - if (fence) { - ret = nouveau_fence_sync(fence, chan); - nouveau_fence_unref(&fence); - } - - return ret; -} - static int validate_list(struct nouveau_channel *chan, struct list_head *list, struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) @@ -412,7 +393,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, list_for_each_entry(nvbo, list, entry) { struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail pre-validate sync\n"); return ret; @@ -435,7 +416,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, return ret; } - ret = validate_sync(chan, nvbo); + ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); if (unlikely(ret)) { NV_ERROR(dev, "fail post-validate sync\n"); return ret; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c index e5a64f0f4cb7..8bccddf4eff0 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_mxm.c @@ -656,16 +656,7 @@ nouveau_mxm_init(struct drm_device *dev) if (mxm_shadow(dev, mxm[0])) { MXM_MSG(dev, "failed to locate valid SIS\n"); -#if 0 - /* we should, perhaps, fall back to some kind of limited - * mode here if the x86 vbios hasn't already done the - * work for us (so we prevent loading with completely - * whacked vbios tables). - */ return -EINVAL; -#else - return 0; -#endif } MXM_MSG(dev, "MXMS Version %d.%d\n", diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c index ec5481dfcd82..03937212e9d8 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_pm.c @@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_pm_state *info; struct pll_lims pll; - int clk, ret = -EINVAL; + int ret = -EINVAL; int N, M, P1, P2; - u32 out; + u32 clk, out; if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac) diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 742f17f009a9..891935271d34 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1184,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, @@ -1353,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, - target_fb->height); + crtc->mode.vdisplay); x &= ~3; y &= ~1; WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, diff --git a/trunk/drivers/gpu/drm/radeon/atombios_dp.c b/trunk/drivers/gpu/drm/radeon/atombios_dp.c index 552b436451fd..a71557ce01dc 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_dp.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_dp.c @@ -564,21 +564,9 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, ENCODER_OBJECT_ID_NUTMEG) panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == - ENCODER_OBJECT_ID_TRAVIS) { - u8 id[6]; - int i; - for (i = 0; i < 6; i++) - id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); - if (id[0] == 0x73 && - id[1] == 0x69 && - id[2] == 0x76 && - id[3] == 0x61 && - id[4] == 0x72 && - id[5] == 0x54) - panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; - else - panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; - } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + ENCODER_OBJECT_ID_TRAVIS) + panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); if (tmp & 1) panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c index accc032c103f..d996f4381130 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -468,42 +468,27 @@ set_default_state(struct radeon_device *rdev) radeon_ring_write(ring, sq_stack_resource_mgmt_2); } -#define I2F_MAX_BITS 15 -#define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) -#define I2F_SHIFT (24 - I2F_MAX_BITS) - -/* - * Converts unsigned integer into 32-bit IEEE floating point representation. - * Conversion is not universal and only works for the range from 0 - * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between - * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, - * I2F_MAX_BITS can be increased, but that will add to the loop iterations - * and slow us down. Conversion is done by shifting the input and counting - * down until the first 1 reaches bit position 23. The resulting counter - * and the shifted input are, respectively, the exponent and the fraction. - * The sign is always zero. - */ static uint32_t i2f(uint32_t input) { u32 result, i, exponent, fraction; - WARN_ON_ONCE(input > I2F_MAX_INPUT); - - if ((input & I2F_MAX_INPUT) == 0) - result = 0; + if ((input & 0x3fff) == 0) + result = 0; /* 0 is a special case */ else { - exponent = 126 + I2F_MAX_BITS; - fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; - - for (i = 0; i < I2F_MAX_BITS; i++) { + exponent = 140; /* exponent biased by 127; */ + fraction = (input & 0x3fff) << 10; /* cheat and only + handle numbers below 2^^15 */ + for (i = 0; i < 14; i++) { if (fraction & 0x800000) break; else { - fraction = fraction << 1; + fraction = fraction << 1; /* keep + shifting left until top bit = 1 */ exponent = exponent - 1; } } - result = exponent << 23 | (fraction & 0x7fffff); + result = exponent << 23 | (fraction & 0x7fffff); /* mask + off top bit; assumed 1 */ } return result; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 98724fcb0088..13ac63ba6075 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -59,9 +59,8 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, obj = (union acpi_object *)buffer.pointer; memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); - len = obj->buffer.length; kfree(buffer.pointer); - return len; + return obj->buffer.length; } bool radeon_atrm_supported(struct pci_dev *pdev) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 49f7cb7e226b..cec51a5b69dd 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -883,8 +883,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - drm_kms_helper_poll_disable(dev); - /* turn off display hw */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); @@ -974,8 +972,6 @@ int radeon_resume_kms(struct drm_device *dev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); } - - drm_kms_helper_poll_enable(dev); return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 98a8ad680109..7bb1b079f480 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -897,7 +897,6 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; i2c->dev = dev; i2c_set_adapdata(&i2c->adapter, i2c); if (rec->mm_i2c || @@ -958,7 +957,6 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, i2c->rec = *rec; i2c->adapter.owner = THIS_MODULE; i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; i2c->dev = dev; snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon aux bus %s", name); diff --git a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b66ef0e3cde1..0af6ebdf205d 100644 --- a/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/trunk/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, unsigned int *handle) { if (handle) - *handle = 0; + handle = 0; return 0; } diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index 6dbfd3e516e4..92f949767ece 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -283,11 +283,11 @@ static inline long temp_from_reg(u8 reg) static inline u8 temp_to_reg(long val) { - if (val <= 0) - return 0; - if (val >= 1000 * 0xff) - return 0xff; - return (val + 500) / 1000; + if (val < 0) + val = 0; + else if (val > 1000 * 0xff) + val = 0xff; + return ((val + 500) / 1000); } /* diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c index 91fdd1fe18b0..6ddeae049058 100644 --- a/trunk/drivers/hwmon/sht15.c +++ b/trunk/drivers/hwmon/sht15.c @@ -883,7 +883,7 @@ static int sht15_invalidate_voltage(struct notifier_block *nb, static int __devinit sht15_probe(struct platform_device *pdev) { - int ret; + int ret = 0; struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL); u8 status = 0; @@ -901,7 +901,6 @@ static int __devinit sht15_probe(struct platform_device *pdev) init_waitqueue_head(&data->wait_queue); if (pdev->dev.platform_data == NULL) { - ret = -EINVAL; dev_err(&pdev->dev, "no platform data supplied\n"); goto err_free_data; } diff --git a/trunk/drivers/hwmon/w83627ehf.c b/trunk/drivers/hwmon/w83627ehf.c index 2dfae7d7cc5b..0e0af0445222 100644 --- a/trunk/drivers/hwmon/w83627ehf.c +++ b/trunk/drivers/hwmon/w83627ehf.c @@ -1319,7 +1319,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, { struct w83627ehf_data *data = dev_get_drvdata(dev); struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); - struct w83627ehf_sio_data *sio_data = dev->platform_data; int nr = sensor_attr->index; unsigned long val; int err; @@ -1331,11 +1330,6 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr, if (val > 1) return -EINVAL; - - /* On NCT67766F, DC mode is only supported for pwm1 */ - if (sio_data->kind == nct6776 && nr && val != 1) - return -EINVAL; - mutex_lock(&data->update_lock); reg = w83627ehf_read_value(data, W83627EHF_REG_PWM_ENABLE[nr]); data->pwm_mode[nr] = val; diff --git a/trunk/drivers/infiniband/core/ucma.c b/trunk/drivers/infiniband/core/ucma.c index 5034a87cc72d..b37b0c02a7b9 100644 --- a/trunk/drivers/infiniband/core/ucma.c +++ b/trunk/drivers/infiniband/core/ucma.c @@ -808,12 +808,9 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, return PTR_ERR(ctx); if (cmd.conn_param.valid) { + ctx->uid = cmd.uid; ucma_copy_conn_param(&conn_param, &cmd.conn_param); - mutex_lock(&file->mut); ret = rdma_accept(ctx->cm_id, &conn_param); - if (!ret) - ctx->uid = cmd.uid; - mutex_unlock(&file->mut); } else ret = rdma_accept(ctx->cm_id, NULL); diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index 4d27e4c3fe34..b930da4c0c63 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -1485,7 +1485,6 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, qp->event_handler = attr.event_handler; qp->qp_context = attr.qp_context; qp->qp_type = attr.qp_type; - atomic_set(&qp->usecnt, 0); atomic_inc(&pd->usecnt); atomic_inc(&attr.send_cq->usecnt); if (attr.recv_cq) diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c index 575b78045aaf..602b1bd723a9 100644 --- a/trunk/drivers/infiniband/core/verbs.c +++ b/trunk/drivers/infiniband/core/verbs.c @@ -421,7 +421,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, qp->uobject = NULL; qp->qp_type = qp_init_attr->qp_type; - atomic_set(&qp->usecnt, 0); if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { qp->event_handler = __ib_shared_qp_event_handler; qp->qp_context = qp; @@ -431,6 +430,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, qp->xrcd = qp_init_attr->xrcd; atomic_inc(&qp_init_attr->xrcd->usecnt); INIT_LIST_HEAD(&qp->open_list); + atomic_set(&qp->usecnt, 0); real_qp = qp; qp = __ib_open_qp(real_qp, qp_init_attr->event_handler, diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index a4de9d58e9b4..b7d4216db3c3 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -89,7 +89,7 @@ static int create_file(const char *name, umode_t mode, error = ipathfs_mknod(parent->d_inode, *dentry, mode, fops, data); else - error = PTR_ERR(*dentry); + error = PTR_ERR(dentry); mutex_unlock(&parent->d_inode->i_mutex); return error; diff --git a/trunk/drivers/infiniband/hw/mlx4/mad.c b/trunk/drivers/infiniband/hw/mlx4/mad.c index 259b0670b51c..95c94d8f0254 100644 --- a/trunk/drivers/infiniband/hw/mlx4/mad.c +++ b/trunk/drivers/infiniband/hw/mlx4/mad.c @@ -257,9 +257,12 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, return IB_MAD_RESULT_SUCCESS; /* - * Don't process SMInfo queries -- the SMA can't handle them. + * Don't process SMInfo queries or vendor-specific + * MADs -- the SMA can't handle them. */ - if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO) + if (in_mad->mad_hdr.attr_id == IB_SMP_ATTR_SM_INFO || + ((in_mad->mad_hdr.attr_id & IB_SMP_ATTR_VENDOR_MASK) == + IB_SMP_ATTR_VENDOR_MASK)) return IB_MAD_RESULT_SUCCESS; } else if (in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT || in_mad->mad_hdr.mgmt_class == MLX4_IB_VENDOR_CLASS1 || diff --git a/trunk/drivers/infiniband/hw/nes/nes.c b/trunk/drivers/infiniband/hw/nes/nes.c index 7140199f562e..7013da5e9eda 100644 --- a/trunk/drivers/infiniband/hw/nes/nes.c +++ b/trunk/drivers/infiniband/hw/nes/nes.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/nes/nes.h b/trunk/drivers/infiniband/hw/nes/nes.h index c438e4691b3c..568b4f11380a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes.h +++ b/trunk/drivers/infiniband/hw/nes/nes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.c b/trunk/drivers/infiniband/hw/nes/nes_cm.c index a4972abedef1..425065b36b8c 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.c +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -233,7 +233,6 @@ static int send_mpa_reject(struct nes_cm_node *cm_node) u8 *start_ptr = &start_addr; u8 **start_buff = &start_ptr; u16 buff_len = 0; - struct ietf_mpa_v1 *mpa_frame; skb = dev_alloc_skb(MAX_CM_BUFFER); if (!skb) { @@ -243,8 +242,6 @@ static int send_mpa_reject(struct nes_cm_node *cm_node) /* send an MPA reject frame */ cm_build_mpa_frame(cm_node, start_buff, &buff_len, NULL, MPA_KEY_REPLY); - mpa_frame = (struct ietf_mpa_v1 *)*start_buff; - mpa_frame->flags |= IETF_MPA_FLAGS_REJECT; form_cm_frame(skb, cm_node, NULL, 0, *start_buff, buff_len, SET_ACK | SET_FIN); cm_node->state = NES_CM_STATE_FIN_WAIT1; @@ -1363,7 +1360,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, neigh->ha, ETH_ALEN)) { /* Mac address same as in nes_arp_table */ - goto out; + ip_rt_put(rt); + return rc; } nes_manage_arp_cache(nesvnic->netdev, @@ -1379,8 +1377,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi neigh_event_send(neigh, NULL); } } - -out: rcu_read_unlock(); ip_rt_put(rt); return rc; diff --git a/trunk/drivers/infiniband/hw/nes/nes_cm.h b/trunk/drivers/infiniband/hw/nes/nes_cm.h index 4646e6666087..bdfa1fbb35fc 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_cm.h +++ b/trunk/drivers/infiniband/hw/nes/nes_cm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_context.h b/trunk/drivers/infiniband/hw/nes/nes_context.h index a69eef16d72d..b4393a16099d 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_context.h +++ b/trunk/drivers/infiniband/hw/nes/nes_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.c b/trunk/drivers/infiniband/hw/nes/nes_hw.c index d42c9f435b1b..055f4b545df0 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.c +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_hw.h b/trunk/drivers/infiniband/hw/nes/nes_hw.h index d748e4b31b8d..0b590e152c6a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_hw.h +++ b/trunk/drivers/infiniband/hw/nes/nes_hw.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. +* Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.c b/trunk/drivers/infiniband/hw/nes/nes_mgt.c index 3ba7be369452..b3b2a240c6e9 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_mgt.c +++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved. + * Copyright (c) 2006 - 2009 Intel-NE, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_mgt.h b/trunk/drivers/infiniband/hw/nes/nes_mgt.h index 4f7f701c4a81..8c8af254555a 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_mgt.h +++ b/trunk/drivers/infiniband/hw/nes/nes_mgt.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2006 - 2011 Intel-NE, Inc. All rights reserved. +* Copyright (c) 2010 Intel-NE, Inc. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_nic.c b/trunk/drivers/infiniband/hw/nes/nes_nic.c index f3a3ecf8d09e..4b3fa711a247 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_nic.c +++ b/trunk/drivers/infiniband/hw/nes/nes_nic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_user.h b/trunk/drivers/infiniband/hw/nes/nes_user.h index 4926de744488..71e133ab209b 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_user.h +++ b/trunk/drivers/infiniband/hw/nes/nes_user.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Topspin Communications. All rights reserved. * Copyright (c) 2005 Cisco Systems. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. diff --git a/trunk/drivers/infiniband/hw/nes/nes_utils.c b/trunk/drivers/infiniband/hw/nes/nes_utils.c index e98f4fc0b768..8b4c2ff54888 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_utils.c +++ b/trunk/drivers/infiniband/hw/nes/nes_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.c b/trunk/drivers/infiniband/hw/nes/nes_verbs.c index 0927b5cc65d3..5095bc41c6cc 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.c +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -3427,8 +3427,6 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_FMR_WQE_LENGTH_LOW_IDX, ib_wr->wr.fast_reg.length); - set_wqe_32bit_value(wqe->wqe_words, - NES_IWARP_SQ_FMR_WQE_LENGTH_HIGH_IDX, 0); set_wqe_32bit_value(wqe->wqe_words, NES_IWARP_SQ_FMR_WQE_MR_STAG_IDX, ib_wr->wr.fast_reg.rkey); @@ -3726,7 +3724,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) entry->opcode = IB_WC_SEND; break; case NES_IWARP_SQ_OP_LOCINV: - entry->opcode = IB_WC_LOCAL_INV; + entry->opcode = IB_WR_LOCAL_INV; break; case NES_IWARP_SQ_OP_FAST_REG: entry->opcode = IB_WC_FAST_REG_MR; diff --git a/trunk/drivers/infiniband/hw/nes/nes_verbs.h b/trunk/drivers/infiniband/hw/nes/nes_verbs.h index 0eff7c44d76b..fe6b6e92fa90 100644 --- a/trunk/drivers/infiniband/hw/nes/nes_verbs.h +++ b/trunk/drivers/infiniband/hw/nes/nes_verbs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 - 2011 Intel Corporation. All rights reserved. + * Copyright (c) 2006 - 2009 Intel Corporation. All rights reserved. * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved. * * This software is available to you under a choice of one of two diff --git a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c index d0c64d514813..4f18e2d332df 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/trunk/drivers/infiniband/hw/qib/qib_iba6120.c @@ -2105,7 +2105,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd) dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev, dd->rcd[0]->rcvhdrq_size, &dd->cspec->dummy_hdrq_phys, - GFP_ATOMIC | __GFP_COMP); + GFP_KERNEL | __GFP_COMP); if (!dd->cspec->dummy_hdrq) { qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n"); /* fallback to just 0'ing */ diff --git a/trunk/drivers/infiniband/hw/qib/qib_pcie.c b/trunk/drivers/infiniband/hw/qib/qib_pcie.c index 0fde788e1100..f695061d688e 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_pcie.c +++ b/trunk/drivers/infiniband/hw/qib/qib_pcie.c @@ -560,7 +560,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd) * BIOS may not set PCIe bus-utilization parameters for best performance. * Check and optionally adjust them to maximize our throughput. */ -static int qib_pcie_caps; +static int qib_pcie_caps = 0x51; module_param_named(pcie_caps, qib_pcie_caps, int, S_IRUGO); MODULE_PARM_DESC(pcie_caps, "Max PCIe tuning: Payload (0..3), ReadReq (4..7)"); diff --git a/trunk/drivers/mfd/mcp-core.c b/trunk/drivers/mfd/mcp-core.c index 86cc3f7841cd..63be60bc3455 100644 --- a/trunk/drivers/mfd/mcp-core.c +++ b/trunk/drivers/mfd/mcp-core.c @@ -26,9 +26,35 @@ #define to_mcp(d) container_of(d, struct mcp, attached_device) #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) +static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, + const char *codec) +{ + while (id->name[0]) { + if (strcmp(codec, id->name) == 0) + return id; + id++; + } + return NULL; +} + +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) +{ + const struct mcp_driver *driver = + to_mcp_driver(mcp->attached_device.driver); + + return mcp_match_id(driver->id_table, mcp->codec); +} +EXPORT_SYMBOL(mcp_get_device_id); + static int mcp_bus_match(struct device *dev, struct device_driver *drv) { - return 1; + const struct mcp *mcp = to_mcp(dev); + const struct mcp_driver *driver = to_mcp_driver(drv); + + if (driver->id_table) + return !!mcp_match_id(driver->id_table, mcp->codec); + + return 0; } static int mcp_bus_probe(struct device *dev) @@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) return ret; } +static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct mcp *mcp = to_mcp(dev); + + add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); + return 0; +} + static struct bus_type mcp_bus_type = { .name = "mcp", .match = mcp_bus_match, + .uevent = mcp_bus_uevent, .probe = mcp_bus_probe, .remove = mcp_bus_remove, .suspend = mcp_bus_suspend, @@ -93,11 +128,9 @@ static struct bus_type mcp_bus_type = { */ void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div) { - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); mcp->ops->set_telecom_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_set_telecom_divisor); @@ -110,11 +143,9 @@ EXPORT_SYMBOL(mcp_set_telecom_divisor); */ void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div) { - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); mcp->ops->set_audio_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_set_audio_divisor); @@ -167,11 +198,10 @@ EXPORT_SYMBOL(mcp_reg_read); */ void mcp_enable(struct mcp *mcp) { - unsigned long flags; - spin_lock_irqsave(&mcp->lock, flags); + spin_lock_irq(&mcp->lock); if (mcp->use_count++ == 0) mcp->ops->enable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); + spin_unlock_irq(&mcp->lock); } EXPORT_SYMBOL(mcp_enable); @@ -217,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) } EXPORT_SYMBOL(mcp_host_alloc); -int mcp_host_register(struct mcp *mcp) +int mcp_host_register(struct mcp *mcp, void *pdata) { + if (!mcp->codec) + return -EINVAL; + + mcp->attached_device.platform_data = pdata; dev_set_name(&mcp->attached_device, "mcp0"); + request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); return device_register(&mcp->attached_device); } EXPORT_SYMBOL(mcp_host_register); diff --git a/trunk/drivers/mfd/mcp-sa11x0.c b/trunk/drivers/mfd/mcp-sa11x0.c index 02c53a0766c4..9adc2eb69492 100644 --- a/trunk/drivers/mfd/mcp-sa11x0.c +++ b/trunk/drivers/mfd/mcp-sa11x0.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,12 +27,19 @@ #include #include -#include - +/* Register offsets */ +#define MCCR0 0x00 +#define MCDR0 0x08 +#define MCDR1 0x0C +#define MCDR2 0x10 +#define MCSR 0x18 +#define MCCR1 0x00 struct mcp_sa11x0 { - u32 mccr0; - u32 mccr1; + u32 mccr0; + u32 mccr1; + unsigned char *mccr0_base; + unsigned char *mccr1_base; }; #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) @@ -39,25 +47,25 @@ struct mcp_sa11x0 { static void mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) { - unsigned int mccr0; + struct mcp_sa11x0 *priv = priv(mcp); divisor /= 32; - mccr0 = Ser4MCCR0 & ~0x00007f00; - mccr0 |= divisor << 8; - Ser4MCCR0 = mccr0; + priv->mccr0 &= ~0x00007f00; + priv->mccr0 |= divisor << 8; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } static void mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) { - unsigned int mccr0; + struct mcp_sa11x0 *priv = priv(mcp); divisor /= 32; - mccr0 = Ser4MCCR0 & ~0x0000007f; - mccr0 |= divisor; - Ser4MCCR0 = mccr0; + priv->mccr0 &= ~0x0000007f; + priv->mccr0 |= divisor; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } /* @@ -71,12 +79,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) { int ret = -ETIME; int i; + u32 mcpreg; + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); + mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff); + __raw_writel(mcpreg, priv->mccr0_base + MCDR2); for (i = 0; i < 2; i++) { udelay(mcp->rw_timeout); - if (Ser4MCSR & MCSR_CWC) { + mcpreg = __raw_readl(priv->mccr0_base + MCSR); + if (mcpreg & MCSR_CWC) { ret = 0; break; } @@ -97,13 +109,18 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) { int ret = -ETIME; int i; + u32 mcpreg; + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCDR2 = reg << 17 | MCDR2_Rd; + mcpreg = reg << 17 | MCDR2_Rd; + __raw_writel(mcpreg, priv->mccr0_base + MCDR2); for (i = 0; i < 2; i++) { udelay(mcp->rw_timeout); - if (Ser4MCSR & MCSR_CRC) { - ret = Ser4MCDR2 & 0xffff; + mcpreg = __raw_readl(priv->mccr0_base + MCSR); + if (mcpreg & MCSR_CRC) { + ret = __raw_readl(priv->mccr0_base + MCDR2) + & 0xffff; break; } } @@ -116,13 +133,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) static void mcp_sa11x0_enable(struct mcp *mcp) { - Ser4MCSR = -1; - Ser4MCCR0 |= MCCR0_MCE; + struct mcp_sa11x0 *priv = priv(mcp); + + __raw_writel(-1, priv->mccr0_base + MCSR); + priv->mccr0 |= MCCR0_MCE; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } static void mcp_sa11x0_disable(struct mcp *mcp) { - Ser4MCCR0 &= ~MCCR0_MCE; + struct mcp_sa11x0 *priv = priv(mcp); + + priv->mccr0 &= ~MCCR0_MCE; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); } /* @@ -142,50 +165,69 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) struct mcp_plat_data *data = pdev->dev.platform_data; struct mcp *mcp; int ret; + struct mcp_sa11x0 *priv; + struct resource *res_mem0, *res_mem1; + u32 size0, size1; if (!data) return -ENODEV; - if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) + if (!data->codec) + return -ENODEV; + + res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mem0) + return -ENODEV; + size0 = res_mem0->end - res_mem0->start + 1; + + res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res_mem1) + return -ENODEV; + size1 = res_mem1->end - res_mem1->start + 1; + + if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp")) return -EBUSY; + if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) { + ret = -EBUSY; + goto release; + } + mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); if (!mcp) { ret = -ENOMEM; - goto release; + goto release2; } + priv = priv(mcp); + mcp->owner = THIS_MODULE; mcp->ops = &mcp_sa11x0; mcp->sclk_rate = data->sclk_rate; - mcp->dma_audio_rd = DMA_Ser4MCP0Rd; - mcp->dma_audio_wr = DMA_Ser4MCP0Wr; - mcp->dma_telco_rd = DMA_Ser4MCP1Rd; - mcp->dma_telco_wr = DMA_Ser4MCP1Wr; - mcp->gpio_base = data->gpio_base; + mcp->dma_audio_rd = DDAR_DevAdd(res_mem0->start + MCDR0) + + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_audio_wr = DDAR_DevAdd(res_mem0->start + MCDR0) + + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_telco_rd = DDAR_DevAdd(res_mem0->start + MCDR1) + + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; + mcp->dma_telco_wr = DDAR_DevAdd(res_mem0->start + MCDR1) + + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; + mcp->codec = data->codec; platform_set_drvdata(pdev, mcp); - if (machine_is_assabet()) { - ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); - } - - /* - * Setup the PPC unit correctly. - */ - PPDR &= ~PPC_RXD4; - PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; - PSDR |= PPC_RXD4; - PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); - PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); - /* * Initialise device. Note that we initially * set the sampling rate to minimum. */ - Ser4MCSR = -1; - Ser4MCCR1 = data->mccr1; - Ser4MCCR0 = data->mccr0 | 0x7f7f; + priv->mccr0_base = ioremap(res_mem0->start, size0); + priv->mccr1_base = ioremap(res_mem1->start, size1); + + __raw_writel(-1, priv->mccr0_base + MCSR); + priv->mccr1 = data->mccr1; + priv->mccr0 = data->mccr0 | 0x7f7f; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); + __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); /* * Calculate the read/write timeout (us) from the bit clock @@ -195,36 +237,53 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / mcp->sclk_rate; - ret = mcp_host_register(mcp); + ret = mcp_host_register(mcp, data->codec_pdata); if (ret == 0) goto out; + release2: + release_mem_region(res_mem1->start, size1); release: - release_mem_region(0x80060000, 0x60); + release_mem_region(res_mem0->start, size0); platform_set_drvdata(pdev, NULL); out: return ret; } -static int mcp_sa11x0_remove(struct platform_device *dev) +static int mcp_sa11x0_remove(struct platform_device *pdev) { - struct mcp *mcp = platform_get_drvdata(dev); + struct mcp *mcp = platform_get_drvdata(pdev); + struct mcp_sa11x0 *priv = priv(mcp); + struct resource *res_mem; + u32 size; - platform_set_drvdata(dev, NULL); + platform_set_drvdata(pdev, NULL); mcp_host_unregister(mcp); - release_mem_region(0x80060000, 0x60); + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res_mem) { + size = res_mem->end - res_mem->start + 1; + release_mem_region(res_mem->start, size); + } + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res_mem) { + size = res_mem->end - res_mem->start + 1; + release_mem_region(res_mem->start, size); + } + iounmap(priv->mccr0_base); + iounmap(priv->mccr1_base); return 0; } static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) { struct mcp *mcp = platform_get_drvdata(dev); + struct mcp_sa11x0 *priv = priv(mcp); + u32 mccr0; - priv(mcp)->mccr0 = Ser4MCCR0; - priv(mcp)->mccr1 = Ser4MCCR1; - Ser4MCCR0 &= ~MCCR0_MCE; + mccr0 = priv->mccr0 & ~MCCR0_MCE; + __raw_writel(mccr0, priv->mccr0_base + MCCR0); return 0; } @@ -232,9 +291,10 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) static int mcp_sa11x0_resume(struct platform_device *dev) { struct mcp *mcp = platform_get_drvdata(dev); + struct mcp_sa11x0 *priv = priv(mcp); - Ser4MCCR1 = priv(mcp)->mccr1; - Ser4MCCR0 = priv(mcp)->mccr0; + __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); + __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); return 0; } @@ -251,6 +311,7 @@ static struct platform_driver mcp_sa11x0_driver = { .resume = mcp_sa11x0_resume, .driver = { .name = "sa11x0-mcp", + .owner = THIS_MODULE, }, }; diff --git a/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index febc90cdef7e..91c4f25e0e55 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); +static struct mcp_device_id ucb1x00_id[] = { + { "ucb1x00", 0 }, /* auto-detection */ + { "ucb1200", UCB_ID_1200 }, + { "ucb1300", UCB_ID_1300 }, + { "tc35143", UCB_ID_TC35143 }, + { } +}; +MODULE_DEVICE_TABLE(mcp, ucb1x00_id); + /** * ucb1x00_io_set_dir - set IO direction * @ucb: UCB1x00 structure describing chip @@ -148,22 +157,16 @@ static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; - unsigned old, mask = 1 << offset; spin_lock_irqsave(&ucb->io_lock, flags); - old = ucb->io_out; + ucb->io_dir |= (1 << offset); + ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); + if (value) - ucb->io_out |= mask; + ucb->io_out |= 1 << offset; else - ucb->io_out &= ~mask; - - if (old != ucb->io_out) - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - - if (!(ucb->io_dir & mask)) { - ucb->io_dir |= mask; - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - } + ucb->io_out &= ~(1 << offset); + ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; @@ -533,17 +536,33 @@ static struct class ucb1x00_class = { static int ucb1x00_probe(struct mcp *mcp) { + const struct mcp_device_id *mid; struct ucb1x00 *ucb; struct ucb1x00_driver *drv; + struct ucb1x00_plat_data *pdata; unsigned int id; int ret = -ENODEV; int temp; mcp_enable(mcp); id = mcp_reg_read(mcp, UCB_ID); + mid = mcp_get_device_id(mcp); - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); + if (mid && mid->driver_data) { + if (id != mid->driver_data) { + printk(KERN_WARNING "%s wrong ID %04x found: %04x\n", + mid->name, (unsigned int) mid->driver_data, id); + goto err_disable; + } + } else { + mid = &ucb1x00_id[1]; + while (mid->driver_data) { + if (id == mid->driver_data) + break; + mid++; + } + printk(KERN_WARNING "%s ID not found: %04x\n", + ucb1x00_id[0].name, id); goto err_disable; } @@ -552,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp) if (!ucb) goto err_disable; - + pdata = mcp->attached_device.platform_data; ucb->dev.class = &ucb1x00_class; ucb->dev.parent = &mcp->attached_device; - dev_set_name(&ucb->dev, "ucb1x00"); + dev_set_name(&ucb->dev, mid->name); spin_lock_init(&ucb->lock); spin_lock_init(&ucb->io_lock); sema_init(&ucb->adc_sem, 1); - ucb->id = id; + ucb->id = mid; ucb->mcp = mcp; ucb->irq = ucb1x00_detect_irq(ucb); if (ucb->irq == NO_IRQ) { - printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); + printk(KERN_ERR "%s: IRQ probe failed\n", mid->name); ret = -ENODEV; goto err_free; } ucb->gpio.base = -1; - if (mcp->gpio_base != 0) { + if (pdata && (pdata->gpio_base >= 0)) { ucb->gpio.label = dev_name(&ucb->dev); - ucb->gpio.base = mcp->gpio_base; + ucb->gpio.base = pdata->gpio_base; ucb->gpio.ngpio = 10; ucb->gpio.set = ucb1x00_gpio_set; ucb->gpio.get = ucb1x00_gpio_get; @@ -586,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp) dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, - "UCB1x00", ucb); + mid->name, ucb); if (ret) { - printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", - ucb->irq, ret); + printk(KERN_ERR "%s: unable to grab irq%d: %d\n", + mid->name, ucb->irq, ret); goto err_gpio; } @@ -693,7 +712,6 @@ static int ucb1x00_resume(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); mutex_lock(&ucb1x00_mutex); list_for_each_entry(dev, &ucb->devs, dev_node) { @@ -712,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = { .remove = ucb1x00_remove, .suspend = ucb1x00_suspend, .resume = ucb1x00_resume, + .id_table = ucb1x00_id, }; static int __init ucb1x00_init(void) diff --git a/trunk/drivers/mfd/ucb1x00-ts.c b/trunk/drivers/mfd/ucb1x00-ts.c index 63a3cbdfa3f3..40ec3c118868 100644 --- a/trunk/drivers/mfd/ucb1x00-ts.c +++ b/trunk/drivers/mfd/ucb1x00-ts.c @@ -47,6 +47,7 @@ struct ucb1x00_ts { u16 x_res; u16 y_res; + unsigned int restart:1; unsigned int adcsync:1; }; @@ -206,17 +207,15 @@ static int ucb1x00_thread(void *_ts) { struct ucb1x00_ts *ts = _ts; DECLARE_WAITQUEUE(wait, current); - bool frozen, ignore = false; int valid = 0; set_freezable(); add_wait_queue(&ts->irq_wait, &wait); - while (!kthread_freezable_should_stop(&frozen)) { + while (!kthread_should_stop()) { unsigned int x, y, p; signed long timeout; - if (frozen) - ignore = true; + ts->restart = 0; ucb1x00_adc_enable(ts->ucb); @@ -259,7 +258,7 @@ static int ucb1x00_thread(void *_ts) * space. We therefore leave it to user space * to do any filtering they please. */ - if (!ignore) { + if (!ts->restart) { ucb1x00_ts_evt_add(ts, p, x, y); valid = 1; } @@ -268,6 +267,8 @@ static int ucb1x00_thread(void *_ts) timeout = HZ / 100; } + try_to_freeze(); + schedule_timeout(timeout); } @@ -339,6 +340,26 @@ static void ucb1x00_ts_close(struct input_dev *idev) ucb1x00_disable(ts->ucb); } +#ifdef CONFIG_PM +static int ucb1x00_ts_resume(struct ucb1x00_dev *dev) +{ + struct ucb1x00_ts *ts = dev->priv; + + if (ts->rtask != NULL) { + /* + * Restart the TS thread to ensure the + * TS interrupt mode is set up again + * after sleep. + */ + ts->restart = 1; + wake_up(&ts->irq_wait); + } + return 0; +} +#else +#define ucb1x00_ts_resume NULL +#endif + /* * Initialisation. @@ -361,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; idev->name = "Touchscreen panel"; - idev->id.product = ts->ucb->id; + idev->id.product = ts->ucb->id->driver_data; idev->open = ucb1x00_ts_open; idev->close = ucb1x00_ts_close; @@ -404,6 +425,7 @@ static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) static struct ucb1x00_driver ucb1x00_ts_driver = { .add = ucb1x00_ts_add, .remove = ucb1x00_ts_remove, + .resume = ucb1x00_ts_resume, }; static int __init ucb1x00_ts_init(void) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 65d1f05007be..752493f00406 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -972,11 +972,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) } #endif + spin_unlock_irqrestore(&trans->shrd->lock, flags); + /* saved interrupt in inta variable now we can reset trans_pcie->inta */ trans_pcie->inta = 0; - spin_unlock_irqrestore(&trans->shrd->lock, flags); - /* Now service all interrupt bits discovered above. */ if (inta & CSR_INT_BIT_HW_ERR) { IWL_ERR(trans, "Hardware error detected. Restarting.\n"); diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 698b905058dd..fa679057630f 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -68,7 +68,7 @@ struct netfront_cb { #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) -#define TX_MAX_TARGET min_t(int, NET_TX_RING_SIZE, 256) +#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) struct netfront_stats { u64 rx_packets; diff --git a/trunk/drivers/pcmcia/sa1111_generic.c b/trunk/drivers/pcmcia/sa1111_generic.c index 27f2fe3b7fb4..59866905ea37 100644 --- a/trunk/drivers/pcmcia/sa1111_generic.c +++ b/trunk/drivers/pcmcia/sa1111_generic.c @@ -205,8 +205,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev) dev_set_drvdata(&dev->dev, NULL); - for (; s; s = next) { - next = s->next; + for (; next = s->next, s; s = next) { soc_pcmcia_remove_one(&s->soc); kfree(s); } diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index 8fe15cf15ac8..569bdb3ef104 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -510,12 +510,10 @@ static struct dentry *debugfs_root; static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) { - struct dentry *device_root; + static struct dentry *device_root; device_root = debugfs_create_dir(dev_name(pctldev->dev), debugfs_root); - pctldev->device_root = device_root; - if (IS_ERR(device_root) || !device_root) { pr_warn("failed to create debugfs directory for %s\n", dev_name(pctldev->dev)); @@ -531,11 +529,6 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) pinconf_init_device_debugfs(device_root, pctldev); } -static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) -{ - debugfs_remove_recursive(pctldev->device_root); -} - static void pinctrl_init_debugfs(void) { debugfs_root = debugfs_create_dir("pinctrl", NULL); @@ -560,10 +553,6 @@ static void pinctrl_init_debugfs(void) { } -static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) -{ -} - #endif /** @@ -583,40 +572,40 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, if (pctldesc->name == NULL) return NULL; - pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); - if (pctldev == NULL) - return NULL; - - /* Initialize pin control device struct */ - pctldev->owner = pctldesc->owner; - pctldev->desc = pctldesc; - pctldev->driver_data = driver_data; - INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); - spin_lock_init(&pctldev->pin_desc_tree_lock); - INIT_LIST_HEAD(&pctldev->gpio_ranges); - mutex_init(&pctldev->gpio_ranges_lock); - pctldev->dev = dev; - /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { - ret = pinmux_check_ops(pctldev); + ret = pinmux_check_ops(pctldesc->pmxops); if (ret) { pr_err("%s pinmux ops lacks necessary functions\n", pctldesc->name); - goto out_err; + return NULL; } } /* If we're implementing pinconfig, check the ops for sanity */ if (pctldesc->confops) { - ret = pinconf_check_ops(pctldev); + ret = pinconf_check_ops(pctldesc->confops); if (ret) { pr_err("%s pin config ops lacks necessary functions\n", pctldesc->name); - goto out_err; + return NULL; } } + pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); + if (pctldev == NULL) + return NULL; + + /* Initialize pin control device struct */ + pctldev->owner = pctldesc->owner; + pctldev->desc = pctldesc; + pctldev->driver_data = driver_data; + INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); + spin_lock_init(&pctldev->pin_desc_tree_lock); + INIT_LIST_HEAD(&pctldev->gpio_ranges); + mutex_init(&pctldev->gpio_ranges_lock); + pctldev->dev = dev; + /* Register all the pins */ pr_debug("try to register %d pins on %s...\n", pctldesc->npins, pctldesc->name); @@ -652,7 +641,6 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) if (pctldev == NULL) return; - pinctrl_remove_device_debugfs(pctldev); pinmux_unhog_maps(pctldev); /* TODO: check that no pinmuxes are still active? */ mutex_lock(&pinctrldev_list_mutex); diff --git a/trunk/drivers/pinctrl/core.h b/trunk/drivers/pinctrl/core.h index cfa86da6b4b1..177a3310547f 100644 --- a/trunk/drivers/pinctrl/core.h +++ b/trunk/drivers/pinctrl/core.h @@ -41,9 +41,6 @@ struct pinctrl_dev { struct device *dev; struct module *owner; void *driver_data; -#ifdef CONFIG_DEBUG_FS - struct dentry *device_root; -#endif #ifdef CONFIG_PINMUX struct mutex pinmux_hogs_lock; struct list_head pinmux_hogs; diff --git a/trunk/drivers/pinctrl/pinconf.c b/trunk/drivers/pinctrl/pinconf.c index 9fb75456824c..1259872b0a1d 100644 --- a/trunk/drivers/pinctrl/pinconf.c +++ b/trunk/drivers/pinctrl/pinconf.c @@ -205,10 +205,8 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, } EXPORT_SYMBOL(pin_config_group_set); -int pinconf_check_ops(struct pinctrl_dev *pctldev) +int pinconf_check_ops(const struct pinconf_ops *ops) { - const struct pinconf_ops *ops = pctldev->desc->confops; - /* We must be able to read out pin status */ if (!ops->pin_config_get && !ops->pin_config_group_get) return -EINVAL; @@ -238,7 +236,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what) seq_puts(s, "Format: pin (name): pinmux setting array\n"); /* The pin number can be retrived from the pin controller descriptor */ - for (i = 0; i < pctldev->desc->npins; i++) { + for (i = 0; pin < pctldev->desc->npins; i++) { struct pin_desc *desc; pin = pctldev->desc->pins[i].number; diff --git a/trunk/drivers/pinctrl/pinconf.h b/trunk/drivers/pinctrl/pinconf.h index 006b77fa737e..e7dc6165032a 100644 --- a/trunk/drivers/pinctrl/pinconf.h +++ b/trunk/drivers/pinctrl/pinconf.h @@ -13,7 +13,7 @@ #ifdef CONFIG_PINCONF -int pinconf_check_ops(struct pinctrl_dev *pctldev); +int pinconf_check_ops(const struct pinconf_ops *ops); void pinconf_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, @@ -23,7 +23,7 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, #else -static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) +static inline int pinconf_check_ops(const struct pinconf_ops *ops) { return 0; } diff --git a/trunk/drivers/pinctrl/pinmux.c b/trunk/drivers/pinctrl/pinmux.c index 7c3193f7a044..a76a348321bb 100644 --- a/trunk/drivers/pinctrl/pinmux.c +++ b/trunk/drivers/pinctrl/pinmux.c @@ -53,6 +53,11 @@ struct pinmux_group { * @dev: the device using this pinmux * @usecount: the number of active users of this mux setting, used to keep * track of nested use cases + * @pins: an array of discrete physical pins used in this mapping, taken + * from the global pin enumeration space (copied from pinmux map) + * @num_pins: the number of pins in this mapping array, i.e. the number of + * elements in .pins so we can iterate over that array (copied from + * pinmux map) * @pctldev: pin control device handling this pinmux * @func_selector: the function selector for the pinmux device handling * this pinmux @@ -147,7 +152,8 @@ static int pin_request(struct pinctrl_dev *pctldev, status = 0; if (status) - dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", + dev_err(pctldev->dev, "->request on device %s failed " + "for pin %d\n", pctldev->desc->name, pin); out_free_pin: if (status) { @@ -349,20 +355,21 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, /* First sanity check the new mapping */ for (i = 0; i < num_maps; i++) { if (!maps[i].name) { - pr_err("failed to register map %d: no map name given\n", - i); + pr_err("failed to register map %d: " + "no map name given\n", i); return -EINVAL; } if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { - pr_err("failed to register map %s (%d): no pin control device given\n", + pr_err("failed to register map %s (%d): " + "no pin control device given\n", maps[i].name, i); return -EINVAL; } if (!maps[i].function) { - pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); + pr_err("failed to register map %s (%d): " + "no function ID given\n", maps[i].name, i); return -EINVAL; } @@ -404,7 +411,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, } /** - * acquire_pins() - acquire all the pins for a certain function on a pinmux + * acquire_pins() - acquire all the pins for a certain funcion on a pinmux * @pctldev: the device to take the pins on * @func_selector: the function selector to acquire the pins for * @group_selector: the group selector containing the pins to acquire @@ -435,7 +442,8 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ret = pin_request(pctldev, pins[i], func, NULL); if (ret) { dev_err(pctldev->dev, - "could not get pin %d for function %s on device %s - conflicting mux mappings?\n", + "could not get pin %d for function %s " + "on device %s - conflicting mux mappings?\n", pins[i], func ? : "(undefined)", pinctrl_dev_get_name(pctldev)); /* On error release all taken pins */ @@ -450,7 +458,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, /** * release_pins() - release pins taken by earlier acquirement - * @pctldev: the device to free the pins on + * @pctldev: the device to free the pinx on * @group_selector: the group selector containing the pins to free */ static void release_pins(struct pinctrl_dev *pctldev, @@ -465,7 +473,8 @@ static void release_pins(struct pinctrl_dev *pctldev, ret = pctlops->get_group_pins(pctldev, group_selector, &pins, &num_pins); if (ret) { - dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", + dev_err(pctldev->dev, "could not get pins to release for " + "group selector %d\n", group_selector); return; } @@ -517,7 +526,8 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, ret = pinctrl_get_group_selector(pctldev, groups[0]); if (ret < 0) { dev_err(pctldev->dev, - "function %s wants group %s but the pin controller does not seem to have that group\n", + "function %s wants group %s but the pin " + "controller does not seem to have that group\n", pmxops->get_function_name(pctldev, func_selector), groups[0]); return ret; @@ -525,7 +535,8 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, if (num_groups > 1) dev_dbg(pctldev->dev, - "function %s support more than one group, default-selecting first group %s (%d)\n", + "function %s support more than one group, " + "default-selecting first group %s (%d)\n", pmxops->get_function_name(pctldev, func_selector), groups[0], ret); @@ -617,8 +628,10 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, if (pmx->pctldev && pmx->pctldev != pctldev) { dev_err(pctldev->dev, - "different pin control devices given for device %s, function %s\n", - devname, map->function); + "different pin control devices given for device %s, " + "function %s\n", + devname, + map->function); return -EINVAL; } pmx->dev = dev; @@ -682,6 +695,7 @@ static void pinmux_free_groups(struct pinmux *pmx) */ struct pinmux *pinmux_get(struct device *dev, const char *name) { + struct pinmux_map const *map = NULL; struct pinctrl_dev *pctldev = NULL; const char *devname = NULL; @@ -731,7 +745,8 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) else if (map->ctrl_dev_name) devname = map->ctrl_dev_name; - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", + pr_warning("could not find a pinctrl device for pinmux " + "function %s, fishy, they shall all have one\n", map->function); pr_warning("given pinctrl device name: %s", devname ? devname : "UNDEFINED"); @@ -889,11 +904,8 @@ void pinmux_disable(struct pinmux *pmx) } EXPORT_SYMBOL_GPL(pinmux_disable); -int pinmux_check_ops(struct pinctrl_dev *pctldev) +int pinmux_check_ops(const struct pinmux_ops *ops) { - const struct pinmux_ops *ops = pctldev->desc->pmxops; - unsigned selector = 0; - /* Check that we implement required operations */ if (!ops->list_functions || !ops->get_function_name || @@ -902,18 +914,6 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) !ops->disable) return -EINVAL; - /* Check that all functions registered have names */ - while (ops->list_functions(pctldev, selector) >= 0) { - const char *fname = ops->get_function_name(pctldev, - selector); - if (!fname) { - pr_err("pinmux ops has no name for function%u\n", - selector); - return -EINVAL; - } - selector++; - } - return 0; } @@ -932,8 +932,8 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, * without any problems, so then we can hog pinmuxes for * all devices that just want a static pin mux at this point. */ - dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", - map->name); + dev_err(pctldev->dev, "map %s wants to hog a non-system " + "pinmux, this is not going to work\n", map->name); return -EINVAL; } @@ -993,12 +993,9 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) for (i = 0; i < pinmux_maps_num; i++) { struct pinmux_map const *map = &pinmux_maps[i]; - if (!map->hog_on_boot) - continue; - - if ((map->ctrl_dev == dev) || - (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname))) { + if (((map->ctrl_dev == dev) || + !strcmp(map->ctrl_dev_name, devname)) && + map->hog_on_boot) { /* OK time to hog! */ ret = pinmux_hog_map(pctldev, map); if (ret) @@ -1125,15 +1122,13 @@ static int pinmux_show(struct seq_file *s, void *what) seq_printf(s, "device: %s function: %s (%u),", pinctrl_dev_get_name(pmx->pctldev), - pmxops->get_function_name(pctldev, - pmx->func_selector), + pmxops->get_function_name(pctldev, pmx->func_selector), pmx->func_selector); seq_printf(s, " groups: ["); list_for_each_entry(grp, &pmx->groups, node) { seq_printf(s, " %s (%u)", - pctlops->get_group_name(pctldev, - grp->group_selector), + pctlops->get_group_name(pctldev, grp->group_selector), grp->group_selector); } seq_printf(s, " ]"); diff --git a/trunk/drivers/pinctrl/pinmux.h b/trunk/drivers/pinctrl/pinmux.h index 97f52223fbc2..844500b3331b 100644 --- a/trunk/drivers/pinctrl/pinmux.h +++ b/trunk/drivers/pinctrl/pinmux.h @@ -12,7 +12,7 @@ */ #ifdef CONFIG_PINMUX -int pinmux_check_ops(struct pinctrl_dev *pctldev); +int pinmux_check_ops(const struct pinmux_ops *ops); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); void pinmux_init_debugfs(struct dentry *subsys_root); @@ -21,7 +21,7 @@ void pinmux_unhog_maps(struct pinctrl_dev *pctldev); #else -static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) +static inline int pinmux_check_ops(const struct pinmux_ops *ops) { return 0; } diff --git a/trunk/drivers/regulator/of_regulator.c b/trunk/drivers/regulator/of_regulator.c index 679734d26a16..f1651eb69648 100644 --- a/trunk/drivers/regulator/of_regulator.c +++ b/trunk/drivers/regulator/of_regulator.c @@ -35,7 +35,7 @@ static void of_get_regulation_constraints(struct device_node *np, if (constraints->min_uV != constraints->max_uV) constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; /* Only one voltage? Then make sure it's set. */ - if (min_uV && max_uV && constraints->min_uV == constraints->max_uV) + if (constraints->min_uV == constraints->max_uV) constraints->apply_uV = true; uV_offset = of_get_property(np, "regulator-microvolt-offset", NULL); diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 3a125b835546..e19a4031f45e 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -774,7 +774,7 @@ config RTC_DRV_EP93XX config RTC_DRV_SA1100 tristate "SA11x0/PXA2xx" - depends on ARCH_SA1100 || ARCH_PXA + depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP help If you say Y here you will get access to the real time clock built into your SA11x0 or PXA2xx CPU. diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index cb9a585312cc..4595d3e645a7 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -27,34 +27,42 @@ #include #include #include -#include #include -#include +#include +#include +#include #include #include -#ifdef CONFIG_ARCH_PXA -#include -#endif - #define RTC_DEF_DIVIDER (32768 - 1) #define RTC_DEF_TRIM 0 - -static const unsigned long RTC_FREQ = 1024; -static struct rtc_time rtc_alarm; -static DEFINE_SPINLOCK(sa1100_rtc_lock); - -static inline int rtc_periodic_alarm(struct rtc_time *tm) -{ - return (tm->tm_year == -1) || - ((unsigned)tm->tm_mon >= 12) || - ((unsigned)(tm->tm_mday - 1) >= 31) || - ((unsigned)tm->tm_hour > 23) || - ((unsigned)tm->tm_min > 59) || - ((unsigned)tm->tm_sec > 59); -} - +#define RTC_FREQ 1024 + +#define RCNR 0x00 /* RTC Count Register */ +#define RTAR 0x04 /* RTC Alarm Register */ +#define RTSR 0x08 /* RTC Status Register */ +#define RTTR 0x0c /* RTC Timer Trim Register */ + +#define RTSR_HZE (1 << 3) /* HZ interrupt enable */ +#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ +#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ +#define RTSR_AL (1 << 0) /* RTC alarm detected */ + +#define rtc_readl(sa1100_rtc, reg) \ + readl_relaxed((sa1100_rtc)->base + (reg)) +#define rtc_writel(sa1100_rtc, reg, value) \ + writel_relaxed((value), (sa1100_rtc)->base + (reg)) + +struct sa1100_rtc { + struct resource *ress; + void __iomem *base; + struct clk *clk; + int irq_1Hz; + int irq_Alrm; + struct rtc_device *rtc; + spinlock_t lock; /* Protects this structure */ +}; /* * Calculate the next alarm time given the requested alarm time mask * and the current time. @@ -82,46 +90,26 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, } } -static int rtc_update_alarm(struct rtc_time *alrm) -{ - struct rtc_time alarm_tm, now_tm; - unsigned long now, time; - int ret; - - do { - now = RCNR; - rtc_time_to_tm(now, &now_tm); - rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); - ret = rtc_tm_to_time(&alarm_tm, &time); - if (ret != 0) - break; - - RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); - RTAR = time; - } while (now != RCNR); - - return ret; -} - static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) { struct platform_device *pdev = to_platform_device(dev_id); - struct rtc_device *rtc = platform_get_drvdata(pdev); + struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); unsigned int rtsr; unsigned long events = 0; - spin_lock(&sa1100_rtc_lock); + spin_lock(&sa1100_rtc->lock); - rtsr = RTSR; /* clear interrupt sources */ - RTSR = 0; + rtsr = rtc_readl(sa1100_rtc, RTSR); + rtc_writel(sa1100_rtc, RTSR, 0); + /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_probe(). */ if (rtsr & (RTSR_ALE | RTSR_HZE)) { /* This is the original code, before there was the if test * above. This code does not clear interrupts that were not * enabled. */ - RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ) & (rtsr >> 2)); } else { /* For some reason, it is possible to enter this routine * without interruptions enabled, it has been tested with @@ -130,13 +118,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) * This situation leads to an infinite "loop" of interrupt * routine calling and as a result the processor seems to * lock on its first call to open(). */ - RTSR = RTSR_AL | RTSR_HZ; + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); } /* clear alarm interrupt if it has occurred */ if (rtsr & RTSR_AL) rtsr &= ~RTSR_ALE; - RTSR = rtsr & (RTSR_ALE | RTSR_HZE); + rtc_writel(sa1100_rtc, RTSR, rtsr & (RTSR_ALE | RTSR_HZE)); /* update irq data & counter */ if (rtsr & RTSR_AL) @@ -144,89 +132,100 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) if (rtsr & RTSR_HZ) events |= RTC_UF | RTC_IRQF; - rtc_update_irq(rtc, 1, events); + rtc_update_irq(sa1100_rtc->rtc, 1, events); - if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) - rtc_update_alarm(&rtc_alarm); - - spin_unlock(&sa1100_rtc_lock); + spin_unlock(&sa1100_rtc->lock); return IRQ_HANDLED; } static int sa1100_rtc_open(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); int ret; - struct platform_device *plat_dev = to_platform_device(dev); - struct rtc_device *rtc = platform_get_drvdata(plat_dev); - ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc 1Hz", dev); + ret = request_irq(sa1100_rtc->irq_1Hz, sa1100_rtc_interrupt, + IRQF_DISABLED, "rtc 1Hz", dev); if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); + dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_1Hz); goto fail_ui; } - ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, - "rtc Alrm", dev); + ret = request_irq(sa1100_rtc->irq_Alrm, sa1100_rtc_interrupt, + IRQF_DISABLED, "rtc Alrm", dev); if (ret) { - dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); + dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_Alrm); goto fail_ai; } - rtc->max_user_freq = RTC_FREQ; - rtc_irq_set_freq(rtc, NULL, RTC_FREQ); + sa1100_rtc->rtc->max_user_freq = RTC_FREQ; + rtc_irq_set_freq(sa1100_rtc->rtc, NULL, RTC_FREQ); return 0; fail_ai: - free_irq(IRQ_RTC1Hz, dev); + free_irq(sa1100_rtc->irq_1Hz, dev); fail_ui: return ret; } static void sa1100_rtc_release(struct device *dev) { - spin_lock_irq(&sa1100_rtc_lock); - RTSR = 0; - spin_unlock_irq(&sa1100_rtc_lock); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + + spin_lock_irq(&sa1100_rtc->lock); + rtc_writel(sa1100_rtc, RTSR, 0); + spin_unlock_irq(&sa1100_rtc->lock); - free_irq(IRQ_RTCAlrm, dev); - free_irq(IRQ_RTC1Hz, dev); + free_irq(sa1100_rtc->irq_Alrm, dev); + free_irq(sa1100_rtc->irq_1Hz, dev); } static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { - spin_lock_irq(&sa1100_rtc_lock); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + unsigned int rtsr; + + spin_lock_irq(&sa1100_rtc->lock); + + rtsr = rtc_readl(sa1100_rtc, RTSR); if (enabled) - RTSR |= RTSR_ALE; + rtsr |= RTSR_ALE; else - RTSR &= ~RTSR_ALE; - spin_unlock_irq(&sa1100_rtc_lock); + rtsr &= ~RTSR_ALE; + rtc_writel(sa1100_rtc, RTSR, rtsr); + + spin_unlock_irq(&sa1100_rtc->lock); return 0; } static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) { - rtc_time_to_tm(RCNR, tm); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + + rtc_time_to_tm(rtc_readl(sa1100_rtc, RCNR), tm); return 0; } static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); unsigned long time; int ret; ret = rtc_tm_to_time(tm, &time); if (ret == 0) - RCNR = time; + rtc_writel(sa1100_rtc, RCNR, time); return ret; } static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - u32 rtsr; + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + unsigned long time; + unsigned int rtsr; - memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); - rtsr = RTSR; + time = rtc_readl(sa1100_rtc, RCNR); + rtc_time_to_tm(time, &alrm->time); + rtsr = rtc_readl(sa1100_rtc, RTSR); alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; return 0; @@ -234,26 +233,39 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - int ret; + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + struct rtc_time now_tm, alarm_tm; + unsigned long time, alarm; + unsigned int rtsr; - spin_lock_irq(&sa1100_rtc_lock); - ret = rtc_update_alarm(&alrm->time); - if (ret == 0) { - if (alrm->enabled) - RTSR |= RTSR_ALE; - else - RTSR &= ~RTSR_ALE; - } - spin_unlock_irq(&sa1100_rtc_lock); + spin_lock_irq(&sa1100_rtc->lock); - return ret; + time = rtc_readl(sa1100_rtc, RCNR); + rtc_time_to_tm(time, &now_tm); + rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); + rtc_tm_to_time(&alarm_tm, &alarm); + rtc_writel(sa1100_rtc, RTAR, alarm); + + rtsr = rtc_readl(sa1100_rtc, RTSR); + if (alrm->enabled) + rtsr |= RTSR_ALE; + else + rtsr &= ~RTSR_ALE; + rtc_writel(sa1100_rtc, RTSR, rtsr); + + spin_unlock_irq(&sa1100_rtc->lock); + + return 0; } static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) { - seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); - seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + seq_printf(seq, "trim/divider\t\t: 0x%08x\n", + rtc_readl(sa1100_rtc, RTTR)); + seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", + rtc_readl(sa1100_rtc, RTSR)); return 0; } @@ -270,7 +282,51 @@ static const struct rtc_class_ops sa1100_rtc_ops = { static int sa1100_rtc_probe(struct platform_device *pdev) { - struct rtc_device *rtc; + struct sa1100_rtc *sa1100_rtc; + unsigned int rttr; + int ret; + + sa1100_rtc = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); + if (!sa1100_rtc) + return -ENOMEM; + + spin_lock_init(&sa1100_rtc->lock); + platform_set_drvdata(pdev, sa1100_rtc); + + ret = -ENXIO; + sa1100_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!sa1100_rtc->ress) { + dev_err(&pdev->dev, "No I/O memory resource defined\n"); + goto err_ress; + } + + sa1100_rtc->irq_1Hz = platform_get_irq(pdev, 0); + if (sa1100_rtc->irq_1Hz < 0) { + dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); + goto err_ress; + } + sa1100_rtc->irq_Alrm = platform_get_irq(pdev, 1); + if (sa1100_rtc->irq_Alrm < 0) { + dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); + goto err_ress; + } + + ret = -ENOMEM; + sa1100_rtc->base = ioremap(sa1100_rtc->ress->start, + resource_size(sa1100_rtc->ress)); + if (!sa1100_rtc->base) { + dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); + goto err_map; + } + + sa1100_rtc->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(sa1100_rtc->clk)) { + dev_err(&pdev->dev, "failed to find rtc clock source\n"); + ret = PTR_ERR(sa1100_rtc->clk); + goto err_clk; + } + clk_prepare(sa1100_rtc->clk); + clk_enable(sa1100_rtc->clk); /* * According to the manual we should be able to let RTTR be zero @@ -279,24 +335,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev) * If the clock divider is uninitialized then reset it to the * default value to get the 1Hz clock. */ - if (RTTR == 0) { - RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); - dev_warn(&pdev->dev, "warning: " - "initializing default clock divider/trim value\n"); + if (rtc_readl(sa1100_rtc, RTTR) == 0) { + rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); + rtc_writel(sa1100_rtc, RTTR, rttr); + dev_warn(&pdev->dev, "warning: initializing default clock" + " divider/trim value\n"); /* The current RTC value probably doesn't make sense either */ - RCNR = 0; + rtc_writel(sa1100_rtc, RCNR, 0); } device_init_wakeup(&pdev->dev, 1); - rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, - THIS_MODULE); - - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(pdev, rtc); - + sa1100_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, + &sa1100_rtc_ops, THIS_MODULE); + if (IS_ERR(sa1100_rtc->rtc)) { + dev_err(&pdev->dev, "Failed to register RTC device -> %d\n", + ret); + goto err_rtc_reg; + } /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). * @@ -319,33 +375,46 @@ static int sa1100_rtc_probe(struct platform_device *pdev) * * Notice that clearing bit 1 and 0 is accomplished by writting ONES to * the corresponding bits in RTSR. */ - RTSR = RTSR_AL | RTSR_HZ; + rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); return 0; + +err_rtc_reg: +err_clk: + iounmap(sa1100_rtc->base); +err_ress: +err_map: + kfree(sa1100_rtc); + return ret; } static int sa1100_rtc_remove(struct platform_device *pdev) { - struct rtc_device *rtc = platform_get_drvdata(pdev); - - if (rtc) - rtc_device_unregister(rtc); + struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); + rtc_device_unregister(sa1100_rtc->rtc); + clk_disable(sa1100_rtc->clk); + clk_unprepare(sa1100_rtc->clk); + iounmap(sa1100_rtc->base); return 0; } #ifdef CONFIG_PM static int sa1100_rtc_suspend(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + if (device_may_wakeup(dev)) - enable_irq_wake(IRQ_RTCAlrm); + enable_irq_wake(sa1100_rtc->irq_Alrm); return 0; } static int sa1100_rtc_resume(struct device *dev) { + struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); + if (device_may_wakeup(dev)) - disable_irq_wake(IRQ_RTCAlrm); + disable_irq_wake(sa1100_rtc->irq_Alrm); return 0; } diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 110137e7ec81..eef27a197c00 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -3261,12 +3261,6 @@ void dasd_generic_path_event(struct ccw_device *cdev, int *path_event) device->path_data.tbvpm |= eventlpm; dasd_schedule_device_bh(device); } - if (path_event[chp] & PE_PATHGROUP_ESTABLISHED) { - DBF_DEV_EVENT(DBF_WARNING, device, "%s", - "Pathgroup re-established\n"); - if (device->discipline->kick_validate) - device->discipline->kick_validate(device); - } } dasd_put_device(device); } diff --git a/trunk/drivers/s390/block/dasd_alias.c b/trunk/drivers/s390/block/dasd_alias.c index b3beed5434e4..553b3c5abb0a 100644 --- a/trunk/drivers/s390/block/dasd_alias.c +++ b/trunk/drivers/s390/block/dasd_alias.c @@ -189,12 +189,14 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) unsigned long flags; struct alias_server *server, *newserver; struct alias_lcu *lcu, *newlcu; + int is_lcu_known; struct dasd_uid uid; private = (struct dasd_eckd_private *) device->private; device->discipline->get_uid(device, &uid); spin_lock_irqsave(&aliastree.lock, flags); + is_lcu_known = 1; server = _find_server(&uid); if (!server) { spin_unlock_irqrestore(&aliastree.lock, flags); @@ -206,6 +208,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) if (!server) { list_add(&newserver->server, &aliastree.serverlist); server = newserver; + is_lcu_known = 0; } else { /* someone was faster */ _free_server(newserver); @@ -223,10 +226,12 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) if (!lcu) { list_add(&newlcu->lcu, &server->lculist); lcu = newlcu; + is_lcu_known = 0; } else { /* someone was faster */ _free_lcu(newlcu); } + is_lcu_known = 0; } spin_lock(&lcu->lock); list_add(&device->alias_list, &lcu->inactive_devices); @@ -234,7 +239,64 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) spin_unlock(&lcu->lock); spin_unlock_irqrestore(&aliastree.lock, flags); - return 0; + return is_lcu_known; +} + +/* + * The first device to be registered on an LCU will have to do + * some additional setup steps to configure that LCU on the + * storage server. All further devices should wait with their + * initialization until the first device is done. + * To synchronize this work, the first device will call + * dasd_alias_lcu_setup_complete when it is done, and all + * other devices will wait for it with dasd_alias_wait_for_lcu_setup. + */ +void dasd_alias_lcu_setup_complete(struct dasd_device *device) +{ + unsigned long flags; + struct alias_server *server; + struct alias_lcu *lcu; + struct dasd_uid uid; + + device->discipline->get_uid(device, &uid); + lcu = NULL; + spin_lock_irqsave(&aliastree.lock, flags); + server = _find_server(&uid); + if (server) + lcu = _find_lcu(server, &uid); + spin_unlock_irqrestore(&aliastree.lock, flags); + if (!lcu) { + DBF_EVENT_DEVID(DBF_ERR, device->cdev, + "could not find lcu for %04x %02x", + uid.ssid, uid.real_unit_addr); + WARN_ON(1); + return; + } + complete_all(&lcu->lcu_setup); +} + +void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) +{ + unsigned long flags; + struct alias_server *server; + struct alias_lcu *lcu; + struct dasd_uid uid; + + device->discipline->get_uid(device, &uid); + lcu = NULL; + spin_lock_irqsave(&aliastree.lock, flags); + server = _find_server(&uid); + if (server) + lcu = _find_lcu(server, &uid); + spin_unlock_irqrestore(&aliastree.lock, flags); + if (!lcu) { + DBF_EVENT_DEVID(DBF_ERR, device->cdev, + "could not find lcu for %04x %02x", + uid.ssid, uid.real_unit_addr); + WARN_ON(1); + return; + } + wait_for_completion(&lcu->lcu_setup); } /* diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 70880be26015..bbcd5e9206ee 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1534,10 +1534,6 @@ static void dasd_eckd_validate_server(struct dasd_device *device) struct dasd_eckd_private *private; int enable_pav; - private = (struct dasd_eckd_private *) device->private; - if (private->uid.type == UA_BASE_PAV_ALIAS || - private->uid.type == UA_HYPER_PAV_ALIAS) - return; if (dasd_nopav || MACHINE_IS_VM) enable_pav = 0; else @@ -1546,28 +1542,11 @@ static void dasd_eckd_validate_server(struct dasd_device *device) /* may be requested feature is not available on server, * therefore just report error and go ahead */ + private = (struct dasd_eckd_private *) device->private; DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " "returned rc=%d", private->uid.ssid, rc); } -/* - * worker to do a validate server in case of a lost pathgroup - */ -static void dasd_eckd_do_validate_server(struct work_struct *work) -{ - struct dasd_device *device = container_of(work, struct dasd_device, - kick_validate); - dasd_eckd_validate_server(device); - dasd_put_device(device); -} - -static void dasd_eckd_kick_validate_server(struct dasd_device *device) -{ - dasd_get_device(device); - /* queue call to do_validate_server to the kernel event daemon. */ - schedule_work(&device->kick_validate); -} - static u32 get_fcx_max_data(struct dasd_device *device) { #if defined(CONFIG_64BIT) @@ -1609,13 +1588,10 @@ dasd_eckd_check_characteristics(struct dasd_device *device) struct dasd_eckd_private *private; struct dasd_block *block; struct dasd_uid temp_uid; - int rc, i; + int is_known, rc, i; int readonly; unsigned long value; - /* setup work queue for validate server*/ - INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server); - if (!ccw_device_is_pathgroup(device->cdev)) { dev_warn(&device->cdev->dev, "A channel path group could not be established\n"); @@ -1675,12 +1651,22 @@ dasd_eckd_check_characteristics(struct dasd_device *device) block->base = device; } - /* register lcu with alias handling, enable PAV */ - rc = dasd_alias_make_device_known_to_lcu(device); - if (rc) + /* register lcu with alias handling, enable PAV if this is a new lcu */ + is_known = dasd_alias_make_device_known_to_lcu(device); + if (is_known < 0) { + rc = is_known; goto out_err2; - - dasd_eckd_validate_server(device); + } + /* + * dasd_eckd_validate_server is done on the first device that + * is found for an LCU. All later other devices have to wait + * for it, so they will read the correct feature codes. + */ + if (!is_known) { + dasd_eckd_validate_server(device); + dasd_alias_lcu_setup_complete(device); + } else + dasd_alias_wait_for_lcu_setup(device); /* device may report different configuration data after LCU setup */ rc = dasd_eckd_read_conf(device); @@ -4112,7 +4098,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device) { struct dasd_eckd_private *private; struct dasd_eckd_characteristics temp_rdc_data; - int rc; + int is_known, rc; struct dasd_uid temp_uid; unsigned long flags; @@ -4135,10 +4121,14 @@ static int dasd_eckd_restore_device(struct dasd_device *device) goto out_err; /* register lcu with alias handling, enable PAV if this is a new lcu */ - rc = dasd_alias_make_device_known_to_lcu(device); - if (rc) - return rc; - dasd_eckd_validate_server(device); + is_known = dasd_alias_make_device_known_to_lcu(device); + if (is_known < 0) + return is_known; + if (!is_known) { + dasd_eckd_validate_server(device); + dasd_alias_lcu_setup_complete(device); + } else + dasd_alias_wait_for_lcu_setup(device); /* RE-Read Configuration Data */ rc = dasd_eckd_read_conf(device); @@ -4280,7 +4270,6 @@ static struct dasd_discipline dasd_eckd_discipline = { .restore = dasd_eckd_restore_device, .reload = dasd_eckd_reload_device, .get_uid = dasd_eckd_get_uid, - .kick_validate = dasd_eckd_kick_validate_server, }; static int __init diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 33a6743ddc55..afe8c33422ed 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -355,7 +355,6 @@ struct dasd_discipline { int (*reload) (struct dasd_device *); int (*get_uid) (struct dasd_device *, struct dasd_uid *); - void (*kick_validate) (struct dasd_device *); }; extern struct dasd_discipline *dasd_diag_discipline_pointer; @@ -456,7 +455,6 @@ struct dasd_device { struct work_struct kick_work; struct work_struct restore_device; struct work_struct reload_device; - struct work_struct kick_validate; struct timer_list timer; debug_info_t *debug_area; diff --git a/trunk/drivers/staging/media/go7007/go7007-usb.c b/trunk/drivers/staging/media/go7007/go7007-usb.c index 5443e25086e9..70e006b50f29 100644 --- a/trunk/drivers/staging/media/go7007/go7007-usb.c +++ b/trunk/drivers/staging/media/go7007/go7007-usb.c @@ -1279,4 +1279,3 @@ static struct usb_driver go7007_usb_driver = { }; module_usb_driver(go7007_usb_driver); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/tty/serial/8250/8250.c b/trunk/drivers/tty/serial/8250.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250.c rename to trunk/drivers/tty/serial/8250.c diff --git a/trunk/drivers/tty/serial/8250/8250.h b/trunk/drivers/tty/serial/8250.h similarity index 100% rename from trunk/drivers/tty/serial/8250/8250.h rename to trunk/drivers/tty/serial/8250.h diff --git a/trunk/drivers/tty/serial/8250/Kconfig b/trunk/drivers/tty/serial/8250/Kconfig deleted file mode 100644 index 591f8018e7dd..000000000000 --- a/trunk/drivers/tty/serial/8250/Kconfig +++ /dev/null @@ -1,280 +0,0 @@ -# -# The 8250/16550 serial drivers. You shouldn't be in this list unless -# you somehow have an implicit or explicit dependency on SERIAL_8250. -# - -config SERIAL_8250 - tristate "8250/16550 and compatible serial support" - select SERIAL_CORE - ---help--- - This selects whether you want to include the driver for the standard - serial ports. The standard answer is Y. People who might say N - here are those that are setting up dedicated Ethernet WWW/FTP - servers, or users that have one of the various bus mice instead of a - serial mouse and don't intend to use their machine's standard serial - port for anything. (Note that the Cyclades and Stallion multi - serial port drivers do not need this driver built in for them to - work.) - - To compile this driver as a module, choose M here: the - module will be called 8250. - [WARNING: Do not compile this driver as a module if you are using - non-standard serial ports, since the configuration information will - be lost when the driver is unloaded. This limitation may be lifted - in the future.] - - BTW1: If you have a mouseman serial mouse which is not recognized by - the X window system, try running gpm first. - - BTW2: If you intend to use a software modem (also called Winmodem) - under Linux, forget it. These modems are crippled and require - proprietary drivers which are only available under Windows. - - Most people will say Y or M here, so that they can use serial mice, - modems and similar devices connecting to the standard serial ports. - -config SERIAL_8250_CONSOLE - bool "Console on 8250/16550 and compatible serial port" - depends on SERIAL_8250=y - select SERIAL_CORE_CONSOLE - ---help--- - If you say Y here, it will be possible to use a serial port as the - system console (the system console is the device which receives all - kernel messages and warnings and which allows logins in single user - mode). This could be useful if some terminal or printer is connected - to that serial port. - - Even if you say Y here, the currently visible virtual console - (/dev/tty0) will still be used as the system console by default, but - you can alter that using a kernel command line option such as - "console=ttyS1". (Try "man bootparam" or see the documentation of - your boot loader (grub or lilo or loadlin) about how to pass options - to the kernel at boot time.) - - If you don't have a VGA card installed and you say Y here, the - kernel will automatically use the first serial line, /dev/ttyS0, as - system console. - - You can set that using a kernel command line option such as - "console=uart8250,io,0x3f8,9600n8" - "console=uart8250,mmio,0xff5e0000,115200n8". - and it will switch to normal serial console when the corresponding - port is ready. - "earlycon=uart8250,io,0x3f8,9600n8" - "earlycon=uart8250,mmio,0xff5e0000,115200n8". - it will not only setup early console. - - If unsure, say N. - -config FIX_EARLYCON_MEM - bool - depends on X86 - default y - -config SERIAL_8250_GSC - tristate - depends on SERIAL_8250 && GSC - default SERIAL_8250 - -config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EXPERT - depends on SERIAL_8250 && PCI - default SERIAL_8250 - help - This builds standard PCI serial support. You may be able to - disable this feature if you only need legacy serial support. - Saves about 9K. - -config SERIAL_8250_PNP - tristate "8250/16550 PNP device support" if EXPERT - depends on SERIAL_8250 && PNP - default SERIAL_8250 - help - This builds standard PNP serial support. You may be able to - disable this feature if you only need legacy serial support. - -config SERIAL_8250_HP300 - tristate - depends on SERIAL_8250 && HP300 - default SERIAL_8250 - -config SERIAL_8250_CS - tristate "8250/16550 PCMCIA device support" - depends on PCMCIA && SERIAL_8250 - ---help--- - Say Y here to enable support for 16-bit PCMCIA serial devices, - including serial port cards, modems, and the modem functions of - multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are - credit-card size devices often used with laptops.) - - To compile this driver as a module, choose M here: the - module will be called serial_cs. - - If unsure, say N. - -config SERIAL_8250_NR_UARTS - int "Maximum number of 8250/16550 serial ports" - depends on SERIAL_8250 - default "4" - help - Set this to the number of serial ports you want the driver - to support. This includes any ports discovered via ACPI or - PCI enumeration and any ports that may be added at run-time - via hot-plug, or any ISA multi-port serial cards. - -config SERIAL_8250_RUNTIME_UARTS - int "Number of 8250/16550 serial ports to register at runtime" - depends on SERIAL_8250 - range 0 SERIAL_8250_NR_UARTS - default "4" - help - Set this to the maximum number of serial ports you want - the kernel to register at boot time. This can be overridden - with the module parameter "nr_uarts", or boot-time parameter - 8250.nr_uarts - -config SERIAL_8250_EXTENDED - bool "Extended 8250/16550 serial driver options" - depends on SERIAL_8250 - help - If you wish to use any non-standard features of the standard "dumb" - driver, say Y here. This includes HUB6 support, shared serial - interrupts, special multiport support, support for more than the - four COM 1/2/3/4 boards, etc. - - Note that the answer to this question won't directly affect the - kernel: saying N will just cause the configurator to skip all - the questions about serial driver options. If unsure, say N. - -config SERIAL_8250_MANY_PORTS - bool "Support more than 4 legacy serial ports" - depends on SERIAL_8250_EXTENDED && !IA64 - help - Say Y here if you have dumb serial boards other than the four - standard COM 1/2/3/4 ports. This may happen if you have an AST - FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available - from ), or other custom - serial port hardware which acts similar to standard serial port - hardware. If you only use the standard COM 1/2/3/4 ports, you can - say N here to save some memory. You can also say Y if you have an - "intelligent" multiport card such as Cyclades, Digiboards, etc. - -# -# Multi-port serial cards -# - -config SERIAL_8250_FOURPORT - tristate "Support Fourport cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have an AST FourPort serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_fourport. - -config SERIAL_8250_ACCENT - tristate "Support Accent cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have an Accent Async serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_accent. - -config SERIAL_8250_BOCA - tristate "Support Boca cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have a Boca serial board. Please read the Boca - mini-HOWTO, available from - - To compile this driver as a module, choose M here: the module - will be called 8250_boca. - -config SERIAL_8250_EXAR_ST16C554 - tristate "Support Exar ST16C554/554D Quad UART" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - The Uplogix Envoy TU301 uses this Exar Quad UART. If you are - tinkering with your Envoy TU301, or have a machine with this UART, - say Y here. - - To compile this driver as a module, choose M here: the module - will be called 8250_exar_st16c554. - -config SERIAL_8250_HUB6 - tristate "Support Hub6 cards" - depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS - help - Say Y here if you have a HUB6 serial board. - - To compile this driver as a module, choose M here: the module - will be called 8250_hub6. - -# -# Misc. options/drivers. -# - -config SERIAL_8250_SHARE_IRQ - bool "Support for sharing serial interrupts" - depends on SERIAL_8250_EXTENDED - help - Some serial boards have hardware support which allows multiple dumb - serial ports on the same board to share a single IRQ. To enable - support for this in the serial driver, say Y here. - -config SERIAL_8250_DETECT_IRQ - bool "Autodetect IRQ on standard ports (unsafe)" - depends on SERIAL_8250_EXTENDED - help - Say Y here if you want the kernel to try to guess which IRQ - to use for your serial port. - - This is considered unsafe; it is far better to configure the IRQ in - a boot script using the setserial command. - - If unsure, say N. - -config SERIAL_8250_RSA - bool "Support RSA serial ports" - depends on SERIAL_8250_EXTENDED - help - ::: To be written ::: - -config SERIAL_8250_MCA - tristate "Support 8250-type ports on MCA buses" - depends on SERIAL_8250 != n && MCA - help - Say Y here if you have a MCA serial ports. - - To compile this driver as a module, choose M here: the module - will be called 8250_mca. - -config SERIAL_8250_ACORN - tristate "Acorn expansion card serial port support" - depends on ARCH_ACORN && SERIAL_8250 - help - If you have an Atomwide Serial card or Serial Port card for an Acorn - system, say Y to this option. The driver can handle 1, 2, or 3 port - cards. If unsure, say N. - -config SERIAL_8250_RM9K - bool "Support for MIPS RM9xxx integrated serial port" - depends on SERIAL_8250 != n && SERIAL_RM9000 - select SERIAL_8250_SHARE_IRQ - help - Selecting this option will add support for the integrated serial - port hardware found on MIPS RM9122 and similar processors. - If unsure, say N. - -config SERIAL_8250_FSL - bool - depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 - default PPC - -config SERIAL_8250_DW - tristate "Support for Synopsys DesignWare 8250 quirks" - depends on SERIAL_8250 && OF - help - Selecting this option will enable handling of the extra features - present in the Synopsys DesignWare APB UART. diff --git a/trunk/drivers/tty/serial/8250/Makefile b/trunk/drivers/tty/serial/8250/Makefile deleted file mode 100644 index 867bba738908..000000000000 --- a/trunk/drivers/tty/serial/8250/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# Makefile for the 8250 serial device drivers. -# - -obj-$(CONFIG_SERIAL_8250) += 8250.o -obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o -obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o -obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o -obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o -obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o -obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o -obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o -obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o -obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o -obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o -obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o -obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o -obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o -obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o -obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o diff --git a/trunk/drivers/tty/serial/8250/8250_accent.c b/trunk/drivers/tty/serial/8250_accent.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_accent.c rename to trunk/drivers/tty/serial/8250_accent.c diff --git a/trunk/drivers/tty/serial/8250/8250_acorn.c b/trunk/drivers/tty/serial/8250_acorn.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_acorn.c rename to trunk/drivers/tty/serial/8250_acorn.c diff --git a/trunk/drivers/tty/serial/8250/8250_boca.c b/trunk/drivers/tty/serial/8250_boca.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_boca.c rename to trunk/drivers/tty/serial/8250_boca.c diff --git a/trunk/drivers/tty/serial/8250/8250_dw.c b/trunk/drivers/tty/serial/8250_dw.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_dw.c rename to trunk/drivers/tty/serial/8250_dw.c diff --git a/trunk/drivers/tty/serial/8250/8250_early.c b/trunk/drivers/tty/serial/8250_early.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_early.c rename to trunk/drivers/tty/serial/8250_early.c diff --git a/trunk/drivers/tty/serial/8250/8250_exar_st16c554.c b/trunk/drivers/tty/serial/8250_exar_st16c554.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_exar_st16c554.c rename to trunk/drivers/tty/serial/8250_exar_st16c554.c diff --git a/trunk/drivers/tty/serial/8250/8250_fourport.c b/trunk/drivers/tty/serial/8250_fourport.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_fourport.c rename to trunk/drivers/tty/serial/8250_fourport.c diff --git a/trunk/drivers/tty/serial/8250/8250_fsl.c b/trunk/drivers/tty/serial/8250_fsl.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_fsl.c rename to trunk/drivers/tty/serial/8250_fsl.c diff --git a/trunk/drivers/tty/serial/8250/8250_gsc.c b/trunk/drivers/tty/serial/8250_gsc.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_gsc.c rename to trunk/drivers/tty/serial/8250_gsc.c diff --git a/trunk/drivers/tty/serial/8250/8250_hp300.c b/trunk/drivers/tty/serial/8250_hp300.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_hp300.c rename to trunk/drivers/tty/serial/8250_hp300.c diff --git a/trunk/drivers/tty/serial/8250/8250_hub6.c b/trunk/drivers/tty/serial/8250_hub6.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_hub6.c rename to trunk/drivers/tty/serial/8250_hub6.c diff --git a/trunk/drivers/tty/serial/8250/8250_mca.c b/trunk/drivers/tty/serial/8250_mca.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_mca.c rename to trunk/drivers/tty/serial/8250_mca.c diff --git a/trunk/drivers/tty/serial/8250/8250_pci.c b/trunk/drivers/tty/serial/8250_pci.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_pci.c rename to trunk/drivers/tty/serial/8250_pci.c diff --git a/trunk/drivers/tty/serial/8250/8250_pnp.c b/trunk/drivers/tty/serial/8250_pnp.c similarity index 100% rename from trunk/drivers/tty/serial/8250/8250_pnp.c rename to trunk/drivers/tty/serial/8250_pnp.c diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 2de99248dfae..aca2386c5ef1 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -5,7 +5,279 @@ menu "Serial drivers" depends on HAS_IOMEM -source "drivers/tty/serial/8250/Kconfig" +# +# The new 8250/16550 serial drivers +config SERIAL_8250 + tristate "8250/16550 and compatible serial support" + select SERIAL_CORE + ---help--- + This selects whether you want to include the driver for the standard + serial ports. The standard answer is Y. People who might say N + here are those that are setting up dedicated Ethernet WWW/FTP + servers, or users that have one of the various bus mice instead of a + serial mouse and don't intend to use their machine's standard serial + port for anything. (Note that the Cyclades and Stallion multi + serial port drivers do not need this driver built in for them to + work.) + + To compile this driver as a module, choose M here: the + module will be called 8250. + [WARNING: Do not compile this driver as a module if you are using + non-standard serial ports, since the configuration information will + be lost when the driver is unloaded. This limitation may be lifted + in the future.] + + BTW1: If you have a mouseman serial mouse which is not recognized by + the X window system, try running gpm first. + + BTW2: If you intend to use a software modem (also called Winmodem) + under Linux, forget it. These modems are crippled and require + proprietary drivers which are only available under Windows. + + Most people will say Y or M here, so that they can use serial mice, + modems and similar devices connecting to the standard serial ports. + +config SERIAL_8250_CONSOLE + bool "Console on 8250/16550 and compatible serial port" + depends on SERIAL_8250=y + select SERIAL_CORE_CONSOLE + ---help--- + If you say Y here, it will be possible to use a serial port as the + system console (the system console is the device which receives all + kernel messages and warnings and which allows logins in single user + mode). This could be useful if some terminal or printer is connected + to that serial port. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttyS1". (Try "man bootparam" or see the documentation of + your boot loader (grub or lilo or loadlin) about how to pass options + to the kernel at boot time.) + + If you don't have a VGA card installed and you say Y here, the + kernel will automatically use the first serial line, /dev/ttyS0, as + system console. + + You can set that using a kernel command line option such as + "console=uart8250,io,0x3f8,9600n8" + "console=uart8250,mmio,0xff5e0000,115200n8". + and it will switch to normal serial console when the corresponding + port is ready. + "earlycon=uart8250,io,0x3f8,9600n8" + "earlycon=uart8250,mmio,0xff5e0000,115200n8". + it will not only setup early console. + + If unsure, say N. + +config FIX_EARLYCON_MEM + bool + depends on X86 + default y + +config SERIAL_8250_GSC + tristate + depends on SERIAL_8250 && GSC + default SERIAL_8250 + +config SERIAL_8250_PCI + tristate "8250/16550 PCI device support" if EXPERT + depends on SERIAL_8250 && PCI + default SERIAL_8250 + help + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. + +config SERIAL_8250_PNP + tristate "8250/16550 PNP device support" if EXPERT + depends on SERIAL_8250 && PNP + default SERIAL_8250 + help + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. + +config SERIAL_8250_FSL + bool + depends on SERIAL_8250_CONSOLE && PPC_UDBG_16550 + default PPC + +config SERIAL_8250_HP300 + tristate + depends on SERIAL_8250 && HP300 + default SERIAL_8250 + +config SERIAL_8250_CS + tristate "8250/16550 PCMCIA device support" + depends on PCMCIA && SERIAL_8250 + ---help--- + Say Y here to enable support for 16-bit PCMCIA serial devices, + including serial port cards, modems, and the modem functions of + multi-function Ethernet/modem cards. (PCMCIA- or PC-cards are + credit-card size devices often used with laptops.) + + To compile this driver as a module, choose M here: the + module will be called serial_cs. + + If unsure, say N. + +config SERIAL_8250_NR_UARTS + int "Maximum number of 8250/16550 serial ports" + depends on SERIAL_8250 + default "4" + help + Set this to the number of serial ports you want the driver + to support. This includes any ports discovered via ACPI or + PCI enumeration and any ports that may be added at run-time + via hot-plug, or any ISA multi-port serial cards. + +config SERIAL_8250_RUNTIME_UARTS + int "Number of 8250/16550 serial ports to register at runtime" + depends on SERIAL_8250 + range 0 SERIAL_8250_NR_UARTS + default "4" + help + Set this to the maximum number of serial ports you want + the kernel to register at boot time. This can be overridden + with the module parameter "nr_uarts", or boot-time parameter + 8250.nr_uarts + +config SERIAL_8250_EXTENDED + bool "Extended 8250/16550 serial driver options" + depends on SERIAL_8250 + help + If you wish to use any non-standard features of the standard "dumb" + driver, say Y here. This includes HUB6 support, shared serial + interrupts, special multiport support, support for more than the + four COM 1/2/3/4 boards, etc. + + Note that the answer to this question won't directly affect the + kernel: saying N will just cause the configurator to skip all + the questions about serial driver options. If unsure, say N. + +config SERIAL_8250_MANY_PORTS + bool "Support more than 4 legacy serial ports" + depends on SERIAL_8250_EXTENDED && !IA64 + help + Say Y here if you have dumb serial boards other than the four + standard COM 1/2/3/4 ports. This may happen if you have an AST + FourPort, Accent Async, Boca (read the Boca mini-HOWTO, available + from ), or other custom + serial port hardware which acts similar to standard serial port + hardware. If you only use the standard COM 1/2/3/4 ports, you can + say N here to save some memory. You can also say Y if you have an + "intelligent" multiport card such as Cyclades, Digiboards, etc. + +# +# Multi-port serial cards +# + +config SERIAL_8250_FOURPORT + tristate "Support Fourport cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an AST FourPort serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_fourport. + +config SERIAL_8250_ACCENT + tristate "Support Accent cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an Accent Async serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_accent. + +config SERIAL_8250_BOCA + tristate "Support Boca cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a Boca serial board. Please read the Boca + mini-HOWTO, available from + + To compile this driver as a module, choose M here: the module + will be called 8250_boca. + +config SERIAL_8250_EXAR_ST16C554 + tristate "Support Exar ST16C554/554D Quad UART" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + The Uplogix Envoy TU301 uses this Exar Quad UART. If you are + tinkering with your Envoy TU301, or have a machine with this UART, + say Y here. + + To compile this driver as a module, choose M here: the module + will be called 8250_exar_st16c554. + +config SERIAL_8250_HUB6 + tristate "Support Hub6 cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a HUB6 serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_hub6. + +config SERIAL_8250_SHARE_IRQ + bool "Support for sharing serial interrupts" + depends on SERIAL_8250_EXTENDED + help + Some serial boards have hardware support which allows multiple dumb + serial ports on the same board to share a single IRQ. To enable + support for this in the serial driver, say Y here. + +config SERIAL_8250_DETECT_IRQ + bool "Autodetect IRQ on standard ports (unsafe)" + depends on SERIAL_8250_EXTENDED + help + Say Y here if you want the kernel to try to guess which IRQ + to use for your serial port. + + This is considered unsafe; it is far better to configure the IRQ in + a boot script using the setserial command. + + If unsure, say N. + +config SERIAL_8250_RSA + bool "Support RSA serial ports" + depends on SERIAL_8250_EXTENDED + help + ::: To be written ::: + +config SERIAL_8250_MCA + tristate "Support 8250-type ports on MCA buses" + depends on SERIAL_8250 != n && MCA + help + Say Y here if you have a MCA serial ports. + + To compile this driver as a module, choose M here: the module + will be called 8250_mca. + +config SERIAL_8250_ACORN + tristate "Acorn expansion card serial port support" + depends on ARCH_ACORN && SERIAL_8250 + help + If you have an Atomwide Serial card or Serial Port card for an Acorn + system, say Y to this option. The driver can handle 1, 2, or 3 port + cards. If unsure, say N. + +config SERIAL_8250_RM9K + bool "Support for MIPS RM9xxx integrated serial port" + depends on SERIAL_8250 != n && SERIAL_RM9000 + select SERIAL_8250_SHARE_IRQ + help + Selecting this option will add support for the integrated serial + port hardware found on MIPS RM9122 and similar processors. + If unsure, say N. + +config SERIAL_8250_DW + tristate "Support for Synopsys DesignWare 8250 quirks" + depends on SERIAL_8250 && OF + help + Selecting this option will enable handling of the extra features + present in the Synopsys DesignWare APB UART. comment "Non-8250 serial port support" @@ -264,6 +536,15 @@ config SERIAL_MAX3107 help MAX3107 chip support +config SERIAL_MAX3107_AAVA + tristate "MAX3107 AAVA platform support" + depends on X86_MRST && SERIAL_MAX3107 && GPIOLIB + select SERIAL_CORE + help + Support for the MAX3107 chip configuration found on the AAVA + platform. Includes the extra initialisation and GPIO support + neded for this device. + config SERIAL_DZ bool "DECstation DZ serial driver" depends on MACH_DECSTATION && 32BIT diff --git a/trunk/drivers/tty/serial/Makefile b/trunk/drivers/tty/serial/Makefile index fef32e10c851..f5b01f2ce525 100644 --- a/trunk/drivers/tty/serial/Makefile +++ b/trunk/drivers/tty/serial/Makefile @@ -14,9 +14,22 @@ obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o -# Now bring in any enabled 8250/16450/16550 type drivers. -obj-$(CONFIG_SERIAL_8250) += 8250/ - +obj-$(CONFIG_SERIAL_8250) += 8250.o +obj-$(CONFIG_SERIAL_8250_PNP) += 8250_pnp.o +obj-$(CONFIG_SERIAL_8250_GSC) += 8250_gsc.o +obj-$(CONFIG_SERIAL_8250_PCI) += 8250_pci.o +obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o +obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o +obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o +obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o +obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o +obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554) += 8250_exar_st16c554.o +obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o +obj-$(CONFIG_SERIAL_8250_FSL) += 8250_fsl.o +obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o @@ -29,6 +42,7 @@ obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o obj-$(CONFIG_SERIAL_MAX3100) += max3100.o obj-$(CONFIG_SERIAL_MAX3107) += max3107.o +obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o obj-$(CONFIG_SERIAL_MUX) += mux.o obj-$(CONFIG_SERIAL_68328) += 68328serial.o diff --git a/trunk/drivers/tty/serial/amba-pl011.c b/trunk/drivers/tty/serial/amba-pl011.c index 6800f5f26241..9ae024025ff3 100644 --- a/trunk/drivers/tty/serial/amba-pl011.c +++ b/trunk/drivers/tty/serial/amba-pl011.c @@ -159,7 +159,6 @@ struct uart_amba_port { unsigned int fifosize; /* vendor-specific */ unsigned int lcrh_tx; /* vendor-specific */ unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ bool autorts; char type[12]; bool interrupt_may_hang; /* vendor-specific */ @@ -1412,9 +1411,7 @@ static int pl011_startup(struct uart_port *port) while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) barrier(); - /* restore RTS and DTR */ - cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); - cr |= UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; + cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; writew(cr, uap->port.membase + UART011_CR); /* Clear pending error interrupts */ @@ -1472,7 +1469,6 @@ static void pl011_shutdown_channel(struct uart_amba_port *uap, static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; - unsigned int cr; /* * disable all interrupts @@ -1492,16 +1488,9 @@ static void pl011_shutdown(struct uart_port *port) /* * disable the port - * disable the port. It should not disable RTS and DTR. - * Also RTS and DTR state should be preserved to restore - * it during startup(). */ uap->autorts = false; - cr = readw(uap->port.membase + UART011_CR); - uap->old_cr = cr; - cr &= UART011_CR_RTS | UART011_CR_DTR; - cr |= UART01x_CR_UARTEN | UART011_CR_TXE; - writew(cr, uap->port.membase + UART011_CR); + writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); /* * disable break condition and fifos @@ -1751,19 +1740,9 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) { struct uart_amba_port *uap = amba_ports[co->index]; unsigned int status, old_cr, new_cr; - unsigned long flags; - int locked = 1; clk_enable(uap->clk); - local_irq_save(flags); - if (uap->port.sysrq) - locked = 0; - else if (oops_in_progress) - locked = spin_trylock(&uap->port.lock); - else - spin_lock(&uap->port.lock); - /* * First save the CR then disable the interrupts */ @@ -1783,10 +1762,6 @@ pl011_console_write(struct console *co, const char *s, unsigned int count) } while (status & UART01x_FR_BUSY); writew(old_cr, uap->port.membase + UART011_CR); - if (locked) - spin_unlock(&uap->port.lock); - local_irq_restore(flags); - clk_disable(uap->clk); } @@ -1930,7 +1905,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->vendor = vendor; uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; - uap->old_cr = 0; uap->fifosize = vendor->fifosize; uap->interrupt_may_hang = vendor->interrupt_may_hang; uap->port.dev = &dev->dev; diff --git a/trunk/drivers/tty/serial/jsm/jsm_driver.c b/trunk/drivers/tty/serial/jsm/jsm_driver.c index 7545fe1b9925..7c867a046c97 100644 --- a/trunk/drivers/tty/serial/jsm/jsm_driver.c +++ b/trunk/drivers/tty/serial/jsm/jsm_driver.c @@ -251,7 +251,6 @@ static void jsm_io_resume(struct pci_dev *pdev) struct jsm_board *brd = pci_get_drvdata(pdev); pci_restore_state(pdev); - pci_save_state(pdev); jsm_uart_port_init(brd); } diff --git a/trunk/drivers/tty/serial/8250/m32r_sio.c b/trunk/drivers/tty/serial/m32r_sio.c similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio.c rename to trunk/drivers/tty/serial/m32r_sio.c diff --git a/trunk/drivers/tty/serial/8250/m32r_sio.h b/trunk/drivers/tty/serial/m32r_sio.h similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio.h rename to trunk/drivers/tty/serial/m32r_sio.h diff --git a/trunk/drivers/tty/serial/8250/m32r_sio_reg.h b/trunk/drivers/tty/serial/m32r_sio_reg.h similarity index 100% rename from trunk/drivers/tty/serial/8250/m32r_sio_reg.h rename to trunk/drivers/tty/serial/m32r_sio_reg.h diff --git a/trunk/drivers/tty/serial/max3107-aava.c b/trunk/drivers/tty/serial/max3107-aava.c new file mode 100644 index 000000000000..aae772a71de6 --- /dev/null +++ b/trunk/drivers/tty/serial/max3107-aava.c @@ -0,0 +1,344 @@ +/* + * max3107.c - spi uart protocol driver for Maxim 3107 + * Based on max3100.c + * by Christian Pellegrin + * and max3110.c + * by Feng Tang + * + * Copyright (C) Aavamobile 2009 + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "max3107.h" + +/* GPIO direction to input function */ +static int max3107_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[1]; /* Buffer for SPI transfer */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO configuration register */ + buf[0] = MAX3107_GPIOCFG_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO read failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + + /* Set GPIO to input */ + buf[0] &= ~(0x0001 << offset); + + /* Write new GPIO configuration register value */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO write failed\n"); + return -EIO; + } + return 0; +} + +/* GPIO direction to output function */ +static int max3107_gpio_direction_out(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[2]; /* Buffer for SPI transfers */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO configuration and data registers */ + buf[0] = MAX3107_GPIOCFG_REG; + buf[1] = MAX3107_GPIODATA_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { + dev_err(&s->spi->dev, "SPI transfer gpio failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + buf[1] &= MAX3107_SPI_RX_DATA_MASK; + + /* Set GPIO to output */ + buf[0] |= (0x0001 << offset); + /* Set value */ + if (value) + buf[1] |= (0x0001 << offset); + else + buf[1] &= ~(0x0001 << offset); + + /* Write new GPIO configuration and data register values */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIOCFG_REG); + buf[1] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 4)) { + dev_err(&s->spi->dev, + "SPI transfer for GPIO conf data w failed\n"); + return -EIO; + } + return 0; +} + +/* GPIO value query function */ +static int max3107_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[1]; /* Buffer for SPI transfer */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return -EINVAL; + } + + /* Read current GPIO data register */ + buf[0] = MAX3107_GPIODATA_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { + dev_err(&s->spi->dev, "SPI transfer GPIO data r failed\n"); + return -EIO; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + + /* Return value */ + return buf[0] & (0x0001 << offset); +} + +/* GPIO value set function */ +static void max3107_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct max3107_port *s = container_of(chip, struct max3107_port, chip); + u16 buf[2]; /* Buffer for SPI transfers */ + + if (offset >= MAX3107_GPIO_COUNT) { + dev_err(&s->spi->dev, "Invalid GPIO\n"); + return; + } + + /* Read current GPIO configuration registers*/ + buf[0] = MAX3107_GPIODATA_REG; + buf[1] = MAX3107_GPIOCFG_REG; + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 4)) { + dev_err(&s->spi->dev, + "SPI transfer for GPIO data and config read failed\n"); + return; + } + buf[0] &= MAX3107_SPI_RX_DATA_MASK; + buf[1] &= MAX3107_SPI_RX_DATA_MASK; + + if (!(buf[1] & (0x0001 << offset))) { + /* Configured as input, can't set value */ + dev_warn(&s->spi->dev, + "Trying to set value for input GPIO\n"); + return; + } + + /* Set value */ + if (value) + buf[0] |= (0x0001 << offset); + else + buf[0] &= ~(0x0001 << offset); + + /* Write new GPIO data register value */ + buf[0] |= (MAX3107_WRITE_BIT | MAX3107_GPIODATA_REG); + /* Perform SPI transfer */ + if (max3107_rw(s, (u8 *)buf, NULL, 2)) + dev_err(&s->spi->dev, "SPI transfer GPIO data w failed\n"); +} + +/* GPIO chip data */ +static struct gpio_chip max3107_gpio_chip = { + .owner = THIS_MODULE, + .direction_input = max3107_gpio_direction_in, + .direction_output = max3107_gpio_direction_out, + .get = max3107_gpio_get, + .set = max3107_gpio_set, + .can_sleep = 1, + .base = MAX3107_GPIO_BASE, + .ngpio = MAX3107_GPIO_COUNT, +}; + +/** + * max3107_aava_reset - reset on AAVA systems + * @spi: The SPI device we are probing + * + * Reset the device ready for probing. + */ + +static int max3107_aava_reset(struct spi_device *spi) +{ + /* Reset the chip */ + if (gpio_request(MAX3107_RESET_GPIO, "max3107")) { + pr_err("Requesting RESET GPIO failed\n"); + return -EIO; + } + if (gpio_direction_output(MAX3107_RESET_GPIO, 0)) { + pr_err("Setting RESET GPIO to 0 failed\n"); + gpio_free(MAX3107_RESET_GPIO); + return -EIO; + } + msleep(MAX3107_RESET_DELAY); + if (gpio_direction_output(MAX3107_RESET_GPIO, 1)) { + pr_err("Setting RESET GPIO to 1 failed\n"); + gpio_free(MAX3107_RESET_GPIO); + return -EIO; + } + gpio_free(MAX3107_RESET_GPIO); + msleep(MAX3107_WAKEUP_DELAY); + return 0; +} + +static int max3107_aava_configure(struct max3107_port *s) +{ + int retval; + + /* Initialize GPIO chip data */ + s->chip = max3107_gpio_chip; + s->chip.label = s->spi->modalias; + s->chip.dev = &s->spi->dev; + + /* Add GPIO chip */ + retval = gpiochip_add(&s->chip); + if (retval) { + dev_err(&s->spi->dev, "Adding GPIO chip failed\n"); + return retval; + } + + /* Temporary fix for EV2 boot problems, set modem reset to 0 */ + max3107_gpio_direction_out(&s->chip, 3, 0); + return 0; +} + +#if 0 +/* This will get enabled once we have the board stuff merged for this + specific case */ + +static const struct baud_table brg13_ext[] = { + { 300, MAX3107_BRG13_B300 }, + { 600, MAX3107_BRG13_B600 }, + { 1200, MAX3107_BRG13_B1200 }, + { 2400, MAX3107_BRG13_B2400 }, + { 4800, MAX3107_BRG13_B4800 }, + { 9600, MAX3107_BRG13_B9600 }, + { 19200, MAX3107_BRG13_B19200 }, + { 57600, MAX3107_BRG13_B57600 }, + { 115200, MAX3107_BRG13_B115200 }, + { 230400, MAX3107_BRG13_B230400 }, + { 460800, MAX3107_BRG13_B460800 }, + { 921600, MAX3107_BRG13_B921600 }, + { 0, 0 } +}; + +static void max3107_aava_init(struct max3107_port *s) +{ + /*override for AAVA SC specific*/ + if (mrst_platform_id() == MRST_PLATFORM_AAVA_SC) { + if (get_koski_build_id() <= KOSKI_EV2) + if (s->ext_clk) { + s->brg_cfg = MAX3107_BRG13_B9600; + s->baud_tbl = (struct baud_table *)brg13_ext; + } + } +} +#endif + +static int __devexit max3107_aava_remove(struct spi_device *spi) +{ + struct max3107_port *s = dev_get_drvdata(&spi->dev); + + /* Remove GPIO chip */ + if (gpiochip_remove(&s->chip)) + dev_warn(&spi->dev, "Removing GPIO chip failed\n"); + + /* Then do the default remove */ + return max3107_remove(spi); +} + +/* Platform data */ +static struct max3107_plat aava_plat_data = { + .loopback = 0, + .ext_clk = 1, +/* .init = max3107_aava_init, */ + .configure = max3107_aava_configure, + .hw_suspend = max3107_hw_susp, + .polled_mode = 0, + .poll_time = 0, +}; + + +static int __devinit max3107_probe_aava(struct spi_device *spi) +{ + int err = max3107_aava_reset(spi); + if (err < 0) + return err; + return max3107_probe(spi, &aava_plat_data); +} + +/* Spi driver data */ +static struct spi_driver max3107_driver = { + .driver = { + .name = "aava-max3107", + .owner = THIS_MODULE, + }, + .probe = max3107_probe_aava, + .remove = __devexit_p(max3107_aava_remove), + .suspend = max3107_suspend, + .resume = max3107_resume, +}; + +/* Driver init function */ +static int __init max3107_init(void) +{ + return spi_register_driver(&max3107_driver); +} + +/* Driver exit function */ +static void __exit max3107_exit(void) +{ + spi_unregister_driver(&max3107_driver); +} + +module_init(max3107_init); +module_exit(max3107_exit); + +MODULE_DESCRIPTION("MAX3107 driver"); +MODULE_AUTHOR("Aavamobile"); +MODULE_ALIAS("spi:aava-max3107"); +MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/tty/serial/omap-serial.c b/trunk/drivers/tty/serial/omap-serial.c index 1c2426931484..d192dcbb82f5 100644 --- a/trunk/drivers/tty/serial/omap-serial.c +++ b/trunk/drivers/tty/serial/omap-serial.c @@ -1160,7 +1160,7 @@ static struct uart_driver serial_omap_reg = { .cons = OMAP_CONSOLE, }; -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_SUSPEND static int serial_omap_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); @@ -1521,7 +1521,6 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) } } -#ifdef CONFIG_PM_RUNTIME static void serial_omap_restore_context(struct uart_omap_port *up) { if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) @@ -1551,6 +1550,7 @@ static void serial_omap_restore_context(struct uart_omap_port *up) serial_out(up, UART_OMAP_MDR1, up->mdr1); } +#ifdef CONFIG_PM_RUNTIME static int serial_omap_runtime_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); diff --git a/trunk/drivers/tty/serial/serial_core.c b/trunk/drivers/tty/serial/serial_core.c index 13056180adf5..c7bf31a6a7e7 100644 --- a/trunk/drivers/tty/serial/serial_core.c +++ b/trunk/drivers/tty/serial/serial_core.c @@ -2348,11 +2348,11 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) */ tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); if (likely(!IS_ERR(tty_dev))) { - device_set_wakeup_capable(tty_dev, 1); - } else { + device_init_wakeup(tty_dev, 1); + device_set_wakeup_enable(tty_dev, 0); + } else printk(KERN_ERR "Cannot register tty device on line %d\n", uport->line); - } /* * Ensure UPF_DEAD is not set. diff --git a/trunk/drivers/tty/serial/8250/serial_cs.c b/trunk/drivers/tty/serial/serial_cs.c similarity index 100% rename from trunk/drivers/tty/serial/8250/serial_cs.c rename to trunk/drivers/tty/serial/serial_cs.c diff --git a/trunk/drivers/tty/tty_port.c b/trunk/drivers/tty/tty_port.c index bf6e238146ae..ef9dd628ba0b 100644 --- a/trunk/drivers/tty/tty_port.c +++ b/trunk/drivers/tty/tty_port.c @@ -227,6 +227,7 @@ int tty_port_block_til_ready(struct tty_port *port, int do_clocal = 0, retval; unsigned long flags; DEFINE_WAIT(wait); + int cd; /* block if port is in the process of being closed */ if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { @@ -283,14 +284,11 @@ int tty_port_block_til_ready(struct tty_port *port, retval = -ERESTARTSYS; break; } - /* - * Probe the carrier. For devices with no carrier detect - * tty_port_carrier_raised will always return true. - * Never ask drivers if CLOCAL is set, this causes troubles - * on some hardware. - */ + /* Probe the carrier. For devices with no carrier detect this + will always return true */ + cd = tty_port_carrier_raised(port); if (!(port->flags & ASYNC_CLOSING) && - (do_clocal || tty_port_carrier_raised(port))) + (do_clocal || cd)) break; if (signal_pending(current)) { retval = -ERESTARTSYS; diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index d2b3cffca3f7..1c50baff7725 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -57,8 +57,6 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_MAX 16 -/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ -#define WDM_DEFAULT_BUFSIZE 256 static DEFINE_MUTEX(wdm_mutex); @@ -90,8 +88,7 @@ struct wdm_device { int count; dma_addr_t shandle; dma_addr_t ihandle; - struct mutex wlock; - struct mutex rlock; + struct mutex lock; wait_queue_head_t wait; struct work_struct rxwork; int werr; @@ -326,7 +323,7 @@ static ssize_t wdm_write } /* concurrent writes and disconnect */ - r = mutex_lock_interruptible(&desc->wlock); + r = mutex_lock_interruptible(&desc->lock); rv = -ERESTARTSYS; if (r) { kfree(buf); @@ -389,7 +386,7 @@ static ssize_t wdm_write out: usb_autopm_put_interface(desc->intf); outnp: - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); outnl: return rv < 0 ? rv : count; } @@ -402,7 +399,7 @@ static ssize_t wdm_read struct wdm_device *desc = file->private_data; - rv = mutex_lock_interruptible(&desc->rlock); /*concurrent reads */ + rv = mutex_lock_interruptible(&desc->lock); /*concurrent reads */ if (rv < 0) return -ERESTARTSYS; @@ -470,16 +467,14 @@ static ssize_t wdm_read for (i = 0; i < desc->length - cntr; i++) desc->ubuf[i] = desc->ubuf[i + cntr]; - spin_lock_irq(&desc->iuspin); desc->length -= cntr; - spin_unlock_irq(&desc->iuspin); /* in case we had outstanding data */ if (!desc->length) clear_bit(WDM_READ, &desc->flags); rv = cntr; err: - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return rv; } @@ -545,8 +540,7 @@ static int wdm_open(struct inode *inode, struct file *file) } intf->needs_remote_wakeup = 1; - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); if (!desc->count++) { desc->werr = 0; desc->rerr = 0; @@ -559,7 +553,7 @@ static int wdm_open(struct inode *inode, struct file *file) } else { rv = 0; } - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); usb_autopm_put_interface(desc->intf); out: mutex_unlock(&wdm_mutex); @@ -571,11 +565,9 @@ static int wdm_release(struct inode *inode, struct file *file) struct wdm_device *desc = file->private_data; mutex_lock(&wdm_mutex); - - /* using write lock to protect desc->count */ - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); desc->count--; - mutex_unlock(&desc->wlock); + mutex_unlock(&desc->lock); if (!desc->count) { dev_dbg(&desc->intf->dev, "wdm_release: cleanup"); @@ -638,7 +630,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; - u16 maxcom = WDM_DEFAULT_BUFSIZE; + u16 maxcom = 0; if (!buffer) goto out; @@ -673,8 +665,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); if (!desc) goto out; - mutex_init(&desc->rlock); - mutex_init(&desc->wlock); + mutex_init(&desc->lock); spin_lock_init(&desc->iuspin); init_waitqueue_head(&desc->wait); desc->wMaxCommand = maxcom; @@ -725,7 +716,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxCommand, + desc->bMaxPacketSize0, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) @@ -788,13 +779,11 @@ static void wdm_disconnect(struct usb_interface *intf) /* to terminate pending flushes */ clear_bit(WDM_IN_USE, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - wake_up_all(&desc->wait); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); cancel_work_sync(&desc->rxwork); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); + wake_up_all(&desc->wait); if (!desc->count) cleanup(desc); mutex_unlock(&wdm_mutex); @@ -809,10 +798,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) dev_dbg(&desc->intf->dev, "wdm%d_suspend\n", intf->minor); /* if this is an autosuspend the caller does the locking */ - if (!PMSG_IS_AUTO(message)) { - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); - } + if (!PMSG_IS_AUTO(message)) + mutex_lock(&desc->lock); spin_lock_irq(&desc->iuspin); if (PMSG_IS_AUTO(message) && @@ -828,10 +815,8 @@ static int wdm_suspend(struct usb_interface *intf, pm_message_t message) kill_urbs(desc); cancel_work_sync(&desc->rxwork); } - if (!PMSG_IS_AUTO(message)) { - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); - } + if (!PMSG_IS_AUTO(message)) + mutex_unlock(&desc->lock); return rv; } @@ -869,8 +854,7 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); - mutex_lock(&desc->rlock); - mutex_lock(&desc->wlock); + mutex_lock(&desc->lock); kill_urbs(desc); /* @@ -892,8 +876,7 @@ static int wdm_post_reset(struct usb_interface *intf) int rv; rv = recover_from_urb_loss(desc); - mutex_unlock(&desc->wlock); - mutex_unlock(&desc->rlock); + mutex_unlock(&desc->lock); return 0; } diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index c8df1dd967ef..2f51de57593a 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -126,6 +126,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, struct dwc3_request *req) { struct dwc3 *dwc = dep->dwc; + u32 type; int ret = 0; req->request.actual = 0; @@ -148,14 +149,20 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, direction = !!(dep->flags & DWC3_EP0_DIR_IN); - if (dwc->ep0state != EP0_DATA_PHASE) { - dev_WARN(dwc->dev, "Unexpected pending request\n"); + if (dwc->ep0state == EP0_STATUS_PHASE) { + type = dwc->three_stage_setup + ? DWC3_TRBCTL_CONTROL_STATUS3 + : DWC3_TRBCTL_CONTROL_STATUS2; + } else if (dwc->ep0state == EP0_DATA_PHASE) { + type = DWC3_TRBCTL_CONTROL_DATA; + } else { + /* should never happen */ + WARN_ON(1); return 0; } ret = dwc3_ep0_start_trans(dwc, direction, - req->request.dma, req->request.length, - DWC3_TRBCTL_CONTROL_DATA); + req->request.dma, req->request.length, type); dep->flags &= ~(DWC3_EP_PENDING_REQUEST | DWC3_EP0_DIR_IN); } else if (dwc->delayed_status) { diff --git a/trunk/drivers/usb/dwc3/gadget.c b/trunk/drivers/usb/dwc3/gadget.c index 064b6e2cd411..a696bde53222 100644 --- a/trunk/drivers/usb/dwc3/gadget.c +++ b/trunk/drivers/usb/dwc3/gadget.c @@ -101,7 +101,7 @@ void dwc3_unmap_buffer_from_dma(struct dwc3_request *req) if (req->request.num_mapped_sgs) { req->request.dma = DMA_ADDR_INVALID; dma_unmap_sg(dwc->dev, req->request.sg, - req->request.num_mapped_sgs, + req->request.num_sgs, req->direction ? DMA_TO_DEVICE : DMA_FROM_DEVICE); diff --git a/trunk/drivers/usb/gadget/composite.c b/trunk/drivers/usb/gadget/composite.c index baaebf2830fc..a95de6a4a134 100644 --- a/trunk/drivers/usb/gadget/composite.c +++ b/trunk/drivers/usb/gadget/composite.c @@ -175,13 +175,14 @@ int config_ep_by_speed(struct usb_gadget *g, _ep->comp_desc = comp_desc; if (g->speed == USB_SPEED_SUPER) { switch (usb_endpoint_type(_ep->desc)) { - case USB_ENDPOINT_XFER_ISOC: - /* mult: bits 1:0 of bmAttributes */ - _ep->mult = comp_desc->bmAttributes & 0x3; case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: _ep->maxburst = comp_desc->bMaxBurst; break; + case USB_ENDPOINT_XFER_ISOC: + /* mult: bits 1:0 of bmAttributes */ + _ep->mult = comp_desc->bmAttributes & 0x3; + break; default: /* Do nothing for control endpoints */ break; diff --git a/trunk/drivers/usb/gadget/epautoconf.c b/trunk/drivers/usb/gadget/epautoconf.c index e0e6375ef5dd..753aa0683ac1 100644 --- a/trunk/drivers/usb/gadget/epautoconf.c +++ b/trunk/drivers/usb/gadget/epautoconf.c @@ -126,7 +126,7 @@ ep_matches ( * descriptor and see if the EP matches it */ if (usb_endpoint_xfer_bulk(desc)) { - if (ep_comp && gadget->max_speed >= USB_SPEED_SUPER) { + if (ep_comp) { num_req_streams = ep_comp->bmAttributes & 0x1f; if (num_req_streams > ep->max_streams) return 0; diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index ee8ceec01560..6353eca1e852 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -3123,15 +3123,15 @@ fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c, struct fsg_module_parameters { char *file[FSG_MAX_LUNS]; - bool ro[FSG_MAX_LUNS]; - bool removable[FSG_MAX_LUNS]; - bool cdrom[FSG_MAX_LUNS]; - bool nofua[FSG_MAX_LUNS]; + int ro[FSG_MAX_LUNS]; + int removable[FSG_MAX_LUNS]; + int cdrom[FSG_MAX_LUNS]; + int nofua[FSG_MAX_LUNS]; unsigned int file_count, ro_count, removable_count, cdrom_count; unsigned int nofua_count; unsigned int luns; /* nluns */ - bool stall; /* can_stall */ + int stall; /* can_stall */ }; #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index b04712f19f1e..d7ea6c076ce9 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -1430,7 +1430,7 @@ static void setup_received_irq(struct fsl_udc *udc, int pipe = get_pipe_by_windex(wIndex); struct fsl_ep *ep; - if (wValue != 0 || wLength != 0 || pipe >= udc->max_ep) + if (wValue != 0 || wLength != 0 || pipe > udc->max_ep) break; ep = get_ep_by_pipe(udc, pipe); @@ -1673,7 +1673,7 @@ static void dtd_complete_irq(struct fsl_udc *udc) if (!bit_pos) return; - for (i = 0; i < udc->max_ep; i++) { + for (i = 0; i < udc->max_ep * 2; i++) { ep_num = i >> 1; direction = i % 2; diff --git a/trunk/drivers/usb/gadget/langwell_udc.c b/trunk/drivers/usb/gadget/langwell_udc.c index e2293c1588ee..fa0fcc11263f 100644 --- a/trunk/drivers/usb/gadget/langwell_udc.c +++ b/trunk/drivers/usb/gadget/langwell_udc.c @@ -11,6 +11,11 @@ /* #undef DEBUG */ /* #undef VERBOSE_DEBUG */ +#if defined(CONFIG_USB_LANGWELL_OTG) +#define OTG_TRANSCEIVER +#endif + + #include #include #include @@ -1517,7 +1522,8 @@ static void langwell_udc_stop(struct langwell_udc *dev) /* stop all USB activities */ -static void stop_activity(struct langwell_udc *dev) +static void stop_activity(struct langwell_udc *dev, + struct usb_gadget_driver *driver) { struct langwell_ep *ep; dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); @@ -1529,9 +1535,9 @@ static void stop_activity(struct langwell_udc *dev) } /* report disconnect; the driver is already quiesced */ - if (dev->driver) { + if (driver) { spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); + driver->disconnect(&dev->gadget); spin_lock(&dev->lock); } @@ -1919,10 +1925,11 @@ static int langwell_stop(struct usb_gadget *g, /* stop all usb activities */ dev->gadget.speed = USB_SPEED_UNKNOWN; + stop_activity(dev, driver); + spin_unlock_irqrestore(&dev->lock, flags); + dev->gadget.dev.driver = NULL; dev->driver = NULL; - stop_activity(dev); - spin_unlock_irqrestore(&dev->lock, flags); device_remove_file(&dev->pdev->dev, &dev_attr_function); @@ -2308,9 +2315,13 @@ static void handle_setup_packet(struct langwell_udc *dev, if (!gadget_is_otg(&dev->gadget)) break; - else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) + else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) { dev->gadget.b_hnp_enable = 1; - else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) +#ifdef OTG_TRANSCEIVER + if (!dev->lotg->otg.default_a) + dev->lotg->hsm.b_hnp_enable = 1; +#endif + } else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) dev->gadget.a_hnp_support = 1; else if (setup->bRequest == USB_DEVICE_A_ALT_HNP_SUPPORT) @@ -2722,7 +2733,7 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->bus_reset = 1; /* reset all the queues, stop all USB activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); dev->usb_state = USB_STATE_DEFAULT; } else { dev_vdbg(&dev->pdev->dev, "device controller reset\n"); @@ -2730,7 +2741,7 @@ static void handle_usb_reset(struct langwell_udc *dev) langwell_udc_reset(dev); /* reset all the queues, stop all USB activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); /* reset ep0 dQH and endptctrl */ ep0_reset(dev); @@ -2741,6 +2752,12 @@ static void handle_usb_reset(struct langwell_udc *dev) dev->usb_state = USB_STATE_ATTACHED; } +#ifdef OTG_TRANSCEIVER + /* refer to USB OTG 6.6.2.3 b_hnp_en is cleared */ + if (!dev->lotg->otg.default_a) + dev->lotg->hsm.b_hnp_enable = 0; +#endif + dev_vdbg(&dev->pdev->dev, "<--- %s()\n", __func__); } @@ -2753,6 +2770,29 @@ static void handle_bus_suspend(struct langwell_udc *dev) dev->resume_state = dev->usb_state; dev->usb_state = USB_STATE_SUSPENDED; +#ifdef OTG_TRANSCEIVER + if (dev->lotg->otg.default_a) { + if (dev->lotg->hsm.b_bus_suspend_vld == 1) { + dev->lotg->hsm.b_bus_suspend = 1; + /* notify transceiver the state changes */ + if (spin_trylock(&dev->lotg->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&dev->lotg->wq_lock); + } + } + dev->lotg->hsm.b_bus_suspend_vld++; + } else { + if (!dev->lotg->hsm.a_bus_suspend) { + dev->lotg->hsm.a_bus_suspend = 1; + /* notify transceiver the state changes */ + if (spin_trylock(&dev->lotg->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&dev->lotg->wq_lock); + } + } + } +#endif + /* report suspend to the driver */ if (dev->driver) { if (dev->driver->suspend) { @@ -2783,6 +2823,11 @@ static void handle_bus_resume(struct langwell_udc *dev) if (dev->pdev->device != 0x0829) langwell_phy_low_power(dev, 0); +#ifdef OTG_TRANSCEIVER + if (dev->lotg->otg.default_a == 0) + dev->lotg->hsm.a_bus_suspend = 0; +#endif + /* report resume to the driver */ if (dev->driver) { if (dev->driver->resume) { @@ -2975,6 +3020,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) dev->done = &done; +#ifndef OTG_TRANSCEIVER /* free dTD dma_pool and dQH */ if (dev->dtd_pool) dma_pool_destroy(dev->dtd_pool); @@ -2986,6 +3032,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) /* release SRAM caching */ if (dev->has_sram && dev->got_sram) sram_deinit(dev); +#endif if (dev->status_req) { kfree(dev->status_req->req.buf); @@ -2998,6 +3045,7 @@ static void langwell_udc_remove(struct pci_dev *pdev) if (dev->got_irq) free_irq(pdev->irq, dev); +#ifndef OTG_TRANSCEIVER if (dev->cap_regs) iounmap(dev->cap_regs); @@ -3007,6 +3055,13 @@ static void langwell_udc_remove(struct pci_dev *pdev) if (dev->enabled) pci_disable_device(pdev); +#else + if (dev->transceiver) { + otg_put_transceiver(dev->transceiver); + dev->transceiver = NULL; + dev->lotg = NULL; + } +#endif dev->cap_regs = NULL; @@ -3017,7 +3072,9 @@ static void langwell_udc_remove(struct pci_dev *pdev) device_remove_file(&pdev->dev, &dev_attr_langwell_udc); device_remove_file(&pdev->dev, &dev_attr_remote_wakeup); +#ifndef OTG_TRANSCEIVER pci_set_drvdata(pdev, NULL); +#endif /* free dev, wait for the release() finished */ wait_for_completion(&done); @@ -3032,7 +3089,9 @@ static int langwell_udc_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct langwell_udc *dev; +#ifndef OTG_TRANSCEIVER unsigned long resource, len; +#endif void __iomem *base = NULL; size_t size; int retval; @@ -3050,6 +3109,16 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->pdev = pdev; dev_dbg(&dev->pdev->dev, "---> %s()\n", __func__); +#ifdef OTG_TRANSCEIVER + /* PCI device is already enabled by otg_transceiver driver */ + dev->enabled = 1; + + /* mem region and register base */ + dev->region = 1; + dev->transceiver = otg_get_transceiver(); + dev->lotg = otg_to_langwell(dev->transceiver); + base = dev->lotg->regs; +#else pci_set_drvdata(pdev, dev); /* now all the pci goodies ... */ @@ -3070,6 +3139,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->region = 1; base = ioremap_nocache(resource, len); +#endif if (base == NULL) { dev_err(&dev->pdev->dev, "can't map memory\n"); retval = -EFAULT; @@ -3093,6 +3163,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->got_sram = 0; dev_vdbg(&dev->pdev->dev, "dev->has_sram: %d\n", dev->has_sram); +#ifndef OTG_TRANSCEIVER /* enable SRAM caching if detected */ if (dev->has_sram && !dev->got_sram) sram_init(dev); @@ -3111,6 +3182,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, goto error; } dev->got_irq = 1; +#endif /* set stopped bit */ dev->stopped = 1; @@ -3185,8 +3257,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, dev->remote_wakeup = 0; dev->dev_status = 1 << USB_DEVICE_SELF_POWERED; +#ifndef OTG_TRANSCEIVER /* reset device controller */ langwell_udc_reset(dev); +#endif /* initialize gadget structure */ dev->gadget.ops = &langwell_ops; /* usb_gadget_ops */ @@ -3194,6 +3268,9 @@ static int langwell_udc_probe(struct pci_dev *pdev, INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ +#ifdef OTG_TRANSCEIVER + dev->gadget.is_otg = 1; /* support otg mode */ +#endif /* the "gadget" abstracts/virtualizes the controller */ dev_set_name(&dev->gadget.dev, "gadget"); @@ -3205,8 +3282,10 @@ static int langwell_udc_probe(struct pci_dev *pdev, /* controller endpoints reinit */ eps_reinit(dev); +#ifndef OTG_TRANSCEIVER /* reset ep0 dQH and endptctrl */ ep0_reset(dev); +#endif /* create dTD dma_pool resource */ dev->dtd_pool = dma_pool_create("langwell_dtd", @@ -3288,7 +3367,7 @@ static int langwell_udc_suspend(struct pci_dev *pdev, pm_message_t state) spin_lock_irq(&dev->lock); /* stop all usb activities */ - stop_activity(dev); + stop_activity(dev, dev->driver); spin_unlock_irq(&dev->lock); /* free dTD dma_pool and dQH */ @@ -3446,14 +3525,22 @@ static struct pci_driver langwell_pci_driver = { static int __init init(void) { +#ifdef OTG_TRANSCEIVER + return langwell_register_peripheral(&langwell_pci_driver); +#else return pci_register_driver(&langwell_pci_driver); +#endif } module_init(init); static void __exit cleanup(void) { +#ifdef OTG_TRANSCEIVER + return langwell_unregister_peripheral(&langwell_pci_driver); +#else pci_unregister_driver(&langwell_pci_driver); +#endif } module_exit(cleanup); diff --git a/trunk/drivers/usb/gadget/langwell_udc.h b/trunk/drivers/usb/gadget/langwell_udc.h index d6e78accaffe..ef79e242b7b0 100644 --- a/trunk/drivers/usb/gadget/langwell_udc.h +++ b/trunk/drivers/usb/gadget/langwell_udc.h @@ -8,6 +8,7 @@ */ #include +#include /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/storage_common.c b/trunk/drivers/usb/gadget/storage_common.c index 85ea14e2545e..c7f291a331df 100644 --- a/trunk/drivers/usb/gadget/storage_common.c +++ b/trunk/drivers/usb/gadget/storage_common.c @@ -598,16 +598,16 @@ static __maybe_unused struct usb_ss_cap_descriptor fsg_ss_cap_desc = { | USB_5GBPS_OPERATION), .bFunctionalitySupport = USB_LOW_SPEED_OPERATION, .bU1devExitLat = USB_DEFAULT_U1_DEV_EXIT_LAT, - .bU2DevExitLat = cpu_to_le16(USB_DEFAULT_U2_DEV_EXIT_LAT), + .bU2DevExitLat = USB_DEFAULT_U2_DEV_EXIT_LAT, }; static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { .bLength = USB_DT_BOS_SIZE, .bDescriptorType = USB_DT_BOS, - .wTotalLength = cpu_to_le16(USB_DT_BOS_SIZE + .wTotalLength = USB_DT_BOS_SIZE + USB_DT_USB_EXT_CAP_SIZE - + USB_DT_USB_SS_CAP_SIZE), + + USB_DT_USB_SS_CAP_SIZE, .bNumDeviceCaps = 2, }; diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index b556a72264d1..e90344a17631 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -125,7 +125,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, */ if (pdata->init && pdata->init(pdev)) { retval = -ENODEV; - goto err4; + goto err3; } /* Enable USB controller, 83xx or 8536 */ diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index 01bb7241d6ef..f4b627d343ac 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -276,9 +276,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* Serial Bus Release Number is at PCI 0x60 offset */ pci_read_config_byte(pdev, 0x60, &ehci->sbrn); - if (pdev->vendor == PCI_VENDOR_ID_STMICRO - && pdev->device == PCI_DEVICE_ID_STMICRO_USB_HOST) - ehci->sbrn = 0x20; /* ConneXT has no sbrn register */ /* Keep this around for a while just in case some EHCI * implementation uses legacy PCI PM support. This test @@ -529,9 +526,6 @@ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), .driver_data = (unsigned long) &ehci_pci_hc_driver, - }, { - PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_HOST), - .driver_data = (unsigned long) &ehci_pci_hc_driver, }, { /* end: all zeroes */ } }; diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 77afabc77f9b..5df0b0e3392b 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -139,23 +139,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, } iclk = clk_get(&pdev->dev, "ohci_clk"); - if (IS_ERR(iclk)) { - dev_err(&pdev->dev, "failed to get ohci_clk\n"); - retval = PTR_ERR(iclk); - goto err3; - } fclk = clk_get(&pdev->dev, "uhpck"); - if (IS_ERR(fclk)) { - dev_err(&pdev->dev, "failed to get uhpck\n"); - retval = PTR_ERR(fclk); - goto err4; - } hclk = clk_get(&pdev->dev, "hclk"); - if (IS_ERR(hclk)) { - dev_err(&pdev->dev, "failed to get hclk\n"); - retval = PTR_ERR(hclk); - goto err5; - } at91_start_hc(pdev); ohci_hcd_init(hcd_to_ohci(hcd)); @@ -168,12 +153,9 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, at91_stop_hc(pdev); clk_put(hclk); - err5: clk_put(fclk); - err4: clk_put(iclk); - err3: iounmap(hcd->regs); err2: @@ -244,8 +226,7 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int if (!gpio_is_valid(pdata->vbus_pin[port])) return; - gpio_set_value(pdata->vbus_pin[port], - !pdata->vbus_pin_active_low[port] ^ enable); + gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); } static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) @@ -256,8 +237,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) if (!gpio_is_valid(pdata->vbus_pin[port])) return -EINVAL; - return gpio_get_value(pdata->vbus_pin[port]) ^ - !pdata->vbus_pin_active_low[port]; + return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; } /* diff --git a/trunk/drivers/usb/host/ohci-dbg.c b/trunk/drivers/usb/host/ohci-dbg.c index e4bcb62b930a..5179fcd73d8a 100644 --- a/trunk/drivers/usb/host/ohci-dbg.c +++ b/trunk/drivers/usb/host/ohci-dbg.c @@ -82,14 +82,6 @@ urb_print(struct urb * urb, char * str, int small, int status) ohci_dbg(ohci,format, ## arg ); \ } while (0); -/* Version for use where "next" is the address of a local variable */ -#define ohci_dbg_nosw(ohci, next, size, format, arg...) \ - do { \ - unsigned s_len; \ - s_len = scnprintf(*next, *size, format, ## arg); \ - *size -= s_len; *next += s_len; \ - } while (0); - static void ohci_dump_intr_mask ( struct ohci_hcd *ohci, @@ -661,7 +653,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* dump driver info, then registers in spec order */ - ohci_dbg_nosw(ohci, &next, &size, + ohci_dbg_sw (ohci, &next, &size, "bus %s, device %s\n" "%s\n" "%s\n", @@ -680,7 +672,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* hcca */ if (ohci->hcca) - ohci_dbg_nosw(ohci, &next, &size, + ohci_dbg_sw (ohci, &next, &size, "hcca frame 0x%04x\n", ohci_frame_no(ohci)); /* other registers mostly affect frame timings */ diff --git a/trunk/drivers/usb/host/ohci-pci.c b/trunk/drivers/usb/host/ohci-pci.c index 1843bb68ac7c..6109810cc2d3 100644 --- a/trunk/drivers/usb/host/ohci-pci.c +++ b/trunk/drivers/usb/host/ohci-pci.c @@ -397,10 +397,6 @@ static const struct pci_device_id pci_ids [] = { { /* handle any USB OHCI controller */ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_OHCI, ~0), .driver_data = (unsigned long) &ohci_pci_hc_driver, - }, { - /* The device in the ConneXT I/O hub has no class reg */ - PCI_VDEVICE(STMICRO, PCI_DEVICE_ID_STMICRO_USB_OHCI), - .driver_data = (unsigned long) &ohci_pci_hc_driver, }, { /* end: all zeroes */ } }; MODULE_DEVICE_TABLE (pci, pci_ids); diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index b62037bff688..b90e1386418b 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -1204,7 +1204,6 @@ static void handle_vendor_event(struct xhci_hcd *xhci, * * Returns a zero-based port number, which is suitable for indexing into each of * the split roothubs' port arrays and bus state arrays. - * Add one to it in order to call xhci_find_slot_id_by_port. */ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, struct xhci_hcd *xhci, u32 port_id) @@ -1325,7 +1324,7 @@ static void handle_port_status(struct xhci_hcd *xhci, xhci_set_link_state(xhci, port_array, faked_port_index, XDEV_U0); slot_id = xhci_find_slot_id_by_port(hcd, xhci, - faked_port_index + 1); + faked_port_index); if (!slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto cleanup; @@ -3324,8 +3323,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Check TD length */ if (running_total != td_len) { xhci_err(xhci, "ISOC TD length unmatch\n"); - ret = -EINVAL; - goto cleanup; + return -EINVAL; } } diff --git a/trunk/drivers/usb/misc/emi26.c b/trunk/drivers/usb/misc/emi26.c index da97dcec1f32..d9b6a0355443 100644 --- a/trunk/drivers/usb/misc/emi26.c +++ b/trunk/drivers/usb/misc/emi26.c @@ -37,6 +37,9 @@ static int emi26_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi26_load_firmware (struct usb_device *dev); static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *id); static void emi26_disconnect(struct usb_interface *intf); +static int __init emi26_init (void); +static void __exit emi26_exit (void); + /* thanks to drivers/usb/serial/keyspan_pda.c code */ static int emi26_writememory (struct usb_device *dev, int address, diff --git a/trunk/drivers/usb/misc/emi62.c b/trunk/drivers/usb/misc/emi62.c index 4e0f167a6c4e..9f39062ebb08 100644 --- a/trunk/drivers/usb/misc/emi62.c +++ b/trunk/drivers/usb/misc/emi62.c @@ -46,6 +46,9 @@ static int emi62_set_reset(struct usb_device *dev, unsigned char reset_bit); static int emi62_load_firmware (struct usb_device *dev); static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *id); static void emi62_disconnect(struct usb_interface *intf); +static int __init emi62_init (void); +static void __exit emi62_exit (void); + /* thanks to drivers/usb/serial/keyspan_pda.c code */ static int emi62_writememory(struct usb_device *dev, int address, diff --git a/trunk/drivers/usb/misc/usbsevseg.c b/trunk/drivers/usb/misc/usbsevseg.c index b2d82b937392..107bf13b1cf1 100644 --- a/trunk/drivers/usb/misc/usbsevseg.c +++ b/trunk/drivers/usb/misc/usbsevseg.c @@ -24,7 +24,7 @@ #define VENDOR_ID 0x0fc5 #define PRODUCT_ID 0x1227 -#define MAXLEN 8 +#define MAXLEN 6 /* table of devices that work with this driver */ static const struct usb_device_id id_table[] = { diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 7c569f51212a..f9a3f62a83b5 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -33,6 +33,9 @@ #include #include +#include +#include +#include #include #include diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 3d11cf64ebd1..56cf0243979e 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -981,9 +981,6 @@ static void musb_shutdown(struct platform_device *pdev) unsigned long flags; pm_runtime_get_sync(musb->controller); - - musb_gadget_cleanup(musb); - spin_lock_irqsave(&musb->lock, flags); musb_platform_disable(musb); musb_generic_disable(musb); @@ -1830,6 +1827,8 @@ static void musb_free(struct musb *musb) sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); #endif + musb_gadget_cleanup(musb); + if (musb->nIrq >= 0) { if (musb->irq_wake) disable_irq_wake(musb->nIrq); diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index df719eae3b03..c27bbbf32b52 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -222,6 +222,7 @@ static inline void omap2430_low_level_init(struct musb *musb) musb_writel(musb->mregs, OTG_FORCESTDBY, l); } +/* blocking notifier support */ static int musb_otg_notifications(struct notifier_block *nb, unsigned long event, void *unused) { @@ -230,7 +231,7 @@ static int musb_otg_notifications(struct notifier_block *nb, musb->xceiv_event = event; schedule_work(&musb->otg_notifier_work); - return NOTIFY_OK; + return 0; } static void musb_otg_notifier_work(struct work_struct *data_notifier_work) @@ -385,7 +386,6 @@ static void omap2430_musb_disable(struct musb *musb) static int omap2430_musb_exit(struct musb *musb) { del_timer_sync(&musb_idle_timer); - cancel_work_sync(&musb->otg_notifier_work); omap2430_low_level_exit(musb); otg_put_transceiver(musb->xceiv); diff --git a/trunk/drivers/usb/otg/Kconfig b/trunk/drivers/usb/otg/Kconfig index 76d629345418..2a25955881fc 100644 --- a/trunk/drivers/usb/otg/Kconfig +++ b/trunk/drivers/usb/otg/Kconfig @@ -86,6 +86,20 @@ config NOP_USB_XCEIV built-in with usb ip or which are autonomous and doesn't require any phy programming such as ISP1x04 etc. +config USB_LANGWELL_OTG + tristate "Intel Langwell USB OTG dual-role support" + depends on USB && PCI && INTEL_SCU_IPC + select USB_OTG + select USB_OTG_UTILS + help + Say Y here if you want to build Intel Langwell USB OTG + transciever driver in kernel. This driver implements role + switch between EHCI host driver and Langwell USB OTG + client driver. + + To compile this driver as a module, choose M here: the + module will be called langwell_otg. + config USB_MSM_OTG tristate "OTG support for Qualcomm on-chip USB controller" depends on (USB || USB_GADGET) && ARCH_MSM @@ -110,7 +124,7 @@ config AB8500_USB config FSL_USB2_OTG bool "Freescale USB OTG Transceiver Driver" - depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 && USB_SUSPEND + depends on USB_EHCI_FSL && USB_GADGET_FSL_USB2 select USB_OTG select USB_OTG_UTILS help @@ -118,7 +132,7 @@ config FSL_USB2_OTG config USB_MV_OTG tristate "Marvell USB OTG support" - depends on USB_MV_UDC && USB_SUSPEND + depends on USB_MV_UDC select USB_OTG select USB_OTG_UTILS help diff --git a/trunk/drivers/usb/otg/Makefile b/trunk/drivers/usb/otg/Makefile index 41aa5098b139..b2c5a9598637 100644 --- a/trunk/drivers/usb/otg/Makefile +++ b/trunk/drivers/usb/otg/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o +obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o obj-$(CONFIG_USB_ULPI) += ulpi.o obj-$(CONFIG_USB_ULPI_VIEWPORT) += ulpi_viewport.o diff --git a/trunk/drivers/usb/otg/langwell_otg.c b/trunk/drivers/usb/otg/langwell_otg.c new file mode 100644 index 000000000000..f08f784086f7 --- /dev/null +++ b/trunk/drivers/usb/otg/langwell_otg.c @@ -0,0 +1,2347 @@ +/* + * Intel Langwell USB OTG transceiver driver + * Copyright (C) 2008 - 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +/* This driver helps to switch Langwell OTG controller function between host + * and peripheral. It works with EHCI driver and Langwell client controller + * driver together. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" +#define DRIVER_VERSION "July 10, 2010" + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Henry Yuan , Hao Wu "); +MODULE_VERSION(DRIVER_VERSION); +MODULE_LICENSE("GPL"); + +static const char driver_name[] = "langwell_otg"; + +static int langwell_otg_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +static void langwell_otg_remove(struct pci_dev *pdev); +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); +static int langwell_otg_resume(struct pci_dev *pdev); + +static int langwell_otg_set_host(struct otg_transceiver *otg, + struct usb_bus *host); +static int langwell_otg_set_peripheral(struct otg_transceiver *otg, + struct usb_gadget *gadget); +static int langwell_otg_start_srp(struct otg_transceiver *otg); + +static const struct pci_device_id pci_ids[] = {{ + .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), + .class_mask = ~0, + .vendor = 0x8086, + .device = 0x0811, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, +}, { /* end: all zeroes */ } +}; + +static struct pci_driver otg_pci_driver = { + .name = (char *) driver_name, + .id_table = pci_ids, + + .probe = langwell_otg_probe, + .remove = langwell_otg_remove, + + .suspend = langwell_otg_suspend, + .resume = langwell_otg_resume, +}; + +/* HSM timers */ +static inline struct langwell_otg_timer *otg_timer_initializer +(void (*function)(unsigned long), unsigned long expires, unsigned long data) +{ + struct langwell_otg_timer *timer; + timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); + if (timer == NULL) + return timer; + + timer->function = function; + timer->expires = expires; + timer->data = data; + return timer; +} + +static struct langwell_otg_timer *a_wait_vrise_tmr, *a_aidl_bdis_tmr, + *b_se0_srp_tmr, *b_srp_init_tmr; + +static struct list_head active_timers; + +static struct langwell_otg *the_transceiver; + +/* host/client notify transceiver when event affects HNP state */ +void langwell_update_transceiver(void) +{ + struct langwell_otg *lnw = the_transceiver; + + dev_dbg(lnw->dev, "transceiver is updated\n"); + + if (!lnw->qwork) + return ; + + queue_work(lnw->qwork, &lnw->work); +} +EXPORT_SYMBOL(langwell_update_transceiver); + +static int langwell_otg_set_host(struct otg_transceiver *otg, + struct usb_bus *host) +{ + otg->host = host; + + return 0; +} + +static int langwell_otg_set_peripheral(struct otg_transceiver *otg, + struct usb_gadget *gadget) +{ + otg->gadget = gadget; + + return 0; +} + +static int langwell_otg_set_power(struct otg_transceiver *otg, + unsigned mA) +{ + return 0; +} + +/* A-device drives vbus, controlled through IPC commands */ +static int langwell_otg_set_vbus(struct otg_transceiver *otg, bool enabled) +{ + struct langwell_otg *lnw = the_transceiver; + u8 sub_id; + + dev_dbg(lnw->dev, "%s <--- %s\n", __func__, enabled ? "on" : "off"); + + if (enabled) + sub_id = 0x8; /* Turn on the VBus */ + else + sub_id = 0x9; /* Turn off the VBus */ + + if (intel_scu_ipc_simple_command(0xef, sub_id)) { + dev_dbg(lnw->dev, "Failed to set Vbus via IPC commands\n"); + return -EBUSY; + } + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + return 0; +} + +/* charge vbus or discharge vbus through a resistor to ground */ +static void langwell_otg_chrg_vbus(int on) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + val = readl(lnw->iotg.base + CI_OTGSC); + + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, + lnw->iotg.base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, + lnw->iotg.base + CI_OTGSC); +} + +/* Start SRP */ +static int langwell_otg_start_srp(struct otg_transceiver *otg) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + val = readl(iotg->base + CI_OTGSC); + + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, + iotg->base + CI_OTGSC); + + /* Check if the data plus is finished or not */ + msleep(8); + val = readl(iotg->base + CI_OTGSC); + if (val & (OTGSC_HADP | OTGSC_DP)) + dev_dbg(lnw->dev, "DataLine SRP Error\n"); + + /* Disable interrupt - b_sess_vld */ + val = readl(iotg->base + CI_OTGSC); + val &= (~(OTGSC_BSVIE | OTGSC_BSEIE)); + writel(val, iotg->base + CI_OTGSC); + + /* Start VBus SRP, drive vbus to generate VBus pulse */ + iotg->otg.set_vbus(&iotg->otg, true); + msleep(15); + iotg->otg.set_vbus(&iotg->otg, false); + + /* Enable interrupt - b_sess_vld*/ + val = readl(iotg->base + CI_OTGSC); + dev_dbg(lnw->dev, "after VBUS pulse otgsc = %x\n", val); + + val |= (OTGSC_BSVIE | OTGSC_BSEIE); + writel(val, iotg->base + CI_OTGSC); + + /* If Vbus is valid, then update the hsm */ + if (val & OTGSC_BSV) { + dev_dbg(lnw->dev, "no b_sess_vld interrupt\n"); + + lnw->iotg.hsm.b_sess_vld = 1; + langwell_update_transceiver(); + } + + dev_dbg(lnw->dev, "%s <---\n", __func__); + return 0; +} + +/* stop SOF via bus_suspend */ +static void langwell_otg_loc_sof(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct usb_hcd *hcd; + int err; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "suspend" : "resume"); + + hcd = bus_to_hcd(lnw->iotg.otg.host); + if (on) + err = hcd->driver->bus_resume(hcd); + else + err = hcd->driver->bus_suspend(hcd); + + if (err) + dev_dbg(lnw->dev, "Fail to resume/suspend USB bus - %d\n", err); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +static int langwell_otg_check_otgsc(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 otgsc, usbcfg; + + dev_dbg(lnw->dev, "check sync OTGSC and USBCFG registers\n"); + + otgsc = readl(lnw->iotg.base + CI_OTGSC); + usbcfg = readl(lnw->usbcfg); + + dev_dbg(lnw->dev, "OTGSC = %08x, USBCFG = %08x\n", + otgsc, usbcfg); + dev_dbg(lnw->dev, "OTGSC_AVV = %d\n", !!(otgsc & OTGSC_AVV)); + dev_dbg(lnw->dev, "USBCFG.VBUSVAL = %d\n", + !!(usbcfg & USBCFG_VBUSVAL)); + dev_dbg(lnw->dev, "OTGSC_ASV = %d\n", !!(otgsc & OTGSC_ASV)); + dev_dbg(lnw->dev, "USBCFG.AVALID = %d\n", + !!(usbcfg & USBCFG_AVALID)); + dev_dbg(lnw->dev, "OTGSC_BSV = %d\n", !!(otgsc & OTGSC_BSV)); + dev_dbg(lnw->dev, "USBCFG.BVALID = %d\n", + !!(usbcfg & USBCFG_BVALID)); + dev_dbg(lnw->dev, "OTGSC_BSE = %d\n", !!(otgsc & OTGSC_BSE)); + dev_dbg(lnw->dev, "USBCFG.SESEND = %d\n", + !!(usbcfg & USBCFG_SESEND)); + + /* Check USBCFG VBusValid/AValid/BValid/SessEnd */ + if (!!(otgsc & OTGSC_AVV) ^ !!(usbcfg & USBCFG_VBUSVAL)) { + dev_dbg(lnw->dev, "OTGSC.AVV != USBCFG.VBUSVAL\n"); + goto err; + } + if (!!(otgsc & OTGSC_ASV) ^ !!(usbcfg & USBCFG_AVALID)) { + dev_dbg(lnw->dev, "OTGSC.ASV != USBCFG.AVALID\n"); + goto err; + } + if (!!(otgsc & OTGSC_BSV) ^ !!(usbcfg & USBCFG_BVALID)) { + dev_dbg(lnw->dev, "OTGSC.BSV != USBCFG.BVALID\n"); + goto err; + } + if (!!(otgsc & OTGSC_BSE) ^ !!(usbcfg & USBCFG_SESEND)) { + dev_dbg(lnw->dev, "OTGSC.BSE != USBCFG.SESSEN\n"); + goto err; + } + + dev_dbg(lnw->dev, "OTGSC and USBCFG are synced\n"); + + return 0; + +err: + dev_warn(lnw->dev, "OTGSC isn't equal to USBCFG\n"); + return -EPIPE; +} + + +static void langwell_otg_phy_low_power(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u8 val, phcd; + int retval; + + dev_dbg(lnw->dev, "%s ---> %s mode\n", + __func__, on ? "Low power" : "Normal"); + + phcd = 0x40; + + val = readb(iotg->base + CI_HOSTPC1 + 2); + + if (on) { + /* Due to hardware issue, after set PHCD, sync will failed + * between USBCFG and OTGSC, so before set PHCD, check if + * sync is in process now. If the answer is "yes", then do + * not touch PHCD bit */ + retval = langwell_otg_check_otgsc(); + if (retval) { + dev_dbg(lnw->dev, "Skip PHCD programming..\n"); + return ; + } + + writeb(val | phcd, iotg->base + CI_HOSTPC1 + 2); + } else + writeb(val & ~phcd, iotg->base + CI_HOSTPC1 + 2); + + dev_dbg(lnw->dev, "%s <--- done\n", __func__); +} + +/* After drv vbus, add 5 ms delay to set PHCD */ +static void langwell_otg_phy_low_power_wait(int on) +{ + struct langwell_otg *lnw = the_transceiver; + + dev_dbg(lnw->dev, "add 5ms delay before programing PHCD\n"); + + mdelay(5); + langwell_otg_phy_low_power(on); +} + +/* Enable/Disable OTG interrupt */ +static void langwell_otg_intr(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + + /* OTGSC_INT_MASK doesn't contains 1msInt */ + if (on) { + val = val | (OTGSC_INT_MASK); + writel(val, iotg->base + CI_OTGSC); + } else { + val = val & ~(OTGSC_INT_MASK); + writel(val, iotg->base + CI_OTGSC); + } + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +/* set HAAR: Hardware Assist Auto-Reset */ +static void langwell_otg_HAAR(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, + iotg->base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, + iotg->base + CI_OTGSC); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +/* set HABA: Hardware Assist B-Disconnect to A-Connect */ +static void langwell_otg_HABA(int on) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val; + + dev_dbg(lnw->dev, "%s ---> %s\n", __func__, on ? "on" : "off"); + + val = readl(iotg->base + CI_OTGSC); + if (on) + writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, + iotg->base + CI_OTGSC); + else + writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, + iotg->base + CI_OTGSC); + + dev_dbg(lnw->dev, "%s <---\n", __func__); +} + +static int langwell_otg_check_se0_srp(int on) +{ + struct langwell_otg *lnw = the_transceiver; + int delay_time = TB_SE0_SRP * 10; + u32 val; + + dev_dbg(lnw->dev, "%s --->\n", __func__); + + do { + udelay(100); + if (!delay_time--) + break; + val = readl(lnw->iotg.base + CI_PORTSC1); + val &= PORTSC_LS; + } while (!val); + + dev_dbg(lnw->dev, "%s <---\n", __func__); + return val; +} + +/* The timeout callback function to set time out bit */ +static void set_tmout(unsigned long indicator) +{ + *(int *)indicator = 1; +} + +void langwell_otg_nsf_msg(unsigned long indicator) +{ + struct langwell_otg *lnw = the_transceiver; + + switch (indicator) { + case 2: + case 4: + case 6: + case 7: + dev_warn(lnw->dev, + "OTG:NSF-%lu - deivce not responding\n", indicator); + break; + case 3: + dev_warn(lnw->dev, + "OTG:NSF-%lu - deivce not supported\n", indicator); + break; + default: + dev_warn(lnw->dev, "Do not have this kind of NSF\n"); + break; + } +} + +/* Initialize timers */ +static int langwell_otg_init_timers(struct otg_hsm *hsm) +{ + /* HSM used timers */ + a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, + (unsigned long)&hsm->a_wait_vrise_tmout); + if (a_wait_vrise_tmr == NULL) + return -ENOMEM; + a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, + (unsigned long)&hsm->a_aidl_bdis_tmout); + if (a_aidl_bdis_tmr == NULL) + return -ENOMEM; + b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, + (unsigned long)&hsm->b_se0_srp); + if (b_se0_srp_tmr == NULL) + return -ENOMEM; + b_srp_init_tmr = otg_timer_initializer(&set_tmout, TB_SRP_INIT, + (unsigned long)&hsm->b_srp_init_tmout); + if (b_srp_init_tmr == NULL) + return -ENOMEM; + + return 0; +} + +/* Free timers */ +static void langwell_otg_free_timers(void) +{ + kfree(a_wait_vrise_tmr); + kfree(a_aidl_bdis_tmr); + kfree(b_se0_srp_tmr); + kfree(b_srp_init_tmr); +} + +/* The timeout callback function to set time out bit */ +static void langwell_otg_timer_fn(unsigned long indicator) +{ + struct langwell_otg *lnw = the_transceiver; + + *(int *)indicator = 1; + + dev_dbg(lnw->dev, "kernel timer - timeout\n"); + + langwell_update_transceiver(); +} + +/* kernel timer used instead of HW based interrupt */ +static void langwell_otg_add_ktimer(enum langwell_otg_timer_type timers) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + unsigned long j = jiffies; + unsigned long data, time; + + switch (timers) { + case TA_WAIT_VRISE_TMR: + iotg->hsm.a_wait_vrise_tmout = 0; + data = (unsigned long)&iotg->hsm.a_wait_vrise_tmout; + time = TA_WAIT_VRISE; + break; + case TA_WAIT_BCON_TMR: + iotg->hsm.a_wait_bcon_tmout = 0; + data = (unsigned long)&iotg->hsm.a_wait_bcon_tmout; + time = TA_WAIT_BCON; + break; + case TA_AIDL_BDIS_TMR: + iotg->hsm.a_aidl_bdis_tmout = 0; + data = (unsigned long)&iotg->hsm.a_aidl_bdis_tmout; + time = TA_AIDL_BDIS; + break; + case TB_ASE0_BRST_TMR: + iotg->hsm.b_ase0_brst_tmout = 0; + data = (unsigned long)&iotg->hsm.b_ase0_brst_tmout; + time = TB_ASE0_BRST; + break; + case TB_SRP_INIT_TMR: + iotg->hsm.b_srp_init_tmout = 0; + data = (unsigned long)&iotg->hsm.b_srp_init_tmout; + time = TB_SRP_INIT; + break; + case TB_SRP_FAIL_TMR: + iotg->hsm.b_srp_fail_tmout = 0; + data = (unsigned long)&iotg->hsm.b_srp_fail_tmout; + time = TB_SRP_FAIL; + break; + case TB_BUS_SUSPEND_TMR: + iotg->hsm.b_bus_suspend_tmout = 0; + data = (unsigned long)&iotg->hsm.b_bus_suspend_tmout; + time = TB_BUS_SUSPEND; + break; + default: + dev_dbg(lnw->dev, "unknown timer, cannot enable it\n"); + return; + } + + lnw->hsm_timer.data = data; + lnw->hsm_timer.function = langwell_otg_timer_fn; + lnw->hsm_timer.expires = j + time * HZ / 1000; /* milliseconds */ + + add_timer(&lnw->hsm_timer); + + dev_dbg(lnw->dev, "add timer successfully\n"); +} + +/* Add timer to timer list */ +static void langwell_otg_add_timer(void *gtimer) +{ + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; + struct langwell_otg_timer *tmp_timer; + struct intel_mid_otg_xceiv *iotg = &the_transceiver->iotg; + u32 val32; + + /* Check if the timer is already in the active list, + * if so update timer count + */ + list_for_each_entry(tmp_timer, &active_timers, list) + if (tmp_timer == timer) { + timer->count = timer->expires; + return; + } + timer->count = timer->expires; + + if (list_empty(&active_timers)) { + val32 = readl(iotg->base + CI_OTGSC); + writel(val32 | OTGSC_1MSE, iotg->base + CI_OTGSC); + } + + list_add_tail(&timer->list, &active_timers); +} + +/* Remove timer from the timer list; clear timeout status */ +static void langwell_otg_del_timer(void *gtimer) +{ + struct langwell_otg *lnw = the_transceiver; + struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; + struct langwell_otg_timer *tmp_timer, *del_tmp; + u32 val32; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) + if (tmp_timer == timer) + list_del(&timer->list); + + if (list_empty(&active_timers)) { + val32 = readl(lnw->iotg.base + CI_OTGSC); + writel(val32 & ~OTGSC_1MSE, lnw->iotg.base + CI_OTGSC); + } +} + +/* Reduce timer count by 1, and find timeout conditions.*/ +static int langwell_otg_tick_timer(u32 *int_sts) +{ + struct langwell_otg *lnw = the_transceiver; + struct langwell_otg_timer *tmp_timer, *del_tmp; + int expired = 0; + + list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { + tmp_timer->count--; + /* check if timer expires */ + if (!tmp_timer->count) { + list_del(&tmp_timer->list); + tmp_timer->function(tmp_timer->data); + expired = 1; + } + } + + if (list_empty(&active_timers)) { + dev_dbg(lnw->dev, "tick timer: disable 1ms int\n"); + *int_sts = *int_sts & ~OTGSC_1MSE; + } + return expired; +} + +static void reset_otg(void) +{ + struct langwell_otg *lnw = the_transceiver; + int delay_time = 1000; + u32 val; + + dev_dbg(lnw->dev, "reseting OTG controller ...\n"); + val = readl(lnw->iotg.base + CI_USBCMD); + writel(val | USBCMD_RST, lnw->iotg.base + CI_USBCMD); + do { + udelay(100); + if (!delay_time--) + dev_dbg(lnw->dev, "reset timeout\n"); + val = readl(lnw->iotg.base + CI_USBCMD); + val &= USBCMD_RST; + } while (val != 0); + dev_dbg(lnw->dev, "reset done.\n"); +} + +static void set_host_mode(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + reset_otg(); + val = readl(lnw->iotg.base + CI_USBMODE); + val = (val & (~USBMODE_CM)) | USBMODE_HOST; + writel(val, lnw->iotg.base + CI_USBMODE); +} + +static void set_client_mode(void) +{ + struct langwell_otg *lnw = the_transceiver; + u32 val; + + reset_otg(); + val = readl(lnw->iotg.base + CI_USBMODE); + val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; + writel(val, lnw->iotg.base + CI_USBMODE); +} + +static void init_hsm(void) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val32; + + /* read OTGSC after reset */ + val32 = readl(lnw->iotg.base + CI_OTGSC); + dev_dbg(lnw->dev, "%s: OTGSC init value = 0x%x\n", __func__, val32); + + /* set init state */ + if (val32 & OTGSC_ID) { + iotg->hsm.id = 1; + iotg->otg.default_a = 0; + set_client_mode(); + iotg->otg.state = OTG_STATE_B_IDLE; + } else { + iotg->hsm.id = 0; + iotg->otg.default_a = 1; + set_host_mode(); + iotg->otg.state = OTG_STATE_A_IDLE; + } + + /* set session indicator */ + if (val32 & OTGSC_BSE) + iotg->hsm.b_sess_end = 1; + if (val32 & OTGSC_BSV) + iotg->hsm.b_sess_vld = 1; + if (val32 & OTGSC_ASV) + iotg->hsm.a_sess_vld = 1; + if (val32 & OTGSC_AVV) + iotg->hsm.a_vbus_vld = 1; + + /* defautly power the bus */ + iotg->hsm.a_bus_req = 1; + iotg->hsm.a_bus_drop = 0; + /* defautly don't request bus as B device */ + iotg->hsm.b_bus_req = 0; + /* no system error */ + iotg->hsm.a_clr_err = 0; + + langwell_otg_phy_low_power_wait(1); +} + +static void update_hsm(void) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 val32; + + /* read OTGSC */ + val32 = readl(lnw->iotg.base + CI_OTGSC); + dev_dbg(lnw->dev, "%s: OTGSC value = 0x%x\n", __func__, val32); + + iotg->hsm.id = !!(val32 & OTGSC_ID); + iotg->hsm.b_sess_end = !!(val32 & OTGSC_BSE); + iotg->hsm.b_sess_vld = !!(val32 & OTGSC_BSV); + iotg->hsm.a_sess_vld = !!(val32 & OTGSC_ASV); + iotg->hsm.a_vbus_vld = !!(val32 & OTGSC_AVV); +} + +static irqreturn_t otg_dummy_irq(int irq, void *_dev) +{ + struct langwell_otg *lnw = the_transceiver; + void __iomem *reg_base = _dev; + u32 val; + u32 int_mask = 0; + + val = readl(reg_base + CI_USBMODE); + if ((val & USBMODE_CM) != USBMODE_DEVICE) + return IRQ_NONE; + + val = readl(reg_base + CI_USBSTS); + int_mask = val & INTR_DUMMY_MASK; + + if (int_mask == 0) + return IRQ_NONE; + + /* clear hsm.b_conn here since host driver can't detect it + * otg_dummy_irq called means B-disconnect happened. + */ + if (lnw->iotg.hsm.b_conn) { + lnw->iotg.hsm.b_conn = 0; + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + } + + /* Clear interrupts */ + writel(int_mask, reg_base + CI_USBSTS); + return IRQ_HANDLED; +} + +static irqreturn_t otg_irq(int irq, void *_dev) +{ + struct langwell_otg *lnw = _dev; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + u32 int_sts, int_en; + u32 int_mask = 0; + int flag = 0; + + int_sts = readl(lnw->iotg.base + CI_OTGSC); + int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; + int_mask = int_sts & int_en; + if (int_mask == 0) + return IRQ_NONE; + + if (int_mask & OTGSC_IDIS) { + dev_dbg(lnw->dev, "%s: id change int\n", __func__); + iotg->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; + dev_dbg(lnw->dev, "id = %d\n", iotg->hsm.id); + flag = 1; + } + if (int_mask & OTGSC_DPIS) { + dev_dbg(lnw->dev, "%s: data pulse int\n", __func__); + iotg->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; + dev_dbg(lnw->dev, "data pulse = %d\n", iotg->hsm.a_srp_det); + flag = 1; + } + if (int_mask & OTGSC_BSEIS) { + dev_dbg(lnw->dev, "%s: b session end int\n", __func__); + iotg->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; + dev_dbg(lnw->dev, "b_sess_end = %d\n", iotg->hsm.b_sess_end); + flag = 1; + } + if (int_mask & OTGSC_BSVIS) { + dev_dbg(lnw->dev, "%s: b session valid int\n", __func__); + iotg->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; + dev_dbg(lnw->dev, "b_sess_vld = %d\n", iotg->hsm.b_sess_end); + flag = 1; + } + if (int_mask & OTGSC_ASVIS) { + dev_dbg(lnw->dev, "%s: a session valid int\n", __func__); + iotg->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; + dev_dbg(lnw->dev, "a_sess_vld = %d\n", iotg->hsm.a_sess_vld); + flag = 1; + } + if (int_mask & OTGSC_AVVIS) { + dev_dbg(lnw->dev, "%s: a vbus valid int\n", __func__); + iotg->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; + dev_dbg(lnw->dev, "a_vbus_vld = %d\n", iotg->hsm.a_vbus_vld); + flag = 1; + } + + if (int_mask & OTGSC_1MSS) { + /* need to schedule otg_work if any timer is expired */ + if (langwell_otg_tick_timer(&int_sts)) + flag = 1; + } + + writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, + lnw->iotg.base + CI_OTGSC); + if (flag) + langwell_update_transceiver(); + + return IRQ_HANDLED; +} + +static int langwell_otg_iotg_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = data; + int flag = 0; + + if (iotg == NULL) + return NOTIFY_BAD; + + if (lnw == NULL) + return NOTIFY_BAD; + + switch (action) { + case MID_OTG_NOTIFY_CONNECT: + dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_conn = 1; + else + iotg->hsm.a_conn = 1; + flag = 1; + break; + case MID_OTG_NOTIFY_DISCONN: + dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_conn = 0; + else + iotg->hsm.a_conn = 0; + flag = 1; + break; + case MID_OTG_NOTIFY_HSUSPEND: + dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.a_suspend_req = 1; + else + iotg->hsm.b_bus_req = 0; + flag = 1; + break; + case MID_OTG_NOTIFY_HRESUME: + dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n"); + if (iotg->otg.default_a == 1) + iotg->hsm.b_bus_resume = 1; + flag = 1; + break; + case MID_OTG_NOTIFY_CSUSPEND: + dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n"); + if (iotg->otg.default_a == 1) { + if (iotg->hsm.b_bus_suspend_vld == 2) { + iotg->hsm.b_bus_suspend = 1; + iotg->hsm.b_bus_suspend_vld = 0; + flag = 1; + } else { + iotg->hsm.b_bus_suspend_vld++; + flag = 0; + } + } else { + if (iotg->hsm.a_bus_suspend == 0) { + iotg->hsm.a_bus_suspend = 1; + flag = 1; + } + } + break; + case MID_OTG_NOTIFY_CRESUME: + dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n"); + if (iotg->otg.default_a == 0) + iotg->hsm.a_bus_suspend = 0; + flag = 0; + break; + case MID_OTG_NOTIFY_HOSTADD: + dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_HOSTREMOVE: + dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_CLIENTADD: + dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n"); + flag = 1; + break; + case MID_OTG_NOTIFY_CLIENTREMOVE: + dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n"); + flag = 1; + break; + default: + dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n"); + return NOTIFY_DONE; + } + + if (flag) + langwell_update_transceiver(); + + return NOTIFY_OK; +} + +static void langwell_otg_work(struct work_struct *work) +{ + struct langwell_otg *lnw; + struct intel_mid_otg_xceiv *iotg; + int retval; + struct pci_dev *pdev; + + lnw = container_of(work, struct langwell_otg, work); + iotg = &lnw->iotg; + pdev = to_pci_dev(lnw->dev); + + dev_dbg(lnw->dev, "%s: old state = %s\n", __func__, + otg_state_string(iotg->otg.state)); + + switch (iotg->otg.state) { + case OTG_STATE_UNDEFINED: + case OTG_STATE_B_IDLE: + if (!iotg->hsm.id) { + langwell_otg_del_timer(b_srp_init_tmr); + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + set_host_mode(); + langwell_otg_phy_low_power(1); + + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.b_sess_vld) { + langwell_otg_del_timer(b_srp_init_tmr); + del_timer_sync(&lnw->hsm_timer); + iotg->hsm.b_sess_end = 0; + iotg->hsm.a_bus_suspend = 0; + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.start_peripheral) { + lnw->iotg.start_peripheral(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } else + dev_dbg(lnw->dev, "client driver not loaded\n"); + + } else if (iotg->hsm.b_srp_init_tmout) { + iotg->hsm.b_srp_init_tmout = 0; + dev_warn(lnw->dev, "SRP init timeout\n"); + } else if (iotg->hsm.b_srp_fail_tmout) { + iotg->hsm.b_srp_fail_tmout = 0; + iotg->hsm.b_bus_req = 0; + + /* No silence failure */ + langwell_otg_nsf_msg(6); + } else if (iotg->hsm.b_bus_req && iotg->hsm.b_sess_end) { + del_timer_sync(&lnw->hsm_timer); + /* workaround for b_se0_srp detection */ + retval = langwell_otg_check_se0_srp(0); + if (retval) { + iotg->hsm.b_bus_req = 0; + dev_dbg(lnw->dev, "LS isn't SE0, try later\n"); + } else { + /* clear the PHCD before start srp */ + langwell_otg_phy_low_power(0); + + /* Start SRP */ + langwell_otg_add_timer(b_srp_init_tmr); + iotg->otg.start_srp(&iotg->otg); + langwell_otg_del_timer(b_srp_init_tmr); + langwell_otg_add_ktimer(TB_SRP_FAIL_TMR); + + /* reset PHY low power mode here */ + langwell_otg_phy_low_power_wait(1); + } + } + break; + case OTG_STATE_B_SRP_INIT: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_chrg_vbus(0); + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.b_sess_vld) { + langwell_otg_chrg_vbus(0); + if (lnw->iotg.start_peripheral) { + lnw->iotg.start_peripheral(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } else + dev_dbg(lnw->dev, "client driver not loaded\n"); + } + break; + case OTG_STATE_B_PERIPHERAL: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + iotg->hsm.b_hnp_enable = 0; + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.b_bus_req && iotg->otg.gadget && + iotg->otg.gadget->b_hnp_enable && + iotg->hsm.a_bus_suspend) { + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + langwell_otg_HAAR(1); + iotg->hsm.a_conn = 0; + + if (lnw->iotg.start_host) { + lnw->iotg.start_host(&lnw->iotg); + iotg->otg.state = OTG_STATE_B_WAIT_ACON; + } else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + + iotg->hsm.a_bus_resume = 0; + langwell_otg_add_ktimer(TB_ASE0_BRST_TMR); + } + break; + + case OTG_STATE_B_WAIT_ACON: + if (!iotg->hsm.id) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + langwell_otg_HAAR(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->hsm.b_hnp_enable = 0; + iotg->hsm.b_bus_req = 0; + + langwell_otg_chrg_vbus(0); + langwell_otg_HAAR(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.a_conn) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + iotg->otg.state = OTG_STATE_B_HOST; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_resume || + iotg->hsm.b_ase0_brst_tmout) { + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + langwell_otg_nsf_msg(7); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.a_bus_suspend = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } + break; + + case OTG_STATE_B_HOST: + if (!iotg->hsm.id) { + iotg->otg.default_a = 1; + iotg->hsm.a_srp_det = 0; + + langwell_otg_chrg_vbus(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.b_sess_vld) { + iotg->hsm.b_hnp_enable = 0; + iotg->hsm.b_bus_req = 0; + + langwell_otg_chrg_vbus(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if ((!iotg->hsm.b_bus_req) || + (!iotg->hsm.a_conn)) { + iotg->hsm.b_bus_req = 0; + langwell_otg_loc_sof(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.a_bus_suspend = 0; + + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + iotg->otg.state = OTG_STATE_B_PERIPHERAL; + } + break; + + case OTG_STATE_A_IDLE: + iotg->otg.default_a = 1; + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + iotg->hsm.vbus_srp_up = 0; + + langwell_otg_chrg_vbus(0); + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_bus_drop && + (iotg->hsm.a_srp_det || iotg->hsm.a_bus_req)) { + langwell_otg_phy_low_power(0); + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + + iotg->hsm.vbus_srp_up = 0; + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_bus_drop && iotg->hsm.a_sess_vld) { + iotg->hsm.vbus_srp_up = 1; + } else if (!iotg->hsm.a_sess_vld && iotg->hsm.vbus_srp_up) { + msleep(10); + langwell_otg_phy_low_power(0); + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + iotg->hsm.a_srp_det = 1; + iotg->hsm.vbus_srp_up = 0; + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_sess_vld && + !iotg->hsm.vbus_srp_up) { + langwell_otg_phy_low_power(1); + } + break; + case OTG_STATE_A_WAIT_VRISE: + if (iotg->hsm.id) { + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.b_bus_req = 0; + iotg->otg.default_a = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + } else if (iotg->hsm.a_vbus_vld) { + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.b_conn = 0; + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else { + dev_dbg(lnw->dev, "host driver not loaded.\n"); + break; + } + + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else if (iotg->hsm.a_wait_vrise_tmout) { + iotg->hsm.b_conn = 0; + if (iotg->hsm.a_vbus_vld) { + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else { + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + break; + } + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else { + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } + } + break; + case OTG_STATE_A_WAIT_BCON: + if (iotg->hsm.id) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_vbus_vld) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->hsm.a_bus_drop || + (iotg->hsm.a_wait_bcon_tmout && + !iotg->hsm.a_bus_req)) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (iotg->hsm.b_conn) { + /* delete hsm timer for a_wait_bcon_tmr */ + del_timer_sync(&lnw->hsm_timer); + + iotg->hsm.a_suspend_req = 0; + iotg->otg.state = OTG_STATE_A_HOST; + if (iotg->hsm.a_srp_det && iotg->otg.host && + !iotg->otg.host->b_hnp_enable) { + /* SRP capable peripheral-only device */ + iotg->hsm.a_bus_req = 1; + iotg->hsm.a_srp_det = 0; + } else if (!iotg->hsm.a_bus_req && iotg->otg.host && + iotg->otg.host->b_hnp_enable) { + /* It is not safe enough to do a fast + * transition from A_WAIT_BCON to + * A_SUSPEND */ + msleep(10000); + if (iotg->hsm.a_bus_req) + break; + + if (request_irq(pdev->irq, + otg_dummy_irq, IRQF_SHARED, + driver_name, iotg->base) != 0) { + dev_dbg(lnw->dev, + "request interrupt %d fail\n", + pdev->irq); + } + + langwell_otg_HABA(1); + iotg->hsm.b_bus_resume = 0; + iotg->hsm.a_aidl_bdis_tmout = 0; + + langwell_otg_loc_sof(0); + /* clear PHCD to enable HW timer */ + langwell_otg_phy_low_power(0); + langwell_otg_add_timer(a_aidl_bdis_tmr); + iotg->otg.state = OTG_STATE_A_SUSPEND; + } else if (!iotg->hsm.a_bus_req && iotg->otg.host && + !iotg->otg.host->b_hnp_enable) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } + } + break; + case OTG_STATE_A_HOST: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_drop || + (iotg->otg.host && + !iotg->otg.host->b_hnp_enable && + !iotg->hsm.a_bus_req)) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (!iotg->hsm.a_vbus_vld) { + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->otg.host && + iotg->otg.host->b_hnp_enable && + !iotg->hsm.a_bus_req) { + /* Set HABA to enable hardware assistance to signal + * A-connect after receiver B-disconnect. Hardware + * will then set client mode and enable URE, SLE and + * PCE after the assistance. otg_dummy_irq is used to + * clean these ints when client driver is not resumed. + */ + if (request_irq(pdev->irq, otg_dummy_irq, IRQF_SHARED, + driver_name, iotg->base) != 0) { + dev_dbg(lnw->dev, + "request interrupt %d failed\n", + pdev->irq); + } + + /* set HABA */ + langwell_otg_HABA(1); + iotg->hsm.b_bus_resume = 0; + iotg->hsm.a_aidl_bdis_tmout = 0; + langwell_otg_loc_sof(0); + /* clear PHCD to enable HW timer */ + langwell_otg_phy_low_power(0); + langwell_otg_add_timer(a_aidl_bdis_tmr); + iotg->otg.state = OTG_STATE_A_SUSPEND; + } else if (!iotg->hsm.b_conn || !iotg->hsm.a_bus_req) { + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } + break; + case OTG_STATE_A_SUSPEND: + if (iotg->hsm.id) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_req || + iotg->hsm.b_bus_resume) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + iotg->hsm.a_suspend_req = 0; + langwell_otg_loc_sof(1); + iotg->otg.state = OTG_STATE_A_HOST; + } else if (iotg->hsm.a_aidl_bdis_tmout || + iotg->hsm.a_bus_drop) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (!iotg->hsm.b_conn && iotg->otg.host && + iotg->otg.host->b_hnp_enable) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + iotg->hsm.b_bus_suspend = 0; + iotg->hsm.b_bus_suspend_vld = 0; + + /* msleep(200); */ + if (lnw->iotg.start_peripheral) + lnw->iotg.start_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver not loaded.\n"); + + langwell_otg_add_ktimer(TB_BUS_SUSPEND_TMR); + iotg->otg.state = OTG_STATE_A_PERIPHERAL; + break; + } else if (!iotg->hsm.a_vbus_vld) { + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + free_irq(pdev->irq, iotg->base); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } + break; + case OTG_STATE_A_PERIPHERAL: + if (iotg->hsm.id) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + iotg->otg.default_a = 0; + iotg->hsm.b_bus_req = 0; + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + set_client_mode(); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (!iotg->hsm.a_vbus_vld) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + langwell_otg_phy_low_power_wait(1); + iotg->otg.state = OTG_STATE_A_VBUS_ERR; + } else if (iotg->hsm.a_bus_drop) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_WAIT_VFALL; + } else if (iotg->hsm.b_bus_suspend) { + /* delete hsm timer for b_bus_suspend_tmr */ + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } else if (iotg->hsm.b_bus_suspend_tmout) { + u32 val; + val = readl(lnw->iotg.base + CI_PORTSC1); + if (!(val & PORTSC_SUSP)) + break; + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(lnw->dev, + "client driver has been removed.\n"); + + if (lnw->iotg.start_host) + lnw->iotg.start_host(&lnw->iotg); + else + dev_dbg(lnw->dev, + "host driver not loaded.\n"); + langwell_otg_add_ktimer(TA_WAIT_BCON_TMR); + iotg->otg.state = OTG_STATE_A_WAIT_BCON; + } + break; + case OTG_STATE_A_VBUS_ERR: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + iotg->hsm.a_clr_err = 0; + iotg->hsm.a_srp_det = 0; + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_clr_err) { + iotg->hsm.a_clr_err = 0; + iotg->hsm.a_srp_det = 0; + reset_otg(); + init_hsm(); + if (iotg->otg.state == OTG_STATE_A_IDLE) + langwell_update_transceiver(); + } else { + /* FW will clear PHCD bit when any VBus + * event detected. Reset PHCD to 1 again */ + langwell_otg_phy_low_power(1); + } + break; + case OTG_STATE_A_WAIT_VFALL: + if (iotg->hsm.id) { + iotg->otg.default_a = 0; + set_client_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_B_IDLE; + langwell_update_transceiver(); + } else if (iotg->hsm.a_bus_req) { + + /* Turn on VBus */ + iotg->otg.set_vbus(&iotg->otg, true); + iotg->hsm.a_wait_vrise_tmout = 0; + langwell_otg_add_timer(a_wait_vrise_tmr); + iotg->otg.state = OTG_STATE_A_WAIT_VRISE; + } else if (!iotg->hsm.a_sess_vld) { + iotg->hsm.a_srp_det = 0; + set_host_mode(); + langwell_otg_phy_low_power(1); + iotg->otg.state = OTG_STATE_A_IDLE; + } + break; + default: + ; + } + + dev_dbg(lnw->dev, "%s: new state = %s\n", __func__, + otg_state_string(iotg->otg.state)); +} + +static ssize_t +show_registers(struct device *_dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, + "\n" + "USBCMD = 0x%08x\n" + "USBSTS = 0x%08x\n" + "USBINTR = 0x%08x\n" + "ASYNCLISTADDR = 0x%08x\n" + "PORTSC1 = 0x%08x\n" + "HOSTPC1 = 0x%08x\n" + "OTGSC = 0x%08x\n" + "USBMODE = 0x%08x\n", + readl(lnw->iotg.base + 0x30), + readl(lnw->iotg.base + 0x34), + readl(lnw->iotg.base + 0x38), + readl(lnw->iotg.base + 0x48), + readl(lnw->iotg.base + 0x74), + readl(lnw->iotg.base + 0xb4), + readl(lnw->iotg.base + 0xf4), + readl(lnw->iotg.base + 0xf8) + ); + size -= t; + next += t; + + return PAGE_SIZE - size; +} +static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); + +static ssize_t +show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + if (iotg->otg.host) + iotg->hsm.a_set_b_hnp_en = iotg->otg.host->b_hnp_enable; + + if (iotg->otg.gadget) + iotg->hsm.b_hnp_enable = iotg->otg.gadget->b_hnp_enable; + + t = scnprintf(next, size, + "\n" + "current state = %s\n" + "a_bus_resume = \t%d\n" + "a_bus_suspend = \t%d\n" + "a_conn = \t%d\n" + "a_sess_vld = \t%d\n" + "a_srp_det = \t%d\n" + "a_vbus_vld = \t%d\n" + "b_bus_resume = \t%d\n" + "b_bus_suspend = \t%d\n" + "b_conn = \t%d\n" + "b_se0_srp = \t%d\n" + "b_sess_end = \t%d\n" + "b_sess_vld = \t%d\n" + "id = \t%d\n" + "a_set_b_hnp_en = \t%d\n" + "b_srp_done = \t%d\n" + "b_hnp_enable = \t%d\n" + "a_wait_vrise_tmout = \t%d\n" + "a_wait_bcon_tmout = \t%d\n" + "a_aidl_bdis_tmout = \t%d\n" + "b_ase0_brst_tmout = \t%d\n" + "a_bus_drop = \t%d\n" + "a_bus_req = \t%d\n" + "a_clr_err = \t%d\n" + "a_suspend_req = \t%d\n" + "b_bus_req = \t%d\n" + "b_bus_suspend_tmout = \t%d\n" + "b_bus_suspend_vld = \t%d\n", + otg_state_string(iotg->otg.state), + iotg->hsm.a_bus_resume, + iotg->hsm.a_bus_suspend, + iotg->hsm.a_conn, + iotg->hsm.a_sess_vld, + iotg->hsm.a_srp_det, + iotg->hsm.a_vbus_vld, + iotg->hsm.b_bus_resume, + iotg->hsm.b_bus_suspend, + iotg->hsm.b_conn, + iotg->hsm.b_se0_srp, + iotg->hsm.b_sess_end, + iotg->hsm.b_sess_vld, + iotg->hsm.id, + iotg->hsm.a_set_b_hnp_en, + iotg->hsm.b_srp_done, + iotg->hsm.b_hnp_enable, + iotg->hsm.a_wait_vrise_tmout, + iotg->hsm.a_wait_bcon_tmout, + iotg->hsm.a_aidl_bdis_tmout, + iotg->hsm.b_ase0_brst_tmout, + iotg->hsm.a_bus_drop, + iotg->hsm.a_bus_req, + iotg->hsm.a_clr_err, + iotg->hsm.a_suspend_req, + iotg->hsm.b_bus_req, + iotg->hsm.b_bus_suspend_tmout, + iotg->hsm.b_bus_suspend_vld + ); + size -= t; + next += t; + + return PAGE_SIZE - size; +} +static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); + +static ssize_t +get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_req); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_a_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.a_bus_req = 0; + dev_dbg(lnw->dev, "User request: a_bus_req = 0\n"); + } else if (buf[0] == '1') { + /* If a_bus_drop is TRUE, a_bus_req can't be set */ + if (iotg->hsm.a_bus_drop) + return -1; + iotg->hsm.a_bus_req = 1; + dev_dbg(lnw->dev, "User request: a_bus_req = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); + +static ssize_t +get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.a_bus_drop); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_a_bus_drop(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.a_bus_drop = 0; + dev_dbg(lnw->dev, "User request: a_bus_drop = 0\n"); + } else if (buf[0] == '1') { + iotg->hsm.a_bus_drop = 1; + iotg->hsm.a_bus_req = 0; + dev_dbg(lnw->dev, "User request: a_bus_drop = 1\n"); + dev_dbg(lnw->dev, "User request: and a_bus_req = 0\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop); + +static ssize_t +get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct langwell_otg *lnw = the_transceiver; + char *next; + unsigned size, t; + + next = buf; + size = PAGE_SIZE; + + t = scnprintf(next, size, "%d", lnw->iotg.hsm.b_bus_req); + size -= t; + next += t; + + return PAGE_SIZE - size; +} + +static ssize_t +set_b_bus_req(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (iotg->otg.default_a) + return -1; + + if (count > 2) + return -1; + + if (buf[0] == '0') { + iotg->hsm.b_bus_req = 0; + dev_dbg(lnw->dev, "User request: b_bus_req = 0\n"); + } else if (buf[0] == '1') { + iotg->hsm.b_bus_req = 1; + dev_dbg(lnw->dev, "User request: b_bus_req = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); + +static ssize_t +set_a_clr_err(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + + if (!iotg->otg.default_a) + return -1; + if (count > 2) + return -1; + + if (buf[0] == '1') { + iotg->hsm.a_clr_err = 1; + dev_dbg(lnw->dev, "User request: a_clr_err = 1\n"); + } + if (spin_trylock(&lnw->wq_lock)) { + langwell_update_transceiver(); + spin_unlock(&lnw->wq_lock); + } + return count; +} +static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); + +static struct attribute *inputs_attrs[] = { + &dev_attr_a_bus_req.attr, + &dev_attr_a_bus_drop.attr, + &dev_attr_b_bus_req.attr, + &dev_attr_a_clr_err.attr, + NULL, +}; + +static struct attribute_group debug_dev_attr_group = { + .name = "inputs", + .attrs = inputs_attrs, +}; + +static int langwell_otg_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + unsigned long resource, len; + void __iomem *base = NULL; + int retval; + u32 val32; + struct langwell_otg *lnw; + char qname[] = "langwell_otg_queue"; + + retval = 0; + dev_dbg(&pdev->dev, "\notg controller is detected.\n"); + if (pci_enable_device(pdev) < 0) { + retval = -ENODEV; + goto done; + } + + lnw = kzalloc(sizeof *lnw, GFP_KERNEL); + if (lnw == NULL) { + retval = -ENOMEM; + goto done; + } + the_transceiver = lnw; + + /* control register: BAR 0 */ + resource = pci_resource_start(pdev, 0); + len = pci_resource_len(pdev, 0); + if (!request_mem_region(resource, len, driver_name)) { + retval = -EBUSY; + goto err; + } + lnw->region = 1; + + base = ioremap_nocache(resource, len); + if (base == NULL) { + retval = -EFAULT; + goto err; + } + lnw->iotg.base = base; + + if (!request_mem_region(USBCFG_ADDR, USBCFG_LEN, driver_name)) { + retval = -EBUSY; + goto err; + } + lnw->cfg_region = 1; + + /* For the SCCB.USBCFG register */ + base = ioremap_nocache(USBCFG_ADDR, USBCFG_LEN); + if (base == NULL) { + retval = -EFAULT; + goto err; + } + lnw->usbcfg = base; + + if (!pdev->irq) { + dev_dbg(&pdev->dev, "No IRQ.\n"); + retval = -ENODEV; + goto err; + } + + lnw->qwork = create_singlethread_workqueue(qname); + if (!lnw->qwork) { + dev_dbg(&pdev->dev, "cannot create workqueue %s\n", qname); + retval = -ENOMEM; + goto err; + } + INIT_WORK(&lnw->work, langwell_otg_work); + + /* OTG common part */ + lnw->dev = &pdev->dev; + lnw->iotg.otg.dev = lnw->dev; + lnw->iotg.otg.label = driver_name; + lnw->iotg.otg.set_host = langwell_otg_set_host; + lnw->iotg.otg.set_peripheral = langwell_otg_set_peripheral; + lnw->iotg.otg.set_power = langwell_otg_set_power; + lnw->iotg.otg.set_vbus = langwell_otg_set_vbus; + lnw->iotg.otg.start_srp = langwell_otg_start_srp; + lnw->iotg.otg.state = OTG_STATE_UNDEFINED; + + if (otg_set_transceiver(&lnw->iotg.otg)) { + dev_dbg(lnw->dev, "can't set transceiver\n"); + retval = -EBUSY; + goto err; + } + + reset_otg(); + init_hsm(); + + spin_lock_init(&lnw->lock); + spin_lock_init(&lnw->wq_lock); + INIT_LIST_HEAD(&active_timers); + retval = langwell_otg_init_timers(&lnw->iotg.hsm); + if (retval) { + dev_dbg(&pdev->dev, "Failed to init timers\n"); + goto err; + } + + init_timer(&lnw->hsm_timer); + ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier); + + lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify; + + retval = intel_mid_otg_register_notifier(&lnw->iotg, + &lnw->iotg_notifier); + if (retval) { + dev_dbg(lnw->dev, "Failed to register notifier\n"); + goto err; + } + + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + driver_name, lnw) != 0) { + dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq); + retval = -EBUSY; + goto err; + } + + /* enable OTGSC int */ + val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | + OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; + writel(val32, lnw->iotg.base + CI_OTGSC); + + retval = device_create_file(&pdev->dev, &dev_attr_registers); + if (retval < 0) { + dev_dbg(lnw->dev, + "Can't register sysfs attribute: %d\n", retval); + goto err; + } + + retval = device_create_file(&pdev->dev, &dev_attr_hsm); + if (retval < 0) { + dev_dbg(lnw->dev, "Can't hsm sysfs attribute: %d\n", retval); + goto err; + } + + retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); + if (retval < 0) { + dev_dbg(lnw->dev, + "Can't register sysfs attr group: %d\n", retval); + goto err; + } + + if (lnw->iotg.otg.state == OTG_STATE_A_IDLE) + langwell_update_transceiver(); + + return 0; + +err: + if (the_transceiver) + langwell_otg_remove(pdev); +done: + return retval; +} + +static void langwell_otg_remove(struct pci_dev *pdev) +{ + struct langwell_otg *lnw = the_transceiver; + + if (lnw->qwork) { + flush_workqueue(lnw->qwork); + destroy_workqueue(lnw->qwork); + } + intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier); + langwell_otg_free_timers(); + + /* disable OTGSC interrupt as OTGSC doesn't change in reset */ + writel(0, lnw->iotg.base + CI_OTGSC); + + if (pdev->irq) + free_irq(pdev->irq, lnw); + if (lnw->usbcfg) + iounmap(lnw->usbcfg); + if (lnw->cfg_region) + release_mem_region(USBCFG_ADDR, USBCFG_LEN); + if (lnw->iotg.base) + iounmap(lnw->iotg.base); + if (lnw->region) + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + + otg_set_transceiver(NULL); + pci_disable_device(pdev); + sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); + device_remove_file(&pdev->dev, &dev_attr_hsm); + device_remove_file(&pdev->dev, &dev_attr_registers); + kfree(lnw); + lnw = NULL; +} + +static void transceiver_suspend(struct pci_dev *pdev) +{ + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); + langwell_otg_phy_low_power(1); +} + +static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) +{ + struct langwell_otg *lnw = the_transceiver; + struct intel_mid_otg_xceiv *iotg = &lnw->iotg; + int ret = 0; + + /* Disbale OTG interrupts */ + langwell_otg_intr(0); + + if (pdev->irq) + free_irq(pdev->irq, lnw); + + /* Prevent more otg_work */ + flush_workqueue(lnw->qwork); + destroy_workqueue(lnw->qwork); + lnw->qwork = NULL; + + /* start actions */ + switch (iotg->otg.state) { + case OTG_STATE_A_WAIT_VFALL: + iotg->otg.state = OTG_STATE_A_IDLE; + case OTG_STATE_A_IDLE: + case OTG_STATE_B_IDLE: + case OTG_STATE_A_VBUS_ERR: + transceiver_suspend(pdev); + break; + case OTG_STATE_A_WAIT_VRISE: + langwell_otg_del_timer(a_wait_vrise_tmr); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_WAIT_BCON: + del_timer_sync(&lnw->hsm_timer); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_HOST: + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_SUSPEND: + langwell_otg_del_timer(a_aidl_bdis_tmr); + langwell_otg_HABA(0); + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(lnw->dev, "host driver has been removed.\n"); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_A_PERIPHERAL: + del_timer_sync(&lnw->hsm_timer); + + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(&pdev->dev, + "client driver has been removed.\n"); + iotg->hsm.a_srp_det = 0; + + /* Turn off VBus */ + iotg->otg.set_vbus(&iotg->otg, false); + iotg->otg.state = OTG_STATE_A_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_HOST: + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + iotg->hsm.b_bus_req = 0; + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_PERIPHERAL: + if (lnw->iotg.stop_peripheral) + lnw->iotg.stop_peripheral(&lnw->iotg); + else + dev_dbg(&pdev->dev, + "client driver has been removed.\n"); + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + case OTG_STATE_B_WAIT_ACON: + /* delete hsm timer for b_ase0_brst_tmr */ + del_timer_sync(&lnw->hsm_timer); + + langwell_otg_HAAR(0); + + if (lnw->iotg.stop_host) + lnw->iotg.stop_host(&lnw->iotg); + else + dev_dbg(&pdev->dev, "host driver has been removed.\n"); + iotg->hsm.b_bus_req = 0; + iotg->otg.state = OTG_STATE_B_IDLE; + transceiver_suspend(pdev); + break; + default: + dev_dbg(lnw->dev, "error state before suspend\n"); + break; + } + + return ret; +} + +static void transceiver_resume(struct pci_dev *pdev) +{ + pci_restore_state(pdev); + pci_set_power_state(pdev, PCI_D0); +} + +static int langwell_otg_resume(struct pci_dev *pdev) +{ + struct langwell_otg *lnw = the_transceiver; + int ret = 0; + + transceiver_resume(pdev); + + lnw->qwork = create_singlethread_workqueue("langwell_otg_queue"); + if (!lnw->qwork) { + dev_dbg(&pdev->dev, "cannot create langwell otg workqueuen"); + ret = -ENOMEM; + goto error; + } + + if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, + driver_name, lnw) != 0) { + dev_dbg(&pdev->dev, "request interrupt %d failed\n", pdev->irq); + ret = -EBUSY; + goto error; + } + + /* enable OTG interrupts */ + langwell_otg_intr(1); + + update_hsm(); + + langwell_update_transceiver(); + + return ret; +error: + langwell_otg_intr(0); + transceiver_suspend(pdev); + return ret; +} + +static int __init langwell_otg_init(void) +{ + return pci_register_driver(&otg_pci_driver); +} +module_init(langwell_otg_init); + +static void __exit langwell_otg_cleanup(void) +{ + pci_unregister_driver(&otg_pci_driver); +} +module_exit(langwell_otg_cleanup); diff --git a/trunk/drivers/usb/otg/mv_otg.c b/trunk/drivers/usb/otg/mv_otg.c index b5fbe1452ab0..db0d4fcdc8e2 100644 --- a/trunk/drivers/usb/otg/mv_otg.c +++ b/trunk/drivers/usb/otg/mv_otg.c @@ -202,7 +202,6 @@ static void mv_otg_init_irq(struct mv_otg *mvotg) static void mv_otg_start_host(struct mv_otg *mvotg, int on) { -#ifdef CONFIG_USB struct otg_transceiver *otg = &mvotg->otg; struct usb_hcd *hcd; @@ -217,7 +216,6 @@ static void mv_otg_start_host(struct mv_otg *mvotg, int on) usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); else usb_remove_hcd(hcd); -#endif /* CONFIG_USB */ } static void mv_otg_start_periphrals(struct mv_otg *mvotg, int on) diff --git a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c index 7542aa94a462..528691d5f3e2 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c @@ -425,7 +425,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, struct usbhs_pipe *pipe; int recip = ctrl->bRequestType & USB_RECIP_MASK; int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; - int ret = 0; + int ret; int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, struct usb_ctrlrequest *ctrl); char *msg; diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index 8dbf51a43c45..fba1147ed916 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -39,8 +39,6 @@ static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *port); static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp); -static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, - struct ktermios *); static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *, struct ktermios*); static int cp210x_tiocmget(struct tty_struct *); @@ -140,7 +138,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ - { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; @@ -204,8 +201,6 @@ static struct usb_serial_driver cp210x_device = { #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 -#define CP210X_GET_BAUDRATE 0x1D -#define CP210X_SET_BAUDRATE 0x1E /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 @@ -365,8 +360,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, * Quantises the baud rate as per AN205 Table 1 */ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { - if (baud <= 300) - baud = 300; + if (baud <= 56) baud = 0; + else if (baud <= 300) baud = 300; else if (baud <= 600) baud = 600; else if (baud <= 1200) baud = 1200; else if (baud <= 1800) baud = 1800; @@ -394,10 +389,10 @@ static unsigned int cp210x_quantise_baudrate(unsigned int baud) { else if (baud <= 491520) baud = 460800; else if (baud <= 567138) baud = 500000; else if (baud <= 670254) baud = 576000; - else if (baud < 1000000) - baud = 921600; - else if (baud > 2000000) - baud = 2000000; + else if (baud <= 1053257) baud = 921600; + else if (baud <= 1474560) baud = 1228800; + else if (baud <= 2457600) baud = 1843200; + else baud = 3686400; return baud; } @@ -414,14 +409,13 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) return result; } + result = usb_serial_generic_open(tty, port); + if (result) + return result; + /* Configure the termios structure */ cp210x_get_termios(tty, port); - - /* The baud rate must be initialised on cp2104 */ - if (tty) - cp210x_change_speed(tty, port, NULL); - - return usb_serial_generic_open(tty, port); + return 0; } static void cp210x_close(struct usb_serial_port *port) @@ -473,7 +467,10 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, dbg("%s - port %d", __func__, port->number); - cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4); + cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); + /* Convert to baudrate */ + if (baud) + baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; @@ -582,64 +579,11 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, *cflagp = cflag; } -/* - * CP2101 supports the following baud rates: - * - * 300, 600, 1200, 1800, 2400, 4800, 7200, 9600, 14400, 19200, 28800, - * 38400, 56000, 57600, 115200, 128000, 230400, 460800, 921600 - * - * CP2102 and CP2103 support the following additional rates: - * - * 4000, 16000, 51200, 64000, 76800, 153600, 250000, 256000, 500000, - * 576000 - * - * The device will map a requested rate to a supported one, but the result - * of requests for rates greater than 1053257 is undefined (see AN205). - * - * CP2104, CP2105 and CP2110 support most rates up to 2M, 921k and 1M baud, - * respectively, with an error less than 1%. The actual rates are determined - * by - * - * div = round(freq / (2 x prescale x request)) - * actual = freq / (2 x prescale x div) - * - * For CP2104 and CP2105 freq is 48Mhz and prescale is 4 for request <= 365bps - * or 1 otherwise. - * For CP2110 freq is 24Mhz and prescale is 4 for request <= 300bps or 1 - * otherwise. - */ -static void cp210x_change_speed(struct tty_struct *tty, - struct usb_serial_port *port, struct ktermios *old_termios) -{ - u32 baud; - - baud = tty->termios->c_ospeed; - - /* This maps the requested rate to a rate valid on cp2102 or cp2103, - * or to an arbitrary rate in [1M,2M]. - * - * NOTE: B0 is not implemented. - */ - baud = cp210x_quantise_baudrate(baud); - - dbg("%s - setting baud rate to %u", __func__, baud); - if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud, - sizeof(baud))) { - dev_warn(&port->dev, "failed to set baud rate to %u\n", baud); - if (old_termios) - baud = old_termios->c_ospeed; - else - baud = 9600; - } - - tty_encode_baud_rate(tty, baud, baud); -} - static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - unsigned int bits; + unsigned int baud = 0, bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); @@ -649,9 +593,20 @@ static void cp210x_set_termios(struct tty_struct *tty, cflag = tty->termios->c_cflag; old_cflag = old_termios->c_cflag; - - if (tty->termios->c_ospeed != old_termios->c_ospeed) - cp210x_change_speed(tty, port, old_termios); + baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); + + /* If the baud rate is to be updated*/ + if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { + dbg("%s - Setting baud rate to %d baud", __func__, + baud); + if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, + ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { + dbg("Baud rate requested not supported by device"); + baud = tty_termios_baud_rate(old_termios); + } + } + /* Report back the resulting baud rate */ + tty_encode_baud_rate(tty, baud, baud); /* If the number of data bits is to be updated */ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index ad654f8208ef..01b6404df395 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -797,7 +797,6 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) }, { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, @@ -806,8 +805,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), - .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, @@ -844,7 +841,6 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, - { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; @@ -1337,7 +1333,8 @@ static int set_serial_info(struct tty_struct *tty, goto check_and_exit; } - if (new_serial.baud_base != priv->baud_base) { + if ((new_serial.baud_base != priv->baud_base) && + (new_serial.baud_base < 9600)) { mutex_unlock(&priv->cfg_lock); return -EINVAL; } @@ -1827,7 +1824,6 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port) static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct ktermios dummy; struct usb_device *dev = port->serial->dev; struct ftdi_private *priv = usb_get_serial_port_data(port); int result; @@ -1846,10 +1842,8 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) This is same behaviour as serial.c/rs_open() - Kuba */ /* ftdi_set_termios will send usb control messages */ - if (tty) { - memset(&dummy, 0, sizeof(dummy)); - ftdi_set_termios(tty, port, &dummy); - } + if (tty) + ftdi_set_termios(tty, port, tty->termios); /* Start reading from the device */ result = usb_serial_generic_open(tty, port); diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index f994503df2dd..df1d7da933ec 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -39,13 +39,6 @@ /* www.candapter.com Ewert Energy Systems CANdapter device */ #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ -/* - * Texas Instruments XDS100v2 JTAG / BeagleBone A3 - * http://processors.wiki.ti.com/index.php/XDS100 - * http://beagleboard.org/bone - */ -#define TI_XDS100V2_PID 0xa6d0 - #define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */ /* US Interface Navigator (http://www.usinterface.com/) */ @@ -531,12 +524,6 @@ #define ADI_GNICE_PID 0xF000 #define ADI_GNICEPLUS_PID 0xF001 -/* - * Hornby Elite - */ -#define HORNBY_VID 0x04D8 -#define HORNBY_ELITE_PID 0x000A - /* * RATOC REX-USB60F */ @@ -1181,9 +1168,3 @@ */ /* TagTracer MIFARE*/ #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID 0xF7C0 - -/* - * Rainforest Automation - */ -/* ZigBee controller */ -#define FTDI_RF_R106 0x8A28 diff --git a/trunk/drivers/usb/serial/io_ti.c b/trunk/drivers/usb/serial/io_ti.c index 5818bfc3261e..65bf06aa591a 100644 --- a/trunk/drivers/usb/serial/io_ti.c +++ b/trunk/drivers/usb/serial/io_ti.c @@ -2657,7 +2657,15 @@ static int edge_startup(struct usb_serial *serial) static void edge_disconnect(struct usb_serial *serial) { + int i; + struct edgeport_port *edge_port; + dbg("%s", __func__); + + for (i = 0; i < serial->num_ports; ++i) { + edge_port = usb_get_serial_port_data(serial->port[i]); + edge_remove_sysfs_attrs(edge_port->port); + } } static void edge_release(struct usb_serial *serial) @@ -2736,7 +2744,6 @@ static struct usb_serial_driver edgeport_1port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -2768,7 +2775,6 @@ static struct usb_serial_driver edgeport_2port_device = { .disconnect = edge_disconnect, .release = edge_release, .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, diff --git a/trunk/drivers/usb/serial/kobil_sct.c b/trunk/drivers/usb/serial/kobil_sct.c index a92a3efb507b..5d3beeeb5fd9 100644 --- a/trunk/drivers/usb/serial/kobil_sct.c +++ b/trunk/drivers/usb/serial/kobil_sct.c @@ -38,7 +38,7 @@ #include #include "kobil_sct.h" -static bool debug; +static int debug; /* Version Information */ #define DRIVER_VERSION "21/05/2004" diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index ea126a4490cd..420d9857394a 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -480,10 +480,6 @@ static void option_instat_callback(struct urb *urb); #define ZD_VENDOR_ID 0x0685 #define ZD_PRODUCT_7000 0x7000 -/* LG products */ -#define LG_VENDOR_ID 0x1004 -#define LG_PRODUCT_L02C 0x618f - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -1187,7 +1183,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) }, - { USB_DEVICE(LG_VENDOR_ID, LG_PRODUCT_L02C) }, /* docomo L-02C modem */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/usb/serial/qcaux.c b/trunk/drivers/usb/serial/qcaux.c index a34819884c1a..30b73e68a904 100644 --- a/trunk/drivers/usb/serial/qcaux.c +++ b/trunk/drivers/usb/serial/qcaux.c @@ -36,7 +36,6 @@ #define UTSTARCOM_PRODUCT_UM175_V1 0x3712 #define UTSTARCOM_PRODUCT_UM175_V2 0x3714 #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 -#define PANTECH_PRODUCT_UML190_VZW 0x3716 #define PANTECH_PRODUCT_UML290_VZW 0x3718 /* CMOTECH devices */ @@ -68,11 +67,7 @@ static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */ - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */ + { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/trunk/drivers/usb/storage/realtek_cr.c b/trunk/drivers/usb/storage/realtek_cr.c index d32f72061c09..1f62723ef1a8 100644 --- a/trunk/drivers/usb/storage/realtek_cr.c +++ b/trunk/drivers/usb/storage/realtek_cr.c @@ -789,7 +789,7 @@ static void rts51x_suspend_timer_fn(unsigned long data) rts51x_set_stat(chip, RTS51X_STAT_SS); /* ignore mass storage interface's children */ pm_suspend_ignore_children(&us->pusb_intf->dev, true); - usb_autopm_put_interface_async(us->pusb_intf); + usb_autopm_put_interface(us->pusb_intf); US_DEBUGP("%s: RTS51X_STAT_SS 01," "intf->pm_usage_cnt:%d, power.usage:%d\n", __func__, diff --git a/trunk/drivers/usb/usb-skeleton.c b/trunk/drivers/usb/usb-skeleton.c index b4a71679c933..8efeae24764f 100644 --- a/trunk/drivers/usb/usb-skeleton.c +++ b/trunk/drivers/usb/usb-skeleton.c @@ -27,6 +27,8 @@ #define USB_SKEL_VENDOR_ID 0xfff0 #define USB_SKEL_PRODUCT_ID 0xfff0 +static DEFINE_MUTEX(skel_mutex); + /* table of devices that work with this driver */ static const struct usb_device_id skel_table[] = { { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, @@ -99,18 +101,25 @@ static int skel_open(struct inode *inode, struct file *file) goto exit; } + mutex_lock(&skel_mutex); dev = usb_get_intfdata(interface); if (!dev) { + mutex_unlock(&skel_mutex); retval = -ENODEV; goto exit; } /* increment our usage count for the device */ kref_get(&dev->kref); + mutex_unlock(&skel_mutex); /* lock the device to allow correctly handling errors * in resumption */ mutex_lock(&dev->io_mutex); + if (!dev->interface) { + retval = -ENODEV; + goto out_err; + } retval = usb_autopm_get_interface(interface); if (retval) @@ -118,7 +127,11 @@ static int skel_open(struct inode *inode, struct file *file) /* save our object in the file's private structure */ file->private_data = dev; + +out_err: mutex_unlock(&dev->io_mutex); + if (retval) + kref_put(&dev->kref, skel_delete); exit: return retval; @@ -598,7 +611,6 @@ static void skel_disconnect(struct usb_interface *interface) int minor = interface->minor; dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); /* give back our minor */ usb_deregister_dev(interface, &skel_class); @@ -610,8 +622,12 @@ static void skel_disconnect(struct usb_interface *interface) usb_kill_anchored_urbs(&dev->submitted); + mutex_lock(&skel_mutex); + usb_set_intfdata(interface, NULL); + /* decrement our usage count */ kref_put(&dev->kref, skel_delete); + mutex_unlock(&skel_mutex); dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor); } diff --git a/trunk/drivers/usb/wusbcore/Kconfig b/trunk/drivers/usb/wusbcore/Kconfig index f29fdd7f6d75..0ead8826ec79 100644 --- a/trunk/drivers/usb/wusbcore/Kconfig +++ b/trunk/drivers/usb/wusbcore/Kconfig @@ -6,7 +6,7 @@ config USB_WUSB depends on EXPERIMENTAL depends on USB depends on PCI - depends on UWB + select UWB select CRYPTO select CRYPTO_BLKCIPHER select CRYPTO_CBC diff --git a/trunk/drivers/virtio/virtio_ring.c b/trunk/drivers/virtio/virtio_ring.c index 5aa43c3392a2..79e1b292c030 100644 --- a/trunk/drivers/virtio/virtio_ring.c +++ b/trunk/drivers/virtio/virtio_ring.c @@ -35,7 +35,7 @@ #define virtio_rmb(vq) \ do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0) #define virtio_wmb(vq) \ - do { if ((vq)->weak_barriers) smp_wmb(); else wmb(); } while(0) + do { if ((vq)->weak_barriers) smp_rmb(); else rmb(); } while(0) #else /* We must force memory ordering even if guest is UP since host could be * running on another CPU, but SMP barriers are defined to barrier() in that @@ -308,9 +308,9 @@ bool virtqueue_kick_prepare(struct virtqueue *_vq) bool needs_kick; START_USE(vq); - /* We need to expose available array entries before checking avail - * event. */ - virtio_mb(vq); + /* Descriptors and available array need to be set before we expose the + * new available array entries. */ + virtio_wmb(vq); old = vq->vring.avail->idx - vq->num_added; new = vq->vring.avail->idx; diff --git a/trunk/drivers/watchdog/dw_wdt.c b/trunk/drivers/watchdog/dw_wdt.c index 63d7b58f1c7d..1b0e3dd81c1a 100644 --- a/trunk/drivers/watchdog/dw_wdt.c +++ b/trunk/drivers/watchdog/dw_wdt.c @@ -300,7 +300,11 @@ static int __devinit dw_wdt_drv_probe(struct platform_device *pdev) if (!mem) return -EINVAL; - dw_wdt.regs = devm_request_and_ioremap(&pdev->dev, mem); + if (!devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), + "dw_wdt")) + return -ENOMEM; + + dw_wdt.regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!dw_wdt.regs) return -ENOMEM; diff --git a/trunk/drivers/watchdog/iTCO_wdt.c b/trunk/drivers/watchdog/iTCO_wdt.c index bdf401b240b5..99796c5d913d 100644 --- a/trunk/drivers/watchdog/iTCO_wdt.c +++ b/trunk/drivers/watchdog/iTCO_wdt.c @@ -36,7 +36,6 @@ * document number TBD : Patsburg (PBG) * document number TBD : DH89xxCC * document number TBD : Panther Point - * document number TBD : Lynx Point */ /* @@ -127,7 +126,6 @@ enum iTCO_chipsets { TCO_PBG, /* Patsburg */ TCO_DH89XXCC, /* DH89xxCC */ TCO_PPT, /* Panther Point */ - TCO_LPT, /* Lynx Point */ }; static struct { @@ -191,7 +189,6 @@ static struct { {"Patsburg", 2}, {"DH89xxCC", 2}, {"Panther Point", 2}, - {"Lynx Point", 2}, {NULL, 0} }; @@ -334,38 +331,6 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { { PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT}, { PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT}, { PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT}, - { PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c43), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c44), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c45), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c46), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c47), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c48), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c49), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4a), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4b), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4c), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4d), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4e), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c4f), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c50), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c51), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c52), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c53), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c54), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c55), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c56), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c57), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c58), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c59), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5a), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5b), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5c), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5d), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5e), TCO_LPT}, - { PCI_VDEVICE(INTEL, 0x8c5f), TCO_LPT}, { 0, }, /* End of list */ }; MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); diff --git a/trunk/drivers/watchdog/imx2_wdt.c b/trunk/drivers/watchdog/imx2_wdt.c index c44c3334003a..b8ef2c6dca7c 100644 --- a/trunk/drivers/watchdog/imx2_wdt.c +++ b/trunk/drivers/watchdog/imx2_wdt.c @@ -247,6 +247,7 @@ static struct miscdevice imx2_wdt_miscdev = { static int __init imx2_wdt_probe(struct platform_device *pdev) { int ret; + int res_size; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -255,7 +256,15 @@ static int __init imx2_wdt_probe(struct platform_device *pdev) return -ENODEV; } - imx2_wdt.base = devm_request_and_ioremap(&pdev->dev, res); + res_size = resource_size(res); + if (!devm_request_mem_region(&pdev->dev, res->start, res_size, + res->name)) { + dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", + res_size, res->start); + return -ENOMEM; + } + + imx2_wdt.base = devm_ioremap_nocache(&pdev->dev, res->start, res_size); if (!imx2_wdt.base) { dev_err(&pdev->dev, "ioremap failed\n"); return -ENOMEM; diff --git a/trunk/drivers/watchdog/nuc900_wdt.c b/trunk/drivers/watchdog/nuc900_wdt.c index 529085b8b8fb..50359bad9177 100644 --- a/trunk/drivers/watchdog/nuc900_wdt.c +++ b/trunk/drivers/watchdog/nuc900_wdt.c @@ -72,7 +72,7 @@ struct nuc900_wdt { }; static unsigned long nuc900wdt_busy; -static struct nuc900_wdt *nuc900_wdt; +struct nuc900_wdt *nuc900_wdt; static inline void nuc900_wdt_keepalive(void) { @@ -287,8 +287,7 @@ static int __devinit nuc900wdt_probe(struct platform_device *pdev) setup_timer(&nuc900_wdt->timer, nuc900_wdt_timer_ping, 0); - ret = misc_register(&nuc900wdt_miscdev); - if (ret) { + if (misc_register(&nuc900wdt_miscdev)) { dev_err(&pdev->dev, "err register miscdev on minor=%d (%d)\n", WATCHDOG_MINOR, ret); goto err_clk; diff --git a/trunk/drivers/watchdog/omap_wdt.c b/trunk/drivers/watchdog/omap_wdt.c index d19ff5145e82..4b33e3fd726b 100644 --- a/trunk/drivers/watchdog/omap_wdt.c +++ b/trunk/drivers/watchdog/omap_wdt.c @@ -339,7 +339,6 @@ static int __devinit omap_wdt_probe(struct platform_device *pdev) return 0; err_misc: - pm_runtime_disable(wdev->dev); platform_set_drvdata(pdev, NULL); iounmap(wdev->base); @@ -372,7 +371,6 @@ static int __devexit omap_wdt_remove(struct platform_device *pdev) struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pm_runtime_disable(wdev->dev); if (!res) return -ENOENT; diff --git a/trunk/drivers/watchdog/pnx4008_wdt.c b/trunk/drivers/watchdog/pnx4008_wdt.c index 8e210aafdfd0..bd143c9dd3e6 100644 --- a/trunk/drivers/watchdog/pnx4008_wdt.c +++ b/trunk/drivers/watchdog/pnx4008_wdt.c @@ -226,7 +226,7 @@ static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd, static int pnx4008_wdt_release(struct inode *inode, struct file *file) { if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) - printk(KERN_WARNING "WATCHDOG: Device closed unexpectedly\n"); + printk(KERN_WARNING "WATCHDOG: Device closed unexpectdly\n"); wdt_disable(); clk_disable(wdt_clk); diff --git a/trunk/drivers/watchdog/stmp3xxx_wdt.c b/trunk/drivers/watchdog/stmp3xxx_wdt.c index e37d81178b9e..4c2a4e8698f9 100644 --- a/trunk/drivers/watchdog/stmp3xxx_wdt.c +++ b/trunk/drivers/watchdog/stmp3xxx_wdt.c @@ -174,7 +174,7 @@ static int stmp3xxx_wdt_release(struct inode *inode, struct file *file) if (!nowayout) { if (!test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_ping(); - pr_debug("%s: Device closed unexpectedly\n", __func__); + pr_debug("%s: Device closed unexpectdly\n", __func__); ret = -EINVAL; } else { wdt_disable(); diff --git a/trunk/drivers/watchdog/via_wdt.c b/trunk/drivers/watchdog/via_wdt.c index 8f07dd4bd94a..026b4bbfa0aa 100644 --- a/trunk/drivers/watchdog/via_wdt.c +++ b/trunk/drivers/watchdog/via_wdt.c @@ -124,6 +124,8 @@ static int wdt_stop(struct watchdog_device *wdd) static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout) { + if (new_timeout < 1 || new_timeout > WDT_TIMEOUT_MAX) + return -EINVAL; writel(new_timeout, wdt_mem + VIA_WDT_COUNT); timeout = new_timeout; return 0; @@ -148,8 +150,6 @@ static const struct watchdog_ops wdt_ops = { static struct watchdog_device wdt_dev = { .info = &wdt_info, .ops = &wdt_ops, - .min_timeout = 1, - .max_timeout = WDT_TIMEOUT_MAX, }; static int __devinit wdt_probe(struct pci_dev *pdev, @@ -233,7 +233,7 @@ static void __devexit wdt_remove(struct pci_dev *pdev) pci_disable_device(pdev); } -static DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = { +DEFINE_PCI_DEVICE_TABLE(wdt_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_CX700) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800) }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, diff --git a/trunk/drivers/watchdog/wafer5823wdt.c b/trunk/drivers/watchdog/wafer5823wdt.c index c3c3188c34d7..42e940c23891 100644 --- a/trunk/drivers/watchdog/wafer5823wdt.c +++ b/trunk/drivers/watchdog/wafer5823wdt.c @@ -152,12 +152,12 @@ static long wafwdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (options & WDIOS_DISABLECARD) { - wafwdt_stop(); + wafwdt_start(); retval = 0; } if (options & WDIOS_ENABLECARD) { - wafwdt_start(); + wafwdt_stop(); retval = 0; } diff --git a/trunk/drivers/watchdog/wm8350_wdt.c b/trunk/drivers/watchdog/wm8350_wdt.c index 5d7113c7e501..909c78650d3e 100644 --- a/trunk/drivers/watchdog/wm8350_wdt.c +++ b/trunk/drivers/watchdog/wm8350_wdt.c @@ -212,10 +212,10 @@ static long wm8350_wdt_ioctl(struct file *file, unsigned int cmd, /* Setting both simultaneously means at least one must fail */ if (options == WDIOS_DISABLECARD) - ret = wm8350_wdt_stop(wm8350); + ret = wm8350_wdt_start(wm8350); if (options == WDIOS_ENABLECARD) - ret = wm8350_wdt_start(wm8350); + ret = wm8350_wdt_stop(wm8350); break; } diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index b4d4eac761db..1cd94daa71db 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -948,12 +948,9 @@ static void gnttab_request_version(void) int rc; struct gnttab_set_version gsv; - if (xen_hvm_domain()) - gsv.version = 1; - else - gsv.version = 2; + gsv.version = 2; rc = HYPERVISOR_grant_table_op(GNTTABOP_set_version, &gsv, 1); - if (rc == 0 && gsv.version == 2) { + if (rc == 0) { grant_table_version = 2; gnttab_interface = &gnttab_v2_ops; } else if (grant_table_version == 2) { diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index 633c701a287d..b9a843226de8 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -297,7 +297,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, struct btrfs_delayed_extent_op *extent_op = head->extent_op; struct rb_node *n = &head->node.rb_node; int sgn; - int ret = 0; + int ret; if (extent_op && extent_op->update_key) btrfs_disk_key_to_cpu(info_key, &extent_op->key); @@ -392,7 +392,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info, struct btrfs_key *info_key, int *info_level, struct list_head *prefs) { - int ret = 0; + int ret; int slot; struct extent_buffer *leaf; struct btrfs_key key; diff --git a/trunk/fs/btrfs/check-integrity.c b/trunk/fs/btrfs/check-integrity.c index b669a7d8e499..ad0b3ba735b7 100644 --- a/trunk/fs/btrfs/check-integrity.c +++ b/trunk/fs/btrfs/check-integrity.c @@ -1662,7 +1662,7 @@ static void btrfsic_process_written_block(struct btrfsic_dev_state *dev_state, block = btrfsic_block_hashtable_lookup(bdev, dev_bytenr, &state->block_hashtable); if (NULL != block) { - u64 bytenr = 0; + u64 bytenr; struct list_head *elem_ref_to; struct list_head *tmp_ref_to; @@ -2777,10 +2777,9 @@ int btrfsic_submit_bh(int rw, struct buffer_head *bh) printk(KERN_INFO "submit_bh(rw=0x%x, blocknr=%lu (bytenr %llu)," " size=%lu, data=%p, bdev=%p)\n", - rw, (unsigned long)bh->b_blocknr, - (unsigned long long)dev_bytenr, - (unsigned long)bh->b_size, bh->b_data, - bh->b_bdev); + rw, bh->b_blocknr, + (unsigned long long)dev_bytenr, bh->b_size, + bh->b_data, bh->b_bdev); btrfsic_process_written_block(dev_state, dev_bytenr, bh->b_data, bh->b_size, NULL, NULL, bh, rw); @@ -2845,7 +2844,7 @@ void btrfsic_submit_bio(int rw, struct bio *bio) printk(KERN_INFO "submit_bio(rw=0x%x, bi_vcnt=%u," " bi_sector=%lu (bytenr %llu), bi_bdev=%p)\n", - rw, bio->bi_vcnt, (unsigned long)bio->bi_sector, + rw, bio->bi_vcnt, bio->bi_sector, (unsigned long long)dev_bytenr, bio->bi_bdev); diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index 811d9f918b1c..7aa9cd36bf1b 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -962,13 +962,6 @@ static int btree_releasepage(struct page *page, gfp_t gfp_flags) tree = &BTRFS_I(page->mapping->host)->io_tree; map = &BTRFS_I(page->mapping->host)->extent_tree; - /* - * We need to mask out eg. __GFP_HIGHMEM and __GFP_DMA32 as we're doing - * slab allocation from alloc_extent_state down the callchain where - * it'd hit a BUG_ON as those flags are not allowed. - */ - gfp_flags &= ~GFP_SLAB_BUG_MASK; - ret = try_release_extent_state(map, tree, page, gfp_flags); if (!ret) return 0; diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 283af7a676a3..700879ed64cf 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -34,24 +34,23 @@ #include "locking.h" #include "free-space-cache.h" -/* - * control flags for do_chunk_alloc's force field +/* control flags for do_chunk_alloc's force field * CHUNK_ALLOC_NO_FORCE means to only allocate a chunk * if we really need one. * + * CHUNK_ALLOC_FORCE means it must try to allocate one + * * CHUNK_ALLOC_LIMITED means to only try and allocate one * if we have very few chunks already allocated. This is * used as part of the clustering code to help make sure * we have a good pool of storage to cluster in, without * filling the FS with empty chunks * - * CHUNK_ALLOC_FORCE means it must try to allocate one - * */ enum { CHUNK_ALLOC_NO_FORCE = 0, - CHUNK_ALLOC_LIMITED = 1, - CHUNK_ALLOC_FORCE = 2, + CHUNK_ALLOC_FORCE = 1, + CHUNK_ALLOC_LIMITED = 2, }; /* @@ -3415,7 +3414,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, again: spin_lock(&space_info->lock); - if (force < space_info->force_alloc) + if (space_info->force_alloc) force = space_info->force_alloc; if (space_info->full) { spin_unlock(&space_info->lock); @@ -5795,7 +5794,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, u64 search_end, struct btrfs_key *ins, u64 data) { - bool final_tried = false; int ret; u64 search_start = 0; @@ -5815,25 +5813,22 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, search_start, search_end, hint_byte, ins, data); - if (ret == -ENOSPC) { - if (!final_tried) { - num_bytes = num_bytes >> 1; - num_bytes = num_bytes & ~(root->sectorsize - 1); - num_bytes = max(num_bytes, min_alloc_size); - do_chunk_alloc(trans, root->fs_info->extent_root, - num_bytes, data, CHUNK_ALLOC_FORCE); - if (num_bytes == min_alloc_size) - final_tried = true; - goto again; - } else if (btrfs_test_opt(root, ENOSPC_DEBUG)) { - struct btrfs_space_info *sinfo; - - sinfo = __find_space_info(root->fs_info, data); - printk(KERN_ERR "btrfs allocation failed flags %llu, " - "wanted %llu\n", (unsigned long long)data, - (unsigned long long)num_bytes); - dump_space_info(sinfo, num_bytes, 1); - } + if (ret == -ENOSPC && num_bytes > min_alloc_size) { + num_bytes = num_bytes >> 1; + num_bytes = num_bytes & ~(root->sectorsize - 1); + num_bytes = max(num_bytes, min_alloc_size); + do_chunk_alloc(trans, root->fs_info->extent_root, + num_bytes, data, CHUNK_ALLOC_FORCE); + goto again; + } + if (ret == -ENOSPC && btrfs_test_opt(root, ENOSPC_DEBUG)) { + struct btrfs_space_info *sinfo; + + sinfo = __find_space_info(root->fs_info, data); + printk(KERN_ERR "btrfs allocation failed flags %llu, " + "wanted %llu\n", (unsigned long long)data, + (unsigned long long)num_bytes); + dump_space_info(sinfo, num_bytes, 1); } trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index fcf77e1ded40..9d09a4f81875 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -3909,8 +3909,6 @@ int extent_range_uptodate(struct extent_io_tree *tree, while (start <= end) { index = start >> PAGE_CACHE_SHIFT; page = find_get_page(tree->mapping, index); - if (!page) - return 1; uptodate = PageUptodate(page); page_cache_release(page); if (!uptodate) { diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index c2f20594c9f7..d20ff87ca603 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -2242,7 +2242,7 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, if (entry->bitmap) { ret = btrfs_alloc_from_bitmap(block_group, cluster, entry, bytes, - cluster->window_start); + min_start); if (ret == 0) { node = rb_next(&entry->offset_index); if (!node) @@ -2251,7 +2251,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, offset_index); continue; } - cluster->window_start += bytes; } else { ret = entry->offset; @@ -2476,7 +2475,7 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, } list_for_each_entry(entry, bitmaps, list) { - if (entry->bytes < bytes) + if (entry->bytes < min_bytes) continue; ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, bytes, cont1_bytes, min_bytes); diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 32214fe0f7e3..0da19a0ea00d 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -6401,23 +6401,18 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) unsigned long zero_start; loff_t size; int ret; - int reserved = 0; u64 page_start; u64 page_end; ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); - if (!ret) { + if (!ret) ret = btrfs_update_time(vma->vm_file); - reserved = 1; - } if (ret) { if (ret == -ENOMEM) ret = VM_FAULT_OOM; else /* -ENOSPC, -EIO, etc */ ret = VM_FAULT_SIGBUS; - if (reserved) - goto out; - goto out_noreserve; + goto out; } ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ @@ -6500,7 +6495,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) unlock_page(page); out: btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE); -out_noreserve: return ret; } diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 03bb62a9ee24..ab620014bcc3 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -1065,7 +1065,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, i = range->start >> PAGE_CACHE_SHIFT; } if (!max_to_defrag) - max_to_defrag = last_index + 1; + max_to_defrag = last_index; /* * make writeback starts from i, so the defrag range can be diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index 966cc74f5d6c..cb877e0886a7 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -1957,8 +1957,7 @@ static int wait_log_commit(struct btrfs_trans_handle *trans, finish_wait(&root->log_commit_wait[index], &wait); mutex_lock(&root->log_mutex); - } while (root->fs_info->last_trans_log_full_commit != - trans->transid && root->log_transid < transid + 2 && + } while (root->log_transid < transid + 2 && atomic_read(&root->log_commit[index])); return 0; } @@ -1967,8 +1966,7 @@ static int wait_for_writer(struct btrfs_trans_handle *trans, struct btrfs_root *root) { DEFINE_WAIT(wait); - while (root->fs_info->last_trans_log_full_commit != - trans->transid && atomic_read(&root->log_writers)) { + while (atomic_read(&root->log_writers)) { prepare_to_wait(&root->log_writer_wait, &wait, TASK_UNINTERRUPTIBLE); mutex_unlock(&root->log_mutex); diff --git a/trunk/fs/ceph/caps.c b/trunk/fs/ceph/caps.c index 620daad201db..b60fc8bfb3e9 100644 --- a/trunk/fs/ceph/caps.c +++ b/trunk/fs/ceph/caps.c @@ -641,10 +641,10 @@ static int __cap_is_valid(struct ceph_cap *cap) unsigned long ttl; u32 gen; - spin_lock(&cap->session->s_gen_ttl_lock); + spin_lock(&cap->session->s_cap_lock); gen = cap->session->s_cap_gen; ttl = cap->session->s_cap_ttl; - spin_unlock(&cap->session->s_gen_ttl_lock); + spin_unlock(&cap->session->s_cap_lock); if (cap->cap_gen < gen || time_after_eq(jiffies, ttl)) { dout("__cap_is_valid %p cap %p issued %s " diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index 3e8094be4604..618246bc2196 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -975,10 +975,10 @@ static int dentry_lease_is_valid(struct dentry *dentry) di = ceph_dentry(dentry); if (di->lease_session) { s = di->lease_session; - spin_lock(&s->s_gen_ttl_lock); + spin_lock(&s->s_cap_lock); gen = s->s_cap_gen; ttl = s->s_cap_ttl; - spin_unlock(&s->s_gen_ttl_lock); + spin_unlock(&s->s_cap_lock); if (di->lease_gen == gen && time_before(jiffies, dentry->d_time) && diff --git a/trunk/fs/ceph/mds_client.c b/trunk/fs/ceph/mds_client.c index 866e8d7ca37d..23ab6a3f1825 100644 --- a/trunk/fs/ceph/mds_client.c +++ b/trunk/fs/ceph/mds_client.c @@ -262,7 +262,6 @@ static int parse_reply_info(struct ceph_msg *msg, /* trace */ ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - ceph_decode_need(&p, end, len, bad); err = parse_reply_info_trace(&p, p+len, info, features); if (err < 0) goto out_bad; @@ -271,7 +270,6 @@ static int parse_reply_info(struct ceph_msg *msg, /* extra */ ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - ceph_decode_need(&p, end, len, bad); err = parse_reply_info_extra(&p, p+len, info, features); if (err < 0) goto out_bad; @@ -400,11 +398,9 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, s->s_con.peer_name.type = CEPH_ENTITY_TYPE_MDS; s->s_con.peer_name.num = cpu_to_le64(mds); - spin_lock_init(&s->s_gen_ttl_lock); + spin_lock_init(&s->s_cap_lock); s->s_cap_gen = 0; s->s_cap_ttl = 0; - - spin_lock_init(&s->s_cap_lock); s->s_renew_requested = 0; s->s_renew_seq = 0; INIT_LIST_HEAD(&s->s_caps); @@ -2330,10 +2326,10 @@ static void handle_session(struct ceph_mds_session *session, case CEPH_SESSION_STALE: pr_info("mds%d caps went stale, renewing\n", session->s_mds); - spin_lock(&session->s_gen_ttl_lock); + spin_lock(&session->s_cap_lock); session->s_cap_gen++; session->s_cap_ttl = 0; - spin_unlock(&session->s_gen_ttl_lock); + spin_unlock(&session->s_cap_lock); send_renew_caps(mdsc, session); break; diff --git a/trunk/fs/ceph/mds_client.h b/trunk/fs/ceph/mds_client.h index 8c7c04ebb595..a50ca0e39475 100644 --- a/trunk/fs/ceph/mds_client.h +++ b/trunk/fs/ceph/mds_client.h @@ -117,13 +117,10 @@ struct ceph_mds_session { void *s_authorizer_buf, *s_authorizer_reply_buf; size_t s_authorizer_buf_len, s_authorizer_reply_buf_len; - /* protected by s_gen_ttl_lock */ - spinlock_t s_gen_ttl_lock; - u32 s_cap_gen; /* inc each time we get mds stale msg */ - unsigned long s_cap_ttl; /* when session caps expire */ - /* protected by s_cap_lock */ spinlock_t s_cap_lock; + u32 s_cap_gen; /* inc each time we get mds stale msg */ + unsigned long s_cap_ttl; /* when session caps expire */ struct list_head s_caps; /* all caps issued by this session */ int s_nr_caps, s_trim_caps; int s_num_cap_releases; diff --git a/trunk/fs/ceph/xattr.c b/trunk/fs/ceph/xattr.c index a76f697303d9..857214ae8c08 100644 --- a/trunk/fs/ceph/xattr.c +++ b/trunk/fs/ceph/xattr.c @@ -111,10 +111,8 @@ static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val, } static struct ceph_vxattr_cb ceph_file_vxattrs[] = { - { true, "ceph.file.layout", ceph_vxattrcb_layout}, - /* The following extended attribute name is deprecated */ { true, "ceph.layout", ceph_vxattrcb_layout}, - { true, NULL, NULL } + { NULL, NULL } }; static struct ceph_vxattr_cb *ceph_inode_vxattrs(struct inode *inode) diff --git a/trunk/fs/logfs/dev_mtd.c b/trunk/fs/logfs/dev_mtd.c index 9c501449450d..e97404d611e0 100644 --- a/trunk/fs/logfs/dev_mtd.c +++ b/trunk/fs/logfs/dev_mtd.c @@ -152,6 +152,9 @@ static struct page *logfs_mtd_find_first_sb(struct super_block *sb, u64 *ofs) filler_t *filler = logfs_mtd_readpage; struct mtd_info *mtd = super->s_mtd; + if (!mtd_can_have_bb(mtd)) + return NULL; + *ofs = 0; while (mtd_block_isbad(mtd, *ofs)) { *ofs += mtd->erasesize; @@ -169,6 +172,9 @@ static struct page *logfs_mtd_find_last_sb(struct super_block *sb, u64 *ofs) filler_t *filler = logfs_mtd_readpage; struct mtd_info *mtd = super->s_mtd; + if (!mtd_can_have_bb(mtd)) + return NULL; + *ofs = mtd->size - mtd->erasesize; while (mtd_block_isbad(mtd, *ofs)) { *ofs -= mtd->erasesize; diff --git a/trunk/fs/logfs/dir.c b/trunk/fs/logfs/dir.c index 3de7a32cadbe..501043e8966c 100644 --- a/trunk/fs/logfs/dir.c +++ b/trunk/fs/logfs/dir.c @@ -71,7 +71,7 @@ static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd, static int write_inode(struct inode *inode) { - return __logfs_write_inode(inode, NULL, WF_LOCK); + return __logfs_write_inode(inode, WF_LOCK); } static s64 dir_seek_data(struct inode *inode, s64 pos) diff --git a/trunk/fs/logfs/file.c b/trunk/fs/logfs/file.c index 3886cded283c..b548c87a86f1 100644 --- a/trunk/fs/logfs/file.c +++ b/trunk/fs/logfs/file.c @@ -230,9 +230,7 @@ int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) return ret; mutex_lock(&inode->i_mutex); - logfs_get_wblocks(sb, NULL, WF_LOCK); logfs_write_anchor(sb); - logfs_put_wblocks(sb, NULL, WF_LOCK); mutex_unlock(&inode->i_mutex); return 0; diff --git a/trunk/fs/logfs/gc.c b/trunk/fs/logfs/gc.c index d4efb061bdc5..caa4419285dc 100644 --- a/trunk/fs/logfs/gc.c +++ b/trunk/fs/logfs/gc.c @@ -367,7 +367,7 @@ static struct gc_candidate *get_candidate(struct super_block *sb) int i, max_dist; struct gc_candidate *cand = NULL, *this; - max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS - 1); + max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS); for (i = max_dist; i >= 0; i--) { this = first_in_list(&super->s_low_list[i]); diff --git a/trunk/fs/logfs/inode.c b/trunk/fs/logfs/inode.c index a422f42238b2..388df1aa35e5 100644 --- a/trunk/fs/logfs/inode.c +++ b/trunk/fs/logfs/inode.c @@ -286,7 +286,7 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc) if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) return 0; - ret = __logfs_write_inode(inode, NULL, flags); + ret = __logfs_write_inode(inode, flags); LOGFS_BUG_ON(ret, inode->i_sb); return ret; } @@ -363,9 +363,7 @@ static void logfs_init_once(void *_li) static int logfs_sync_fs(struct super_block *sb, int wait) { - logfs_get_wblocks(sb, NULL, WF_LOCK); logfs_write_anchor(sb); - logfs_put_wblocks(sb, NULL, WF_LOCK); return 0; } diff --git a/trunk/fs/logfs/journal.c b/trunk/fs/logfs/journal.c index 1e1c369df22b..9da29706f91c 100644 --- a/trunk/fs/logfs/journal.c +++ b/trunk/fs/logfs/journal.c @@ -612,6 +612,7 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type, if (len == 0) return logfs_write_header(super, header, 0, type); + BUG_ON(len > sb->s_blocksize); compr_len = logfs_compress(buf, data, len, sb->s_blocksize); if (compr_len < 0 || type == JE_ANCHOR) { memcpy(data, buf, len); diff --git a/trunk/fs/logfs/logfs.h b/trunk/fs/logfs/logfs.h index 5f0937609465..926373866a55 100644 --- a/trunk/fs/logfs/logfs.h +++ b/trunk/fs/logfs/logfs.h @@ -528,7 +528,7 @@ void logfs_destroy_inode_cache(void); void logfs_set_blocks(struct inode *inode, u64 no); /* these logically belong into inode.c but actually reside in readwrite.c */ int logfs_read_inode(struct inode *inode); -int __logfs_write_inode(struct inode *inode, struct page *, long flags); +int __logfs_write_inode(struct inode *inode, long flags); void logfs_evict_inode(struct inode *inode); /* journal.c */ @@ -577,8 +577,6 @@ void initialize_block_counters(struct page *page, struct logfs_block *block, __be64 *array, int page_is_empty); int logfs_exist_block(struct inode *inode, u64 bix); int get_page_reserve(struct inode *inode, struct page *page); -void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock); -void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock); extern struct logfs_block_ops indirect_block_ops; /* segment.c */ @@ -596,7 +594,6 @@ int logfs_init_mapping(struct super_block *sb); void logfs_sync_area(struct logfs_area *area); void logfs_sync_segments(struct super_block *sb); void freeseg(struct super_block *sb, u32 segno); -void free_areas(struct super_block *sb); /* area handling */ int logfs_init_areas(struct super_block *sb); diff --git a/trunk/fs/logfs/readwrite.c b/trunk/fs/logfs/readwrite.c index 4153e65b0148..2ac4217b7901 100644 --- a/trunk/fs/logfs/readwrite.c +++ b/trunk/fs/logfs/readwrite.c @@ -244,7 +244,8 @@ static void preunlock_page(struct super_block *sb, struct page *page, int lock) * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked * in addition to PG_locked. */ -void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) +static void logfs_get_wblocks(struct super_block *sb, struct page *page, + int lock) { struct logfs_super *super = logfs_super(sb); @@ -259,7 +260,8 @@ void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) } } -void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock) +static void logfs_put_wblocks(struct super_block *sb, struct page *page, + int lock) { struct logfs_super *super = logfs_super(sb); @@ -422,7 +424,7 @@ static void inode_write_block(struct logfs_block *block) if (inode->i_ino == LOGFS_INO_MASTER) logfs_write_anchor(inode->i_sb); else { - ret = __logfs_write_inode(inode, NULL, 0); + ret = __logfs_write_inode(inode, 0); /* see indirect_write_block comment */ BUG_ON(ret); } @@ -558,13 +560,8 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block) static void indirect_free_block(struct super_block *sb, struct logfs_block *block) { - struct page *page = block->page; - - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + ClearPagePrivate(block->page); + block->page->private = 0; __free_block(sb, block); } @@ -653,11 +650,8 @@ static void alloc_data_block(struct inode *inode, struct page *page) logfs_unpack_index(page->index, &bix, &level); block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); block->page = page; - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - + page->private = (unsigned long)block; block->ops = &indirect_block_ops; } @@ -1576,15 +1570,11 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags) static int __logfs_delete(struct inode *inode, struct page *page) { long flags = WF_DELETE; - int err; inode->i_ctime = inode->i_mtime = CURRENT_TIME; if (page->index < I0_BLOCKS) return logfs_write_direct(inode, page, flags); - err = grow_inode(inode, page->index, 0); - if (err) - return err; return logfs_write_rec(inode, page, page->index, 0, flags); } @@ -1633,7 +1623,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, if (inode->i_ino == LOGFS_INO_MASTER) logfs_write_anchor(inode->i_sb); else { - err = __logfs_write_inode(inode, page, flags); + err = __logfs_write_inode(inode, flags); } } } @@ -1883,7 +1873,7 @@ int logfs_truncate(struct inode *inode, u64 target) logfs_get_wblocks(sb, NULL, 1); err = __logfs_truncate(inode, size); if (!err) - err = __logfs_write_inode(inode, NULL, 0); + err = __logfs_write_inode(inode, 0); logfs_put_wblocks(sb, NULL, 1); } @@ -1911,11 +1901,8 @@ static void move_page_to_inode(struct inode *inode, struct page *page) li->li_block = block; block->page = NULL; - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + page->private = 0; + ClearPagePrivate(page); } static void move_inode_to_page(struct page *page, struct inode *inode) @@ -1931,12 +1918,8 @@ static void move_inode_to_page(struct page *page, struct inode *inode) BUG_ON(PagePrivate(page)); block->ops = &indirect_block_ops; block->page = page; - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - } + page->private = (unsigned long)block; + SetPagePrivate(page); block->inode = NULL; li->li_block = NULL; @@ -2123,14 +2106,14 @@ void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec) ec_level); } -int __logfs_write_inode(struct inode *inode, struct page *page, long flags) +int __logfs_write_inode(struct inode *inode, long flags) { struct super_block *sb = inode->i_sb; int ret; - logfs_get_wblocks(sb, page, flags & WF_LOCK); + logfs_get_wblocks(sb, NULL, flags & WF_LOCK); ret = do_write_inode(inode); - logfs_put_wblocks(sb, page, flags & WF_LOCK); + logfs_put_wblocks(sb, NULL, flags & WF_LOCK); return ret; } diff --git a/trunk/fs/logfs/segment.c b/trunk/fs/logfs/segment.c index ab798ed1cc88..9d5187353255 100644 --- a/trunk/fs/logfs/segment.c +++ b/trunk/fs/logfs/segment.c @@ -86,11 +86,7 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, BUG_ON(!page); /* FIXME: reserve a pool */ SetPageUptodate(page); memcpy(page_address(page) + offset, buf, copylen); - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); buf += copylen; @@ -114,10 +110,7 @@ static void pad_partial_page(struct logfs_area *area) page = get_mapping_page(sb, index, 0); BUG_ON(!page); /* FIXME: reserve a pool */ memset(page_address(page) + offset, 0xff, len); - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); } } @@ -137,10 +130,7 @@ static void pad_full_pages(struct logfs_area *area) BUG_ON(!page); /* FIXME: reserve a pool */ SetPageUptodate(page); memset(page_address(page), 0xff, PAGE_CACHE_SIZE); - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - } + SetPagePrivate(page); page_cache_release(page); index++; no_indizes--; @@ -495,12 +485,8 @@ static void move_btree_to_page(struct inode *inode, struct page *page, mempool_free(item, super->s_alias_pool); } block->page = page; - - if (!PagePrivate(page)) { - SetPagePrivate(page); - page_cache_get(page); - set_page_private(page, (unsigned long) block); - } + SetPagePrivate(page); + page->private = (unsigned long)block; block->ops = &indirect_block_ops; initialize_block_counters(page, block, data, 0); } @@ -550,12 +536,8 @@ void move_page_to_btree(struct page *page) list_add(&item->list, &block->item_list); } block->page = NULL; - - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - set_page_private(page, 0); - } + ClearPagePrivate(page); + page->private = 0; block->ops = &btree_block_ops; err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, block); @@ -720,10 +702,7 @@ void freeseg(struct super_block *sb, u32 segno) page = find_get_page(mapping, ofs >> PAGE_SHIFT); if (!page) continue; - if (PagePrivate(page)) { - ClearPagePrivate(page); - page_cache_release(page); - } + ClearPagePrivate(page); page_cache_release(page); } } @@ -862,16 +841,6 @@ static void free_area(struct logfs_area *area) kfree(area); } -void free_areas(struct super_block *sb) -{ - struct logfs_super *super = logfs_super(sb); - int i; - - for_each_area(i) - free_area(super->s_area[i]); - free_area(super->s_journal_area); -} - static struct logfs_area *alloc_area(struct super_block *sb) { struct logfs_area *area; @@ -954,6 +923,10 @@ int logfs_init_areas(struct super_block *sb) void logfs_cleanup_areas(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); + int i; btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); + for_each_area(i) + free_area(super->s_area[i]); + free_area(super->s_journal_area); } diff --git a/trunk/fs/logfs/super.c b/trunk/fs/logfs/super.c index c9ee7f5d1caf..e795c234ea33 100644 --- a/trunk/fs/logfs/super.c +++ b/trunk/fs/logfs/super.c @@ -486,15 +486,14 @@ static void logfs_kill_sb(struct super_block *sb) /* Alias entries slow down mount, so evict as many as possible */ sync_filesystem(sb); logfs_write_anchor(sb); - free_areas(sb); /* * From this point on alias entries are simply dropped - and any * writes to the object store are considered bugs. */ + super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; log_super("LogFS: Now in shutdown\n"); generic_shutdown_super(sb); - super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index d4548dd49b02..9cde9edf9c4d 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -198,6 +198,26 @@ static int proc_root_link(struct dentry *dentry, struct path *path) return result; } +static struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) +{ + struct mm_struct *mm; + int err; + + err = mutex_lock_killable(&task->signal->cred_guard_mutex); + if (err) + return ERR_PTR(err); + + mm = get_task_mm(task); + if (mm && mm != current->mm && + !ptrace_may_access(task, mode)) { + mmput(mm); + mm = ERR_PTR(-EACCES); + } + mutex_unlock(&task->signal->cred_guard_mutex); + + return mm; +} + struct mm_struct *mm_for_maps(struct task_struct *task) { return mm_access(task, PTRACE_MODE_READ); @@ -691,13 +711,6 @@ static int mem_open(struct inode* inode, struct file* file) if (IS_ERR(mm)) return PTR_ERR(mm); - if (mm) { - /* ensure this mm_struct can't be freed */ - atomic_inc(&mm->mm_count); - /* but do not pin its memory */ - mmput(mm); - } - /* OK to pass negative loff_t, we can catch out-of-range */ file->f_mode |= FMODE_UNSIGNED_OFFSET; file->private_data = mm; @@ -705,13 +718,13 @@ static int mem_open(struct inode* inode, struct file* file) return 0; } -static ssize_t mem_rw(struct file *file, char __user *buf, - size_t count, loff_t *ppos, int write) +static ssize_t mem_read(struct file * file, char __user * buf, + size_t count, loff_t *ppos) { - struct mm_struct *mm = file->private_data; - unsigned long addr = *ppos; - ssize_t copied; + int ret; char *page; + unsigned long src = *ppos; + struct mm_struct *mm = file->private_data; if (!mm) return 0; @@ -720,55 +733,76 @@ static ssize_t mem_rw(struct file *file, char __user *buf, if (!page) return -ENOMEM; - copied = 0; - if (!atomic_inc_not_zero(&mm->mm_users)) - goto free; - + ret = 0; + while (count > 0) { - int this_len = min_t(int, count, PAGE_SIZE); + int this_len, retval; - if (write && copy_from_user(page, buf, this_len)) { - copied = -EFAULT; + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + retval = access_remote_vm(mm, src, page, this_len, 0); + if (!retval) { + if (!ret) + ret = -EIO; break; } - this_len = access_remote_vm(mm, addr, page, this_len, write); - if (!this_len) { - if (!copied) - copied = -EIO; + if (copy_to_user(buf, page, retval)) { + ret = -EFAULT; break; } + + ret += retval; + src += retval; + buf += retval; + count -= retval; + } + *ppos = src; - if (!write && copy_to_user(buf, page, this_len)) { + free_page((unsigned long) page); + return ret; +} + +static ssize_t mem_write(struct file * file, const char __user *buf, + size_t count, loff_t *ppos) +{ + int copied; + char *page; + unsigned long dst = *ppos; + struct mm_struct *mm = file->private_data; + + if (!mm) + return 0; + + page = (char *)__get_free_page(GFP_TEMPORARY); + if (!page) + return -ENOMEM; + + copied = 0; + while (count > 0) { + int this_len, retval; + + this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; + if (copy_from_user(page, buf, this_len)) { copied = -EFAULT; break; } - - buf += this_len; - addr += this_len; - copied += this_len; - count -= this_len; + retval = access_remote_vm(mm, dst, page, this_len, 1); + if (!retval) { + if (!copied) + copied = -EIO; + break; + } + copied += retval; + buf += retval; + dst += retval; + count -= retval; } - *ppos = addr; + *ppos = dst; - mmput(mm); -free: free_page((unsigned long) page); return copied; } -static ssize_t mem_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - return mem_rw(file, buf, count, ppos, 0); -} - -static ssize_t mem_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - return mem_rw(file, (char __user*)buf, count, ppos, 1); -} - loff_t mem_lseek(struct file *file, loff_t offset, int orig) { switch (orig) { @@ -788,8 +822,8 @@ loff_t mem_lseek(struct file *file, loff_t offset, int orig) static int mem_release(struct inode *inode, struct file *file) { struct mm_struct *mm = file->private_data; - if (mm) - mmdrop(mm); + + mmput(mm); return 0; } diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index 00012e31829d..62f4fb37789e 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -493,12 +493,6 @@ int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr, const void *ns = NULL; int err; - if (!dir_sd) { - WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n", - kobject_name(kobj)); - return -ENOENT; - } - err = 0; if (!sysfs_ns_type(dir_sd)) goto out; diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 85eb81683a29..4a802b4a9056 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -318,11 +318,8 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const cha struct sysfs_addrm_cxt acxt; struct sysfs_dirent *sd; - if (!dir_sd) { - WARN(1, KERN_WARNING "sysfs: can not remove '%s', no directory\n", - name); + if (!dir_sd) return -ENOENT; - } sysfs_addrm_start(&acxt, dir_sd); diff --git a/trunk/include/linux/freezer.h b/trunk/include/linux/freezer.h index d09af4b67cf1..0ab54e16a91f 100644 --- a/trunk/include/linux/freezer.h +++ b/trunk/include/linux/freezer.h @@ -39,7 +39,6 @@ extern bool __refrigerator(bool check_kthr_stop); extern int freeze_processes(void); extern int freeze_kernel_threads(void); extern void thaw_processes(void); -extern void thaw_kernel_threads(void); static inline bool try_to_freeze(void) { @@ -175,7 +174,6 @@ static inline bool __refrigerator(bool check_kthr_stop) { return false; } static inline int freeze_processes(void) { return -ENOSYS; } static inline int freeze_kernel_threads(void) { return -ENOSYS; } static inline void thaw_processes(void) {} -static inline void thaw_kernel_threads(void) {} static inline bool try_to_freeze(void) { return false; } diff --git a/trunk/include/linux/ftrace.h b/trunk/include/linux/ftrace.h index 028e26f0bf08..f33fb3b041c6 100644 --- a/trunk/include/linux/ftrace.h +++ b/trunk/include/linux/ftrace.h @@ -178,9 +178,9 @@ struct dyn_ftrace { }; int ftrace_force_update(void); -void ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, +int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, int len, int reset); -void ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, +int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, int len, int reset); void ftrace_set_global_filter(unsigned char *buf, int len, int reset); void ftrace_set_global_notrace(unsigned char *buf, int len, int reset); diff --git a/trunk/include/linux/lp8727.h b/trunk/include/linux/lp8727.h old mode 100644 new mode 100755 diff --git a/trunk/include/linux/mfd/mcp.h b/trunk/include/linux/mfd/mcp.h index f88c1cc0cb0f..1515e64e3663 100644 --- a/trunk/include/linux/mfd/mcp.h +++ b/trunk/include/linux/mfd/mcp.h @@ -10,6 +10,7 @@ #ifndef MCP_H #define MCP_H +#include #include struct mcp_ops; @@ -26,7 +27,7 @@ struct mcp { dma_device_t dma_telco_rd; dma_device_t dma_telco_wr; struct device attached_device; - int gpio_base; + const char *codec; }; struct mcp_ops { @@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int); unsigned int mcp_reg_read(struct mcp *, unsigned int); void mcp_enable(struct mcp *); void mcp_disable(struct mcp *); +const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp); #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) struct mcp *mcp_host_alloc(struct device *, size_t); -int mcp_host_register(struct mcp *); +int mcp_host_register(struct mcp *, void *); void mcp_host_unregister(struct mcp *); struct mcp_driver { @@ -56,6 +58,7 @@ struct mcp_driver { void (*remove)(struct mcp *); int (*suspend)(struct mcp *, pm_message_t); int (*resume)(struct mcp *); + const struct mcp_device_id *id_table; }; int mcp_driver_register(struct mcp_driver *); @@ -64,9 +67,6 @@ void mcp_driver_unregister(struct mcp_driver *); #define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device) #define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d) -static inline void *mcp_priv(struct mcp *mcp) -{ - return mcp + 1; -} +#define mcp_priv(mcp) ((void *)((mcp)+1)) #endif diff --git a/trunk/include/linux/mfd/ucb1x00.h b/trunk/include/linux/mfd/ucb1x00.h index 4321f044d1e4..bc19e5fb7ea8 100644 --- a/trunk/include/linux/mfd/ucb1x00.h +++ b/trunk/include/linux/mfd/ucb1x00.h @@ -104,6 +104,9 @@ #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) #define UCB_MODE_AUD_OFF_CAN (1 << 13) +struct ucb1x00_plat_data { + int gpio_base; +}; struct ucb1x00_irq { void *devid; @@ -116,7 +119,7 @@ struct ucb1x00 { unsigned int irq; struct semaphore adc_sem; spinlock_t io_lock; - u16 id; + const struct mcp_device_id *id; u16 io_dir; u16 io_out; u16 adc_cr; diff --git a/trunk/include/linux/mod_devicetable.h b/trunk/include/linux/mod_devicetable.h index 83ac0713ed0a..b29e7f6f8fa5 100644 --- a/trunk/include/linux/mod_devicetable.h +++ b/trunk/include/linux/mod_devicetable.h @@ -436,6 +436,17 @@ struct spi_device_id { __attribute__((aligned(sizeof(kernel_ulong_t)))); }; +/* mcp */ + +#define MCP_NAME_SIZE 20 +#define MCP_MODULE_PREFIX "mcp:" + +struct mcp_device_id { + char name[MCP_NAME_SIZE]; + kernel_ulong_t driver_data /* Data private to the driver */ + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* dmi */ enum dmi_field { DMI_NONE, diff --git a/trunk/include/linux/mpi.h b/trunk/include/linux/mpi.h index d02cca6cc8ce..06f88994ccaa 100644 --- a/trunk/include/linux/mpi.h +++ b/trunk/include/linux/mpi.h @@ -57,6 +57,8 @@ struct gcry_mpi { typedef struct gcry_mpi *MPI; +#define MPI_NULL NULL + #define mpi_get_nlimbs(a) ((a)->nlimbs) #define mpi_is_neg(a) ((a)->sign) diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index 887ebe318c75..1a81fde8f333 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -441,7 +441,7 @@ static inline void mtd_resume(struct mtd_info *mtd) static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->block_isbad) - return 0; + return -EOPNOTSUPP; return mtd->block_isbad(mtd, ofs); } diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 7d379a6bfd88..2234985a5e65 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -2259,12 +2259,6 @@ static inline void mmdrop(struct mm_struct * mm) extern void mmput(struct mm_struct *); /* Grab a reference to a task's mm, if it is not already going away */ extern struct mm_struct *get_task_mm(struct task_struct *task); -/* - * Grab a reference to a task's mm, if it is not already going away - * and ptrace_may_access with the mode parameter passed to it - * succeeds. - */ -extern struct mm_struct *mm_access(struct task_struct *task, unsigned int mode); /* Remove the current tasks stale references to the old mm_struct */ extern void mm_release(struct task_struct *, struct mm_struct *); /* Allocate a new mm structure and copy contents from tsk->mm */ diff --git a/trunk/include/linux/sysdev.h b/trunk/include/linux/sysdev.h new file mode 100644 index 000000000000..20f63d3e6144 --- /dev/null +++ b/trunk/include/linux/sysdev.h @@ -0,0 +1,164 @@ +/** + * System devices follow a slightly different driver model. + * They don't need to do dynammic driver binding, can't be probed, + * and don't reside on any type of peripheral bus. + * So, we represent and treat them a little differently. + * + * We still have a notion of a driver for a system device, because we still + * want to perform basic operations on these devices. + * + * We also support auxiliary drivers binding to devices of a certain class. + * + * This allows configurable drivers to register themselves for devices of + * a certain type. And, it allows class definitions to reside in generic + * code while arch-specific code can register specific drivers. + * + * Auxiliary drivers registered with a NULL cls are registered as drivers + * for all system devices, and get notification calls for each device. + */ + + +#ifndef _SYSDEV_H_ +#define _SYSDEV_H_ + +#include +#include + + +struct sys_device; +struct sysdev_class_attribute; + +struct sysdev_class { + const char *name; + struct list_head drivers; + struct sysdev_class_attribute **attrs; + struct kset kset; +}; + +struct sysdev_class_attribute { + struct attribute attr; + ssize_t (*show)(struct sysdev_class *, struct sysdev_class_attribute *, + char *); + ssize_t (*store)(struct sysdev_class *, struct sysdev_class_attribute *, + const char *, size_t); +}; + +#define _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ +{ \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +} + +#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ + struct sysdev_class_attribute attr_##_name = \ + _SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) + + +extern int sysdev_class_register(struct sysdev_class *); +extern void sysdev_class_unregister(struct sysdev_class *); + +extern int sysdev_class_create_file(struct sysdev_class *, + struct sysdev_class_attribute *); +extern void sysdev_class_remove_file(struct sysdev_class *, + struct sysdev_class_attribute *); +/** + * Auxiliary system device drivers. + */ + +struct sysdev_driver { + struct list_head entry; + int (*add)(struct sys_device *); + int (*remove)(struct sys_device *); +}; + + +extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *); +extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *); + + +/** + * sys_devices can be simplified a lot from regular devices, because they're + * simply not as versatile. + */ + +struct sys_device { + u32 id; + struct sysdev_class * cls; + struct kobject kobj; +}; + +extern int sysdev_register(struct sys_device *); +extern void sysdev_unregister(struct sys_device *); + + +struct sysdev_attribute { + struct attribute attr; + ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *); + ssize_t (*store)(struct sys_device *, struct sysdev_attribute *, + const char *, size_t); +}; + + +#define _SYSDEV_ATTR(_name, _mode, _show, _store) \ +{ \ + .attr = { .name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +} + +#define SYSDEV_ATTR(_name, _mode, _show, _store) \ + struct sysdev_attribute attr_##_name = \ + _SYSDEV_ATTR(_name, _mode, _show, _store); + +extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); +extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); + +/* Create/remove NULL terminated attribute list */ +static inline int +sysdev_create_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_create_files(&d->kobj, (const struct attribute **)a); +} + +static inline void +sysdev_remove_files(struct sys_device *d, struct sysdev_attribute **a) +{ + return sysfs_remove_files(&d->kobj, (const struct attribute **)a); +} + +struct sysdev_ext_attribute { + struct sysdev_attribute attr; + void *var; +}; + +/* + * Support for simple variable sysdev attributes. + * The pointer to the variable is stored in a sysdev_ext_attribute + */ + +/* Add more types as needed */ + +extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *, + char *); +extern ssize_t sysdev_store_ulong(struct sys_device *, + struct sysdev_attribute *, const char *, size_t); +extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *, + char *); +extern ssize_t sysdev_store_int(struct sys_device *, + struct sysdev_attribute *, const char *, size_t); + +#define _SYSDEV_ULONG_ATTR(_name, _mode, _var) \ + { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \ + &(_var) } +#define SYSDEV_ULONG_ATTR(_name, _mode, _var) \ + struct sysdev_ext_attribute attr_##_name = \ + _SYSDEV_ULONG_ATTR(_name, _mode, _var); +#define _SYSDEV_INT_ATTR(_name, _mode, _var) \ + { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \ + &(_var) } +#define SYSDEV_INT_ATTR(_name, _mode, _var) \ + struct sysdev_ext_attribute attr_##_name = \ + _SYSDEV_INT_ATTR(_name, _mode, _var); + +#endif /* _SYSDEV_H_ */ diff --git a/trunk/include/linux/usb/langwell_otg.h b/trunk/include/linux/usb/langwell_otg.h new file mode 100644 index 000000000000..51f17b16d312 --- /dev/null +++ b/trunk/include/linux/usb/langwell_otg.h @@ -0,0 +1,139 @@ +/* + * Intel Langwell USB OTG transceiver driver + * Copyright (C) 2008 - 2010, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef __LANGWELL_OTG_H +#define __LANGWELL_OTG_H + +#include + +#define CI_USBCMD 0x30 +# define USBCMD_RST BIT(1) +# define USBCMD_RS BIT(0) +#define CI_USBSTS 0x34 +# define USBSTS_SLI BIT(8) +# define USBSTS_URI BIT(6) +# define USBSTS_PCI BIT(2) +#define CI_PORTSC1 0x74 +# define PORTSC_PP BIT(12) +# define PORTSC_LS (BIT(11) | BIT(10)) +# define PORTSC_SUSP BIT(7) +# define PORTSC_CCS BIT(0) +#define CI_HOSTPC1 0xb4 +# define HOSTPC1_PHCD BIT(22) +#define CI_OTGSC 0xf4 +# define OTGSC_DPIE BIT(30) +# define OTGSC_1MSE BIT(29) +# define OTGSC_BSEIE BIT(28) +# define OTGSC_BSVIE BIT(27) +# define OTGSC_ASVIE BIT(26) +# define OTGSC_AVVIE BIT(25) +# define OTGSC_IDIE BIT(24) +# define OTGSC_DPIS BIT(22) +# define OTGSC_1MSS BIT(21) +# define OTGSC_BSEIS BIT(20) +# define OTGSC_BSVIS BIT(19) +# define OTGSC_ASVIS BIT(18) +# define OTGSC_AVVIS BIT(17) +# define OTGSC_IDIS BIT(16) +# define OTGSC_DPS BIT(14) +# define OTGSC_1MST BIT(13) +# define OTGSC_BSE BIT(12) +# define OTGSC_BSV BIT(11) +# define OTGSC_ASV BIT(10) +# define OTGSC_AVV BIT(9) +# define OTGSC_ID BIT(8) +# define OTGSC_HABA BIT(7) +# define OTGSC_HADP BIT(6) +# define OTGSC_IDPU BIT(5) +# define OTGSC_DP BIT(4) +# define OTGSC_OT BIT(3) +# define OTGSC_HAAR BIT(2) +# define OTGSC_VC BIT(1) +# define OTGSC_VD BIT(0) +# define OTGSC_INTEN_MASK (0x7f << 24) +# define OTGSC_INT_MASK (0x5f << 24) +# define OTGSC_INTSTS_MASK (0x7f << 16) +#define CI_USBMODE 0xf8 +# define USBMODE_CM (BIT(1) | BIT(0)) +# define USBMODE_IDLE 0 +# define USBMODE_DEVICE 0x2 +# define USBMODE_HOST 0x3 +#define USBCFG_ADDR 0xff10801c +#define USBCFG_LEN 4 +# define USBCFG_VBUSVAL BIT(14) +# define USBCFG_AVALID BIT(13) +# define USBCFG_BVALID BIT(12) +# define USBCFG_SESEND BIT(11) + +#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI) + +enum langwell_otg_timer_type { + TA_WAIT_VRISE_TMR, + TA_WAIT_BCON_TMR, + TA_AIDL_BDIS_TMR, + TB_ASE0_BRST_TMR, + TB_SE0_SRP_TMR, + TB_SRP_INIT_TMR, + TB_SRP_FAIL_TMR, + TB_BUS_SUSPEND_TMR +}; + +#define TA_WAIT_VRISE 100 +#define TA_WAIT_BCON 30000 +#define TA_AIDL_BDIS 15000 +#define TB_ASE0_BRST 5000 +#define TB_SE0_SRP 2 +#define TB_SRP_INIT 100 +#define TB_SRP_FAIL 5500 +#define TB_BUS_SUSPEND 500 + +struct langwell_otg_timer { + unsigned long expires; /* Number of count increase to timeout */ + unsigned long count; /* Tick counter */ + void (*function)(unsigned long); /* Timeout function */ + unsigned long data; /* Data passed to function */ + struct list_head list; +}; + +struct langwell_otg { + struct intel_mid_otg_xceiv iotg; + struct device *dev; + + void __iomem *usbcfg; /* SCCBUSB config Reg */ + + unsigned region; + unsigned cfg_region; + + struct work_struct work; + struct workqueue_struct *qwork; + struct timer_list hsm_timer; + + spinlock_t lock; + spinlock_t wq_lock; + + struct notifier_block iotg_notifier; +}; + +static inline +struct langwell_otg *mid_xceiv_to_lnw(struct intel_mid_otg_xceiv *iotg) +{ + return container_of(iotg, struct langwell_otg, iotg); +} + +#endif /* __LANGWELL_OTG_H__ */ diff --git a/trunk/include/net/netns/generic.h b/trunk/include/net/netns/generic.h index d55f43443335..3419bf5cd154 100644 --- a/trunk/include/net/netns/generic.h +++ b/trunk/include/net/netns/generic.h @@ -41,7 +41,6 @@ static inline void *net_generic(const struct net *net, int id) ptr = ng->ptr[id - 1]; rcu_read_unlock(); - BUG_ON(!ptr); return ptr; } #endif diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 91c1c8baf020..4c69ac165e6b 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -55,7 +55,6 @@ #include #include #include -#include #include #include diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index d49db0113a06..0118ea999f67 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -311,8 +311,6 @@ extern struct proto tcp_prot; #define TCP_ADD_STATS_USER(net, field, val) SNMP_ADD_STATS_USER((net)->mib.tcp_statistics, field, val) #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val) -extern void tcp_init_mem(struct net *net); - extern void tcp_v4_err(struct sk_buff *skb, u32); extern void tcp_shutdown (struct sock *sk, int how); diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index 4b4042f9bc6a..294b1709170d 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -1038,22 +1038,6 @@ void do_exit(long code) if (tsk->nr_dirtied) __this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied); exit_rcu(); - - /* - * The setting of TASK_RUNNING by try_to_wake_up() may be delayed - * when the following two conditions become true. - * - There is race condition of mmap_sem (It is acquired by - * exit_mm()), and - * - SMI occurs before setting TASK_RUNINNG. - * (or hypervisor of virtual machine switches to other guest) - * As a result, we may become TASK_RUNNING after becoming TASK_DEAD - * - * To avoid it, we have to wait for releasing tsk->pi_lock which - * is held by try_to_wake_up() - */ - smp_mb(); - raw_spin_unlock_wait(&tsk->pi_lock); - /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */ diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 1b2ef3c23ae4..051f090d40c1 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -647,26 +647,6 @@ struct mm_struct *get_task_mm(struct task_struct *task) } EXPORT_SYMBOL_GPL(get_task_mm); -struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) -{ - struct mm_struct *mm; - int err; - - err = mutex_lock_killable(&task->signal->cred_guard_mutex); - if (err) - return ERR_PTR(err); - - mm = get_task_mm(task); - if (mm && mm != current->mm && - !ptrace_may_access(task, mode)) { - mmput(mm); - mm = ERR_PTR(-EACCES); - } - mutex_unlock(&task->signal->cred_guard_mutex); - - return mm; -} - /* Please note the differences between mmput and mm_release. * mmput is called whenever we stop holding onto a mm_struct, * error success whatever. diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index eeca00311f39..77274c9ba2f1 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -188,22 +188,3 @@ void thaw_processes(void) printk("done.\n"); } -void thaw_kernel_threads(void) -{ - struct task_struct *g, *p; - - pm_nosig_freezing = false; - printk("Restarting kernel threads ... "); - - thaw_workqueues(); - - read_lock(&tasklist_lock); - do_each_thread(g, p) { - if (p->flags & (PF_KTHREAD | PF_WQ_WORKER)) - __thaw_task(p); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); - - schedule(); - printk("done.\n"); -} diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index e5a21a857302..6b1ab7a88522 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -274,15 +274,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, swsusp_free(); memset(&data->handle, 0, sizeof(struct snapshot_handle)); data->ready = 0; - /* - * It is necessary to thaw kernel threads here, because - * SNAPSHOT_CREATE_IMAGE may be invoked directly after - * SNAPSHOT_FREE. In that case, if kernel threads were not - * thawed, the preallocation of memory carried out by - * hibernation_snapshot() might run into problems (i.e. it - * might fail or even deadlock). - */ - thaw_kernel_threads(); break; case SNAPSHOT_PREF_IMAGE_SIZE: diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 5255c9d2e053..df00cb09263e 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -74,7 +74,6 @@ #include #include -#include #ifdef CONFIG_PARAVIRT #include #endif @@ -724,6 +723,9 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) p->sched_class->dequeue_task(rq, p, flags); } +/* + * activate_task - move a task to the runqueue. + */ void activate_task(struct rq *rq, struct task_struct *p, int flags) { if (task_contributes_to_load(p)) @@ -732,6 +734,9 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags) enqueue_task(rq, p, flags); } +/* + * deactivate_task - remove a task from the runqueue. + */ void deactivate_task(struct rq *rq, struct task_struct *p, int flags) { if (task_contributes_to_load(p)) @@ -4129,7 +4134,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, on_rq = p->on_rq; running = task_current(rq, p); if (on_rq) - dequeue_task(rq, p, 0); + deactivate_task(rq, p, 0); if (running) p->sched_class->put_prev_task(rq, p); @@ -4142,7 +4147,7 @@ static int __sched_setscheduler(struct task_struct *p, int policy, if (running) p->sched_class->set_curr_task(rq); if (on_rq) - enqueue_task(rq, p, 0); + activate_task(rq, p, 0); check_class_changed(rq, p, prev_class, oldprio); task_rq_unlock(rq, p, &flags); @@ -4993,9 +4998,9 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) * placed properly. */ if (p->on_rq) { - dequeue_task(rq_src, p, 0); + deactivate_task(rq_src, p, 0); set_task_cpu(p, dest_cpu); - enqueue_task(rq_dest, p, 0); + activate_task(rq_dest, p, 0); check_preempt_curr(rq_dest, p, 0); } done: @@ -7027,10 +7032,10 @@ static void normalize_task(struct rq *rq, struct task_struct *p) on_rq = p->on_rq; if (on_rq) - dequeue_task(rq, p, 0); + deactivate_task(rq, p, 0); __setscheduler(rq, p, SCHED_NORMAL, 0); if (on_rq) { - enqueue_task(rq, p, 0); + activate_task(rq, p, 0); resched_task(rq->curr); } diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index 7c6414fc669d..84adb2d66cbd 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -4866,15 +4866,6 @@ static void nohz_balancer_kick(int cpu) return; } -static inline void clear_nohz_tick_stopped(int cpu) -{ - if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { - cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); - atomic_dec(&nohz.nr_cpus); - clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); - } -} - static inline void set_cpu_sd_state_busy(void) { struct sched_domain *sd; @@ -4913,12 +4904,6 @@ void select_nohz_load_balancer(int stop_tick) { int cpu = smp_processor_id(); - /* - * If this cpu is going down, then nothing needs to be done. - */ - if (!cpu_active(cpu)) - return; - if (stop_tick) { if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu))) return; @@ -4929,18 +4914,6 @@ void select_nohz_load_balancer(int stop_tick) } return; } - -static int __cpuinit sched_ilb_notifier(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_DYING: - clear_nohz_tick_stopped(smp_processor_id()); - return NOTIFY_OK; - default: - return NOTIFY_DONE; - } -} #endif static DEFINE_SPINLOCK(balancing); @@ -5097,7 +5070,11 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) * busy tick after returning from idle, we will update the busy stats. */ set_cpu_sd_state_busy(); - clear_nohz_tick_stopped(cpu); + if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { + clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); + cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); + atomic_dec(&nohz.nr_cpus); + } /* * None are in tickless mode and hence no need for NOHZ idle load @@ -5613,7 +5590,6 @@ __init void init_sched_fair_class(void) #ifdef CONFIG_NO_HZ zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT); - cpu_notifier(sched_ilb_notifier, 0); #endif #endif /* SMP */ diff --git a/trunk/kernel/sched/rt.c b/trunk/kernel/sched/rt.c index f42ae7fb5ec5..3640ebbb466b 100644 --- a/trunk/kernel/sched/rt.c +++ b/trunk/kernel/sched/rt.c @@ -1587,11 +1587,6 @@ static int push_rt_task(struct rq *rq) if (!next_task) return 0; -#ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW - if (unlikely(task_running(rq, next_task))) - return 0; -#endif - retry: if (unlikely(next_task == rq->curr)) { WARN_ON(1); diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 683d559a0eef..e2e0597c0845 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -3146,8 +3146,10 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, mutex_lock(&ftrace_regex_lock); if (reset) ftrace_filter_reset(hash); - if (buf) - ftrace_match_records(hash, buf, len); + if (buf && !ftrace_match_records(hash, buf, len)) { + ret = -EINVAL; + goto out_regex_unlock; + } mutex_lock(&ftrace_lock); ret = ftrace_hash_move(ops, enable, orig_hash, hash); @@ -3157,6 +3159,7 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, mutex_unlock(&ftrace_lock); + out_regex_unlock: mutex_unlock(&ftrace_regex_lock); free_ftrace_hash(hash); @@ -3173,10 +3176,10 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, * Filters denote which functions should be enabled when tracing is enabled. * If @buf is NULL and reset is set, all functions will be enabled for tracing. */ -void ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, +int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, int len, int reset) { - ftrace_set_regex(ops, buf, len, reset, 1); + return ftrace_set_regex(ops, buf, len, reset, 1); } EXPORT_SYMBOL_GPL(ftrace_set_filter); @@ -3191,10 +3194,10 @@ EXPORT_SYMBOL_GPL(ftrace_set_filter); * is enabled. If @buf is NULL and reset is set, all functions will be enabled * for tracing. */ -void ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, +int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, int len, int reset) { - ftrace_set_regex(ops, buf, len, reset, 0); + return ftrace_set_regex(ops, buf, len, reset, 0); } EXPORT_SYMBOL_GPL(ftrace_set_notrace); /** diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 14bc092fb12c..1d7bca7f4f52 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -3,9 +3,12 @@ * * started by Don Zickus, Copyright (C) 2010 Red Hat, Inc. * - * Note: Most of this code is borrowed heavily from the original softlockup - * detector, so thanks to Ingo for the initial implementation. - * Some chunks also taken from the old x86-specific nmi watchdog code, thanks + * this code detects hard lockups: incidents in where on a CPU + * the kernel does not respond to anything except NMI. + * + * Note: Most of this code is borrowed heavily from softlockup.c, + * so thanks to Ingo for the initial implementation. + * Some chunks also taken from arch/x86/kernel/apic/nmi.c, thanks * to those contributors as well. */ @@ -114,10 +117,9 @@ static unsigned long get_sample_period(void) { /* * convert watchdog_thresh from seconds to ns - * the divide by 5 is to give hrtimer several chances (two - * or three with the current relation between the soft - * and hard thresholds) to increment before the - * hardlockup detector generates a warning + * the divide by 5 is to give hrtimer 5 chances to + * increment before the hardlockup detector generates + * a warning */ return get_softlockup_thresh() * (NSEC_PER_SEC / 5); } @@ -294,7 +296,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer) if (__this_cpu_read(soft_watchdog_warn) == true) return HRTIMER_RESTART; - printk(KERN_EMERG "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", + printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %us! [%s:%d]\n", smp_processor_id(), duration, current->comm, task_pid_nr(current)); print_modules(); @@ -334,11 +336,9 @@ static int watchdog(void *unused) set_current_state(TASK_INTERRUPTIBLE); /* - * Run briefly (kicked by the hrtimer callback function) once every - * get_sample_period() seconds (4 seconds by default) to reset the - * softlockup timestamp. If this gets delayed for more than - * 2*watchdog_thresh seconds then the debug-printout triggers in - * watchdog_timer_fn(). + * Run briefly once per second to reset the softlockup timestamp. + * If this gets delayed for more than 60 seconds then the + * debug-printout triggers in watchdog_timer_fn(). */ while (!kthread_should_stop()) { __touch_watchdog(); diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index d69d321a0997..169eb7c598e5 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -279,9 +279,6 @@ config AVERAGE If unsure, say N. -config CLZ_TAB - bool - config CORDIC tristate "CORDIC algorithm" help @@ -290,7 +287,6 @@ config CORDIC config MPILIB tristate - select CLZ_TAB help Multiprecision maths library from GnuPG. It is used to implement RSA digital signature verification, diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index 9739c0b45e93..8745ac7d1f75 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -166,21 +166,18 @@ config LOCKUP_DETECTOR hard and soft lockups. Softlockups are bugs that cause the kernel to loop in kernel - mode for more than 20 seconds, without giving other tasks a + mode for more than 60 seconds, without giving other tasks a chance to run. The current stack trace is displayed upon detection and the system will stay locked up. Hardlockups are bugs that cause the CPU to loop in kernel mode - for more than 10 seconds, without letting other interrupts have a + for more than 60 seconds, without letting other interrupts have a chance to run. The current stack trace is displayed upon detection and the system will stay locked up. The overhead should be minimal. A periodic hrtimer runs to - generate interrupts and kick the watchdog task every 4 seconds. - An NMI is generated every 10 seconds or so to check for hardlockups. - - The frequency of hrtimer and NMI events and the soft and hard lockup - thresholds can be controlled through the sysctl watchdog_thresh. + generate interrupts and kick the watchdog task every 10-12 seconds. + An NMI is generated every 60 seconds or so to check for hardlockups. config HARDLOCKUP_DETECTOR def_bool LOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI && \ @@ -192,8 +189,7 @@ config BOOTPARAM_HARDLOCKUP_PANIC help Say Y here to enable the kernel to panic on "hard lockups", which are bugs that cause the kernel to loop in kernel - mode with interrupts disabled for more than 10 seconds (configurable - using the watchdog_thresh sysctl). + mode with interrupts disabled for more than 60 seconds. Say N if unsure. @@ -210,8 +206,8 @@ config BOOTPARAM_SOFTLOCKUP_PANIC help Say Y here to enable the kernel to panic on "soft lockups", which are bugs that cause the kernel to loop in kernel - mode for more than 20 seconds (configurable using the watchdog_thresh - sysctl), without giving other tasks a chance to run. + mode for more than 60 seconds, without giving other tasks a + chance to run. The panic can be used in combination with panic_timeout, to cause the system to reboot automatically after a diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 18515f0267c4..d71aae1b01b3 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -121,8 +121,6 @@ obj-$(CONFIG_DQL) += dynamic_queue_limits.o obj-$(CONFIG_MPILIB) += mpi/ obj-$(CONFIG_SIGNATURE) += digsig.o -obj-$(CONFIG_CLZ_TAB) += clz_tab.o - hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/trunk/lib/bug.c b/trunk/lib/bug.c index a28c1415357c..19552096d16b 100644 --- a/trunk/lib/bug.c +++ b/trunk/lib/bug.c @@ -169,7 +169,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) return BUG_TRAP_TYPE_WARN; } - printk(KERN_DEFAULT "------------[ cut here ]------------\n"); + printk(KERN_EMERG "------------[ cut here ]------------\n"); if (file) printk(KERN_CRIT "kernel BUG at %s:%u!\n", diff --git a/trunk/lib/clz_tab.c b/trunk/lib/clz_tab.c deleted file mode 100644 index 7287b4a991a7..000000000000 --- a/trunk/lib/clz_tab.c +++ /dev/null @@ -1,18 +0,0 @@ -const unsigned char __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, -}; diff --git a/trunk/lib/digsig.c b/trunk/lib/digsig.c index 286d558033e2..fd2402f67f89 100644 --- a/trunk/lib/digsig.c +++ b/trunk/lib/digsig.c @@ -34,9 +34,14 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, unsigned long msglen, unsigned long modulus_bitlen, unsigned char *out, - unsigned long *outlen) + unsigned long *outlen, + int *is_valid) { unsigned long modulus_len, ps_len, i; + int result; + + /* default to invalid packet */ + *is_valid = 0; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); @@ -45,30 +50,39 @@ static int pkcs_1_v1_5_decode_emsa(const unsigned char *msg, return -EINVAL; /* separate encoded message */ - if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) - return -EINVAL; + if ((msg[0] != 0x00) || (msg[1] != (unsigned char)1)) { + result = -EINVAL; + goto bail; + } for (i = 2; i < modulus_len - 1; i++) if (msg[i] != 0xFF) break; /* separator check */ - if (msg[i] != 0) + if (msg[i] != 0) { /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ - return -EINVAL; + result = -EINVAL; + goto bail; + } ps_len = i - 2; if (*outlen < (msglen - (2 + ps_len + 1))) { *outlen = msglen - (2 + ps_len + 1); - return -EOVERFLOW; + result = -EOVERFLOW; + goto bail; } *outlen = (msglen - (2 + ps_len + 1)); memcpy(out, &msg[2 + ps_len + 1], *outlen); - return 0; + /* valid packet */ + *is_valid = 1; + result = 0; +bail: + return result; } /* @@ -82,7 +96,7 @@ static int digsig_verify_rsa(struct key *key, unsigned long len; unsigned long mlen, mblen; unsigned nret, l; - int head, i; + int valid, head, i; unsigned char *out1 = NULL, *out2 = NULL; MPI in = NULL, res = NULL, pkey[2]; uint8_t *p, *datap, *endp; @@ -91,10 +105,6 @@ static int digsig_verify_rsa(struct key *key, down_read(&key->sem); ukp = key->payload.data; - - if (ukp->datalen < sizeof(*pkh)) - goto err1; - pkh = (struct pubkey_hdr *)ukp->data; if (pkh->version != 1) @@ -107,23 +117,18 @@ static int digsig_verify_rsa(struct key *key, goto err1; datap = pkh->mpi; - endp = ukp->data + ukp->datalen; - - err = -ENOMEM; + endp = datap + ukp->datalen; for (i = 0; i < pkh->nmpi; i++) { unsigned int remaining = endp - datap; pkey[i] = mpi_read_from_buffer(datap, &remaining); - if (!pkey[i]) - goto err; datap += remaining; } mblen = mpi_get_nbits(pkey[0]); mlen = (mblen + 7)/8; - if (mlen == 0) - goto err; + err = -ENOMEM; out1 = kzalloc(mlen, GFP_KERNEL); if (!out1) @@ -162,9 +167,10 @@ static int digsig_verify_rsa(struct key *key, memset(out1, 0, head); memcpy(out1 + head, p, l); - err = pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len); + err = -EINVAL; + pkcs_1_v1_5_decode_emsa(out1, len, mblen, out2, &len, &valid); - if (!err && len == hlen) + if (valid && len == hlen) err = memcmp(out2, h, hlen); err: @@ -172,8 +178,8 @@ static int digsig_verify_rsa(struct key *key, mpi_free(res); kfree(out1); kfree(out2); - while (--i >= 0) - mpi_free(pkey[i]); + mpi_free(pkey[0]); + mpi_free(pkey[1]); err1: up_read(&key->sem); diff --git a/trunk/lib/mpi/longlong.h b/trunk/lib/mpi/longlong.h index 29f98624ef93..b87487b40a8b 100644 --- a/trunk/lib/mpi/longlong.h +++ b/trunk/lib/mpi/longlong.h @@ -1200,40 +1200,18 @@ do { \ "r" ((USItype)(v)) \ : "%g1", "%g2" __AND_CLOBBER_CC) #define UMUL_TIME 39 /* 39 instructions */ -/* It's quite necessary to add this much assembler for the sparc. - The default udiv_qrnnd (in C) is more than 10 times slower! */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("! Inlined udiv_qrnnd\n\t" \ - "mov 32,%%g1\n\t" \ - "subcc %1,%2,%%g0\n\t" \ - "1: bcs 5f\n\t" \ - "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ - "sub %1,%2,%1 ! this kills msb of n\n\t" \ - "addx %1,%1,%1 ! so this can't give carry\n\t" \ - "subcc %%g1,1,%%g1\n\t" \ - "2: bne 1b\n\t" \ - "subcc %1,%2,%%g0\n\t" \ - "bcs 3f\n\t" \ - "addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n\t" \ - "b 3f\n\t" \ - "sub %1,%2,%1 ! this kills msb of n\n\t" \ - "4: sub %1,%2,%1\n\t" \ - "5: addxcc %1,%1,%1\n\t" \ - "bcc 2b\n\t" \ - "subcc %%g1,1,%%g1\n\t" \ - "! Got carry from n. Subtract next step to cancel this carry.\n\t" \ - "bne 4b\n\t" \ - "addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n\t" \ - "sub %1,%2,%1\n\t" \ - "3: xnor %0,0,%0\n\t" \ - "! End of inline udiv_qrnnd\n" \ - : "=&r" ((USItype)(q)), \ - "=&r" ((USItype)(r)) \ - : "r" ((USItype)(d)), \ - "1" ((USItype)(n1)), \ - "0" ((USItype)(n0)) : "%g1", "cc") -#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ #endif +#ifndef udiv_qrnnd +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ +do { USItype __r; \ + (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ + (r) = __r; \ +} while (0) + extern USItype __udiv_qrnnd(); +#define UDIV_TIME 140 +#endif /* LONGLONG_STANDALONE */ +#endif /* udiv_qrnnd */ #endif /* __sparc__ */ /*************************************** diff --git a/trunk/lib/mpi/mpi-bit.c b/trunk/lib/mpi/mpi-bit.c index 2f526627e4f5..854c9c6da025 100644 --- a/trunk/lib/mpi/mpi-bit.c +++ b/trunk/lib/mpi/mpi-bit.c @@ -21,6 +21,25 @@ #include "mpi-internal.h" #include "longlong.h" +const unsigned char __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, +}; + #define A_LIMB_1 ((mpi_limb_t) 1) /**************** diff --git a/trunk/lib/mpi/mpi-div.c b/trunk/lib/mpi/mpi-div.c index f68cbbb4d4a4..c3087d1390ce 100644 --- a/trunk/lib/mpi/mpi-div.c +++ b/trunk/lib/mpi/mpi-div.c @@ -149,9 +149,6 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) mpi_ptr_t marker[5]; int markidx = 0; - if (!dsize) - return -EINVAL; - memset(marker, 0, sizeof(marker)); /* Ensure space is enough for quotient and remainder. @@ -210,8 +207,6 @@ int mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den) * numerator would be gradually overwritten by the quotient limbs. */ if (qp == np) { /* Copy NP object to temporary space. */ np = marker[markidx++] = mpi_alloc_limb_space(nsize); - if (!np) - goto nomem; MPN_COPY(np, qp, nsize); } } else /* Put quotient at top of remainder. */ diff --git a/trunk/lib/mpi/mpi-pow.c b/trunk/lib/mpi/mpi-pow.c index 67f3e79af914..b04a3cf80080 100644 --- a/trunk/lib/mpi/mpi-pow.c +++ b/trunk/lib/mpi/mpi-pow.c @@ -59,7 +59,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod) ep = exp->d; if (!msize) - return -EINVAL; + msize = 1 / msize; /* provoke a signal */ if (!esize) { /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 diff --git a/trunk/lib/mpi/mpicoder.c b/trunk/lib/mpi/mpicoder.c index f26b41fcb48c..716802b774ea 100644 --- a/trunk/lib/mpi/mpicoder.c +++ b/trunk/lib/mpi/mpicoder.c @@ -20,15 +20,78 @@ #include "mpi-internal.h" +#define DIM(v) (sizeof(v)/sizeof((v)[0])) #define MAX_EXTERN_MPI_BITS 16384 +static uint8_t asn[15] = /* Object ID is 1.3.14.3.2.26 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 +}; + +MPI do_encode_md(const void *sha_buffer, unsigned nbits) +{ + int nframe = (nbits + 7) / 8; + uint8_t *frame, *fr_pt; + int i = 0, n; + size_t asnlen = DIM(asn); + MPI a = MPI_NULL; + + if (SHA1_DIGEST_LENGTH + asnlen + 4 > nframe) + pr_info("MPI: can't encode a %d bit MD into a %d bits frame\n", + (int)(SHA1_DIGEST_LENGTH * 8), (int)nbits); + + /* We encode the MD in this way: + * + * 0 A PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes) + * + * PAD consists of FF bytes. + */ + frame = kmalloc(nframe, GFP_KERNEL); + if (!frame) + return MPI_NULL; + n = 0; + frame[n++] = 0; + frame[n++] = 1; /* block type */ + i = nframe - SHA1_DIGEST_LENGTH - asnlen - 3; + + if (i <= 1) { + pr_info("MPI: message digest encoding failed\n"); + kfree(frame); + return a; + } + + memset(frame + n, 0xff, i); + n += i; + frame[n++] = 0; + memcpy(frame + n, &asn, asnlen); + n += asnlen; + memcpy(frame + n, sha_buffer, SHA1_DIGEST_LENGTH); + n += SHA1_DIGEST_LENGTH; + + i = nframe; + fr_pt = frame; + + if (n != nframe) { + printk + ("MPI: message digest encoding failed, frame length is wrong\n"); + kfree(frame); + return a; + } + + a = mpi_alloc((nframe + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB); + mpi_set_buffer(a, frame, nframe, 0); + kfree(frame); + + return a; +} + MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) { const uint8_t *buffer = xbuffer; int i, j; unsigned nbits, nbytes, nlimbs, nread = 0; mpi_limb_t a; - MPI val = NULL; + MPI val = MPI_NULL; if (*ret_nread < 2) goto leave; @@ -45,7 +108,7 @@ MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; val = mpi_alloc(nlimbs); if (!val) - return NULL; + return MPI_NULL; i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; i %= BYTES_PER_MPI_LIMB; val->nbits = nbits; @@ -148,6 +211,30 @@ int mpi_fromstr(MPI val, const char *str) } EXPORT_SYMBOL_GPL(mpi_fromstr); +/**************** + * Special function to get the low 8 bytes from an mpi. + * This can be used as a keyid; KEYID is an 2 element array. + * Return the low 4 bytes. + */ +u32 mpi_get_keyid(const MPI a, u32 *keyid) +{ +#if BYTES_PER_MPI_LIMB == 4 + if (keyid) { + keyid[0] = a->nlimbs >= 2 ? a->d[1] : 0; + keyid[1] = a->nlimbs >= 1 ? a->d[0] : 0; + } + return a->nlimbs >= 1 ? a->d[0] : 0; +#elif BYTES_PER_MPI_LIMB == 8 + if (keyid) { + keyid[0] = a->nlimbs ? (u32) (a->d[0] >> 32) : 0; + keyid[1] = a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0; + } + return a->nlimbs ? (u32) (a->d[0] & 0xffffffff) : 0; +#else +#error Make this function work with other LIMB sizes +#endif +} + /**************** * Return an allocated buffer with the MPI (msb first). * NBYTES receives the length of this buffer. Caller must free the diff --git a/trunk/lib/mpi/mpih-div.c b/trunk/lib/mpi/mpih-div.c index cde1aaec18da..87ede162dfab 100644 --- a/trunk/lib/mpi/mpih-div.c +++ b/trunk/lib/mpi/mpih-div.c @@ -217,10 +217,6 @@ mpihelp_divrem(mpi_ptr_t qp, mpi_size_t qextra_limbs, case 0: /* We are asked to divide by zero, so go ahead and do it! (To make the compiler not remove this statement, return the value.) */ - /* - * existing clients of this function have been modified - * not to call it with dsize == 0, so this should not happen - */ return 1 / dsize; case 1: diff --git a/trunk/lib/mpi/mpiutil.c b/trunk/lib/mpi/mpiutil.c index 26e4ed31e256..eefc55d6b7f5 100644 --- a/trunk/lib/mpi/mpiutil.c +++ b/trunk/lib/mpi/mpiutil.c @@ -58,9 +58,6 @@ mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs) { size_t len = nlimbs * sizeof(mpi_limb_t); - if (!len) - return NULL; - return kmalloc(len, GFP_KERNEL); } @@ -138,7 +135,7 @@ int mpi_copy(MPI *copied, const MPI a) size_t i; MPI b; - *copied = NULL; + *copied = MPI_NULL; if (a) { b = mpi_alloc(a->nlimbs); diff --git a/trunk/mm/process_vm_access.c b/trunk/mm/process_vm_access.c index c20ff48994c2..e920aa3ce104 100644 --- a/trunk/mm/process_vm_access.c +++ b/trunk/mm/process_vm_access.c @@ -298,18 +298,23 @@ static ssize_t process_vm_rw_core(pid_t pid, const struct iovec *lvec, goto free_proc_pages; } - mm = mm_access(task, PTRACE_MODE_ATTACH); - if (!mm || IS_ERR(mm)) { - rc = IS_ERR(mm) ? PTR_ERR(mm) : -ESRCH; - /* - * Explicitly map EACCES to EPERM as EPERM is a more a - * appropriate error code for process_vw_readv/writev - */ - if (rc == -EACCES) - rc = -EPERM; + task_lock(task); + if (__ptrace_may_access(task, PTRACE_MODE_ATTACH)) { + task_unlock(task); + rc = -EPERM; + goto put_task_struct; + } + mm = task->mm; + + if (!mm || (task->flags & PF_KTHREAD)) { + task_unlock(task); + rc = -EINVAL; goto put_task_struct; } + atomic_inc(&mm->mm_users); + task_unlock(task); + for (i = 0; i < riovcnt && iov_l_curr_idx < liovcnt; i++) { rc = process_vm_rw_single_vec( (unsigned long)rvec[i].iov_base, rvec[i].iov_len, diff --git a/trunk/net/caif/caif_dev.c b/trunk/net/caif/caif_dev.c index 82c57069415f..673728add60b 100644 --- a/trunk/net/caif/caif_dev.c +++ b/trunk/net/caif/caif_dev.c @@ -59,6 +59,8 @@ struct cfcnfg *get_cfcnfg(struct net *net) { struct caif_net *caifn; caifn = net_generic(net, caif_net_id); + if (!caifn) + return NULL; return caifn->cfg; } EXPORT_SYMBOL(get_cfcnfg); @@ -67,6 +69,8 @@ static struct caif_device_entry_list *caif_device_list(struct net *net) { struct caif_net *caifn; caifn = net_generic(net, caif_net_id); + if (!caifn) + return NULL; return &caifn->caifdevs; } @@ -95,6 +99,8 @@ static struct caif_device_entry *caif_device_alloc(struct net_device *dev) struct caif_device_entry *caifd; caifdevs = caif_device_list(dev_net(dev)); + if (!caifdevs) + return NULL; caifd = kzalloc(sizeof(*caifd), GFP_KERNEL); if (!caifd) @@ -114,6 +120,8 @@ static struct caif_device_entry *caif_get(struct net_device *dev) struct caif_device_entry_list *caifdevs = caif_device_list(dev_net(dev)); struct caif_device_entry *caifd; + if (!caifdevs) + return NULL; list_for_each_entry_rcu(caifd, &caifdevs->list, list) { if (caifd->netdev == dev) @@ -313,6 +321,8 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, struct caif_device_entry_list *caifdevs; caifdevs = caif_device_list(dev_net(dev)); + if (!cfg || !caifdevs) + return; caifd = caif_device_alloc(dev); if (!caifd) return; @@ -364,6 +374,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, cfg = get_cfcnfg(dev_net(dev)); caifdevs = caif_device_list(dev_net(dev)); + if (!cfg || !caifdevs) + return 0; caifd = caif_get(dev); if (caifd == NULL && dev->type != ARPHRD_CAIF) @@ -495,6 +507,9 @@ static struct notifier_block caif_device_notifier = { static int caif_init_net(struct net *net) { struct caif_net *caifn = net_generic(net, caif_net_id); + if (WARN_ON(!caifn)) + return -EINVAL; + INIT_LIST_HEAD(&caifn->caifdevs.list); mutex_init(&caifn->caifdevs.lock); @@ -512,6 +527,9 @@ static void caif_exit_net(struct net *net) caif_device_list(net); struct cfcnfg *cfg = get_cfcnfg(net); + if (!cfg || !caifdevs) + return; + rtnl_lock(); mutex_lock(&caifdevs->lock); @@ -551,7 +569,7 @@ static int __init caif_device_init(void) { int result; - result = register_pernet_subsys(&caif_net_ops); + result = register_pernet_device(&caif_net_ops); if (result) return result; @@ -564,7 +582,7 @@ static int __init caif_device_init(void) static void __exit caif_device_exit(void) { - unregister_pernet_subsys(&caif_net_ops); + unregister_pernet_device(&caif_net_ops); unregister_netdevice_notifier(&caif_device_notifier); dev_remove_pack(&caif_packet_type); } diff --git a/trunk/net/caif/cfcnfg.c b/trunk/net/caif/cfcnfg.c index ba9cfd47778a..598aafb4cb51 100644 --- a/trunk/net/caif/cfcnfg.c +++ b/trunk/net/caif/cfcnfg.c @@ -309,6 +309,7 @@ int caif_connect_client(struct net *net, struct caif_connect_request *conn_req, int err; struct cfctrl_link_param param; struct cfcnfg *cfg = get_cfcnfg(net); + caif_assert(cfg != NULL); rcu_read_lock(); err = caif_connect_req_to_link_param(cfg, conn_req, ¶m); diff --git a/trunk/net/ceph/ceph_common.c b/trunk/net/ceph/ceph_common.c index 761ad9d6cc3b..97f70e50ad3b 100644 --- a/trunk/net/ceph/ceph_common.c +++ b/trunk/net/ceph/ceph_common.c @@ -85,6 +85,8 @@ int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid) } else { pr_info("client%lld fsid %pU\n", ceph_client_id(client), fsid); memcpy(&client->fsid, fsid, sizeof(*fsid)); + ceph_debugfs_client_init(client); + client->have_fsid = true; } return 0; } diff --git a/trunk/net/ceph/mon_client.c b/trunk/net/ceph/mon_client.c index 1845cde26227..0b62deae42bd 100644 --- a/trunk/net/ceph/mon_client.c +++ b/trunk/net/ceph/mon_client.c @@ -8,8 +8,8 @@ #include #include -#include #include + #include /* @@ -340,19 +340,8 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc, client->monc.monmap = monmap; kfree(old); - if (!client->have_fsid) { - client->have_fsid = true; - mutex_unlock(&monc->mutex); - /* - * do debugfs initialization without mutex to avoid - * creating a locking dependency - */ - ceph_debugfs_client_init(client); - goto out_unlocked; - } out: mutex_unlock(&monc->mutex); -out_unlocked: wake_up_all(&client->auth_wq); } diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 0e950fda9a0a..aefcd7acbffa 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -30,20 +30,6 @@ EXPORT_SYMBOL(init_net); #define INITIAL_NET_GEN_PTRS 13 /* +1 for len +2 for rcu_head */ -static unsigned int max_gen_ptrs = INITIAL_NET_GEN_PTRS; - -static struct net_generic *net_alloc_generic(void) -{ - struct net_generic *ng; - size_t generic_size = offsetof(struct net_generic, ptr[max_gen_ptrs]); - - ng = kzalloc(generic_size, GFP_KERNEL); - if (ng) - ng->len = max_gen_ptrs; - - return ng; -} - static int net_assign_generic(struct net *net, int id, void *data) { struct net_generic *ng, *old_ng; @@ -57,7 +43,8 @@ static int net_assign_generic(struct net *net, int id, void *data) if (old_ng->len >= id) goto assign; - ng = net_alloc_generic(); + ng = kzalloc(sizeof(struct net_generic) + + id * sizeof(void *), GFP_KERNEL); if (ng == NULL) return -ENOMEM; @@ -72,6 +59,7 @@ static int net_assign_generic(struct net *net, int id, void *data) * the old copy for kfree after a grace period. */ + ng->len = id; memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*)); rcu_assign_pointer(net->gen, ng); @@ -173,6 +161,18 @@ static __net_init int setup_net(struct net *net) goto out; } +static struct net_generic *net_alloc_generic(void) +{ + struct net_generic *ng; + size_t generic_size = sizeof(struct net_generic) + + INITIAL_NET_GEN_PTRS * sizeof(void *); + + ng = kzalloc(generic_size, GFP_KERNEL); + if (ng) + ng->len = INITIAL_NET_GEN_PTRS; + + return ng; +} #ifdef CONFIG_NET_NS static struct kmem_cache *net_cachep; @@ -483,7 +483,6 @@ static int register_pernet_operations(struct list_head *list, } return error; } - max_gen_ptrs = max_t(unsigned int, max_gen_ptrs, *ops->id); } error = __register_pernet_operations(list, ops); if (error) { diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 65aebd450027..f16444bc6cbb 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -1509,9 +1509,6 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); - min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev), - min_ifinfo_dump_size); - return err; } diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 19d66cefd7d3..2e4e24476c4c 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -123,14 +123,11 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) smallest_size = tb->num_owners; smallest_rover = rover; if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) { + spin_unlock(&head->lock); snum = smallest_rover; - goto tb_found; + goto have_snum; } } - if (!inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) { - snum = rover; - goto tb_found; - } goto next; } break; diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 6b3ca5ba4450..2b53a1f7abf6 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -422,10 +422,6 @@ static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, if (register_netdevice(dev) < 0) goto failed_free; - /* Can use a lockless transmit, unless we generate output sequences */ - if (!(nt->parms.o_flags & GRE_SEQ)) - dev->features |= NETIF_F_LLTX; - dev_hold(dev); ipgre_tunnel_link(ign, nt); return nt; diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index 4cb9cd2f2c39..4aa7e9dc0cbb 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -814,7 +814,6 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) net->ipv4.sysctl_rt_cache_rebuild_count = 4; - tcp_init_mem(net); limit = nr_free_buffer_pages() / 8; limit = max(limit, 128UL); net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 06373b4a449a..9bcdec3ad772 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -3216,16 +3216,6 @@ static int __init set_thash_entries(char *str) } __setup("thash_entries=", set_thash_entries); -void tcp_init_mem(struct net *net) -{ - /* Set per-socket limits to no more than 1/128 the pressure threshold */ - unsigned long limit = nr_free_buffer_pages() / 8; - limit = max(limit, 128UL); - net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; - net->ipv4.sysctl_tcp_mem[1] = limit; - net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2; -} - void __init tcp_init(void) { struct sk_buff *skb = NULL; @@ -3286,9 +3276,9 @@ void __init tcp_init(void) sysctl_tcp_max_orphans = cnt / 2; sysctl_max_syn_backlog = max(128, cnt / 256); - tcp_init_mem(&init_net); - limit = nr_free_buffer_pages() / 8; - limit = max(limit, 128UL); + /* Set per-socket limits to no more than 1/128 the pressure threshold */ + limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1]) + << (PAGE_SHIFT - 7); max_share = min(4UL*1024*1024, limit); sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 4ff3b6dc74fc..8c8de2780c7a 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1141,9 +1141,11 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) sk_mem_uncharge(sk, len); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); - /* Any change of skb->len requires recalculation of tso factor. */ + /* Any change of skb->len requires recalculation of tso + * factor and mss. + */ if (tcp_skb_pcount(skb) > 1) - tcp_set_skb_tso_segs(sk, skb, tcp_skb_mss(skb)); + tcp_set_skb_tso_segs(sk, skb, tcp_current_mss(sk)); return 0; } diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 55670ec3cd0f..d21e7ebd91ca 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -393,6 +393,11 @@ static int l2tp_ip_backlog_recv(struct sock *sk, struct sk_buff *skb) { int rc; + if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) + goto drop; + + nf_reset(skb); + /* Charge it to the socket, dropping if the queue is full. */ rc = sock_queue_rcv_skb(sk, skb); if (rc < 0) diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index a4643969a13b..b3d76b756cd5 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -106,7 +106,6 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; - local->oper_channel = chan; channel_type = ifibss->channel_type; if (channel_type > NL80211_CHAN_HT20 && !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 01a21c2f6ab3..e47768cb8cb3 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -1314,7 +1314,6 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) continue; } /* count everything else */ - sdata->vif.bss_conf.idle = false; count++; } diff --git a/trunk/net/sunrpc/auth_generic.c b/trunk/net/sunrpc/auth_generic.c index 75762f346975..1426ec3d0a53 100644 --- a/trunk/net/sunrpc/auth_generic.c +++ b/trunk/net/sunrpc/auth_generic.c @@ -92,7 +92,6 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) if (gcred->acred.group_info != NULL) get_group_info(gcred->acred.group_info); gcred->acred.machine_cred = acred->machine_cred; - gcred->acred.principal = acred->principal; dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", gcred->acred.machine_cred ? "machine" : "generic", @@ -124,17 +123,6 @@ generic_destroy_cred(struct rpc_cred *cred) call_rcu(&cred->cr_rcu, generic_free_cred_callback); } -static int -machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags) -{ - if (!gcred->acred.machine_cred || - gcred->acred.principal != acred->principal || - gcred->acred.uid != acred->uid || - gcred->acred.gid != acred->gid) - return 0; - return 1; -} - /* * Match credentials against current process creds. */ @@ -144,12 +132,9 @@ generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); int i; - if (acred->machine_cred) - return machine_cred_match(acred, gcred, flags); - if (gcred->acred.uid != acred->uid || gcred->acred.gid != acred->gid || - gcred->acred.machine_cred != 0) + gcred->acred.machine_cred != acred->machine_cred) goto out_nomatch; /* Optimisation in the case where pointers are identical... */ diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 85d3bb7490aa..aad8fb699989 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -1918,7 +1918,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; unix_state_lock(sk); - skb = skb_peek(&sk->sk_receive_queue); + skb = skb_dequeue(&sk->sk_receive_queue); if (skb == NULL) { unix_sk(sk)->recursion_level = 0; if (copied >= target) @@ -1958,8 +1958,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (check_creds) { /* Never glue messages from different writers */ if ((UNIXCB(skb).pid != siocb->scm->pid) || - (UNIXCB(skb).cred != siocb->scm->cred)) + (UNIXCB(skb).cred != siocb->scm->cred)) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; + } } else { /* Copy credentials */ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); @@ -1974,6 +1977,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, chunk = min_t(unsigned int, skb->len, size); if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); if (copied == 0) copied = -EFAULT; break; @@ -1988,10 +1993,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (UNIXCB(skb).fp) unix_detach_fds(siocb->scm, skb); - if (skb->len) + /* put the skb back if we didn't use it up.. */ + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; + } - skb_unlink(skb, &sk->sk_receive_queue); consume_skb(skb); if (siocb->scm->fp) @@ -2002,6 +2010,9 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (UNIXCB(skb).fp) siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); + /* put message back and return */ + skb_queue_head(&sk->sk_receive_queue, skb); + sk->sk_data_ready(sk, skb->len); break; } } while (size); diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index e8c969577768..c0e14b3f2306 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -823,6 +823,16 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, } ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry); +/* Looks like: mcp:S */ +static int do_mcp_entry(const char *filename, struct mcp_device_id *id, + char *alias) +{ + sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); + + return 1; +} +ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry); + static const struct dmifield { const char *prefix; int field; diff --git a/trunk/sound/core/compress_offload.c b/trunk/sound/core/compress_offload.c index a68aed7fce02..dac3633507c9 100644 --- a/trunk/sound/core/compress_offload.c +++ b/trunk/sound/core/compress_offload.c @@ -441,22 +441,19 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) params = kmalloc(sizeof(*params), GFP_KERNEL); if (!params) return -ENOMEM; - if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { - retval = -EFAULT; - goto out; - } + if (copy_from_user(params, (void __user *)arg, sizeof(*params))) + return -EFAULT; retval = snd_compr_allocate_buffer(stream, params); if (retval) { - retval = -ENOMEM; - goto out; + kfree(params); + return -ENOMEM; } retval = stream->ops->set_params(stream, params); if (retval) goto out; stream->runtime->state = SNDRV_PCM_STATE_SETUP; - } else { + } else return -EPERM; - } out: kfree(params); return retval; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 0db1dc49382b..c95c8bde12d0 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -5586,7 +5586,6 @@ static const struct hda_amp_list alc861_loopbacks[] = { /* Pin config fixes */ enum { PINFIX_FSC_AMILO_PI1505, - PINFIX_ASUS_A6RP, }; static const struct alc_fixup alc861_fixups[] = { @@ -5598,19 +5597,9 @@ static const struct alc_fixup alc861_fixups[] = { { } } }, - [PINFIX_ASUS_A6RP] = { - .type = ALC_FIXUP_VERBS, - .v.verbs = (const struct hda_verb[]) { - /* node 0x0f VREF seems controlling the master output */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, - { } - }, - }, }; static const struct snd_pci_quirk alc861_fixup_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP), - SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), {} }; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 948f0be2f4f3..336cfcd324f9 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -4870,14 +4870,7 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) /* BIOS bug: unfilled OEM string */ if (strstr(dev->name, "HP_Mute_LED_P_G")) { set_hp_led_gpio(codec); - switch (codec->subsystem_id) { - case 0x103c148a: - spec->gpio_led_polarity = 0; - break; - default: - spec->gpio_led_polarity = 1; - break; - } + spec->gpio_led_polarity = 1; return 1; } } diff --git a/trunk/sound/pci/ymfpci/ymfpci.c b/trunk/sound/pci/ymfpci/ymfpci.c index 94ab728f5ca8..e57b89e8aa89 100644 --- a/trunk/sound/pci/ymfpci/ymfpci.c +++ b/trunk/sound/pci/ymfpci/ymfpci.c @@ -286,22 +286,17 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, snd_card_free(card); return err; } - err = snd_ymfpci_mixer(chip, rear_switch[dev]); - if (err < 0) { + if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) { snd_card_free(card); return err; } - if (chip->ac97->ext_id & AC97_EI_SDAC) { - err = snd_ymfpci_pcm_4ch(chip, 2, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } - err = snd_ymfpci_pcm2(chip, 3, NULL); - if (err < 0) { - snd_card_free(card); - return err; - } + if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) { + snd_card_free(card); + return err; + } + if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { + snd_card_free(card); + return err; } if ((err = snd_ymfpci_timer(chip, 0)) < 0) { snd_card_free(card); diff --git a/trunk/sound/pci/ymfpci/ymfpci_main.c b/trunk/sound/pci/ymfpci/ymfpci_main.c index 12a9a2b03387..03ee4e365311 100644 --- a/trunk/sound/pci/ymfpci/ymfpci_main.c +++ b/trunk/sound/pci/ymfpci/ymfpci_main.c @@ -1614,14 +1614,6 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "4ch Duplication", - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .info = snd_ymfpci_info_dup4ch, - .get = snd_ymfpci_get_dup4ch, - .put = snd_ymfpci_put_dup4ch, -}; static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { { @@ -1650,6 +1642,13 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), +{ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "4ch Duplication", + .info = snd_ymfpci_info_dup4ch, + .get = snd_ymfpci_get_dup4ch, + .put = snd_ymfpci_put_dup4ch, +}, }; @@ -1839,12 +1838,6 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) return err; } - if (chip->ac97->ext_id & AC97_EI_SDAC) { - kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); - err = snd_ctl_add(chip->card, kctl); - if (err < 0) - return err; - } /* add S/PDIF control */ if (snd_BUG_ON(!chip->pcm_spdif)) diff --git a/trunk/tools/perf/Documentation/Makefile b/trunk/tools/perf/Documentation/Makefile index ca600e09c8d4..4626a398836a 100644 --- a/trunk/tools/perf/Documentation/Makefile +++ b/trunk/tools/perf/Documentation/Makefile @@ -1,10 +1,3 @@ -OUTPUT := ./ -ifeq ("$(origin O)", "command line") - ifneq ($(O),) - OUTPUT := $(O)/ - endif -endif - MAN1_TXT= \ $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ $(wildcard perf-*.txt)) \ @@ -13,11 +6,10 @@ MAN5_TXT= MAN7_TXT= MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT) -_MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) -_MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) +MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT)) +MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT)) -MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML)) -MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML)) +DOC_HTML=$(MAN_HTML) ARTICLES = # with their own formatting rules. @@ -26,17 +18,11 @@ API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technica SP_ARTICLES += $(API_DOCS) SP_ARTICLES += technical/api-index -_DOC_HTML = $(_MAN_HTML) -_DOC_HTML+=$(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES)) -DOC_HTML=$(addprefix $(OUTPUT),$(_DOC_HTML)) +DOC_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES)) -_DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT)) -_DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT)) -_DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT)) - -DOC_MAN1=$(addprefix $(OUTPUT),$(_DOC_MAN1)) -DOC_MAN5=$(addprefix $(OUTPUT),$(_DOC_MAN5)) -DOC_MAN7=$(addprefix $(OUTPUT),$(_DOC_MAN7)) +DOC_MAN1=$(patsubst %.txt,%.1,$(MAN1_TXT)) +DOC_MAN5=$(patsubst %.txt,%.5,$(MAN5_TXT)) +DOC_MAN7=$(patsubst %.txt,%.7,$(MAN7_TXT)) # Make the path relative to DESTDIR, not prefix ifndef DESTDIR @@ -164,9 +150,9 @@ man1: $(DOC_MAN1) man5: $(DOC_MAN5) man7: $(DOC_MAN7) -info: $(OUTPUT)perf.info $(OUTPUT)perfman.info +info: perf.info perfman.info -pdf: $(OUTPUT)user-manual.pdf +pdf: user-manual.pdf install: install-man @@ -180,7 +166,7 @@ install-man: man install-info: info $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) - $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir) + $(INSTALL) -m 644 perf.info perfman.info $(DESTDIR)$(infodir) if test -r $(DESTDIR)$(infodir)/dir; then \ $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\ $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\ @@ -190,7 +176,7 @@ install-info: info install-pdf: pdf $(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir) - $(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir) + $(INSTALL) -m 644 user-manual.pdf $(DESTDIR)$(pdfdir) #install-html: html # '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir) @@ -203,14 +189,14 @@ install-pdf: pdf # # Determine "include::" file references in asciidoc files. # -$(OUTPUT)doc.dep : $(wildcard *.txt) build-docdep.perl +doc.dep : $(wildcard *.txt) build-docdep.perl $(QUIET_GEN)$(RM) $@+ $@ && \ $(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \ mv $@+ $@ --include $(OUPTUT)doc.dep +-include doc.dep -_cmds_txt = cmds-ancillaryinterrogators.txt \ +cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-ancillarymanipulators.txt \ cmds-mainporcelain.txt \ cmds-plumbinginterrogators.txt \ @@ -219,36 +205,32 @@ _cmds_txt = cmds-ancillaryinterrogators.txt \ cmds-synchelpers.txt \ cmds-purehelpers.txt \ cmds-foreignscminterface.txt -cmds_txt=$(addprefix $(OUTPUT),$(_cmds_txt)) -$(cmds_txt): $(OUTPUT)cmd-list.made +$(cmds_txt): cmd-list.made -$(OUTPUT)cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) +cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) $(QUIET_GEN)$(RM) $@ && \ $(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \ date >$@ clean: - $(RM) $(MAN_XML) $(addsuffix +,$(MAN_XML)) - $(RM) $(MAN_HTML) $(addsuffix +,$(MAN_HTML)) - $(RM) $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7) - $(RM) $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++ - $(RM) $(OUTPUT)perf.info $(OUTPUT)perfman.info - $(RM) $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep - $(RM) $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt - $(RM) $(cmds_txt) $(OUTPUT)*.made - -$(MAN_HTML): $(OUTPUT)%.html : %.txt + $(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 + $(RM) *.texi *.texi+ *.texi++ perf.info perfman.info + $(RM) howto-index.txt howto/*.html doc.dep + $(RM) technical/api-*.html technical/api-index.txt + $(RM) $(cmds_txt) *.made + +$(MAN_HTML): %.html : %.txt $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ $(ASCIIDOC) -b xhtml11 -d manpage -f asciidoc.conf \ $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \ mv $@+ $@ -$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml +%.1 %.5 %.7 : %.xml $(QUIET_XMLTO)$(RM) $@ && \ - xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< + xmlto -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< -$(OUTPUT)%.xml : %.txt +%.xml : %.txt $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \ $(ASCIIDOC_EXTRA) -aperf_version=$(PERF_VERSION) -o $@+ $< && \ @@ -257,25 +239,25 @@ $(OUTPUT)%.xml : %.txt XSLT = docbook.xsl XSLTOPTS = --xinclude --stringparam html.stylesheet docbook-xsl.css -$(OUTPUT)user-manual.html: $(OUTPUT)user-manual.xml +user-manual.html: user-manual.xml $(QUIET_XSLTPROC)xsltproc $(XSLTOPTS) -o $@ $(XSLT) $< -$(OUTPUT)perf.info: $(OUTPUT)user-manual.texi - $(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ $(OUTPUT)user-manual.texi +perf.info: user-manual.texi + $(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi -$(OUTPUT)user-manual.texi: $(OUTPUT)user-manual.xml +user-manual.texi: user-manual.xml $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ - $(DOCBOOK2X_TEXI) $(OUTPUT)user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \ + $(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@++ && \ $(PERL_PATH) fix-texi.perl <$@++ >$@+ && \ rm $@++ && \ mv $@+ $@ -$(OUTPUT)user-manual.pdf: $(OUTPUT)user-manual.xml +user-manual.pdf: user-manual.xml $(QUIET_DBLATEX)$(RM) $@+ $@ && \ $(DBLATEX) -o $@+ -p /etc/asciidoc/dblatex/asciidoc-dblatex.xsl -s /etc/asciidoc/dblatex/asciidoc-dblatex.sty $< && \ mv $@+ $@ -$(OUTPUT)perfman.texi: $(MAN_XML) cat-texi.perl +perfman.texi: $(MAN_XML) cat-texi.perl $(QUIET_DB2TEXI)$(RM) $@+ $@ && \ ($(foreach xml,$(MAN_XML),$(DOCBOOK2X_TEXI) --encoding=UTF-8 \ --to-stdout $(xml) &&) true) > $@++ && \ @@ -283,7 +265,7 @@ $(OUTPUT)perfman.texi: $(MAN_XML) cat-texi.perl rm $@++ && \ mv $@+ $@ -$(OUTPUT)perfman.info: $(OUTPUT)perfman.texi +perfman.info: perfman.texi $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $*.texi $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml diff --git a/trunk/tools/perf/Documentation/perf-record.txt b/trunk/tools/perf/Documentation/perf-record.txt index a5766b4b0125..ff9a66e0d4e4 100644 --- a/trunk/tools/perf/Documentation/perf-record.txt +++ b/trunk/tools/perf/Documentation/perf-record.txt @@ -52,11 +52,11 @@ OPTIONS -p:: --pid=:: - Record events on existing process ID (comma separated list). + Record events on existing process ID. -t:: --tid=:: - Record events on existing thread ID (comma separated list). + Record events on existing thread ID. -u:: --uid=:: diff --git a/trunk/tools/perf/Documentation/perf-stat.txt b/trunk/tools/perf/Documentation/perf-stat.txt index 2fa173b51970..8966b9ab2014 100644 --- a/trunk/tools/perf/Documentation/perf-stat.txt +++ b/trunk/tools/perf/Documentation/perf-stat.txt @@ -35,11 +35,11 @@ OPTIONS child tasks do not inherit counters -p:: --pid=:: - stat events on existing process id (comma separated list) + stat events on existing process id -t:: --tid=:: - stat events on existing thread id (comma separated list) + stat events on existing thread id -a:: diff --git a/trunk/tools/perf/Documentation/perf-top.txt b/trunk/tools/perf/Documentation/perf-top.txt index 4a5680cb242e..ab1454ed450f 100644 --- a/trunk/tools/perf/Documentation/perf-top.txt +++ b/trunk/tools/perf/Documentation/perf-top.txt @@ -72,11 +72,11 @@ Default is to monitor all CPUS. -p :: --pid=:: - Profile events on existing Process ID (comma separated list). + Profile events on existing Process ID. -t :: --tid=:: - Profile events on existing thread ID (comma separated list). + Profile events on existing thread ID. -u:: --uid=:: diff --git a/trunk/tools/perf/MANIFEST b/trunk/tools/perf/MANIFEST index 5476bc0a1eac..1078c5fadd5b 100644 --- a/trunk/tools/perf/MANIFEST +++ b/trunk/tools/perf/MANIFEST @@ -9,7 +9,6 @@ lib/rbtree.c include/linux/swab.h arch/*/include/asm/unistd*.h arch/*/lib/memcpy*.S -arch/*/lib/memset*.S include/linux/poison.h include/linux/magic.h include/linux/hw_breakpoint.h diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index e011b5060f92..d64f5819a380 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -183,10 +183,7 @@ SCRIPT_SH += perf-archive.sh grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) -PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) -PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py - -$(OUTPUT)python/perf.so: $(PYRF_OBJS) $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) +$(OUTPUT)python/perf.so: $(PYRF_OBJS) $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ --quiet build_ext; \ mkdir -p $(OUTPUT)python && \ @@ -259,7 +256,6 @@ LIB_H += util/callchain.h LIB_H += util/build-id.h LIB_H += util/debug.h LIB_H += util/debugfs.h -LIB_H += util/sysfs.h LIB_H += util/event.h LIB_H += util/evsel.h LIB_H += util/evlist.h @@ -306,7 +302,6 @@ LIB_OBJS += $(OUTPUT)util/build-id.o LIB_OBJS += $(OUTPUT)util/config.o LIB_OBJS += $(OUTPUT)util/ctype.o LIB_OBJS += $(OUTPUT)util/debugfs.o -LIB_OBJS += $(OUTPUT)util/sysfs.o LIB_OBJS += $(OUTPUT)util/environment.o LIB_OBJS += $(OUTPUT)util/event.o LIB_OBJS += $(OUTPUT)util/evlist.o @@ -799,6 +794,7 @@ help: @echo ' quick-install-html - install the html documentation quickly' @echo '' @echo 'Perf maintainer targets:' + @echo ' distclean - alias to clean' @echo ' clean - clean all binary objects and build output' doc: diff --git a/trunk/tools/perf/bench/mem-memcpy-x86-64-asm.S b/trunk/tools/perf/bench/mem-memcpy-x86-64-asm.S index fcd9cf00600a..a20780bd0771 100644 --- a/trunk/tools/perf/bench/mem-memcpy-x86-64-asm.S +++ b/trunk/tools/perf/bench/mem-memcpy-x86-64-asm.S @@ -4,9 +4,3 @@ #define Lmemcpy_c globl memcpy_c; memcpy_c #define Lmemcpy_c_e globl memcpy_c_e; memcpy_c_e #include "../../../arch/x86/lib/memcpy_64.S" -/* - * We need to provide note.GNU-stack section, saying that we want - * NOT executable stack. Otherwise the final linking will assume that - * the ELF stack should not be restricted at all and set it RWX. - */ -.section .note.GNU-stack,"",@progbits diff --git a/trunk/tools/perf/bench/mem-memset-x86-64-asm.S b/trunk/tools/perf/bench/mem-memset-x86-64-asm.S index 9e5af89ed13a..cb9217063776 100644 --- a/trunk/tools/perf/bench/mem-memset-x86-64-asm.S +++ b/trunk/tools/perf/bench/mem-memset-x86-64-asm.S @@ -4,10 +4,3 @@ #define Lmemset_c globl memset_c; memset_c #define Lmemset_c_e globl memset_c_e; memset_c_e #include "../../../arch/x86/lib/memset_64.S" - -/* - * We need to provide note.GNU-stack section, saying that we want - * NOT executable stack. Otherwise the final linking will assume that - * the ELF stack should not be restricted at all and set it RWX. - */ -.section .note.GNU-stack,"",@progbits diff --git a/trunk/tools/perf/builtin-probe.c b/trunk/tools/perf/builtin-probe.c index 4935c09dd5b5..fb8566181f27 100644 --- a/trunk/tools/perf/builtin-probe.c +++ b/trunk/tools/perf/builtin-probe.c @@ -58,7 +58,7 @@ static struct { struct perf_probe_event events[MAX_PROBES]; struct strlist *dellist; struct line_range line_range; - const char *target; + const char *target_module; int max_probe_points; struct strfilter *filter; } params; @@ -246,7 +246,7 @@ static const struct option options[] = { "file", "vmlinux pathname"), OPT_STRING('s', "source", &symbol_conf.source_prefix, "directory", "path to kernel source"), - OPT_STRING('m', "module", ¶ms.target, + OPT_STRING('m', "module", ¶ms.target_module, "modname|path", "target module name (for online) or path (for offline)"), #endif @@ -333,7 +333,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) if (!params.filter) params.filter = strfilter__new(DEFAULT_FUNC_FILTER, NULL); - ret = show_available_funcs(params.target, + ret = show_available_funcs(params.target_module, params.filter); strfilter__delete(params.filter); if (ret < 0) @@ -354,7 +354,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) usage_with_options(probe_usage, options); } - ret = show_line_range(¶ms.line_range, params.target); + ret = show_line_range(¶ms.line_range, params.target_module); if (ret < 0) pr_err(" Error: Failed to show lines. (%d)\n", ret); return ret; @@ -371,7 +371,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) ret = show_available_vars(params.events, params.nevents, params.max_probe_points, - params.target, + params.target_module, params.filter, params.show_ext_vars); strfilter__delete(params.filter); @@ -393,7 +393,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) if (params.nevents) { ret = add_perf_probe_events(params.events, params.nevents, params.max_probe_points, - params.target, + params.target_module, params.force_add); if (ret < 0) { pr_err(" Error: Failed to add events. (%d)\n", ret); diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index 75d230fef202..32870eef952f 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -205,11 +205,8 @@ static void perf_record__open(struct perf_record *rec) if (opts->group && pos != first) group_fd = first->fd; -fallback_missing_features: - if (opts->exclude_guest_missing) - attr->exclude_guest = attr->exclude_host = 0; retry_sample_id: - attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; + attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0; try_again: if (perf_evsel__open(pos, evlist->cpus, evlist->threads, opts->group, group_fd) < 0) { @@ -221,23 +218,15 @@ static void perf_record__open(struct perf_record *rec) } else if (err == ENODEV && opts->cpu_list) { die("No such device - did you specify" " an out-of-range profile CPU?\n"); - } else if (err == EINVAL) { - if (!opts->exclude_guest_missing && - (attr->exclude_guest || attr->exclude_host)) { - pr_debug("Old kernel, cannot exclude " - "guest or host samples.\n"); - opts->exclude_guest_missing = true; - goto fallback_missing_features; - } else if (!opts->sample_id_all_missing) { - /* - * Old kernel, no attr->sample_id_type_all field - */ - opts->sample_id_all_missing = true; - if (!opts->sample_time && !opts->raw_samples && !time_needed) - attr->sample_type &= ~PERF_SAMPLE_TIME; - - goto retry_sample_id; - } + } else if (err == EINVAL && opts->sample_id_all_avail) { + /* + * Old kernel, no attr->sample_id_type_all field + */ + opts->sample_id_all_avail = false; + if (!opts->sample_time && !opts->raw_samples && !time_needed) + attr->sample_type &= ~PERF_SAMPLE_TIME; + + goto retry_sample_id; } /* @@ -397,7 +386,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) { struct stat st; int flags; - int err, output, feat; + int err, output; unsigned long waking = 0; const bool forks = argc > 0; struct machine *machine; @@ -464,14 +453,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) rec->session = session; - for (feat = HEADER_FIRST_FEATURE; feat < HEADER_LAST_FEATURE; feat++) - perf_header__set_feat(&session->header, feat); - - if (rec->no_buildid) - perf_header__clear_feat(&session->header, HEADER_BUILD_ID); - - if (!have_tracepoints(&evsel_list->entries)) - perf_header__clear_feat(&session->header, HEADER_TRACE_INFO); + if (!rec->no_buildid) + perf_header__set_feat(&session->header, HEADER_BUILD_ID); if (!rec->file_new) { err = perf_session__read_header(session, output); @@ -479,6 +462,22 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) goto out_delete_session; } + if (have_tracepoints(&evsel_list->entries)) + perf_header__set_feat(&session->header, HEADER_TRACE_INFO); + + perf_header__set_feat(&session->header, HEADER_HOSTNAME); + perf_header__set_feat(&session->header, HEADER_OSRELEASE); + perf_header__set_feat(&session->header, HEADER_ARCH); + perf_header__set_feat(&session->header, HEADER_CPUDESC); + perf_header__set_feat(&session->header, HEADER_NRCPUS); + perf_header__set_feat(&session->header, HEADER_EVENT_DESC); + perf_header__set_feat(&session->header, HEADER_CMDLINE); + perf_header__set_feat(&session->header, HEADER_VERSION); + perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_TOTAL_MEM); + perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_CPUID); + if (forks) { err = perf_evlist__prepare_workload(evsel_list, opts, argv); if (err < 0) { @@ -505,9 +504,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) return err; } - if (!rec->no_buildid + if (!!rec->no_buildid && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { - pr_err("Couldn't generate buildids. " + pr_err("Couldn't generating buildids. " "Use --no-buildid to profile anyway.\n"); return -1; } @@ -656,10 +655,13 @@ static const char * const record_usage[] = { */ static struct perf_record record = { .opts = { + .target_pid = -1, + .target_tid = -1, .mmap_pages = UINT_MAX, .user_freq = UINT_MAX, .user_interval = ULLONG_MAX, .freq = 1000, + .sample_id_all_avail = true, }, .write_mode = WRITE_FORCE, .file_new = true, @@ -678,9 +680,9 @@ const struct option record_options[] = { parse_events_option), OPT_CALLBACK(0, "filter", &record.evlist, "filter", "event filter", parse_filter), - OPT_STRING('p', "pid", &record.opts.target_pid, "pid", + OPT_INTEGER('p', "pid", &record.opts.target_pid, "record events on existing process id"), - OPT_STRING('t', "tid", &record.opts.target_tid, "tid", + OPT_INTEGER('t', "tid", &record.opts.target_tid, "record events on existing thread id"), OPT_INTEGER('r', "realtime", &record.realtime_prio, "collect data with this RT SCHED_FIFO priority"), @@ -747,7 +749,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) argc = parse_options(argc, argv, record_options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); - if (!argc && !rec->opts.target_pid && !rec->opts.target_tid && + if (!argc && rec->opts.target_pid == -1 && rec->opts.target_tid == -1 && !rec->opts.system_wide && !rec->opts.cpu_list && !rec->uid_str) usage_with_options(record_usage, record_options); @@ -793,7 +795,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) if (rec->uid_str != NULL && rec->opts.uid == UINT_MAX - 1) goto out_free_fd; - if (rec->opts.target_pid) + if (rec->opts.target_pid != -1) rec->opts.target_tid = rec->opts.target_pid; if (perf_evlist__create_maps(evsel_list, rec->opts.target_pid, diff --git a/trunk/tools/perf/builtin-stat.c b/trunk/tools/perf/builtin-stat.c index ea40e4e8b227..459b8620a5d9 100644 --- a/trunk/tools/perf/builtin-stat.c +++ b/trunk/tools/perf/builtin-stat.c @@ -182,8 +182,8 @@ static int run_count = 1; static bool no_inherit = false; static bool scale = true; static bool no_aggr = false; -static const char *target_pid; -static const char *target_tid; +static pid_t target_pid = -1; +static pid_t target_tid = -1; static pid_t child_pid = -1; static bool null_run = false; static int detailed_run = 0; @@ -296,7 +296,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, if (system_wide) return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group, group_fd); - if (!target_pid && !target_tid) { + if (target_pid == -1 && target_tid == -1) { attr->disabled = 1; attr->enable_on_exec = 1; } @@ -446,7 +446,7 @@ static int run_perf_stat(int argc __used, const char **argv) exit(-1); } - if (!target_tid && !target_pid && !system_wide) + if (target_tid == -1 && target_pid == -1 && !system_wide) evsel_list->threads->map[0] = child_pid; /* @@ -576,8 +576,6 @@ static void nsec_printout(int cpu, struct perf_evsel *evsel, double avg) if (perf_evsel__match(evsel, SOFTWARE, SW_TASK_CLOCK)) fprintf(output, " # %8.3f CPUs utilized ", avg / avg_stats(&walltime_nsecs_stats)); - else - fprintf(output, " "); } /* used for get_ratio_color() */ @@ -846,18 +844,12 @@ static void abs_printout(int cpu, struct perf_evsel *evsel, double avg) fprintf(output, " # %8.3f GHz ", ratio); } else if (runtime_nsecs_stats[cpu].n != 0) { - char unit = 'M'; - total = avg_stats(&runtime_nsecs_stats[cpu]); if (total) ratio = 1000.0 * avg / total; - if (ratio < 0.001) { - ratio *= 1000; - unit = 'K'; - } - fprintf(output, " # %8.3f %c/sec ", ratio, unit); + fprintf(output, " # %8.3f M/sec ", ratio); } else { fprintf(output, " "); } @@ -968,14 +960,14 @@ static void print_stat(int argc, const char **argv) if (!csv_output) { fprintf(output, "\n"); fprintf(output, " Performance counter stats for "); - if (!target_pid && !target_tid) { + if(target_pid == -1 && target_tid == -1) { fprintf(output, "\'%s", argv[0]); for (i = 1; i < argc; i++) fprintf(output, " %s", argv[i]); - } else if (target_pid) - fprintf(output, "process id \'%s", target_pid); + } else if (target_pid != -1) + fprintf(output, "process id \'%d", target_pid); else - fprintf(output, "thread id \'%s", target_tid); + fprintf(output, "thread id \'%d", target_tid); fprintf(output, "\'"); if (run_count > 1) @@ -1049,10 +1041,10 @@ static const struct option options[] = { "event filter", parse_filter), OPT_BOOLEAN('i', "no-inherit", &no_inherit, "child tasks do not inherit counters"), - OPT_STRING('p', "pid", &target_pid, "pid", - "stat events on existing process id"), - OPT_STRING('t', "tid", &target_tid, "tid", - "stat events on existing thread id"), + OPT_INTEGER('p', "pid", &target_pid, + "stat events on existing process id"), + OPT_INTEGER('t', "tid", &target_tid, + "stat events on existing thread id"), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), OPT_BOOLEAN('g', "group", &group, @@ -1190,7 +1182,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) } else if (big_num_opt == 0) /* User passed --no-big-num */ big_num = false; - if (!argc && !target_pid && !target_tid) + if (!argc && target_pid == -1 && target_tid == -1) usage_with_options(stat_usage, options); if (run_count <= 0) usage_with_options(stat_usage, options); @@ -1206,11 +1198,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) if (add_default_attributes()) goto out; - if (target_pid) + if (target_pid != -1) target_tid = target_pid; - evsel_list->threads = thread_map__new_str(target_pid, - target_tid, UINT_MAX); + evsel_list->threads = thread_map__new(target_pid, target_tid, UINT_MAX); if (evsel_list->threads == NULL) { pr_err("Problems finding threads of monitor\n"); usage_with_options(stat_usage, options); diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 3e087ce8daa6..70c4eb2bdf72 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -1010,9 +1010,12 @@ static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, static int test__PERF_RECORD(void) { struct perf_record_opts opts = { + .target_pid = -1, + .target_tid = -1, .no_delay = true, .freq = 10, .mmap_pages = 256, + .sample_id_all_avail = true, }; cpu_set_t *cpu_mask = NULL; size_t cpu_mask_size = 0; diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index e3c63aef8efc..d869b214ada2 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -677,12 +677,6 @@ static void perf_event__process_sample(struct perf_tool *tool, return; } - if (!machine) { - pr_err("%u unprocessable samples recorded.", - top->session->hists.stats.nr_unprocessable_samples++); - return; - } - if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) top->exact_samples++; @@ -872,11 +866,8 @@ static void perf_top__start_counters(struct perf_top *top) attr->mmap = 1; attr->comm = 1; attr->inherit = top->inherit; -fallback_missing_features: - if (top->exclude_guest_missing) - attr->exclude_guest = attr->exclude_host = 0; retry_sample_id: - attr->sample_id_all = top->sample_id_all_missing ? 0 : 1; + attr->sample_id_all = top->sample_id_all_avail ? 1 : 0; try_again: if (perf_evsel__open(counter, top->evlist->cpus, top->evlist->threads, top->group, @@ -886,20 +877,12 @@ static void perf_top__start_counters(struct perf_top *top) if (err == EPERM || err == EACCES) { ui__error_paranoid(); goto out_err; - } else if (err == EINVAL) { - if (!top->exclude_guest_missing && - (attr->exclude_guest || attr->exclude_host)) { - pr_debug("Old kernel, cannot exclude " - "guest or host samples.\n"); - top->exclude_guest_missing = true; - goto fallback_missing_features; - } else if (!top->sample_id_all_missing) { - /* - * Old kernel, no attr->sample_id_type_all field - */ - top->sample_id_all_missing = true; - goto retry_sample_id; - } + } else if (err == EINVAL && top->sample_id_all_avail) { + /* + * Old kernel, no attr->sample_id_type_all field + */ + top->sample_id_all_avail = false; + goto retry_sample_id; } /* * If it's cycles then fall back to hrtimer @@ -982,7 +965,7 @@ static int __cmd_top(struct perf_top *top) if (ret) goto out_delete; - if (top->target_tid || top->uid != UINT_MAX) + if (top->target_tid != -1 || top->uid != UINT_MAX) perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, perf_event__process, &top->session->host_machine); @@ -1120,8 +1103,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) struct perf_top top = { .count_filter = 5, .delay_secs = 2, + .target_pid = -1, + .target_tid = -1, .uid = UINT_MAX, .freq = 1000, /* 1 KHz */ + .sample_id_all_avail = true, .mmap_pages = 128, .sym_pcnt_filter = 5, }; @@ -1132,9 +1118,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) parse_events_option), OPT_INTEGER('c', "count", &top.default_interval, "event period to sample"), - OPT_STRING('p', "pid", &top.target_pid, "pid", + OPT_INTEGER('p', "pid", &top.target_pid, "profile events on existing process id"), - OPT_STRING('t', "tid", &top.target_tid, "tid", + OPT_INTEGER('t', "tid", &top.target_tid, "profile events on existing thread id"), OPT_BOOLEAN('a', "all-cpus", &top.system_wide, "system-wide collection from all CPUs"), @@ -1224,13 +1210,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) goto out_delete_evlist; /* CPU and PID are mutually exclusive */ - if (top.target_tid && top.cpu_list) { + if (top.target_tid > 0 && top.cpu_list) { printf("WARNING: PID switch overriding CPU\n"); sleep(1); top.cpu_list = NULL; } - if (top.target_pid) + if (top.target_pid != -1) top.target_tid = top.target_pid; if (perf_evlist__create_maps(top.evlist, top.target_pid, diff --git a/trunk/tools/perf/perf.h b/trunk/tools/perf/perf.h index f0227e93665d..92af1688bae4 100644 --- a/trunk/tools/perf/perf.h +++ b/trunk/tools/perf/perf.h @@ -167,6 +167,7 @@ sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) { + attr->size = sizeof(*attr); return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags); } @@ -185,8 +186,8 @@ extern const char perf_version_string[]; void pthread__unblock_sigwinch(void); struct perf_record_opts { - const char *target_pid; - const char *target_tid; + pid_t target_pid; + pid_t target_tid; uid_t uid; bool call_graph; bool group; @@ -198,8 +199,7 @@ struct perf_record_opts { bool raw_samples; bool sample_address; bool sample_time; - bool sample_id_all_missing; - bool exclude_guest_missing; + bool sample_id_all_avail; bool system_wide; bool period; unsigned int freq; diff --git a/trunk/tools/perf/util/bitmap.c b/trunk/tools/perf/util/bitmap.c index 0a1adc1111fd..5e230acae1e9 100644 --- a/trunk/tools/perf/util/bitmap.c +++ b/trunk/tools/perf/util/bitmap.c @@ -19,13 +19,3 @@ int __bitmap_weight(const unsigned long *bitmap, int bits) return w; } - -void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits) -{ - int k; - int nr = BITS_TO_LONGS(bits); - - for (k = 0; k < nr; k++) - dst[k] = bitmap1[k] | bitmap2[k]; -} diff --git a/trunk/tools/perf/util/ctype.c b/trunk/tools/perf/util/ctype.c index aada3ac5e891..35073621e5de 100644 --- a/trunk/tools/perf/util/ctype.c +++ b/trunk/tools/perf/util/ctype.c @@ -3,7 +3,7 @@ * * No surprises, and works with signed and unsigned chars. */ -#include "util.h" +#include "cache.h" enum { S = GIT_SPACE, diff --git a/trunk/tools/perf/util/debugfs.c b/trunk/tools/perf/util/debugfs.c index dd8b19319c03..ffc35e748e89 100644 --- a/trunk/tools/perf/util/debugfs.c +++ b/trunk/tools/perf/util/debugfs.c @@ -15,6 +15,32 @@ static const char *debugfs_known_mountpoints[] = { 0, }; +/* use this to force a umount */ +void debugfs_force_cleanup(void) +{ + debugfs_find_mountpoint(); + debugfs_premounted = 0; + debugfs_umount(); +} + +/* construct a full path to a debugfs element */ +int debugfs_make_path(const char *element, char *buffer, int size) +{ + int len; + + if (strlen(debugfs_mountpoint) == 0) { + buffer[0] = '\0'; + return -1; + } + + len = strlen(debugfs_mountpoint) + strlen(element) + 1; + if (len >= size) + return len+1; + + snprintf(buffer, size-1, "%s/%s", debugfs_mountpoint, element); + return 0; +} + static int debugfs_found; /* find the path to the mounted debugfs */ @@ -71,6 +97,17 @@ int debugfs_valid_mountpoint(const char *debugfs) return 0; } + +int debugfs_valid_entry(const char *path) +{ + struct stat st; + + if (stat(path, &st)) + return -errno; + + return 0; +} + static void debugfs_set_tracing_events_path(const char *mountpoint) { snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", @@ -112,3 +149,107 @@ void debugfs_set_path(const char *mountpoint) snprintf(debugfs_mountpoint, sizeof(debugfs_mountpoint), "%s", mountpoint); debugfs_set_tracing_events_path(mountpoint); } + +/* umount the debugfs */ + +int debugfs_umount(void) +{ + char umountcmd[128]; + int ret; + + /* if it was already mounted, leave it */ + if (debugfs_premounted) + return 0; + + /* make sure it's a valid mount point */ + ret = debugfs_valid_mountpoint(debugfs_mountpoint); + if (ret) + return ret; + + snprintf(umountcmd, sizeof(umountcmd), + "/bin/umount %s", debugfs_mountpoint); + return system(umountcmd); +} + +int debugfs_write(const char *entry, const char *value) +{ + char path[PATH_MAX + 1]; + int ret, count; + int fd; + + /* construct the path */ + snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry); + + /* verify that it exists */ + ret = debugfs_valid_entry(path); + if (ret) + return ret; + + /* get how many chars we're going to write */ + count = strlen(value); + + /* open the debugfs entry */ + fd = open(path, O_RDWR); + if (fd < 0) + return -errno; + + while (count > 0) { + /* write it */ + ret = write(fd, value, count); + if (ret <= 0) { + if (ret == EAGAIN) + continue; + close(fd); + return -errno; + } + count -= ret; + } + + /* close it */ + close(fd); + + /* return success */ + return 0; +} + +/* + * read a debugfs entry + * returns the number of chars read or a negative errno + */ +int debugfs_read(const char *entry, char *buffer, size_t size) +{ + char path[PATH_MAX + 1]; + int ret; + int fd; + + /* construct the path */ + snprintf(path, sizeof(path), "%s/%s", debugfs_mountpoint, entry); + + /* verify that it exists */ + ret = debugfs_valid_entry(path); + if (ret) + return ret; + + /* open the debugfs entry */ + fd = open(path, O_RDONLY); + if (fd < 0) + return -errno; + + do { + /* read it */ + ret = read(fd, buffer, size); + if (ret == 0) { + close(fd); + return EOF; + } + } while (ret < 0 && errno == EAGAIN); + + /* close it */ + close(fd); + + /* make *sure* there's a null character at the end */ + buffer[ret] = '\0'; + + /* return the number of chars read */ + return ret; +} diff --git a/trunk/tools/perf/util/debugfs.h b/trunk/tools/perf/util/debugfs.h index 68f3e87ec57f..4a878f735eb0 100644 --- a/trunk/tools/perf/util/debugfs.h +++ b/trunk/tools/perf/util/debugfs.h @@ -3,8 +3,14 @@ const char *debugfs_find_mountpoint(void); int debugfs_valid_mountpoint(const char *debugfs); +int debugfs_valid_entry(const char *path); char *debugfs_mount(const char *mountpoint); +int debugfs_umount(void); void debugfs_set_path(const char *mountpoint); +int debugfs_write(const char *entry, const char *value); +int debugfs_read(const char *entry, char *buffer, size_t size); +void debugfs_force_cleanup(void); +int debugfs_make_path(const char *element, char *buffer, int size); extern char debugfs_mountpoint[]; extern char tracing_events_path[]; diff --git a/trunk/tools/perf/util/event.c b/trunk/tools/perf/util/event.c index 2044324b755a..73ddaf06b8e7 100644 --- a/trunk/tools/perf/util/event.c +++ b/trunk/tools/perf/util/event.c @@ -554,7 +554,7 @@ static int perf_event__process_kernel_mmap(struct perf_tool *tool __used, is_kernel_mmap = memcmp(event->mmap.filename, kmmap_prefix, - strlen(kmmap_prefix) - 1) == 0; + strlen(kmmap_prefix)) == 0; if (event->mmap.filename[0] == '/' || (!is_kernel_mmap && event->mmap.filename[0] == '[')) { diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index 5c61dc57d7c7..a6d50e376257 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -97,9 +97,9 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) ++evlist->nr_entries; } -void perf_evlist__splice_list_tail(struct perf_evlist *evlist, - struct list_head *list, - int nr_entries) +static void perf_evlist__splice_list_tail(struct perf_evlist *evlist, + struct list_head *list, + int nr_entries) { list_splice_tail(list, &evlist->entries); evlist->nr_entries += nr_entries; @@ -593,15 +593,15 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, return perf_evlist__mmap_per_cpu(evlist, prot, mask); } -int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid, - const char *target_tid, uid_t uid, const char *cpu_list) +int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, + pid_t target_tid, uid_t uid, const char *cpu_list) { - evlist->threads = thread_map__new_str(target_pid, target_tid, uid); + evlist->threads = thread_map__new(target_pid, target_tid, uid); if (evlist->threads == NULL) return -1; - if (uid != UINT_MAX || (cpu_list == NULL && target_tid)) + if (uid != UINT_MAX || (cpu_list == NULL && target_tid != -1)) evlist->cpus = cpu_map__dummy_new(); else evlist->cpus = cpu_map__new(cpu_list); @@ -820,7 +820,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, exit(-1); } - if (!opts->system_wide && !opts->target_tid && !opts->target_pid) + if (!opts->system_wide && opts->target_tid == -1 && opts->target_pid == -1) evlist->threads->map[0] = evlist->workload.pid; close(child_ready_pipe[1]); diff --git a/trunk/tools/perf/util/evlist.h b/trunk/tools/perf/util/evlist.h index 21f1c9e57f13..9c516607ce20 100644 --- a/trunk/tools/perf/util/evlist.h +++ b/trunk/tools/perf/util/evlist.h @@ -106,8 +106,8 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist, evlist->threads = threads; } -int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid, - const char *tid, uid_t uid, const char *cpu_list); +int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, + pid_t tid, uid_t uid, const char *cpu_list); void perf_evlist__delete_maps(struct perf_evlist *evlist); int perf_evlist__set_filters(struct perf_evlist *evlist); @@ -117,9 +117,4 @@ u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); - -void perf_evlist__splice_list_tail(struct perf_evlist *evlist, - struct list_head *list, - int nr_entries); - #endif /* __PERF_EVLIST_H */ diff --git a/trunk/tools/perf/util/evsel.c b/trunk/tools/perf/util/evsel.c index 302d49a9f985..dcfefab53e00 100644 --- a/trunk/tools/perf/util/evsel.c +++ b/trunk/tools/perf/util/evsel.c @@ -68,7 +68,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) struct perf_event_attr *attr = &evsel->attr; int track = !evsel->idx; /* only the first counter needs these */ - attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; + attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0; attr->inherit = !opts->no_inherit; attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING | @@ -111,7 +111,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) if (opts->period) attr->sample_type |= PERF_SAMPLE_PERIOD; - if (!opts->sample_id_all_missing && + if (opts->sample_id_all_avail && (opts->sample_time || opts->system_wide || !opts->no_inherit || opts->cpu_list)) attr->sample_type |= PERF_SAMPLE_TIME; @@ -130,7 +130,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) attr->mmap = track; attr->comm = track; - if (!opts->target_pid && !opts->target_tid && !opts->system_wide) { + if (opts->target_pid == -1 && opts->target_tid == -1 && !opts->system_wide) { attr->disabled = 1; attr->enable_on_exec = 1; } @@ -463,7 +463,6 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, memset(data, 0, sizeof(*data)); data->cpu = data->pid = data->tid = -1; data->stream_id = data->id = data->time = -1ULL; - data->period = 1; if (event->header.type != PERF_RECORD_SAMPLE) { if (!sample_id_all) diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index 9f867d96c6a5..ecd7f4dd7eea 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -63,20 +63,9 @@ char *perf_header__find_event(u64 id) return NULL; } -/* - * magic2 = "PERFILE2" - * must be a numerical value to let the endianness - * determine the memory layout. That way we are able - * to detect endianness when reading the perf.data file - * back. - * - * we check for legacy (PERFFILE) format. - */ -static const char *__perf_magic1 = "PERFFILE"; -static const u64 __perf_magic2 = 0x32454c4946524550ULL; -static const u64 __perf_magic2_sw = 0x50455246494c4532ULL; +static const char *__perf_magic = "PERFFILE"; -#define PERF_MAGIC __perf_magic2 +#define PERF_MAGIC (*(u64 *)__perf_magic) struct perf_file_attr { struct perf_event_attr attr; @@ -1316,198 +1305,25 @@ static void print_cpuid(struct perf_header *ph, int fd, FILE *fp) free(str); } -static int __event_process_build_id(struct build_id_event *bev, - char *filename, - struct perf_session *session) -{ - int err = -1; - struct list_head *head; - struct machine *machine; - u16 misc; - struct dso *dso; - enum dso_kernel_type dso_type; - - machine = perf_session__findnew_machine(session, bev->pid); - if (!machine) - goto out; - - misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - - switch (misc) { - case PERF_RECORD_MISC_KERNEL: - dso_type = DSO_TYPE_KERNEL; - head = &machine->kernel_dsos; - break; - case PERF_RECORD_MISC_GUEST_KERNEL: - dso_type = DSO_TYPE_GUEST_KERNEL; - head = &machine->kernel_dsos; - break; - case PERF_RECORD_MISC_USER: - case PERF_RECORD_MISC_GUEST_USER: - dso_type = DSO_TYPE_USER; - head = &machine->user_dsos; - break; - default: - goto out; - } - - dso = __dsos__findnew(head, filename); - if (dso != NULL) { - char sbuild_id[BUILD_ID_SIZE * 2 + 1]; - - dso__set_build_id(dso, &bev->build_id); - - if (filename[0] == '[') - dso->kernel = dso_type; - - build_id__sprintf(dso->build_id, sizeof(dso->build_id), - sbuild_id); - pr_debug("build id event received for %s: %s\n", - dso->long_name, sbuild_id); - } - - err = 0; -out: - return err; -} - -static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, - int input, u64 offset, u64 size) -{ - struct perf_session *session = container_of(header, struct perf_session, header); - struct { - struct perf_event_header header; - u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; - char filename[0]; - } old_bev; - struct build_id_event bev; - char filename[PATH_MAX]; - u64 limit = offset + size; - - while (offset < limit) { - ssize_t len; - - if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) - return -1; - - if (header->needs_swap) - perf_event_header__bswap(&old_bev.header); - - len = old_bev.header.size - sizeof(old_bev); - if (read(input, filename, len) != len) - return -1; - - bev.header = old_bev.header; - - /* - * As the pid is the missing value, we need to fill - * it properly. The header.misc value give us nice hint. - */ - bev.pid = HOST_KERNEL_ID; - if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER || - bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL) - bev.pid = DEFAULT_GUEST_KERNEL_ID; - - memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); - __event_process_build_id(&bev, filename, session); - - offset += bev.header.size; - } - - return 0; -} - -static int perf_header__read_build_ids(struct perf_header *header, - int input, u64 offset, u64 size) -{ - struct perf_session *session = container_of(header, struct perf_session, header); - struct build_id_event bev; - char filename[PATH_MAX]; - u64 limit = offset + size, orig_offset = offset; - int err = -1; - - while (offset < limit) { - ssize_t len; - - if (read(input, &bev, sizeof(bev)) != sizeof(bev)) - goto out; - - if (header->needs_swap) - perf_event_header__bswap(&bev.header); - - len = bev.header.size - sizeof(bev); - if (read(input, filename, len) != len) - goto out; - /* - * The a1645ce1 changeset: - * - * "perf: 'perf kvm' tool for monitoring guest performance from host" - * - * Added a field to struct build_id_event that broke the file - * format. - * - * Since the kernel build-id is the first entry, process the - * table using the old format if the well known - * '[kernel.kallsyms]' string for the kernel build-id has the - * first 4 characters chopped off (where the pid_t sits). - */ - if (memcmp(filename, "nel.kallsyms]", 13) == 0) { - if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) - return -1; - return perf_header__read_build_ids_abi_quirk(header, input, offset, size); - } - - __event_process_build_id(&bev, filename, session); - - offset += bev.header.size; - } - err = 0; -out: - return err; -} - -static int process_trace_info(struct perf_file_section *section __unused, - struct perf_header *ph __unused, - int feat __unused, int fd) -{ - trace_report(fd, false); - return 0; -} - -static int process_build_id(struct perf_file_section *section, - struct perf_header *ph, - int feat __unused, int fd) -{ - if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) - pr_debug("Failed to read buildids, continuing...\n"); - return 0; -} - struct feature_ops { int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist); void (*print)(struct perf_header *h, int fd, FILE *fp); - int (*process)(struct perf_file_section *section, - struct perf_header *h, int feat, int fd); const char *name; bool full_only; }; #define FEAT_OPA(n, func) \ [n] = { .name = #n, .write = write_##func, .print = print_##func } -#define FEAT_OPP(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .process = process_##func } #define FEAT_OPF(n, func) \ - [n] = { .name = #n, .write = write_##func, .print = print_##func, \ - .full_only = true } + [n] = { .name = #n, .write = write_##func, .print = print_##func, .full_only = true } /* feature_ops not implemented: */ #define print_trace_info NULL #define print_build_id NULL static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = { - FEAT_OPP(HEADER_TRACE_INFO, trace_info), - FEAT_OPP(HEADER_BUILD_ID, build_id), + FEAT_OPA(HEADER_TRACE_INFO, trace_info), + FEAT_OPA(HEADER_BUILD_ID, build_id), FEAT_OPA(HEADER_HOSTNAME, hostname), FEAT_OPA(HEADER_OSRELEASE, osrelease), FEAT_OPA(HEADER_VERSION, version), @@ -1804,59 +1620,24 @@ int perf_header__process_sections(struct perf_header *header, int fd, return err; } -static int check_magic_endian(u64 *magic, struct perf_file_header *header, - struct perf_header *ph) -{ - int ret; - - /* check for legacy format */ - ret = memcmp(magic, __perf_magic1, sizeof(*magic)); - if (ret == 0) { - pr_debug("legacy perf.data format\n"); - if (!header) - return -1; - - if (header->attr_size != sizeof(struct perf_file_attr)) { - u64 attr_size = bswap_64(header->attr_size); - - if (attr_size != sizeof(struct perf_file_attr)) - return -1; - - ph->needs_swap = true; - } - return 0; - } - - /* check magic number with same endianness */ - if (*magic == __perf_magic2) - return 0; - - /* check magic number but opposite endianness */ - if (*magic != __perf_magic2_sw) - return -1; - - ph->needs_swap = true; - - return 0; -} - int perf_file_header__read(struct perf_file_header *header, struct perf_header *ph, int fd) { - int ret; - lseek(fd, 0, SEEK_SET); - ret = readn(fd, header, sizeof(*header)); - if (ret <= 0) + if (readn(fd, header, sizeof(*header)) <= 0 || + memcmp(&header->magic, __perf_magic, sizeof(header->magic))) return -1; - if (check_magic_endian(&header->magic, header, ph) < 0) - return -1; + if (header->attr_size != sizeof(struct perf_file_attr)) { + u64 attr_size = bswap_64(header->attr_size); + + if (attr_size != sizeof(struct perf_file_attr)) + return -1; - if (ph->needs_swap) { mem_bswap_64(header, offsetof(struct perf_file_header, - adds_features)); + adds_features)); + ph->needs_swap = true; } if (header->size != sizeof(*header)) { @@ -1908,6 +1689,156 @@ int perf_file_header__read(struct perf_file_header *header, return 0; } +static int __event_process_build_id(struct build_id_event *bev, + char *filename, + struct perf_session *session) +{ + int err = -1; + struct list_head *head; + struct machine *machine; + u16 misc; + struct dso *dso; + enum dso_kernel_type dso_type; + + machine = perf_session__findnew_machine(session, bev->pid); + if (!machine) + goto out; + + misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + + switch (misc) { + case PERF_RECORD_MISC_KERNEL: + dso_type = DSO_TYPE_KERNEL; + head = &machine->kernel_dsos; + break; + case PERF_RECORD_MISC_GUEST_KERNEL: + dso_type = DSO_TYPE_GUEST_KERNEL; + head = &machine->kernel_dsos; + break; + case PERF_RECORD_MISC_USER: + case PERF_RECORD_MISC_GUEST_USER: + dso_type = DSO_TYPE_USER; + head = &machine->user_dsos; + break; + default: + goto out; + } + + dso = __dsos__findnew(head, filename); + if (dso != NULL) { + char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + + dso__set_build_id(dso, &bev->build_id); + + if (filename[0] == '[') + dso->kernel = dso_type; + + build_id__sprintf(dso->build_id, sizeof(dso->build_id), + sbuild_id); + pr_debug("build id event received for %s: %s\n", + dso->long_name, sbuild_id); + } + + err = 0; +out: + return err; +} + +static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, + int input, u64 offset, u64 size) +{ + struct perf_session *session = container_of(header, struct perf_session, header); + struct { + struct perf_event_header header; + u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; + char filename[0]; + } old_bev; + struct build_id_event bev; + char filename[PATH_MAX]; + u64 limit = offset + size; + + while (offset < limit) { + ssize_t len; + + if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) + return -1; + + if (header->needs_swap) + perf_event_header__bswap(&old_bev.header); + + len = old_bev.header.size - sizeof(old_bev); + if (read(input, filename, len) != len) + return -1; + + bev.header = old_bev.header; + + /* + * As the pid is the missing value, we need to fill + * it properly. The header.misc value give us nice hint. + */ + bev.pid = HOST_KERNEL_ID; + if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER || + bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL) + bev.pid = DEFAULT_GUEST_KERNEL_ID; + + memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); + __event_process_build_id(&bev, filename, session); + + offset += bev.header.size; + } + + return 0; +} + +static int perf_header__read_build_ids(struct perf_header *header, + int input, u64 offset, u64 size) +{ + struct perf_session *session = container_of(header, struct perf_session, header); + struct build_id_event bev; + char filename[PATH_MAX]; + u64 limit = offset + size, orig_offset = offset; + int err = -1; + + while (offset < limit) { + ssize_t len; + + if (read(input, &bev, sizeof(bev)) != sizeof(bev)) + goto out; + + if (header->needs_swap) + perf_event_header__bswap(&bev.header); + + len = bev.header.size - sizeof(bev); + if (read(input, filename, len) != len) + goto out; + /* + * The a1645ce1 changeset: + * + * "perf: 'perf kvm' tool for monitoring guest performance from host" + * + * Added a field to struct build_id_event that broke the file + * format. + * + * Since the kernel build-id is the first entry, process the + * table using the old format if the well known + * '[kernel.kallsyms]' string for the kernel build-id has the + * first 4 characters chopped off (where the pid_t sits). + */ + if (memcmp(filename, "nel.kallsyms]", 13) == 0) { + if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return perf_header__read_build_ids_abi_quirk(header, input, offset, size); + } + + __event_process_build_id(&bev, filename, session); + + offset += bev.header.size; + } + err = 0; +out: + return err; +} + static int perf_file_section__process(struct perf_file_section *section, struct perf_header *ph, int feat, int fd, void *data __used) @@ -1923,23 +1854,27 @@ static int perf_file_section__process(struct perf_file_section *section, return 0; } - if (!feat_ops[feat].process) - return 0; + switch (feat) { + case HEADER_TRACE_INFO: + trace_report(fd, false); + break; + case HEADER_BUILD_ID: + if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) + pr_debug("Failed to read buildids, continuing...\n"); + break; + default: + break; + } - return feat_ops[feat].process(section, ph, feat, fd); + return 0; } static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, struct perf_header *ph, int fd, bool repipe) { - int ret; - - ret = readn(fd, header, sizeof(*header)); - if (ret <= 0) - return -1; - - if (check_magic_endian(&header->magic, NULL, ph) < 0) + if (readn(fd, header, sizeof(*header)) <= 0 || + memcmp(&header->magic, __perf_magic, sizeof(header->magic))) return -1; if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0) diff --git a/trunk/tools/perf/util/header.h b/trunk/tools/perf/util/header.h index e68f617d082f..ac4ec956024e 100644 --- a/trunk/tools/perf/util/header.h +++ b/trunk/tools/perf/util/header.h @@ -11,7 +11,6 @@ enum { HEADER_RESERVED = 0, /* always cleared */ - HEADER_FIRST_FEATURE = 1, HEADER_TRACE_INFO = 1, HEADER_BUILD_ID, diff --git a/trunk/tools/perf/util/hist.h b/trunk/tools/perf/util/hist.h index 48e5acd1e862..0d486135d10f 100644 --- a/trunk/tools/perf/util/hist.h +++ b/trunk/tools/perf/util/hist.h @@ -32,7 +32,6 @@ struct events_stats { u32 nr_unknown_events; u32 nr_invalid_chains; u32 nr_unknown_id; - u32 nr_unprocessable_samples; }; enum hist_column { diff --git a/trunk/tools/perf/util/include/linux/bitmap.h b/trunk/tools/perf/util/include/linux/bitmap.h index bb162e40c76c..eda4416efa0a 100644 --- a/trunk/tools/perf/util/include/linux/bitmap.h +++ b/trunk/tools/perf/util/include/linux/bitmap.h @@ -5,8 +5,6 @@ #include int __bitmap_weight(const unsigned long *bitmap, int bits); -void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, - const unsigned long *bitmap2, int bits); #define BITMAP_LAST_WORD_MASK(nbits) \ ( \ @@ -34,13 +32,4 @@ static inline int bitmap_weight(const unsigned long *src, int nbits) return __bitmap_weight(src, nbits); } -static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, - const unsigned long *src2, int nbits) -{ - if (small_const_nbits(nbits)) - *dst = *src1 | *src2; - else - __bitmap_or(dst, src1, src2, nbits); -} - #endif /* _PERF_BITOPS_H */ diff --git a/trunk/tools/perf/util/probe-event.c b/trunk/tools/perf/util/probe-event.c index c1a513e56764..b9bbdd236357 100644 --- a/trunk/tools/perf/util/probe-event.c +++ b/trunk/tools/perf/util/probe-event.c @@ -273,10 +273,10 @@ static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, /* Try to find perf_probe_event with debuginfo */ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event **tevs, - int max_tevs, const char *target) + int max_tevs, const char *module) { bool need_dwarf = perf_probe_event_need_dwarf(pev); - struct debuginfo *dinfo = open_debuginfo(target); + struct debuginfo *dinfo = open_debuginfo(module); int ntevs, ret = 0; if (!dinfo) { @@ -295,9 +295,9 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, if (ntevs > 0) { /* Succeeded to find trace events */ pr_debug("find %d probe_trace_events.\n", ntevs); - if (target) + if (module) ret = add_module_to_probe_trace_events(*tevs, ntevs, - target); + module); return ret < 0 ? ret : ntevs; } @@ -1796,14 +1796,14 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, static int convert_to_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event **tevs, - int max_tevs, const char *target) + int max_tevs, const char *module) { struct symbol *sym; int ret = 0, i; struct probe_trace_event *tev; /* Convert perf_probe_event with debuginfo */ - ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target); + ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module); if (ret != 0) return ret; /* Found in debuginfo or got an error */ @@ -1819,8 +1819,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, goto error; } - if (target) { - tev->point.module = strdup(target); + if (module) { + tev->point.module = strdup(module); if (tev->point.module == NULL) { ret = -ENOMEM; goto error; @@ -1884,7 +1884,7 @@ struct __event_package { }; int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, - int max_tevs, const char *target, bool force_add) + int max_tevs, const char *module, bool force_add) { int i, j, ret; struct __event_package *pkgs; @@ -1907,7 +1907,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, ret = convert_to_probe_trace_events(pkgs[i].pev, &pkgs[i].tevs, max_tevs, - target); + module); if (ret < 0) goto end; pkgs[i].ntevs = ret; @@ -2063,7 +2063,7 @@ static int filter_available_functions(struct map *map __unused, return 1; } -int show_available_funcs(const char *target, struct strfilter *_filter) +int show_available_funcs(const char *module, struct strfilter *_filter) { struct map *map; int ret; @@ -2074,9 +2074,9 @@ int show_available_funcs(const char *target, struct strfilter *_filter) if (ret < 0) return ret; - map = kernel_get_module_map(target); + map = kernel_get_module_map(module); if (!map) { - pr_err("Failed to find %s map.\n", (target) ? : "kernel"); + pr_err("Failed to find %s map.\n", (module) ? : "kernel"); return -EINVAL; } available_func_filter = _filter; diff --git a/trunk/tools/perf/util/python-ext-sources b/trunk/tools/perf/util/python-ext-sources deleted file mode 100644 index 2884e67ee625..000000000000 --- a/trunk/tools/perf/util/python-ext-sources +++ /dev/null @@ -1,19 +0,0 @@ -# -# List of files needed by perf python extention -# -# Each source file must be placed on its own line so that it can be -# processed by Makefile and util/setup.py accordingly. -# - -util/python.c -util/ctype.c -util/evlist.c -util/evsel.c -util/cpumap.c -util/thread_map.c -util/util.c -util/xyarray.c -util/cgroup.c -util/debugfs.c -util/strlist.c -../../lib/rbtree.c diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index 9f833cf9c6a9..552c1c50eea1 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -796,10 +796,6 @@ static int perf_session_deliver_event(struct perf_session *session, ++session->hists.stats.nr_unknown_id; return -1; } - if (machine == NULL) { - ++session->hists.stats.nr_unprocessable_samples; - return -1; - } return tool->sample(tool, event, sample, evsel, machine); case PERF_RECORD_MMAP: return tool->mmap(tool, event, sample, machine); @@ -968,12 +964,6 @@ static void perf_session__warn_about_errors(const struct perf_session *session, session->hists.stats.nr_invalid_chains, session->hists.stats.nr_events[PERF_RECORD_SAMPLE]); } - - if (session->hists.stats.nr_unprocessable_samples != 0) { - ui__warning("%u unprocessable samples recorded.\n" - "Do you have a KVM guest running and not using 'perf kvm'?\n", - session->hists.stats.nr_unprocessable_samples); - } } #define session_done() (*(volatile int *)(&session_done)) diff --git a/trunk/tools/perf/util/setup.py b/trunk/tools/perf/util/setup.py index d0f9f29cf181..36d4c5619575 100644 --- a/trunk/tools/perf/util/setup.py +++ b/trunk/tools/perf/util/setup.py @@ -24,11 +24,11 @@ def finalize_options(self): build_lib = getenv('PYTHON_EXTBUILD_LIB') build_tmp = getenv('PYTHON_EXTBUILD_TMP') -ext_sources = [f.strip() for f in file('util/python-ext-sources') - if len(f.strip()) > 0 and f[0] != '#'] - perf = Extension('perf', - sources = ext_sources, + sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', + 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', + 'util/util.c', 'util/xyarray.c', 'util/cgroup.c', + 'util/debugfs.c'], include_dirs = ['util/include'], extra_compile_args = cflags, ) diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index 5dd83c3e2c0c..fc6e12fe4b44 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,7 +12,6 @@ #include #include #include "build-id.h" -#include "util.h" #include "debug.h" #include "symbol.h" #include "strlist.h" diff --git a/trunk/tools/perf/util/sysfs.c b/trunk/tools/perf/util/sysfs.c deleted file mode 100644 index 48c6902e749f..000000000000 --- a/trunk/tools/perf/util/sysfs.c +++ /dev/null @@ -1,60 +0,0 @@ - -#include "util.h" -#include "sysfs.h" - -static const char * const sysfs_known_mountpoints[] = { - "/sys", - 0, -}; - -static int sysfs_found; -char sysfs_mountpoint[PATH_MAX]; - -static int sysfs_valid_mountpoint(const char *sysfs) -{ - struct statfs st_fs; - - if (statfs(sysfs, &st_fs) < 0) - return -ENOENT; - else if (st_fs.f_type != (long) SYSFS_MAGIC) - return -ENOENT; - - return 0; -} - -const char *sysfs_find_mountpoint(void) -{ - const char * const *ptr; - char type[100]; - FILE *fp; - - if (sysfs_found) - return (const char *) sysfs_mountpoint; - - ptr = sysfs_known_mountpoints; - while (*ptr) { - if (sysfs_valid_mountpoint(*ptr) == 0) { - sysfs_found = 1; - strcpy(sysfs_mountpoint, *ptr); - return sysfs_mountpoint; - } - ptr++; - } - - /* give up and parse /proc/mounts */ - fp = fopen("/proc/mounts", "r"); - if (fp == NULL) - return NULL; - - while (!sysfs_found && - fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", - sysfs_mountpoint, type) == 2) { - - if (strcmp(type, "sysfs") == 0) - sysfs_found = 1; - } - - fclose(fp); - - return sysfs_found ? sysfs_mountpoint : NULL; -} diff --git a/trunk/tools/perf/util/sysfs.h b/trunk/tools/perf/util/sysfs.h deleted file mode 100644 index a813b7203938..000000000000 --- a/trunk/tools/perf/util/sysfs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __SYSFS_H__ -#define __SYSFS_H__ - -const char *sysfs_find_mountpoint(void); - -#endif /* __DEBUGFS_H__ */ diff --git a/trunk/tools/perf/util/thread_map.c b/trunk/tools/perf/util/thread_map.c index e15983cf077d..3d4b6c5931b9 100644 --- a/trunk/tools/perf/util/thread_map.c +++ b/trunk/tools/perf/util/thread_map.c @@ -6,8 +6,6 @@ #include #include #include -#include "strlist.h" -#include #include "thread_map.h" /* Skip "." and ".." directories */ @@ -154,132 +152,6 @@ struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid) return thread_map__new_by_tid(tid); } -static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) -{ - struct thread_map *threads = NULL, *nt; - char name[256]; - int items, total_tasks = 0; - struct dirent **namelist = NULL; - int i, j = 0; - pid_t pid, prev_pid = INT_MAX; - char *end_ptr; - struct str_node *pos; - struct strlist *slist = strlist__new(false, pid_str); - - if (!slist) - return NULL; - - strlist__for_each(pos, slist) { - pid = strtol(pos->s, &end_ptr, 10); - - if (pid == INT_MIN || pid == INT_MAX || - (*end_ptr != '\0' && *end_ptr != ',')) - goto out_free_threads; - - if (pid == prev_pid) - continue; - - sprintf(name, "/proc/%d/task", pid); - items = scandir(name, &namelist, filter, NULL); - if (items <= 0) - goto out_free_threads; - - total_tasks += items; - nt = realloc(threads, (sizeof(*threads) + - sizeof(pid_t) * total_tasks)); - if (nt == NULL) - goto out_free_threads; - - threads = nt; - - if (threads) { - for (i = 0; i < items; i++) - threads->map[j++] = atoi(namelist[i]->d_name); - threads->nr = total_tasks; - } - - for (i = 0; i < items; i++) - free(namelist[i]); - free(namelist); - - if (!threads) - break; - } - -out: - strlist__delete(slist); - return threads; - -out_free_threads: - free(threads); - threads = NULL; - goto out; -} - -static struct thread_map *thread_map__new_by_tid_str(const char *tid_str) -{ - struct thread_map *threads = NULL, *nt; - int ntasks = 0; - pid_t tid, prev_tid = INT_MAX; - char *end_ptr; - struct str_node *pos; - struct strlist *slist; - - /* perf-stat expects threads to be generated even if tid not given */ - if (!tid_str) { - threads = malloc(sizeof(*threads) + sizeof(pid_t)); - if (threads != NULL) { - threads->map[1] = -1; - threads->nr = 1; - } - return threads; - } - - slist = strlist__new(false, tid_str); - if (!slist) - return NULL; - - strlist__for_each(pos, slist) { - tid = strtol(pos->s, &end_ptr, 10); - - if (tid == INT_MIN || tid == INT_MAX || - (*end_ptr != '\0' && *end_ptr != ',')) - goto out_free_threads; - - if (tid == prev_tid) - continue; - - ntasks++; - nt = realloc(threads, sizeof(*threads) + sizeof(pid_t) * ntasks); - - if (nt == NULL) - goto out_free_threads; - - threads = nt; - threads->map[ntasks - 1] = tid; - threads->nr = ntasks; - } -out: - return threads; - -out_free_threads: - free(threads); - threads = NULL; - goto out; -} - -struct thread_map *thread_map__new_str(const char *pid, const char *tid, - uid_t uid) -{ - if (pid) - return thread_map__new_by_pid_str(pid); - - if (!tid && uid != UINT_MAX) - return thread_map__new_by_uid(uid); - - return thread_map__new_by_tid_str(tid); -} - void thread_map__delete(struct thread_map *threads) { free(threads); diff --git a/trunk/tools/perf/util/thread_map.h b/trunk/tools/perf/util/thread_map.h index 7da80f14418b..c75ddbaba005 100644 --- a/trunk/tools/perf/util/thread_map.h +++ b/trunk/tools/perf/util/thread_map.h @@ -13,10 +13,6 @@ struct thread_map *thread_map__new_by_pid(pid_t pid); struct thread_map *thread_map__new_by_tid(pid_t tid); struct thread_map *thread_map__new_by_uid(uid_t uid); struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid); - -struct thread_map *thread_map__new_str(const char *pid, - const char *tid, uid_t uid); - void thread_map__delete(struct thread_map *threads); size_t thread_map__fprintf(struct thread_map *threads, FILE *fp); diff --git a/trunk/tools/perf/util/top.c b/trunk/tools/perf/util/top.c index 09fe579ccafb..e4370ca27193 100644 --- a/trunk/tools/perf/util/top.c +++ b/trunk/tools/perf/util/top.c @@ -69,11 +69,11 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) ret += SNPRINTF(bf + ret, size - ret, "], "); - if (top->target_pid) - ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s", + if (top->target_pid != -1) + ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %d", top->target_pid); - else if (top->target_tid) - ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s", + else if (top->target_tid != -1) + ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %d", top->target_tid); else if (top->uid_str != NULL) ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", @@ -85,7 +85,7 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", top->evlist->cpus->nr > 1 ? "s" : "", top->cpu_list); else { - if (top->target_tid) + if (top->target_tid != -1) ret += SNPRINTF(bf + ret, size - ret, ")"); else ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", diff --git a/trunk/tools/perf/util/top.h b/trunk/tools/perf/util/top.h index ce61cb2d1acf..def3e53e0fe0 100644 --- a/trunk/tools/perf/util/top.h +++ b/trunk/tools/perf/util/top.h @@ -23,7 +23,7 @@ struct perf_top { u64 guest_us_samples, guest_kernel_samples; int print_entries, count_filter, delay_secs; int freq; - const char *target_pid, *target_tid; + pid_t target_pid, target_tid; uid_t uid; bool hide_kernel_symbols, hide_user_symbols, zero; bool system_wide; @@ -34,8 +34,7 @@ struct perf_top { bool vmlinux_warned; bool inherit; bool group; - bool sample_id_all_missing; - bool exclude_guest_missing; + bool sample_id_all_avail; bool dump_symtab; const char *cpu_list; struct hist_entry *sym_filter_entry; diff --git a/trunk/tools/perf/util/usage.c b/trunk/tools/perf/util/usage.c index 52bb07c6442a..d0c013934f30 100644 --- a/trunk/tools/perf/util/usage.c +++ b/trunk/tools/perf/util/usage.c @@ -83,7 +83,7 @@ void warning(const char *warn, ...) va_end(params); } -uid_t parse_target_uid(const char *str, const char *tid, const char *pid) +uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid) { struct passwd pwd, *result; char buf[1024]; @@ -91,8 +91,8 @@ uid_t parse_target_uid(const char *str, const char *tid, const char *pid) if (str == NULL) return UINT_MAX; - /* UID and PID are mutually exclusive */ - if (tid || pid) { + /* CPU and PID are mutually exclusive */ + if (tid > 0 || pid > 0) { ui__warning("PID/TID switch overriding UID\n"); sleep(1); return UINT_MAX; diff --git a/trunk/tools/perf/util/util.c b/trunk/tools/perf/util/util.c index 8109a907841e..813141047fc2 100644 --- a/trunk/tools/perf/util/util.c +++ b/trunk/tools/perf/util/util.c @@ -6,7 +6,7 @@ * XXX We need to find a better place for these things... */ bool perf_host = true; -bool perf_guest = false; +bool perf_guest = true; void event_attr_init(struct perf_event_attr *attr) { @@ -14,8 +14,6 @@ void event_attr_init(struct perf_event_attr *attr) attr->exclude_host = 1; if (!perf_guest) attr->exclude_guest = 1; - /* to capture ABI version */ - attr->size = sizeof(*attr); } int mkdir_p(char *path, mode_t mode) diff --git a/trunk/tools/perf/util/util.h b/trunk/tools/perf/util/util.h index 0f99f394d8e0..232d17ef3e60 100644 --- a/trunk/tools/perf/util/util.h +++ b/trunk/tools/perf/util/util.h @@ -199,8 +199,6 @@ static inline int has_extension(const char *filename, const char *ext) #undef isalpha #undef isprint #undef isalnum -#undef islower -#undef isupper #undef tolower #undef toupper @@ -221,8 +219,6 @@ extern unsigned char sane_ctype[256]; #define isalpha(x) sane_istest(x,GIT_ALPHA) #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) #define isprint(x) sane_istest(x,GIT_PRINT) -#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20)) -#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20)) #define tolower(x) sane_case((unsigned char)(x), 0x20) #define toupper(x) sane_case((unsigned char)(x), 0) @@ -249,7 +245,7 @@ struct perf_event_attr; void event_attr_init(struct perf_event_attr *attr); -uid_t parse_target_uid(const char *str, const char *tid, const char *pid); +uid_t parse_target_uid(const char *str, pid_t tid, pid_t pid); #define _STR(x) #x #define STR(x) _STR(x)