From e2911921a83ba073ab06dbd634bbbb9d84f7dec0 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Fri, 29 Apr 2011 11:26:22 +0200 Subject: [PATCH] --- yaml --- r: 251861 b: refs/heads/master c: 90d231f7673e20acc4f8b5c3effb5c12098179a7 h: refs/heads/master i: 251859: 8233d9c7d0940c0034f660d637cf288ca4cade8b v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/genericirq.tmpl | 82 ++-- trunk/Makefile | 2 +- trunk/arch/alpha/include/asm/unistd.h | 6 +- trunk/arch/alpha/kernel/systbls.S | 12 +- trunk/arch/alpha/kernel/time.c | 3 +- trunk/arch/arm/configs/omap2plus_defconfig | 83 +++- trunk/arch/arm/mach-omap2/Kconfig | 1 - trunk/arch/arm/mach-omap2/Makefile | 4 +- trunk/arch/arm/mach-omap2/board-2430sdp.c | 27 +- trunk/arch/arm/mach-omap2/board-3430sdp.c | 151 ++++-- trunk/arch/arm/mach-omap2/board-4430sdp.c | 114 ++++- trunk/arch/arm/mach-omap2/board-am3517crane.c | 10 +- trunk/arch/arm/mach-omap2/board-am3517evm.c | 56 ++- trunk/arch/arm/mach-omap2/board-apollon.c | 29 +- trunk/arch/arm/mach-omap2/board-cm-t35.c | 236 +++++++-- trunk/arch/arm/mach-omap2/board-cm-t3517.c | 9 +- trunk/arch/arm/mach-omap2/board-devkit8000.c | 131 ++++- trunk/arch/arm/mach-omap2/board-igep0020.c | 449 +++++++++-------- trunk/arch/arm/mach-omap2/board-igep0030.c | 458 ++++++++++++++++++ trunk/arch/arm/mach-omap2/board-ldp.c | 138 +++++- trunk/arch/arm/mach-omap2/board-n8x0.c | 28 +- trunk/arch/arm/mach-omap2/board-omap3beagle.c | 194 ++++++-- trunk/arch/arm/mach-omap2/board-omap3evm.c | 242 +++++++-- trunk/arch/arm/mach-omap2/board-omap3logic.c | 14 +- .../arch/arm/mach-omap2/board-omap3pandora.c | 90 +++- .../arch/arm/mach-omap2/board-omap3stalker.c | 133 ++++- .../arm/mach-omap2/board-omap3touchbook.c | 121 ++++- trunk/arch/arm/mach-omap2/board-omap4panda.c | 79 ++- trunk/arch/arm/mach-omap2/board-overo.c | 265 ++++++++-- trunk/arch/arm/mach-omap2/board-rm680.c | 21 +- .../arm/mach-omap2/board-rx51-peripherals.c | 42 +- trunk/arch/arm/mach-omap2/board-rx51-video.c | 5 +- .../arm/mach-omap2/board-zoom-debugboard.c | 65 ++- .../arch/arm/mach-omap2/board-zoom-display.c | 31 +- .../arm/mach-omap2/board-zoom-peripherals.c | 29 +- .../arm/mach-omap2/common-board-devices.c | 163 ------- .../arm/mach-omap2/common-board-devices.h | 35 -- trunk/arch/arm/mach-omap2/gpmc-smc91x.c | 11 +- trunk/arch/arm/mach-omap2/gpmc-smsc911x.c | 44 +- trunk/arch/arm/mach-omap2/irq.c | 97 +++- trunk/arch/arm/mach-omap2/omap_l3_noc.c | 51 +- trunk/arch/arm/mach-omap2/omap_l3_smx.c | 42 +- trunk/arch/arm/mach-omap2/omap_phy_internal.c | 9 +- trunk/arch/arm/mach-omap2/pm44xx.c | 2 + trunk/arch/arm/mach-omap2/smartreflex.c | 23 +- trunk/arch/arm/mach-omap2/usb-musb.c | 22 +- trunk/arch/arm/mach-omap2/usb-tusb6010.c | 3 +- trunk/arch/arm/mach-omap2/voltage.c | 1 + .../plat-omap/include/plat/gpmc-smsc911x.h | 4 +- .../arm/plat-omap/include/plat/uncompress.h | 1 + trunk/arch/arm/plat-omap/include/plat/usb.h | 2 +- trunk/arch/mips/ar7/gpio.c | 4 +- trunk/arch/mips/include/asm/dma-mapping.h | 2 + trunk/arch/mips/kernel/traps.c | 6 +- trunk/arch/mips/rb532/gpio.c | 2 +- trunk/arch/powerpc/platforms/83xx/suspend.c | 7 +- trunk/arch/powerpc/sysdev/fsl_msi.c | 7 +- trunk/arch/sparc/kernel/apc.c | 2 +- trunk/arch/sparc/kernel/pci_sabre.c | 5 +- trunk/arch/sparc/kernel/pci_schizo.c | 8 +- trunk/arch/sparc/kernel/pmc.c | 2 +- trunk/arch/sparc/kernel/smp_32.c | 10 +- trunk/arch/sparc/kernel/time_32.c | 2 +- trunk/arch/sparc/lib/checksum_32.S | 12 +- trunk/arch/um/os-Linux/util.c | 23 +- trunk/arch/x86/include/asm/apicdef.h | 1 + trunk/arch/x86/include/asm/pgtable_types.h | 1 + trunk/arch/x86/include/asm/uv/uv_bau.h | 17 +- trunk/arch/x86/include/asm/uv/uv_hub.h | 2 + trunk/arch/x86/include/asm/uv/uv_mmrs.h | 16 +- trunk/arch/x86/include/asm/x86_init.h | 12 + trunk/arch/x86/kernel/apic/x2apic_uv_x.c | 48 +- trunk/arch/x86/kernel/cpu/amd.c | 4 +- trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c | 1 + .../arch/x86/kernel/cpu/mcheck/therm_throt.c | 12 +- trunk/arch/x86/kernel/kprobes.c | 5 +- trunk/arch/x86/kernel/x86_init.c | 4 + trunk/arch/x86/mm/init.c | 24 +- trunk/arch/x86/platform/uv/tlb_uv.c | 92 ++-- trunk/arch/x86/xen/mmu.c | 138 +----- trunk/block/blk-cgroup.c | 7 + trunk/block/blk-cgroup.h | 3 + trunk/block/blk-core.c | 4 +- trunk/block/blk-throttle.c | 9 +- trunk/block/cfq-iosched.c | 11 +- trunk/drivers/ata/libahci.c | 21 - trunk/drivers/ata/libata-eh.c | 2 +- trunk/drivers/atm/fore200e.c | 7 +- trunk/drivers/block/DAC960.c | 1 - trunk/drivers/block/amiflop.c | 1 - trunk/drivers/block/ataflop.c | 1 - trunk/drivers/block/floppy.c | 1 - trunk/drivers/block/paride/pcd.c | 1 - trunk/drivers/block/paride/pd.c | 1 - trunk/drivers/block/paride/pf.c | 1 - trunk/drivers/block/rbd.c | 177 ++++++- trunk/drivers/block/swim.c | 1 - trunk/drivers/block/swim3.c | 1 - trunk/drivers/block/ub.c | 1 - trunk/drivers/block/xsysace.c | 1 - trunk/drivers/cdrom/cdrom.c | 6 +- trunk/drivers/cdrom/gdrom.c | 1 - trunk/drivers/cdrom/viocd.c | 1 - trunk/drivers/char/hw_random/n2-drv.c | 7 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 7 +- .../char/xilinx_hwicap/xilinx_hwicap.c | 14 +- trunk/drivers/edac/ppc4xx_edac.c | 2 +- trunk/drivers/gpu/drm/drm_fb_helper.c | 26 +- trunk/drivers/gpu/drm/i915/i915_drv.c | 2 +- trunk/drivers/gpu/drm/i915/intel_display.c | 2 + trunk/drivers/gpu/drm/radeon/evergreen.c | 5 +- trunk/drivers/gpu/drm/radeon/evergreend.h | 1 + .../drivers/gpu/drm/radeon/radeon_atombios.c | 14 +- trunk/drivers/gpu/drm/radeon/reg_srcs/cayman | 1 + .../drivers/gpu/drm/radeon/reg_srcs/evergreen | 1 + trunk/drivers/gpu/vga/vga_switcheroo.c | 6 +- trunk/drivers/i2c/busses/i2c-mpc.c | 9 +- trunk/drivers/i2c/busses/i2c-pnx.c | 2 +- trunk/drivers/input/touchscreen/ads7846.c | 13 +- trunk/drivers/leds/leds-lm3530.c | 1 + trunk/drivers/media/video/cx88/cx88-input.c | 2 +- trunk/drivers/media/video/soc_camera.c | 48 +- trunk/drivers/media/video/v4l2-device.c | 5 +- trunk/drivers/media/video/v4l2-subdev.c | 14 +- trunk/drivers/message/i2o/i2o_block.c | 1 - trunk/drivers/mmc/core/host.c | 9 +- trunk/drivers/mmc/host/sdhci-of-core.c | 7 +- trunk/drivers/mtd/maps/physmap_of.c | 7 +- trunk/drivers/net/Makefile | 6 +- trunk/drivers/net/bonding/bond_3ad.h | 10 +- trunk/drivers/net/can/mscan/mpc5xxx_can.c | 7 +- trunk/drivers/net/ehea/ehea_main.c | 6 +- trunk/drivers/net/fs_enet/fs_enet-main.c | 9 +- trunk/drivers/net/fs_enet/mii-fec.c | 7 +- trunk/drivers/net/hydra.c | 14 +- trunk/drivers/net/ne-h8300.c | 16 +- trunk/drivers/net/sfc/mcdi.c | 49 +- trunk/drivers/net/sfc/nic.c | 7 + trunk/drivers/net/sfc/nic.h | 2 + trunk/drivers/net/sfc/siena.c | 25 +- trunk/drivers/net/sunhme.c | 7 +- trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c | 3 + trunk/drivers/net/wireless/ath/ath9k/main.c | 8 + .../drivers/net/wireless/iwlegacy/iwl-core.c | 7 + trunk/drivers/net/wireless/iwlegacy/iwl-dev.h | 6 + trunk/drivers/net/wireless/libertas/cmd.c | 6 +- trunk/drivers/net/zorro8390.c | 12 +- trunk/drivers/pci/setup-bus.c | 4 +- trunk/drivers/rapidio/switches/idt_gen2.c | 9 + trunk/drivers/rapidio/switches/idtcps.c | 6 + trunk/drivers/rapidio/switches/tsi57x.c | 6 + trunk/drivers/rtc/rtc-davinci.c | 5 +- trunk/drivers/rtc/rtc-ds1286.c | 2 +- trunk/drivers/rtc/rtc-ep93xx.c | 5 +- trunk/drivers/rtc/rtc-m41t80.c | 5 +- trunk/drivers/rtc/rtc-max8925.c | 5 +- trunk/drivers/rtc/rtc-max8998.c | 5 +- trunk/drivers/rtc/rtc-mc13xxx.c | 8 +- trunk/drivers/rtc/rtc-msm6242.c | 3 +- trunk/drivers/rtc/rtc-mxc.c | 19 +- trunk/drivers/rtc/rtc-pcap.c | 4 +- trunk/drivers/rtc/rtc-rp5c01.c | 5 +- trunk/drivers/s390/char/tape_block.c | 1 - trunk/drivers/scsi/qlogicpti.c | 7 +- trunk/drivers/scsi/scsi_lib.c | 20 +- trunk/drivers/scsi/scsi_scan.c | 2 + trunk/drivers/tty/serial/of_serial.c | 7 +- trunk/drivers/usb/gadget/fsl_qe_udc.c | 7 +- trunk/drivers/video/fbmem.c | 223 ++++++--- trunk/drivers/video/omap/Makefile | 1 + trunk/drivers/video/omap/lcd_omap2evm.c | 192 ++++++++ trunk/drivers/watchdog/mpc8xxx_wdt.c | 7 +- trunk/fs/block_dev.c | 27 +- trunk/fs/btrfs/acl.c | 5 +- trunk/fs/btrfs/extent-tree.c | 37 +- trunk/fs/btrfs/ioctl.c | 24 +- trunk/fs/cifs/cifs_unicode.c | 14 +- trunk/fs/cifs/connect.c | 5 + trunk/fs/configfs/dir.c | 39 +- trunk/fs/fuse/dir.c | 2 +- trunk/fs/namei.c | 2 +- trunk/fs/nfs/nfs4filelayout.c | 27 +- trunk/fs/nfs/nfs4filelayout.h | 2 +- trunk/fs/nfs/nfs4filelayoutdev.c | 34 +- trunk/fs/nfs/nfs4proc.c | 6 + trunk/fs/nfs/pnfs.c | 34 +- trunk/fs/nfs/pnfs.h | 6 +- trunk/fs/nfs/read.c | 4 +- trunk/fs/nfs/write.c | 4 +- trunk/fs/ocfs2/cluster/heartbeat.c | 61 ++- trunk/fs/ocfs2/dir.c | 2 +- trunk/fs/ocfs2/dlm/dlmdomain.c | 3 +- trunk/fs/ocfs2/dlm/dlmmaster.c | 3 + trunk/fs/ocfs2/file.c | 12 + trunk/fs/ocfs2/journal.c | 3 + trunk/include/drm/drm_fb_helper.h | 2 +- trunk/include/linux/capability.h | 13 +- trunk/include/linux/cred.h | 10 +- trunk/include/linux/device.h | 1 - trunk/include/linux/fb.h | 1 + trunk/include/linux/fs.h | 1 - trunk/include/linux/irq.h | 179 +------ trunk/include/linux/irqdesc.h | 6 +- trunk/include/linux/mmc/host.h | 1 + trunk/include/linux/nfs_xdr.h | 1 + trunk/include/linux/of_device.h | 8 +- trunk/include/linux/proc_fs.h | 2 + trunk/include/net/inet_ecn.h | 16 +- trunk/include/net/llc_pdu.h | 8 +- trunk/include/scsi/scsi_device.h | 1 + trunk/kernel/capability.c | 12 + trunk/kernel/cred.c | 12 +- trunk/kernel/irq/Makefile | 1 - trunk/kernel/irq/chip.c | 1 - trunk/kernel/irq/debug.h | 1 - trunk/kernel/irq/generic-chip.c | 354 -------------- trunk/kernel/irq/manage.c | 3 +- trunk/kernel/irq/settings.h | 17 - trunk/kernel/time/clocksource.c | 4 +- trunk/kernel/time/tick-broadcast.c | 12 +- trunk/lib/vsprintf.c | 2 +- trunk/mm/page_alloc.c | 1 + trunk/mm/shmem.c | 10 +- trunk/mm/vmscan.c | 2 +- trunk/net/9p/protocol.c | 1 + trunk/net/bridge/br_netfilter.c | 2 +- trunk/net/core/dev.c | 22 +- trunk/net/mac80211/tx.c | 4 + trunk/net/netfilter/ipvs/ip_vs_app.c | 2 +- trunk/net/netfilter/ipvs/ip_vs_conn.c | 4 +- trunk/net/netfilter/ipvs/ip_vs_ctl.c | 6 +- trunk/security/selinux/ss/policydb.c | 4 - trunk/sound/soc/codecs/ssm2602.c | 10 +- trunk/sound/soc/codecs/uda134x.c | 2 - trunk/sound/soc/codecs/wm8903.c | 2 +- trunk/sound/soc/jz4740/jz4740-i2s.c | 2 +- trunk/sound/soc/mid-x86/sst_platform.c | 6 + trunk/sound/soc/omap/Kconfig | 8 + trunk/sound/soc/omap/Makefile | 1 + trunk/sound/soc/omap/omap2evm.c | 139 ++++++ trunk/sound/soc/soc-core.c | 2 + trunk/tools/perf/builtin-record.c | 2 +- trunk/tools/perf/builtin-test.c | 2 +- trunk/tools/perf/builtin-top.c | 8 +- trunk/tools/perf/util/evlist.c | 153 ++++-- trunk/tools/perf/util/evlist.h | 3 +- trunk/tools/perf/util/python.c | 2 +- 248 files changed, 4658 insertions(+), 2339 deletions(-) create mode 100644 trunk/arch/arm/mach-omap2/board-igep0030.c delete mode 100644 trunk/arch/arm/mach-omap2/common-board-devices.c delete mode 100644 trunk/arch/arm/mach-omap2/common-board-devices.h create mode 100644 trunk/drivers/video/omap/lcd_omap2evm.c delete mode 100644 trunk/kernel/irq/generic-chip.c create mode 100644 trunk/sound/soc/omap/omap2evm.c diff --git a/[refs] b/[refs] index 3803cbd34140..bbca6defdec9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b7679ab3f70482ff4b75a8c735c8224ebedb6020 +refs/heads/master: 90d231f7673e20acc4f8b5c3effb5c12098179a7 diff --git a/trunk/Documentation/DocBook/genericirq.tmpl b/trunk/Documentation/DocBook/genericirq.tmpl index b3422341d65c..fb10fd08c05c 100644 --- a/trunk/Documentation/DocBook/genericirq.tmpl +++ b/trunk/Documentation/DocBook/genericirq.tmpl @@ -191,8 +191,8 @@ Whenever an interrupt triggers, the lowlevel arch code calls into the generic interrupt code by calling desc->handle_irq(). - This highlevel IRQ handling function only uses desc->irq_data.chip - primitives referenced by the assigned chip descriptor structure. + This highlevel IRQ handling function only uses desc->chip primitives + referenced by the assigned chip descriptor structure. @@ -206,11 +206,11 @@ enable_irq() disable_irq_nosync() (SMP only) synchronize_irq() (SMP only) - irq_set_irq_type() - irq_set_irq_wake() - irq_set_handler_data() - irq_set_chip() - irq_set_chip_data() + set_irq_type() + set_irq_wake() + set_irq_data() + set_irq_chip() + set_irq_chip_data() See the autogenerated function documentation for details. @@ -225,8 +225,6 @@ handle_fasteoi_irq handle_simple_irq handle_percpu_irq - handle_edge_eoi_irq - handle_bad_irq The interrupt flow handlers (either predefined or architecture specific) are assigned to specific interrupts by the architecture @@ -243,13 +241,13 @@ default_enable(struct irq_data *data) { - desc->irq_data.chip->irq_unmask(data); + desc->chip->irq_unmask(data); } default_disable(struct irq_data *data) { if (!delay_disable(data)) - desc->irq_data.chip->irq_mask(data); + desc->chip->irq_mask(data); } default_ack(struct irq_data *data) @@ -286,9 +284,9 @@ noop(struct irq_data *data)) The following control flow is implemented (simplified excerpt): -desc->irq_data.chip->irq_mask_ack(); -handle_irq_event(desc->action); -desc->irq_data.chip->irq_unmask(); +desc->chip->irq_mask(); +handle_IRQ_event(desc->action); +desc->chip->irq_unmask(); @@ -302,8 +300,8 @@ desc->irq_data.chip->irq_unmask(); The following control flow is implemented (simplified excerpt): -handle_irq_event(desc->action); -desc->irq_data.chip->irq_eoi(); +handle_IRQ_event(desc->action); +desc->chip->irq_eoi(); @@ -317,17 +315,17 @@ desc->irq_data.chip->irq_eoi(); The following control flow is implemented (simplified excerpt): if (desc->status & running) { - desc->irq_data.chip->irq_mask_ack(); + desc->chip->irq_mask(); desc->status |= pending | masked; return; } -desc->irq_data.chip->irq_ack(); +desc->chip->irq_ack(); desc->status |= running; do { if (desc->status & masked) - desc->irq_data.chip->irq_unmask(); + desc->chip->irq_unmask(); desc->status &= ~pending; - handle_irq_event(desc->action); + handle_IRQ_event(desc->action); } while (status & pending); desc->status &= ~running; @@ -346,7 +344,7 @@ desc->status &= ~running; The following control flow is implemented (simplified excerpt): -handle_irq_event(desc->action); +handle_IRQ_event(desc->action); @@ -364,29 +362,12 @@ handle_irq_event(desc->action); The following control flow is implemented (simplified excerpt): -if (desc->irq_data.chip->irq_ack) - desc->irq_data.chip->irq_ack(); -handle_irq_event(desc->action); -if (desc->irq_data.chip->irq_eoi) - desc->irq_data.chip->irq_eoi(); +handle_IRQ_event(desc->action); +if (desc->chip->irq_eoi) + desc->chip->irq_eoi(); - - EOI Edge IRQ flow handler - - handle_edge_eoi_irq provides an abnomination of the edge - handler which is solely used to tame a badly wreckaged - irq controller on powerpc/cell. - - - - Bad IRQ flow handler - - handle_bad_irq is used for spurious interrupts which - have no real handler assigned.. - - Quirks and optimizations @@ -429,7 +410,6 @@ if (desc->irq_data.chip->irq_eoi) irq_mask_ack() - Optional, recommended for performance irq_mask() irq_unmask() - irq_eoi() - Optional, required for eoi flow handlers irq_retrigger() - Optional irq_set_type() - Optional irq_set_wake() - Optional @@ -444,24 +424,32 @@ if (desc->irq_data.chip->irq_eoi) __do_IRQ entry point - The original implementation __do_IRQ() was an alternative entry - point for all types of interrupts. It not longer exists. + The original implementation __do_IRQ() is an alternative entry + point for all types of interrupts. This handler turned out to be not suitable for all interrupt hardware and was therefore reimplemented with split - functionality for edge/level/simple/percpu interrupts. This is not + functionality for egde/level/simple/percpu interrupts. This is not only a functional optimization. It also shortens code paths for interrupts. + + To make use of the split implementation, replace the call to + __do_IRQ by a call to desc->handle_irq() and associate + the appropriate handler function to desc->handle_irq(). + In most cases the generic handler implementations should + be sufficient. + Locking on SMP The locking of chip registers is up to the architecture that - defines the chip primitives. The per-irq structure is - protected via desc->lock, by the generic layer. + defines the chip primitives. There is a chip->lock field that can be used + for serialization, but the generic layer does not touch it. The per-irq + structure is protected via desc->lock, by the generic layer. diff --git a/trunk/Makefile b/trunk/Makefile index 41ea6fbec55a..123d858dae03 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 39 -EXTRAVERSION = -rc7 +EXTRAVERSION = NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/alpha/include/asm/unistd.h b/trunk/arch/alpha/include/asm/unistd.h index 058937bf5a77..b1834166922d 100644 --- a/trunk/arch/alpha/include/asm/unistd.h +++ b/trunk/arch/alpha/include/asm/unistd.h @@ -452,10 +452,14 @@ #define __NR_fanotify_init 494 #define __NR_fanotify_mark 495 #define __NR_prlimit64 496 +#define __NR_name_to_handle_at 497 +#define __NR_open_by_handle_at 498 +#define __NR_clock_adjtime 499 +#define __NR_syncfs 500 #ifdef __KERNEL__ -#define NR_SYSCALLS 497 +#define NR_SYSCALLS 501 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/arch/alpha/kernel/systbls.S b/trunk/arch/alpha/kernel/systbls.S index a6a1de9db16f..15f999d41c75 100644 --- a/trunk/arch/alpha/kernel/systbls.S +++ b/trunk/arch/alpha/kernel/systbls.S @@ -498,23 +498,27 @@ sys_call_table: .quad sys_ni_syscall /* sys_timerfd */ .quad sys_eventfd .quad sys_recvmmsg - .quad sys_fallocate /* 480 */ + .quad sys_fallocate /* 480 */ .quad sys_timerfd_create .quad sys_timerfd_settime .quad sys_timerfd_gettime .quad sys_signalfd4 - .quad sys_eventfd2 /* 485 */ + .quad sys_eventfd2 /* 485 */ .quad sys_epoll_create1 .quad sys_dup3 .quad sys_pipe2 .quad sys_inotify_init1 - .quad sys_preadv /* 490 */ + .quad sys_preadv /* 490 */ .quad sys_pwritev .quad sys_rt_tgsigqueueinfo .quad sys_perf_event_open .quad sys_fanotify_init - .quad sys_fanotify_mark /* 495 */ + .quad sys_fanotify_mark /* 495 */ .quad sys_prlimit64 + .quad sys_name_to_handle_at + .quad sys_open_by_handle_at + .quad sys_clock_adjtime + .quad sys_syncfs /* 500 */ .size sys_call_table, . - sys_call_table .type sys_call_table, @object diff --git a/trunk/arch/alpha/kernel/time.c b/trunk/arch/alpha/kernel/time.c index 918e8e0b72ff..818e74ed45dc 100644 --- a/trunk/arch/alpha/kernel/time.c +++ b/trunk/arch/alpha/kernel/time.c @@ -375,8 +375,7 @@ static struct clocksource clocksource_rpcc = { static inline void register_rpcc_clocksource(long cycle_freq) { - clocksource_calc_mult_shift(&clocksource_rpcc, cycle_freq, 4); - clocksource_register(&clocksource_rpcc); + clocksource_register_hz(&clocksource_rpcc, cycle_freq); } #else /* !CONFIG_SMP */ static inline void register_rpcc_clocksource(long cycle_freq) diff --git a/trunk/arch/arm/configs/omap2plus_defconfig b/trunk/arch/arm/configs/omap2plus_defconfig index d5f00d7eb075..076db52ff672 100644 --- a/trunk/arch/arm/configs/omap2plus_defconfig +++ b/trunk/arch/arm/configs/omap2plus_defconfig @@ -21,22 +21,58 @@ CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_OMAP=y +CONFIG_ARCH_OMAP2=y +CONFIG_ARCH_OMAP3=y +CONFIG_ARCH_OMAP4=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y +CONFIG_OMAP_32K_TIMER=y +CONFIG_MACH_OMAP_GENERIC=y +CONFIG_ARCH_OMAP2420=y +CONFIG_ARCH_OMAP2430=y +CONFIG_ARCH_OMAP3430=y +CONFIG_MACH_OMAP_H4=y +CONFIG_MACH_OMAP_APOLLON=y +CONFIG_MACH_OMAP_2430SDP=y +CONFIG_MACH_OMAP3_BEAGLE=y +CONFIG_MACH_DEVKIT8000=y +CONFIG_MACH_OMAP_LDP=y +CONFIG_MACH_OVERO=y +CONFIG_MACH_OMAP3EVM=y +CONFIG_MACH_OMAP3517EVM=y +CONFIG_MACH_OMAP3_PANDORA=y +CONFIG_MACH_OMAP3_TOUCHBOOK=y +CONFIG_MACH_OMAP_3430SDP=y +CONFIG_MACH_NOKIA_N8X0=y +CONFIG_MACH_NOKIA_RX51=y +CONFIG_MACH_OMAP_ZOOM2=y +CONFIG_MACH_OMAP_ZOOM3=y +CONFIG_MACH_CM_T35=y +CONFIG_MACH_IGEP0020=y +CONFIG_MACH_SBC3530=y +CONFIG_MACH_OMAP_3630SDP=y +CONFIG_MACH_OMAP_4430SDP=y CONFIG_ARM_THUMBEE=y +CONFIG_ARM_L1_CACHE_SHIFT=5 CONFIG_ARM_ERRATA_411920=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 +# CONFIG_LOCAL_TIMERS is not set +CONFIG_AEABI=y CONFIG_LEDS=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200" CONFIG_KEXEC=y CONFIG_FPE_NWFPE=y +CONFIG_VFP=y +CONFIG_NEON=y CONFIG_BINFMT_MISC=y +CONFIG_PM=y CONFIG_PM_DEBUG=y +CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -53,6 +89,14 @@ CONFIG_IP_PNP_RARP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_BT=m +CONFIG_BT_L2CAP=m +CONFIG_BT_SCO=m +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y @@ -63,9 +107,11 @@ CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y +CONFIG_MTD_CONCAT=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y @@ -81,6 +127,7 @@ CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_EEPROM_LEGACY=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y @@ -111,15 +158,19 @@ CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_INPUT_MISC=y CONFIG_INPUT_TWL4030_PWRBUTTON=y CONFIG_VT_HW_CONSOLE_BINDING=y -# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y +# CONFIG_LEGACY_PTYS is not set CONFIG_HW_RANDOM=y +CONFIG_I2C=y CONFIG_I2C_CHARDEV=y +CONFIG_I2C_OMAP=y CONFIG_SPI=y CONFIG_SPI_OMAP24XX=y CONFIG_DEBUG_GPIO=y @@ -130,6 +181,10 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y +CONFIG_MENELAUS=y +CONFIG_TWL4030_CORE=y +CONFIG_TWL4030_POWER=y +CONFIG_REGULATOR=y CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y @@ -153,6 +208,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y CONFIG_DISPLAY_SUPPORT=y +# CONFIG_VGA_CONSOLE is not set CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -161,20 +217,25 @@ CONFIG_FONT_8x16=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y CONFIG_SND_VERBOSE_PRINTK=y CONFIG_SND_DEBUG=y -CONFIG_SND_USB_AUDIO=m -CONFIG_SND_SOC=m -CONFIG_SND_OMAP_SOC=m -CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_OMAP_SOC=y +CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG_WHITELIST is not set CONFIG_USB_MON=y +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_MUSB_OTG is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +CONFIG_USB_MUSB_DEBUG=y CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y CONFIG_USB_LIBUSUAL=y @@ -189,12 +250,18 @@ CONFIG_MMC_UNSAFE_RESUME=y CONFIG_SDIO_UART=y CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_TWL92330=y CONFIG_RTC_DRV_TWL4030=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set +CONFIG_INOTIFY=y CONFIG_QUOTA=y CONFIG_QFMT_V2=y CONFIG_MSDOS_FS=y @@ -218,10 +285,12 @@ CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y +# CONFIG_LOCK_STAT is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index 19d5891c48e3..b997a35830fc 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -288,7 +288,6 @@ config MACH_IGEP0030 depends on ARCH_OMAP3 default y select OMAP_PACKAGE_CBB - select MACH_IGEP0020 config MACH_SBC3530 bool "OMAP3 SBC STALKER board" diff --git a/trunk/arch/arm/mach-omap2/Makefile b/trunk/arch/arm/mach-omap2/Makefile index f082f7d65760..512b15204450 100644 --- a/trunk/arch/arm/mach-omap2/Makefile +++ b/trunk/arch/arm/mach-omap2/Makefile @@ -229,6 +229,8 @@ obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \ hsmmc.o +obj-$(CONFIG_MACH_IGEP0030) += board-igep0030.o \ + hsmmc.o obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ @@ -268,5 +270,3 @@ obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o disp-$(CONFIG_OMAP2_DSS) := display.o obj-y += $(disp-m) $(disp-y) - -obj-y += common-board-devices.o diff --git a/trunk/arch/arm/mach-omap2/board-2430sdp.c b/trunk/arch/arm/mach-omap2/board-2430sdp.c index d54969be0a54..1fa6bb896f41 100644 --- a/trunk/arch/arm/mach-omap2/board-2430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-2430sdp.c @@ -41,7 +41,6 @@ #include "mux.h" #include "hsmmc.h" -#include "common-board-devices.h" #define SDP2430_CS0_BASE 0x04000000 #define SECONDARY_LCD_GPIO 147 @@ -181,6 +180,15 @@ static struct twl4030_platform_data sdp2430_twldata = { .vmmc1 = &sdp2430_vmmc1, }; +static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_24XX_SYS_NIRQ, + .platform_data = &sdp2430_twldata, + }, +}; + static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = { { I2C_BOARD_INFO("isp1301_omap", 0x2D), @@ -193,7 +201,8 @@ static int __init omap2430_i2c_init(void) { omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo, ARRAY_SIZE(sdp2430_i2c1_boardinfo)); - omap2_pmic_init("twl4030", &sdp2430_twldata); + omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo, + ARRAY_SIZE(sdp2430_i2c_boardinfo)); return 0; } @@ -208,6 +217,11 @@ static struct omap2_hsmmc_info mmc[] __initdata = { {} /* Terminator */ }; +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; static struct omap_usb_config sdp2430_usb_config __initdata = { .otg = 1, #ifdef CONFIG_USB_GADGET_OMAP @@ -226,6 +240,8 @@ static struct omap_board_mux board_mux[] __initdata = { static void __init omap_2430sdp_init(void) { + int ret; + omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC); omap_board_config = sdp2430_config; @@ -239,13 +255,14 @@ static void __init omap_2430sdp_init(void) omap2_usbfs_init(&sdp2430_usb_config); omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); board_smc91x_init(); /* Turn off secondary LCD backlight */ - gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW, - "Secondary LCD backlight"); + ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight"); + if (ret == 0) + gpio_direction_output(SECONDARY_LCD_GPIO, 0); } static void __init omap_2430sdp_map_io(void) diff --git a/trunk/arch/arm/mach-omap2/board-3430sdp.c b/trunk/arch/arm/mach-omap2/board-3430sdp.c index 99218a5299ca..7ffad7bfb820 100644 --- a/trunk/arch/arm/mach-omap2/board-3430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-3430sdp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -47,7 +48,6 @@ #include "hsmmc.h" #include "pm.h" #include "control.h" -#include "common-board-devices.h" #define CONFIG_DISABLE_HFCLK 1 @@ -59,24 +59,6 @@ #define TWL4030_MSECURE_GPIO 22 -/* FIXME: These values need to be updated based on more profiling on 3430sdp*/ -static struct cpuidle_params omap3_cpuidle_params_table[] = { - /* C1 */ - {1, 2, 2, 5}, - /* C2 */ - {1, 10, 10, 30}, - /* C3 */ - {1, 50, 50, 300}, - /* C4 */ - {1, 1500, 1800, 4000}, - /* C5 */ - {1, 2500, 7500, 12000}, - /* C6 */ - {1, 3000, 8500, 15000}, - /* C7 */ - {1, 10000, 30000, 300000}, -}; - static uint32_t board_keymap[] = { KEY(0, 0, KEY_LEFT), KEY(0, 1, KEY_RIGHT), @@ -123,14 +105,63 @@ static struct twl4030_keypad_data sdp3430_kp_data = { .rep = 1, }; -#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8 -#define SDP3430_LCD_PANEL_ENABLE_GPIO 5 +static int ts_gpio; /* Needed for ads7846_get_pendown_state */ + +/** + * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq + * + * @return - void. If request gpio fails then Flag KERN_ERR. + */ +static void ads7846_dev_init(void) +{ + if (gpio_request(ts_gpio, "ADS7846 pendown") < 0) { + printk(KERN_ERR "can't get ads746 pen down GPIO\n"); + return; + } -static struct gpio sdp3430_dss_gpios[] __initdata = { - {SDP3430_LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "LCD reset" }, - {SDP3430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD Backlight"}, + gpio_direction_input(ts_gpio); + gpio_set_debounce(ts_gpio, 310); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(ts_gpio); +} + +static struct ads7846_platform_data tsc2046_config __initdata = { + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, + .wakeup = true, }; + +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info sdp3430_spi_board_info[] __initdata = { + [0] = { + /* + * TSC2046 operates at a max freqency of 2MHz, so + * operate slightly below at 1.5MHz + */ + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &tsc2046_mcspi_config, + .irq = 0, + .platform_data = &tsc2046_config, + }, +}; + + +#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8 +#define SDP3430_LCD_PANEL_ENABLE_GPIO 5 + +static unsigned backlight_gpio; +static unsigned enable_gpio; static int lcd_enabled; static int dvi_enabled; @@ -138,11 +169,29 @@ static void __init sdp3430_display_init(void) { int r; - r = gpio_request_array(sdp3430_dss_gpios, - ARRAY_SIZE(sdp3430_dss_gpios)); - if (r) - printk(KERN_ERR "failed to get LCD control GPIOs\n"); + enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO; + backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO; + + r = gpio_request(enable_gpio, "LCD reset"); + if (r) { + printk(KERN_ERR "failed to get LCD reset GPIO\n"); + goto err0; + } + + r = gpio_request(backlight_gpio, "LCD Backlight"); + if (r) { + printk(KERN_ERR "failed to get LCD backlight GPIO\n"); + goto err1; + } + + gpio_direction_output(enable_gpio, 0); + gpio_direction_output(backlight_gpio, 0); + return; +err1: + gpio_free(enable_gpio); +err0: + return; } static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev) @@ -152,8 +201,8 @@ static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev) return -EINVAL; } - gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 1); - gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 1); + gpio_direction_output(enable_gpio, 1); + gpio_direction_output(backlight_gpio, 1); lcd_enabled = 1; @@ -164,8 +213,8 @@ static void sdp3430_panel_disable_lcd(struct omap_dss_device *dssdev) { lcd_enabled = 0; - gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 0); - gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 0); + gpio_direction_output(enable_gpio, 0); + gpio_direction_output(backlight_gpio, 0); } static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev) @@ -293,10 +342,12 @@ static int sdp3430_twl_gpio_setup(struct device *dev, omap2_hsmmc_init(mmc); /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl"); + gpio_request(gpio + 7, "sub_lcd_en_bkl"); + gpio_direction_output(gpio + 7, 0); /* gpio + 15 is "sub_lcd_nRST" (output) */ - gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST"); + gpio_request(gpio + 15, "sub_lcd_nRST"); + gpio_direction_output(gpio + 15, 0); return 0; } @@ -511,10 +562,20 @@ static struct twl4030_platform_data sdp3430_twldata = { .vpll2 = &sdp3430_vpll2, }; +static struct i2c_board_info __initdata sdp3430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &sdp3430_twldata, + }, +}; + static int __init omap3430_i2c_init(void) { /* i2c1 for PMIC only */ - omap3_pmic_init("twl4030", &sdp3430_twldata); + omap_register_i2c_bus(1, 2600, sdp3430_i2c_boardinfo, + ARRAY_SIZE(sdp3430_i2c_boardinfo)); /* i2c2 on camera connector (for sensor control) and optional isp1301 */ omap_register_i2c_bus(2, 400, NULL, 0); /* i2c3 on display connector (for DVI, tfp410) */ @@ -793,23 +854,29 @@ static struct flash_partitions sdp_flash_partitions[] = { }, }; +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void __init omap_3430sdp_init(void) { - int gpio_pendown; - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap_board_config = sdp3430_config; omap_board_config_size = ARRAY_SIZE(sdp3430_config); - omap3_pm_init_cpuidle(omap3_cpuidle_params_table); omap3430_i2c_init(); omap_display_init(&sdp3430_dss_data); if (omap_rev() > OMAP3430_REV_ES1_0) - gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2; + ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; else - gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1; - omap_ads7846_init(1, gpio_pendown, 310, NULL); + ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV1; + sdp3430_spi_board_info[0].irq = gpio_to_irq(ts_gpio); + spi_register_board_info(sdp3430_spi_board_info, + ARRAY_SIZE(sdp3430_spi_board_info)); + ads7846_dev_init(); board_serial_init(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); board_smc91x_init(); board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); sdp3430_display_init(); diff --git a/trunk/arch/arm/mach-omap2/board-4430sdp.c b/trunk/arch/arm/mach-omap2/board-4430sdp.c index ae3153c5396d..56702c5e577f 100644 --- a/trunk/arch/arm/mach-omap2/board-4430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-4430sdp.c @@ -42,7 +42,6 @@ #include "hsmmc.h" #include "timer-gp.h" #include "control.h" -#include "common-board-devices.h" #define ETH_KS8851_IRQ 34 #define ETH_KS8851_POWER_ON 48 @@ -252,22 +251,58 @@ static struct spi_board_info sdp4430_spi_board_info[] __initdata = { }, }; -static struct gpio sdp4430_eth_gpios[] __initdata = { - { ETH_KS8851_POWER_ON, GPIOF_OUT_INIT_HIGH, "eth_power" }, - { ETH_KS8851_QUART, GPIOF_OUT_INIT_HIGH, "quart" }, - { ETH_KS8851_IRQ, GPIOF_IN, "eth_irq" }, -}; - static int omap_ethernet_init(void) { int status; /* Request of GPIO lines */ - status = gpio_request_array(sdp4430_eth_gpios, - ARRAY_SIZE(sdp4430_eth_gpios)); - if (status) - pr_err("Cannot request ETH GPIOs\n"); + status = gpio_request(ETH_KS8851_POWER_ON, "eth_power"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_POWER_ON); + return status; + } + + status = gpio_request(ETH_KS8851_QUART, "quart"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_QUART); + goto error1; + } + + status = gpio_request(ETH_KS8851_IRQ, "eth_irq"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_IRQ); + goto error2; + } + + /* Configuration of requested GPIO lines */ + + status = gpio_direction_output(ETH_KS8851_POWER_ON, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + status = gpio_direction_output(ETH_KS8851_QUART, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_QUART); + goto error3; + } + + status = gpio_direction_input(ETH_KS8851_IRQ); + if (status) { + pr_err("Cannot set input GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + return 0; + +error3: + gpio_free(ETH_KS8851_IRQ); +error2: + gpio_free(ETH_KS8851_QUART); +error1: + gpio_free(ETH_KS8851_POWER_ON); return status; } @@ -540,6 +575,14 @@ static struct twl4030_platform_data sdp4430_twldata = { .usb = &omap4_usbphy_data }; +static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl6030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = OMAP44XX_IRQ_SYS_1N, + .platform_data = &sdp4430_twldata, + }, +}; static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = { { I2C_BOARD_INFO("tmp105", 0x48), @@ -555,7 +598,12 @@ static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = { }; static int __init omap4_i2c_init(void) { - omap4_pmic_init("twl6030", &sdp4430_twldata); + /* + * Phoenix Audio IC needs I2C1 to + * start with 400 KHz or less + */ + omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo, + ARRAY_SIZE(sdp4430_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); @@ -566,13 +614,21 @@ static int __init omap4_i2c_init(void) static void __init omap_sfh7741prox_init(void) { - int error; + int error; - error = gpio_request_one(OMAP4_SFH7741_ENABLE_GPIO, - GPIOF_OUT_INIT_LOW, "sfh7741"); - if (error < 0) + error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741"); + if (error < 0) { pr_err("%s:failed to request GPIO %d, error %d\n", __func__, OMAP4_SFH7741_ENABLE_GPIO, error); + return; + } + + error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0); + if (error < 0) { + pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n", + __func__, OMAP4_SFH7741_ENABLE_GPIO, error); + gpio_free(OMAP4_SFH7741_ENABLE_GPIO); + } } static void sdp4430_hdmi_mux_init(void) @@ -589,19 +645,27 @@ static void sdp4430_hdmi_mux_init(void) OMAP_PIN_INPUT_PULLUP); } -static struct gpio sdp4430_hdmi_gpios[] = { - { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, - { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, -}; - static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) { int status; - status = gpio_request_array(sdp4430_hdmi_gpios, - ARRAY_SIZE(sdp4430_hdmi_gpios)); - if (status) - pr_err("%s: Cannot request HDMI GPIOs\n", __func__); + status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, + "hdmi_gpio_hpd"); + if (status) { + pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD); + return status; + } + status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, + "hdmi_gpio_ls_oe"); + if (status) { + pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE); + goto error1; + } + + return 0; + +error1: + gpio_free(HDMI_GPIO_HPD); return status; } diff --git a/trunk/arch/arm/mach-omap2/board-am3517crane.c b/trunk/arch/arm/mach-omap2/board-am3517crane.c index 5e438a77cd72..a890d244fec6 100644 --- a/trunk/arch/arm/mach-omap2/board-am3517crane.c +++ b/trunk/arch/arm/mach-omap2/board-am3517crane.c @@ -89,13 +89,19 @@ static void __init am3517_crane_init(void) return; } - ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH, - "usb_ehci_enable"); + ret = gpio_request(GPIO_USB_POWER, "usb_ehci_enable"); if (ret < 0) { pr_err("Can not request GPIO %d\n", GPIO_USB_POWER); return; } + ret = gpio_direction_output(GPIO_USB_POWER, 1); + if (ret < 0) { + gpio_free(GPIO_USB_POWER); + pr_err("Unable to initialize EHCI power\n"); + return; + } + usbhs_init(&usbhs_bdata); } diff --git a/trunk/arch/arm/mach-omap2/board-am3517evm.c b/trunk/arch/arm/mach-omap2/board-am3517evm.c index be44147d911a..ce7d5e6e4150 100644 --- a/trunk/arch/arm/mach-omap2/board-am3517evm.c +++ b/trunk/arch/arm/mach-omap2/board-am3517evm.c @@ -174,14 +174,19 @@ static void __init am3517_evm_rtc_init(void) int r; omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP); - - r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq"); + r = gpio_request(GPIO_RTCS35390A_IRQ, "rtcs35390a-irq"); if (r < 0) { printk(KERN_WARNING "failed to request GPIO#%d\n", GPIO_RTCS35390A_IRQ); return; } - + r = gpio_direction_input(GPIO_RTCS35390A_IRQ); + if (r < 0) { + printk(KERN_WARNING "GPIO#%d cannot be configured as input\n", + GPIO_RTCS35390A_IRQ); + gpio_free(GPIO_RTCS35390A_IRQ); + return; + } am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ); } @@ -237,15 +242,6 @@ static int dvi_enabled; #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \ defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE) -static struct gpio am3517_evm_dss_gpios[] __initdata = { - /* GPIO 182 = LCD Backlight Power */ - { LCD_PANEL_BKLIGHT_PWR, GPIOF_OUT_INIT_HIGH, "lcd_backlight_pwr" }, - /* GPIO 181 = LCD Panel PWM */ - { LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd bl enable" }, - /* GPIO 176 = LCD Panel Power enable pin */ - { LCD_PANEL_PWR, GPIOF_OUT_INIT_HIGH, "dvi enable" }, -}; - static void __init am3517_evm_display_init(void) { int r; @@ -253,15 +249,41 @@ static void __init am3517_evm_display_init(void) omap_mux_init_gpio(LCD_PANEL_PWR, OMAP_PIN_INPUT_PULLUP); omap_mux_init_gpio(LCD_PANEL_BKLIGHT_PWR, OMAP_PIN_INPUT_PULLDOWN); omap_mux_init_gpio(LCD_PANEL_PWM, OMAP_PIN_INPUT_PULLDOWN); - - r = gpio_request_array(am3517_evm_dss_gpios, - ARRAY_SIZE(am3517_evm_dss_gpios)); + /* + * Enable GPIO 182 = LCD Backlight Power + */ + r = gpio_request(LCD_PANEL_BKLIGHT_PWR, "lcd_backlight_pwr"); if (r) { - printk(KERN_ERR "failed to get DSS panel control GPIOs\n"); + printk(KERN_ERR "failed to get lcd_backlight_pwr\n"); return; } + gpio_direction_output(LCD_PANEL_BKLIGHT_PWR, 1); + /* + * Enable GPIO 181 = LCD Panel PWM + */ + r = gpio_request(LCD_PANEL_PWM, "lcd_pwm"); + if (r) { + printk(KERN_ERR "failed to get lcd_pwm\n"); + goto err_1; + } + gpio_direction_output(LCD_PANEL_PWM, 1); + /* + * Enable GPIO 176 = LCD Panel Power enable pin + */ + r = gpio_request(LCD_PANEL_PWR, "lcd_panel_pwr"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_pwr\n"); + goto err_2; + } + gpio_direction_output(LCD_PANEL_PWR, 1); printk(KERN_INFO "Display initialized successfully\n"); + return; + +err_2: + gpio_free(LCD_PANEL_PWM); +err_1: + gpio_free(LCD_PANEL_BKLIGHT_PWR); } #else static void __init am3517_evm_display_init(void) {} @@ -374,7 +396,7 @@ static struct omap_musb_board_data musb_board_data = { .power = 500, .set_phy_power = am35x_musb_phy_power, .clear_irq = am35x_musb_clear_irq, - .set_mode = am35x_set_mode, + .set_mode = am35x_musb_set_mode, .reset = am35x_musb_reset, }; diff --git a/trunk/arch/arm/mach-omap2/board-apollon.c b/trunk/arch/arm/mach-omap2/board-apollon.c index f3beb8eeef77..f4f8374a0298 100644 --- a/trunk/arch/arm/mach-omap2/board-apollon.c +++ b/trunk/arch/arm/mach-omap2/board-apollon.c @@ -202,7 +202,6 @@ static inline void __init apollon_init_smc91x(void) unsigned int rate; struct clk *gpmc_fck; int eth_cs; - int err; gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ if (IS_ERR(gpmc_fck)) { @@ -246,13 +245,15 @@ static inline void __init apollon_init_smc91x(void) apollon_smc91x_resources[0].end = base + 0x30f; udelay(100); - omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0); - err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq"); - if (err) { + omap_mux_init_gpio(74, 0); + if (gpio_request(APOLLON_ETHR_GPIO_IRQ, "SMC91x irq") < 0) { printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n", APOLLON_ETHR_GPIO_IRQ); gpmc_cs_free(APOLLON_ETH_CS); + goto out; } + gpio_direction_input(APOLLON_ETHR_GPIO_IRQ); + out: clk_disable(gpmc_fck); clk_put(gpmc_fck); @@ -279,19 +280,20 @@ static void __init omap_apollon_init_early(void) omap2_init_common_devices(NULL, NULL); } -static struct gpio apollon_gpio_leds[] __initdata = { - { LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */ - { LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */ - { LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4 */ -}; - static void __init apollon_led_init(void) { + /* LED0 - AA10 */ omap_mux_init_signal("vlynq_clk.gpio_13", 0); + gpio_request(LED0_GPIO13, "LED0"); + gpio_direction_output(LED0_GPIO13, 0); + /* LED1 - AA6 */ omap_mux_init_signal("vlynq_rx1.gpio_14", 0); + gpio_request(LED1_GPIO14, "LED1"); + gpio_direction_output(LED1_GPIO14, 0); + /* LED2 - AA4 */ omap_mux_init_signal("vlynq_rx0.gpio_15", 0); - - gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds)); + gpio_request(LED2_GPIO15, "LED2"); + gpio_direction_output(LED2_GPIO15, 0); } static void __init apollon_usb_init(void) @@ -299,7 +301,8 @@ static void __init apollon_usb_init(void) /* USB device */ /* DEVICE_SUSPEND */ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0); - gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend"); + gpio_request(12, "USB suspend"); + gpio_direction_output(12, 0); omap2_usbfs_init(&apollon_usb_config); } diff --git a/trunk/arch/arm/mach-omap2/board-cm-t35.c b/trunk/arch/arm/mach-omap2/board-cm-t35.c index 6063be82b563..02a12b41c0ff 100644 --- a/trunk/arch/arm/mach-omap2/board-cm-t35.c +++ b/trunk/arch/arm/mach-omap2/board-cm-t35.c @@ -54,7 +54,6 @@ #include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" -#include "common-board-devices.h" #define CM_T35_GPIO_PENDOWN 57 @@ -67,28 +66,86 @@ #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) #include -#include -static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = { - .id = 0, - .cs = CM_T35_SMSC911X_CS, - .gpio_irq = CM_T35_SMSC911X_GPIO, - .gpio_reset = -EINVAL, +static struct smsc911x_platform_config cm_t35_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct resource cm_t35_smsc911x_resources[] = { + { + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO), + .end = OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct platform_device cm_t35_smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(cm_t35_smsc911x_resources), + .resource = cm_t35_smsc911x_resources, + .dev = { + .platform_data = &cm_t35_smsc911x_config, + }, +}; + +static struct resource sb_t35_smsc911x_resources[] = { + { + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO), + .end = OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, }; -static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = { +static struct platform_device sb_t35_smsc911x_device = { + .name = "smsc911x", .id = 1, - .cs = SB_T35_SMSC911X_CS, - .gpio_irq = SB_T35_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, + .num_resources = ARRAY_SIZE(sb_t35_smsc911x_resources), + .resource = sb_t35_smsc911x_resources, + .dev = { + .platform_data = &cm_t35_smsc911x_config, + }, }; +static void __init cm_t35_init_smsc911x(struct platform_device *dev, + int cs, int irq_gpio) +{ + unsigned long cs_mem_base; + + if (gpmc_cs_request(cs, SZ_16M, &cs_mem_base) < 0) { + pr_err("CM-T35: Failed request for GPMC mem for smsc911x\n"); + return; + } + + dev->resource[0].start = cs_mem_base + 0x0; + dev->resource[0].end = cs_mem_base + 0xff; + + if ((gpio_request(irq_gpio, "ETH IRQ") == 0) && + (gpio_direction_input(irq_gpio) == 0)) { + gpio_export(irq_gpio, 0); + } else { + pr_err("CM-T35: could not obtain gpio for SMSC911X IRQ\n"); + return; + } + + platform_device_register(dev); +} + static void __init cm_t35_init_ethernet(void) { - gpmc_smsc911x_init(&cm_t35_smsc911x_cfg); - gpmc_smsc911x_init(&sb_t35_smsc911x_cfg); + cm_t35_init_smsc911x(&cm_t35_smsc911x_device, + CM_T35_SMSC911X_CS, CM_T35_SMSC911X_GPIO); + cm_t35_init_smsc911x(&sb_t35_smsc911x_device, + SB_T35_SMSC911X_CS, SB_T35_SMSC911X_GPIO); } #else static inline void __init cm_t35_init_ethernet(void) { return; } @@ -178,10 +235,69 @@ static void __init cm_t35_init_nand(void) static inline void cm_t35_init_nand(void) {} #endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +#include + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(CM_T35_GPIO_PENDOWN); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, +}; + +static struct spi_board_info cm_t35_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(CM_T35_GPIO_PENDOWN), + .platform_data = &ads7846_config, + }, +}; + +static void __init cm_t35_init_ads7846(void) +{ + if ((gpio_request(CM_T35_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) && + (gpio_direction_input(CM_T35_GPIO_PENDOWN) == 0)) { + gpio_export(CM_T35_GPIO_PENDOWN, 0); + } else { + pr_err("CM-T35: could not obtain gpio for ADS7846_PENDOWN\n"); + return; + } + + spi_register_board_info(cm_t35_spi_board_info, + ARRAY_SIZE(cm_t35_spi_board_info)); +} +#else +static inline void cm_t35_init_ads7846(void) {} +#endif + #define CM_T35_LCD_EN_GPIO 157 #define CM_T35_LCD_BL_GPIO 58 #define CM_T35_DVI_EN_GPIO 54 +static int lcd_bl_gpio; +static int lcd_en_gpio; +static int dvi_en_gpio; + static int lcd_enabled; static int dvi_enabled; @@ -192,8 +308,8 @@ static int cm_t35_panel_enable_lcd(struct omap_dss_device *dssdev) return -EINVAL; } - gpio_set_value(CM_T35_LCD_EN_GPIO, 1); - gpio_set_value(CM_T35_LCD_BL_GPIO, 1); + gpio_set_value(lcd_en_gpio, 1); + gpio_set_value(lcd_bl_gpio, 1); lcd_enabled = 1; @@ -204,8 +320,8 @@ static void cm_t35_panel_disable_lcd(struct omap_dss_device *dssdev) { lcd_enabled = 0; - gpio_set_value(CM_T35_LCD_BL_GPIO, 0); - gpio_set_value(CM_T35_LCD_EN_GPIO, 0); + gpio_set_value(lcd_bl_gpio, 0); + gpio_set_value(lcd_en_gpio, 0); } static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev) @@ -215,7 +331,7 @@ static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev) return -EINVAL; } - gpio_set_value(CM_T35_DVI_EN_GPIO, 0); + gpio_set_value(dvi_en_gpio, 0); dvi_enabled = 1; return 0; @@ -223,7 +339,7 @@ static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev) static void cm_t35_panel_disable_dvi(struct omap_dss_device *dssdev) { - gpio_set_value(CM_T35_DVI_EN_GPIO, 1); + gpio_set_value(dvi_en_gpio, 1); dvi_enabled = 0; } @@ -305,38 +421,62 @@ static struct spi_board_info cm_t35_lcd_spi_board_info[] __initdata = { }, }; -static struct gpio cm_t35_dss_gpios[] __initdata = { - { CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW, "lcd enable" }, - { CM_T35_LCD_BL_GPIO, GPIOF_OUT_INIT_LOW, "lcd bl enable" }, - { CM_T35_DVI_EN_GPIO, GPIOF_OUT_INIT_HIGH, "dvi enable" }, -}; - static void __init cm_t35_init_display(void) { int err; + lcd_en_gpio = CM_T35_LCD_EN_GPIO; + lcd_bl_gpio = CM_T35_LCD_BL_GPIO; + dvi_en_gpio = CM_T35_DVI_EN_GPIO; + spi_register_board_info(cm_t35_lcd_spi_board_info, ARRAY_SIZE(cm_t35_lcd_spi_board_info)); - err = gpio_request_array(cm_t35_dss_gpios, - ARRAY_SIZE(cm_t35_dss_gpios)); + err = gpio_request(lcd_en_gpio, "LCD RST"); if (err) { - pr_err("CM-T35: failed to request DSS control GPIOs\n"); - return; + pr_err("CM-T35: failed to get LCD reset GPIO\n"); + goto out; + } + + err = gpio_request(lcd_bl_gpio, "LCD BL"); + if (err) { + pr_err("CM-T35: failed to get LCD backlight control GPIO\n"); + goto err_lcd_bl; } - gpio_export(CM_T35_LCD_EN_GPIO, 0); - gpio_export(CM_T35_LCD_BL_GPIO, 0); - gpio_export(CM_T35_DVI_EN_GPIO, 0); + err = gpio_request(dvi_en_gpio, "DVI EN"); + if (err) { + pr_err("CM-T35: failed to get DVI reset GPIO\n"); + goto err_dvi_en; + } + + gpio_export(lcd_en_gpio, 0); + gpio_export(lcd_bl_gpio, 0); + gpio_export(dvi_en_gpio, 0); + gpio_direction_output(lcd_en_gpio, 0); + gpio_direction_output(lcd_bl_gpio, 0); + gpio_direction_output(dvi_en_gpio, 1); msleep(50); - gpio_set_value(CM_T35_LCD_EN_GPIO, 1); + gpio_set_value(lcd_en_gpio, 1); err = omap_display_init(&cm_t35_dss_data); if (err) { pr_err("CM-T35: failed to register DSS device\n"); - gpio_free_array(cm_t35_dss_gpios, ARRAY_SIZE(cm_t35_dss_gpios)); + goto err_dev_reg; } + + return; + +err_dev_reg: + gpio_free(dvi_en_gpio); +err_dvi_en: + gpio_free(lcd_bl_gpio); +err_lcd_bl: + gpio_free(lcd_en_gpio); +out: + + return; } static struct regulator_consumer_supply cm_t35_vmmc1_supply = { @@ -469,8 +609,10 @@ static int cm_t35_twl_gpio_setup(struct device *dev, unsigned gpio, { int wlan_rst = gpio + 2; - if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) { + if ((gpio_request(wlan_rst, "WLAN RST") == 0) && + (gpio_direction_output(wlan_rst, 1) == 0)) { gpio_export(wlan_rst, 0); + udelay(10); gpio_set_value(wlan_rst, 0); udelay(10); @@ -511,9 +653,19 @@ static struct twl4030_platform_data cm_t35_twldata = { .vpll2 = &cm_t35_vpll2, }; +static struct i2c_board_info __initdata cm_t35_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("tps65930", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &cm_t35_twldata, + }, +}; + static void __init cm_t35_init_i2c(void) { - omap3_pmic_init("tps65930", &cm_t35_twldata); + omap_register_i2c_bus(1, 2600, cm_t35_i2c_boardinfo, + ARRAY_SIZE(cm_t35_i2c_boardinfo)); } static void __init cm_t35_init_early(void) @@ -623,6 +775,12 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static struct omap_board_config_kernel cm_t35_config[] __initdata = { }; @@ -634,12 +792,12 @@ static void __init cm_t35_init(void) omap_serial_init(); cm_t35_init_i2c(); cm_t35_init_nand(); - omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL); + cm_t35_init_ads7846(); cm_t35_init_ethernet(); cm_t35_init_led(); cm_t35_init_display(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); } diff --git a/trunk/arch/arm/mach-omap2/board-cm-t3517.c b/trunk/arch/arm/mach-omap2/board-cm-t3517.c index 08f08e812492..a27e3eee8292 100644 --- a/trunk/arch/arm/mach-omap2/board-cm-t3517.c +++ b/trunk/arch/arm/mach-omap2/board-cm-t3517.c @@ -148,13 +148,14 @@ static void __init cm_t3517_init_rtc(void) { int err; - err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH, - "rtc cs en"); + err = gpio_request(RTC_CS_EN_GPIO, "rtc cs en"); if (err) { pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err); return; } + gpio_direction_output(RTC_CS_EN_GPIO, 1); + platform_device_register(&cm_t3517_rtc_device); } #else @@ -181,11 +182,11 @@ static int cm_t3517_init_usbh(void) { int err; - err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW, - "usb hub rst"); + err = gpio_request(USB_HUB_RESET_GPIO, "usb hub rst"); if (err) { pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err); } else { + gpio_direction_output(USB_HUB_RESET_GPIO, 0); udelay(10); gpio_set_value(USB_HUB_RESET_GPIO, 1); msleep(1); diff --git a/trunk/arch/arm/mach-omap2/board-devkit8000.c b/trunk/arch/arm/mach-omap2/board-devkit8000.c index 3bd344a527e2..65f9fde2c567 100644 --- a/trunk/arch/arm/mach-omap2/board-devkit8000.c +++ b/trunk/arch/arm/mach-omap2/board-devkit8000.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -59,7 +60,6 @@ #include "mux.h" #include "hsmmc.h" #include "timer-gp.h" -#include "common-board-devices.h" #define NAND_BLOCK_SIZE SZ_128K @@ -97,6 +97,13 @@ static struct mtd_partition devkit8000_nand_partitions[] = { }, }; +static struct omap_nand_platform_data devkit8000_nand_data = { + .options = NAND_BUSWIDTH_16, + .parts = devkit8000_nand_partitions, + .nr_parts = ARRAY_SIZE(devkit8000_nand_partitions), + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ +}; + static struct omap2_hsmmc_info mmc[] = { { .mmc = 1, @@ -242,7 +249,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev, /* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */ devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0; ret = gpio_request_one(devkit8000_lcd_device.reset_gpio, - GPIOF_OUT_INIT_LOW, "LCD_PWREN"); + GPIOF_DIR_OUT | GPIOF_INIT_LOW, "LCD_PWREN"); if (ret < 0) { devkit8000_lcd_device.reset_gpio = -EINVAL; printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n"); @@ -251,7 +258,7 @@ static int devkit8000_twl_gpio_setup(struct device *dev, /* gpio + 7 is "DVI_PD" (out, active low) */ devkit8000_dvi_device.reset_gpio = gpio + 7; ret = gpio_request_one(devkit8000_dvi_device.reset_gpio, - GPIOF_OUT_INIT_LOW, "DVI PowerDown"); + GPIOF_DIR_OUT | GPIOF_INIT_LOW, "DVI PowerDown"); if (ret < 0) { devkit8000_dvi_device.reset_gpio = -EINVAL; printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n"); @@ -359,9 +366,19 @@ static struct twl4030_platform_data devkit8000_twldata = { .keypad = &devkit8000_kp_data, }; +static struct i2c_board_info __initdata devkit8000_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("tps65930", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &devkit8000_twldata, + }, +}; + static int __init devkit8000_i2c_init(void) { - omap3_pmic_init("tps65930", &devkit8000_twldata); + omap_register_i2c_bus(1, 2600, devkit8000_i2c_boardinfo, + ARRAY_SIZE(devkit8000_i2c_boardinfo)); /* Bus 3 is attached to the DVI port where devices like the pico DLP * projector don't work reliably with 400kHz */ omap_register_i2c_bus(3, 400, NULL, 0); @@ -446,6 +463,56 @@ static void __init devkit8000_init_irq(void) #endif } +static void __init devkit8000_ads7846_init(void) +{ + int gpio = OMAP3_DEVKIT_TS_GPIO; + int ret; + + ret = gpio_request(gpio, "ads7846_pen_down"); + if (ret < 0) { + printk(KERN_ERR "Failed to request GPIO %d for " + "ads7846 pen down IRQ\n", gpio); + return; + } + + gpio_direction_input(gpio); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OMAP3_DEVKIT_TS_GPIO); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 5, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, + .settle_delay_usecs = 150, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info devkit8000_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 2, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_DEVKIT_TS_GPIO), + .platform_data = &ads7846_config, + } +}; + #define OMAP_DM9000_BASE 0x2c000000 static struct resource omap_dm9000_resources[] = { @@ -483,14 +550,14 @@ static void __init omap_dm9000_init(void) { unsigned char *eth_addr = omap_dm9000_platdata.dev_addr; struct omap_die_id odi; - int ret; - ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq"); - if (ret < 0) { + if (gpio_request(OMAP_DM9000_GPIO_IRQ, "dm9000 irq") < 0) { printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n", OMAP_DM9000_GPIO_IRQ); return; - } + } + + gpio_direction_input(OMAP_DM9000_GPIO_IRQ); /* init the mac address using DIE id */ omap_get_die_id(&odi); @@ -509,6 +576,45 @@ static struct platform_device *devkit8000_devices[] __initdata = { &omap_dm9000_dev, }; +static void __init devkit8000_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + + /* find out the chip-select on which NAND exists */ + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + if ((ret & 0xC00) == 0x800) { + printk(KERN_INFO "Found NAND on CS%d\n", cs); + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + } + cs++; + } + + if (nandcs > GPMC_CS_NUM) { + printk(KERN_INFO "NAND: Unable to find configuration " + "in GPMC\n "); + return; + } + + if (nandcs < GPMC_CS_NUM) { + devkit8000_nand_data.cs = nandcs; + + printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); + if (gpmc_nand_init(&devkit8000_nand_data) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); + } +} + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, @@ -689,13 +795,14 @@ static void __init devkit8000_init(void) ARRAY_SIZE(devkit8000_devices)); omap_display_init(&devkit8000_dss_data); + spi_register_board_info(devkit8000_spi_board_info, + ARRAY_SIZE(devkit8000_spi_board_info)); - omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL); + devkit8000_ads7846_init(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); - omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions, - ARRAY_SIZE(devkit8000_nand_partitions)); + devkit8000_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); diff --git a/trunk/arch/arm/mach-omap2/board-igep0020.c b/trunk/arch/arm/mach-omap2/board-igep0020.c index 0d6d583e8b3c..34cf982b9679 100644 --- a/trunk/arch/arm/mach-omap2/board-igep0020.c +++ b/trunk/arch/arm/mach-omap2/board-igep0020.c @@ -38,7 +38,6 @@ #include "mux.h" #include "hsmmc.h" #include "sdram-numonyx-m65kxxxxam.h" -#include "common-board-devices.h" #define IGEP2_SMSC911X_CS 5 #define IGEP2_SMSC911X_GPIO 176 @@ -55,11 +54,6 @@ #define IGEP2_RC_GPIO_WIFI_NRESET 139 #define IGEP2_RC_GPIO_BT_NRESET 137 -#define IGEP3_GPIO_LED0_GREEN 54 -#define IGEP3_GPIO_LED0_RED 53 -#define IGEP3_GPIO_LED1_RED 16 -#define IGEP3_GPIO_USBH_NRESET 183 - /* * IGEP2 Hardware Revision Table * @@ -74,7 +68,6 @@ #define IGEP2_BOARD_HWREV_B 0 #define IGEP2_BOARD_HWREV_C 1 -#define IGEP3_BOARD_HWREV 2 static u8 hwrev; @@ -82,29 +75,24 @@ static void __init igep2_get_revision(void) { u8 ret; - if (machine_is_igep0030()) { - hwrev = IGEP3_BOARD_HWREV; - return; - } - omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT); - if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) { - pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n"); - pr_err("IGEP2: Unknown Hardware Revision\n"); - return; - } - - ret = gpio_get_value(IGEP2_GPIO_LED1_RED); - if (ret == 0) { - pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n"); - hwrev = IGEP2_BOARD_HWREV_C; - } else if (ret == 1) { - pr_info("IGEP2: Hardware Revision B/C (B compatible)\n"); - hwrev = IGEP2_BOARD_HWREV_B; + if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_HW0_REV") == 0) && + (gpio_direction_input(IGEP2_GPIO_LED1_RED) == 0)) { + ret = gpio_get_value(IGEP2_GPIO_LED1_RED); + if (ret == 0) { + pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n"); + hwrev = IGEP2_BOARD_HWREV_C; + } else if (ret == 1) { + pr_info("IGEP2: Hardware Revision B/C (B compatible)\n"); + hwrev = IGEP2_BOARD_HWREV_B; + } else { + pr_err("IGEP2: Unknown Hardware Revision\n"); + hwrev = -1; + } } else { + pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n"); pr_err("IGEP2: Unknown Hardware Revision\n"); - hwrev = -1; } gpio_free(IGEP2_GPIO_LED1_RED); @@ -123,7 +111,7 @@ static void __init igep2_get_revision(void) * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048) */ -static struct mtd_partition igep_onenand_partitions[] = { +static struct mtd_partition igep2_onenand_partitions[] = { { .name = "X-Loader", .offset = 0, @@ -151,21 +139,21 @@ static struct mtd_partition igep_onenand_partitions[] = { }, }; -static struct omap_onenand_platform_data igep_onenand_data = { - .parts = igep_onenand_partitions, - .nr_parts = ARRAY_SIZE(igep_onenand_partitions), +static struct omap_onenand_platform_data igep2_onenand_data = { + .parts = igep2_onenand_partitions, + .nr_parts = ARRAY_SIZE(igep2_onenand_partitions), .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ }; -static struct platform_device igep_onenand_device = { +static struct platform_device igep2_onenand_device = { .name = "omap2-onenand", .id = -1, .dev = { - .platform_data = &igep_onenand_data, + .platform_data = &igep2_onenand_data, }, }; -static void __init igep_flash_init(void) +static void __init igep2_flash_init(void) { u8 cs = 0; u8 onenandcs = GPMC_CS_NUM + 1; @@ -177,7 +165,7 @@ static void __init igep_flash_init(void) /* Check if NAND/oneNAND is configured */ if ((ret & 0xC00) == 0x800) /* NAND found */ - pr_err("IGEP: Unsupported NAND found\n"); + pr_err("IGEP2: Unsupported NAND found\n"); else { ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); if ((ret & 0x3F) == (ONENAND_MAP >> 24)) @@ -187,46 +175,85 @@ static void __init igep_flash_init(void) } if (onenandcs > GPMC_CS_NUM) { - pr_err("IGEP: Unable to find configuration in GPMC\n"); + pr_err("IGEP2: Unable to find configuration in GPMC\n"); return; } - igep_onenand_data.cs = onenandcs; + igep2_onenand_data.cs = onenandcs; - if (platform_device_register(&igep_onenand_device) < 0) - pr_err("IGEP: Unable to register OneNAND device\n"); + if (platform_device_register(&igep2_onenand_device) < 0) + pr_err("IGEP2: Unable to register OneNAND device\n"); } #else -static void __init igep_flash_init(void) {} +static void __init igep2_flash_init(void) {} #endif #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) #include -#include -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = IGEP2_SMSC911X_CS, - .gpio_irq = IGEP2_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +static struct smsc911x_platform_config igep2_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS , + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct resource igep2_smsc911x_resources[] = { + { + .flags = IORESOURCE_MEM, + }, + { + .start = OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO), + .end = OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO), + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct platform_device igep2_smsc911x_device = { + .name = "smsc911x", + .id = 0, + .num_resources = ARRAY_SIZE(igep2_smsc911x_resources), + .resource = igep2_smsc911x_resources, + .dev = { + .platform_data = &igep2_smsc911x_config, + }, }; static inline void __init igep2_init_smsc911x(void) { - gpmc_smsc911x_init(&smsc911x_cfg); + unsigned long cs_mem_base; + + if (gpmc_cs_request(IGEP2_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) { + pr_err("IGEP v2: Failed request for GPMC mem for smsc911x\n"); + gpmc_cs_free(IGEP2_SMSC911X_CS); + return; + } + + igep2_smsc911x_resources[0].start = cs_mem_base + 0x0; + igep2_smsc911x_resources[0].end = cs_mem_base + 0xff; + + if ((gpio_request(IGEP2_SMSC911X_GPIO, "SMSC911X IRQ") == 0) && + (gpio_direction_input(IGEP2_SMSC911X_GPIO) == 0)) { + gpio_export(IGEP2_SMSC911X_GPIO, 0); + } else { + pr_err("IGEP v2: Could not obtain gpio for for SMSC911X IRQ\n"); + return; + } + + platform_device_register(&igep2_smsc911x_device); } #else static inline void __init igep2_init_smsc911x(void) { } #endif -static struct regulator_consumer_supply igep_vmmc1_supply = +static struct regulator_consumer_supply igep2_vmmc1_supply = REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -static struct regulator_init_data igep_vmmc1 = { +static struct regulator_init_data igep2_vmmc1 = { .constraints = { .min_uV = 1850000, .max_uV = 3150000, @@ -237,13 +264,13 @@ static struct regulator_init_data igep_vmmc1 = { | REGULATOR_CHANGE_STATUS, }, .num_consumer_supplies = 1, - .consumer_supplies = &igep_vmmc1_supply, + .consumer_supplies = &igep2_vmmc1_supply, }; -static struct regulator_consumer_supply igep_vio_supply = +static struct regulator_consumer_supply igep2_vio_supply = REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"); -static struct regulator_init_data igep_vio = { +static struct regulator_init_data igep2_vio = { .constraints = { .min_uV = 1800000, .max_uV = 1800000, @@ -255,34 +282,34 @@ static struct regulator_init_data igep_vio = { | REGULATOR_CHANGE_STATUS, }, .num_consumer_supplies = 1, - .consumer_supplies = &igep_vio_supply, + .consumer_supplies = &igep2_vio_supply, }; -static struct regulator_consumer_supply igep_vmmc2_supply = +static struct regulator_consumer_supply igep2_vmmc2_supply = REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); -static struct regulator_init_data igep_vmmc2 = { +static struct regulator_init_data igep2_vmmc2 = { .constraints = { .valid_modes_mask = REGULATOR_MODE_NORMAL, .always_on = 1, }, .num_consumer_supplies = 1, - .consumer_supplies = &igep_vmmc2_supply, + .consumer_supplies = &igep2_vmmc2_supply, }; -static struct fixed_voltage_config igep_vwlan = { +static struct fixed_voltage_config igep2_vwlan = { .supply_name = "vwlan", .microvolts = 3300000, .gpio = -EINVAL, .enabled_at_boot = 1, - .init_data = &igep_vmmc2, + .init_data = &igep2_vmmc2, }; -static struct platform_device igep_vwlan_device = { +static struct platform_device igep2_vwlan_device = { .name = "reg-fixed-voltage", .id = 0, .dev = { - .platform_data = &igep_vwlan, + .platform_data = &igep2_vwlan, }, }; @@ -307,17 +334,20 @@ static struct omap2_hsmmc_info mmc[] = { #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) #include -static struct gpio_led igep_gpio_leds[] = { +static struct gpio_led igep2_gpio_leds[] = { [0] = { .name = "gpio-led:red:d0", + .gpio = IGEP2_GPIO_LED0_RED, .default_trigger = "default-off" }, [1] = { .name = "gpio-led:green:d0", + .gpio = IGEP2_GPIO_LED0_GREEN, .default_trigger = "default-off", }, [2] = { .name = "gpio-led:red:d1", + .gpio = IGEP2_GPIO_LED1_RED, .default_trigger = "default-off", }, [3] = { @@ -328,119 +358,94 @@ static struct gpio_led igep_gpio_leds[] = { }, }; -static struct gpio_led_platform_data igep_led_pdata = { - .leds = igep_gpio_leds, - .num_leds = ARRAY_SIZE(igep_gpio_leds), +static struct gpio_led_platform_data igep2_led_pdata = { + .leds = igep2_gpio_leds, + .num_leds = ARRAY_SIZE(igep2_gpio_leds), }; -static struct platform_device igep_led_device = { +static struct platform_device igep2_led_device = { .name = "leds-gpio", .id = -1, .dev = { - .platform_data = &igep_led_pdata, + .platform_data = &igep2_led_pdata, }, }; -static void __init igep_leds_init(void) +static void __init igep2_leds_init(void) { - if (machine_is_igep0020()) { - igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED; - } else { - igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED; - } - - platform_device_register(&igep_led_device); + platform_device_register(&igep2_led_device); } #else -static struct gpio igep_gpio_leds[] __initdata = { - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d0" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "gpio-led:red:d1" }, -}; - -static inline void igep_leds_init(void) +static inline void igep2_leds_init(void) { - int i; + if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) && + (gpio_direction_output(IGEP2_GPIO_LED0_RED, 0) == 0)) + gpio_export(IGEP2_GPIO_LED0_RED, 0); + else + pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n"); - if (machine_is_igep0020()) { - igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED; - } else { - igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED; - igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN; - igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED; - } + if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) && + (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 0) == 0)) + gpio_export(IGEP2_GPIO_LED0_GREEN, 0); + else + pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n"); - if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) { - pr_warning("IGEP v2: Could not obtain leds gpios\n"); - return; - } + if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) && + (gpio_direction_output(IGEP2_GPIO_LED1_RED, 0) == 0)) + gpio_export(IGEP2_GPIO_LED1_RED, 0); + else + pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n"); - for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++) - gpio_export(igep_gpio_leds[i].gpio, 0); } #endif -static struct gpio igep2_twl_gpios[] = { - { -EINVAL, GPIOF_IN, "GPIO_EHCI_NOC" }, - { -EINVAL, GPIOF_OUT_INIT_LOW, "GPIO_USBH_CPEN" }, -}; - -static int igep_twl_gpio_setup(struct device *dev, +static int igep2_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - int ret; - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ mmc[0].gpio_cd = gpio + 0; omap2_hsmmc_init(mmc); - /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ -#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) - ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH, - "gpio-led:green:d1"); - if (ret == 0) - gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); - else - pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n"); -#else - igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; -#endif - - if (machine_is_igep0030()) - return 0; - /* * REVISIT: need ehci-omap hooks for external VBUS * power switch and overcurrent detect */ - igep2_twl_gpios[0].gpio = gpio + 1; + if ((gpio_request(gpio + 1, "GPIO_EHCI_NOC") < 0) || + (gpio_direction_input(gpio + 1) < 0)) + pr_err("IGEP2: Could not obtain gpio for EHCI NOC"); - /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */ - igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX; - - ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios)); - if (ret < 0) + /* + * TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN + * (out, active low) + */ + if ((gpio_request(gpio + TWL4030_GPIO_MAX, "GPIO_USBH_CPEN") < 0) || + (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0)) pr_err("IGEP2: Could not obtain gpio for USBH_CPEN"); + /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ +#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) + if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0) + && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) + gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); + else + pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n"); +#else + igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; +#endif + return 0; }; -static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = { +static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = { .gpio_base = OMAP_MAX_GPIO_LINES, .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, .use_leds = true, - .setup = igep_twl_gpio_setup, + .setup = igep2_twl_gpio_setup, }; -static struct twl4030_usb_data igep_usb_data = { +static struct twl4030_usb_data igep2_usb_data = { .usb_mode = T2_USB_MODE_ULPI, }; @@ -502,17 +507,16 @@ static struct regulator_init_data igep2_vpll2 = { static void __init igep2_display_init(void) { - int err = gpio_request_one(IGEP2_GPIO_DVI_PUP, GPIOF_OUT_INIT_HIGH, - "GPIO_DVI_PUP"); - if (err) + if (gpio_request(IGEP2_GPIO_DVI_PUP, "GPIO_DVI_PUP") && + gpio_direction_output(IGEP2_GPIO_DVI_PUP, 1)) pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n"); } -static struct platform_device *igep_devices[] __initdata = { - &igep_vwlan_device, +static struct platform_device *igep2_devices[] __initdata = { + &igep2_vwlan_device, }; -static void __init igep_init_early(void) +static void __init igep2_init_early(void) { omap2_init_common_infrastructure(); omap2_init_common_devices(m65kxxxxam_sdrc_params, @@ -557,15 +561,27 @@ static struct twl4030_keypad_data igep2_keypad_pdata = { .rep = 1, }; -static struct twl4030_platform_data igep_twldata = { +static struct twl4030_platform_data igep2_twldata = { .irq_base = TWL4030_IRQ_BASE, .irq_end = TWL4030_IRQ_END, /* platform_data for children goes here */ - .usb = &igep_usb_data, - .gpio = &igep_twl4030_gpio_pdata, - .vmmc1 = &igep_vmmc1, - .vio = &igep_vio, + .usb = &igep2_usb_data, + .codec = &igep2_codec_data, + .gpio = &igep2_twl4030_gpio_pdata, + .keypad = &igep2_keypad_pdata, + .vmmc1 = &igep2_vmmc1, + .vpll2 = &igep2_vpll2, + .vio = &igep2_vio, +}; + +static struct i2c_board_info __initdata igep2_i2c1_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &igep2_twldata, + }, }; static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = { @@ -574,29 +590,32 @@ static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = { }, }; -static void __init igep_i2c_init(void) +static void __init igep2_i2c_init(void) { int ret; - if (machine_is_igep0020()) { - /* - * Bus 3 is attached to the DVI port where devices like the - * pico DLP projector don't work reliably with 400kHz - */ - ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo, - ARRAY_SIZE(igep2_i2c3_boardinfo)); - if (ret) - pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret); - - igep_twldata.codec = &igep2_codec_data; - igep_twldata.keypad = &igep2_keypad_pdata; - igep_twldata.vpll2 = &igep2_vpll2; - } + ret = omap_register_i2c_bus(1, 2600, igep2_i2c1_boardinfo, + ARRAY_SIZE(igep2_i2c1_boardinfo)); + if (ret) + pr_warning("IGEP2: Could not register I2C1 bus (%d)\n", ret); - omap3_pmic_init("twl4030", &igep_twldata); + /* + * Bus 3 is attached to the DVI port where devices like the pico DLP + * projector don't work reliably with 400kHz + */ + ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo, + ARRAY_SIZE(igep2_i2c3_boardinfo)); + if (ret) + pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret); } -static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = { +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, @@ -607,17 +626,6 @@ static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = { .reset_gpio_port[2] = -EINVAL, }; -static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = { - .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, - .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, - .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, - - .phy_reset = true, - .reset_gpio_port[0] = -EINVAL, - .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET, - .reset_gpio_port[2] = -EINVAL, -}; - #ifdef CONFIG_OMAP_MUX static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, @@ -625,95 +633,82 @@ static struct omap_board_mux board_mux[] __initdata = { #endif #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) -static struct gpio igep_wlan_bt_gpios[] __initdata = { - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD" }, - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" }, - { -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET" }, -}; -static void __init igep_wlan_bt_init(void) +static void __init igep2_wlan_bt_init(void) { - int err; + unsigned npd, wreset, btreset; /* GPIO's for WLAN-BT combo depends on hardware revision */ if (hwrev == IGEP2_BOARD_HWREV_B) { - igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD; - igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET; - igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET; - } else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) { - igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD; - igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET; - igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET; + npd = IGEP2_RB_GPIO_WIFI_NPD; + wreset = IGEP2_RB_GPIO_WIFI_NRESET; + btreset = IGEP2_RB_GPIO_BT_NRESET; + } else if (hwrev == IGEP2_BOARD_HWREV_C) { + npd = IGEP2_RC_GPIO_WIFI_NPD; + wreset = IGEP2_RC_GPIO_WIFI_NRESET; + btreset = IGEP2_RC_GPIO_BT_NRESET; } else return; - err = gpio_request_array(igep_wlan_bt_gpios, - ARRAY_SIZE(igep_wlan_bt_gpios)); - if (err) { - pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n"); - return; - } - - gpio_export(igep_wlan_bt_gpios[0].gpio, 0); - gpio_export(igep_wlan_bt_gpios[1].gpio, 0); - gpio_export(igep_wlan_bt_gpios[2].gpio, 0); - - gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0); - udelay(10); - gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1); + /* Set GPIO's for WLAN-BT combo module */ + if ((gpio_request(npd, "GPIO_WIFI_NPD") == 0) && + (gpio_direction_output(npd, 1) == 0)) { + gpio_export(npd, 0); + } else + pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NPD\n"); + + if ((gpio_request(wreset, "GPIO_WIFI_NRESET") == 0) && + (gpio_direction_output(wreset, 1) == 0)) { + gpio_export(wreset, 0); + gpio_set_value(wreset, 0); + udelay(10); + gpio_set_value(wreset, 1); + } else + pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NRESET\n"); + if ((gpio_request(btreset, "GPIO_BT_NRESET") == 0) && + (gpio_direction_output(btreset, 1) == 0)) { + gpio_export(btreset, 0); + } else + pr_warning("IGEP2: Could not obtain gpio GPIO_BT_NRESET\n"); } #else -static inline void __init igep_wlan_bt_init(void) { } +static inline void __init igep2_wlan_bt_init(void) { } #endif -static void __init igep_init(void) +static void __init igep2_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); /* Get IGEP2 hardware revision */ igep2_get_revision(); /* Register I2C busses and drivers */ - igep_i2c_init(); - platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices)); + igep2_i2c_init(); + platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices)); + omap_display_init(&igep2_dss_data); omap_serial_init(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); + usbhs_init(&usbhs_bdata); - igep_flash_init(); - igep_leds_init(); + igep2_flash_init(); + igep2_leds_init(); + igep2_display_init(); + igep2_init_smsc911x(); /* * WLAN-BT combo module from MuRata which has a Marvell WLAN * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. */ - igep_wlan_bt_init(); + igep2_wlan_bt_init(); - if (machine_is_igep0020()) { - omap_display_init(&igep2_dss_data); - igep2_display_init(); - igep2_init_smsc911x(); - usbhs_init(&igep2_usbhs_bdata); - } else { - usbhs_init(&igep3_usbhs_bdata); - } } MACHINE_START(IGEP0020, "IGEP v2 board") .boot_params = 0x80000100, .reserve = omap_reserve, .map_io = omap3_map_io, - .init_early = igep_init_early, - .init_irq = omap_init_irq, - .init_machine = igep_init, - .timer = &omap_timer, -MACHINE_END - -MACHINE_START(IGEP0030, "IGEP OMAP3 module") - .boot_params = 0x80000100, - .reserve = omap_reserve, - .map_io = omap3_map_io, - .init_early = igep_init_early, + .init_early = igep2_init_early, .init_irq = omap_init_irq, - .init_machine = igep_init, + .init_machine = igep2_init, .timer = &omap_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-omap2/board-igep0030.c b/trunk/arch/arm/mach-omap2/board-igep0030.c new file mode 100644 index 000000000000..2cf86c3cb1a3 --- /dev/null +++ b/trunk/arch/arm/mach-omap2/board-igep0030.c @@ -0,0 +1,458 @@ +/* + * Copyright (C) 2010 - ISEE 2007 SL + * + * Modified from mach-omap2/board-generic.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "mux.h" +#include "hsmmc.h" +#include "sdram-numonyx-m65kxxxxam.h" + +#define IGEP3_GPIO_LED0_GREEN 54 +#define IGEP3_GPIO_LED0_RED 53 +#define IGEP3_GPIO_LED1_RED 16 + +#define IGEP3_GPIO_WIFI_NPD 138 +#define IGEP3_GPIO_WIFI_NRESET 139 +#define IGEP3_GPIO_BT_NRESET 137 + +#define IGEP3_GPIO_USBH_NRESET 183 + + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) + +#define ONENAND_MAP 0x20000000 + +/* + * x2 Flash built-in COMBO POP MEMORY + * Since the device is equipped with two DataRAMs, and two-plane NAND + * Flash memory array, these two component enables simultaneous program + * of 4KiB. Plane1 has only even blocks such as block0, block2, block4 + * while Plane2 has only odd blocks such as block1, block3, block5. + * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048) + */ + +static struct mtd_partition igep3_onenand_partitions[] = { + { + .name = "X-Loader", + .offset = 0, + .size = 2 * (64*(2*2048)) + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = 6 * (64*(2*2048)), + }, + { + .name = "Environment", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64*(2*2048)), + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = 12 * (64*(2*2048)), + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_onenand_platform_data igep3_onenand_pdata = { + .parts = igep3_onenand_partitions, + .nr_parts = ARRAY_SIZE(igep3_onenand_partitions), + .onenand_setup = NULL, + .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ +}; + +static struct platform_device igep3_onenand_device = { + .name = "omap2-onenand", + .id = -1, + .dev = { + .platform_data = &igep3_onenand_pdata, + }, +}; + +static void __init igep3_flash_init(void) +{ + u8 cs = 0; + u8 onenandcs = GPMC_CS_NUM + 1; + + for (cs = 0; cs < GPMC_CS_NUM; cs++) { + u32 ret; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + /* Check if NAND/oneNAND is configured */ + if ((ret & 0xC00) == 0x800) + /* NAND found */ + pr_err("IGEP3: Unsupported NAND found\n"); + else { + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + + if ((ret & 0x3F) == (ONENAND_MAP >> 24)) + /* OneNAND found */ + onenandcs = cs; + } + } + + if (onenandcs > GPMC_CS_NUM) { + pr_err("IGEP3: Unable to find configuration in GPMC\n"); + return; + } + + igep3_onenand_pdata.cs = onenandcs; + + if (platform_device_register(&igep3_onenand_device) < 0) + pr_err("IGEP3: Unable to register OneNAND device\n"); +} + +#else +static void __init igep3_flash_init(void) {} +#endif + +static struct regulator_consumer_supply igep3_vmmc1_supply = + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); + +/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ +static struct regulator_init_data igep3_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &igep3_vmmc1_supply, +}; + +static struct regulator_consumer_supply igep3_vio_supply = + REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"); + +static struct regulator_init_data igep3_vio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = 1, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &igep3_vio_supply, +}; + +static struct regulator_consumer_supply igep3_vmmc2_supply = + REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); + +static struct regulator_init_data igep3_vmmc2 = { + .constraints = { + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .always_on = 1, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &igep3_vmmc2_supply, +}; + +static struct fixed_voltage_config igep3_vwlan = { + .supply_name = "vwlan", + .microvolts = 3300000, + .gpio = -EINVAL, + .enabled_at_boot = 1, + .init_data = &igep3_vmmc2, +}; + +static struct platform_device igep3_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &igep3_vwlan, + }, +}; + +static struct omap2_hsmmc_info mmc[] = { + [0] = { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, +#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) + [1] = { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, +#endif + {} /* Terminator */ +}; + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +#include + +static struct gpio_led igep3_gpio_leds[] = { + [0] = { + .name = "gpio-led:red:d0", + .gpio = IGEP3_GPIO_LED0_RED, + .default_trigger = "default-off" + }, + [1] = { + .name = "gpio-led:green:d0", + .gpio = IGEP3_GPIO_LED0_GREEN, + .default_trigger = "default-off", + }, + [2] = { + .name = "gpio-led:red:d1", + .gpio = IGEP3_GPIO_LED1_RED, + .default_trigger = "default-off", + }, + [3] = { + .name = "gpio-led:green:d1", + .default_trigger = "heartbeat", + .gpio = -EINVAL, /* gets replaced */ + }, +}; + +static struct gpio_led_platform_data igep3_led_pdata = { + .leds = igep3_gpio_leds, + .num_leds = ARRAY_SIZE(igep3_gpio_leds), +}; + +static struct platform_device igep3_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &igep3_led_pdata, + }, +}; + +static void __init igep3_leds_init(void) +{ + platform_device_register(&igep3_led_device); +} + +#else +static inline void igep3_leds_init(void) +{ + if ((gpio_request(IGEP3_GPIO_LED0_RED, "gpio-led:red:d0") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED0_RED, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED0_RED, 0); + gpio_set_value(IGEP3_GPIO_LED0_RED, 1); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_RED\n"); + + if ((gpio_request(IGEP3_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED0_GREEN, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED0_GREEN, 0); + gpio_set_value(IGEP3_GPIO_LED0_GREEN, 1); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_GREEN\n"); + + if ((gpio_request(IGEP3_GPIO_LED1_RED, "gpio-led:red:d1") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED1_RED, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED1_RED, 0); + gpio_set_value(IGEP3_GPIO_LED1_RED, 1); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_RED\n"); +} +#endif + +static int igep3_twl4030_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap2_hsmmc_init(mmc); + + /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ +#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) + if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0) + && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) { + gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); + gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_GREEN\n"); +#else + igep3_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; +#endif + + return 0; +}; + +static struct twl4030_gpio_platform_data igep3_twl4030_gpio_pdata = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .setup = igep3_twl4030_gpio_setup, +}; + +static struct twl4030_usb_data igep3_twl4030_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + +static struct platform_device *igep3_devices[] __initdata = { + &igep3_vwlan_device, +}; + +static void __init igep3_init_early(void) +{ + omap2_init_common_infrastructure(); + omap2_init_common_devices(m65kxxxxam_sdrc_params, + m65kxxxxam_sdrc_params); +} + +static struct twl4030_platform_data igep3_twl4030_pdata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .usb = &igep3_twl4030_usb_data, + .gpio = &igep3_twl4030_gpio_pdata, + .vmmc1 = &igep3_vmmc1, + .vio = &igep3_vio, +}; + +static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &igep3_twl4030_pdata, + }, +}; + +static int __init igep3_i2c_init(void) +{ + omap_register_i2c_bus(1, 2600, igep3_i2c_boardinfo, + ARRAY_SIZE(igep3_i2c_boardinfo)); + + return 0; +} + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE) + +static void __init igep3_wifi_bt_init(void) +{ + /* Configure MUX values for W-LAN + Bluetooth GPIO's */ + omap_mux_init_gpio(IGEP3_GPIO_WIFI_NPD, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(IGEP3_GPIO_WIFI_NRESET, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(IGEP3_GPIO_BT_NRESET, OMAP_PIN_OUTPUT); + + /* Set GPIO's for W-LAN + Bluetooth combo module */ + if ((gpio_request(IGEP3_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) && + (gpio_direction_output(IGEP3_GPIO_WIFI_NPD, 1) == 0)) { + gpio_export(IGEP3_GPIO_WIFI_NPD, 0); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NPD\n"); + + if ((gpio_request(IGEP3_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) && + (gpio_direction_output(IGEP3_GPIO_WIFI_NRESET, 1) == 0)) { + gpio_export(IGEP3_GPIO_WIFI_NRESET, 0); + gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 0); + udelay(10); + gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 1); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NRESET\n"); + + if ((gpio_request(IGEP3_GPIO_BT_NRESET, "GPIO_BT_NRESET") == 0) && + (gpio_direction_output(IGEP3_GPIO_BT_NRESET, 1) == 0)) { + gpio_export(IGEP3_GPIO_BT_NRESET, 0); + } else + pr_warning("IGEP3: Could not obtain gpio GPIO_BT_NRESET\n"); +} +#else +void __init igep3_wifi_bt_init(void) {} +#endif + +static const struct usbhs_omap_board_data usbhs_bdata __initconst = { + .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED, + .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY, + .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED, + + .phy_reset = true, + .reset_gpio_port[0] = -EINVAL, + .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET, + .reset_gpio_port[2] = -EINVAL, +}; + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static void __init igep3_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + /* Register I2C busses and drivers */ + igep3_i2c_init(); + platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices)); + omap_serial_init(); + usb_musb_init(&musb_board_data); + usbhs_init(&usbhs_bdata); + + igep3_flash_init(); + igep3_leds_init(); + + /* + * WLAN-BT combo module from MuRata which has a Marvell WLAN + * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface. + */ + igep3_wifi_bt_init(); + +} + +MACHINE_START(IGEP0030, "IGEP OMAP3 module") + .boot_params = 0x80000100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = igep3_init_early, + .init_irq = omap_init_irq, + .init_machine = igep3_init, + .timer = &omap_timer, +MACHINE_END diff --git a/trunk/arch/arm/mach-omap2/board-ldp.c b/trunk/arch/arm/mach-omap2/board-ldp.c index f7d6038075f0..e2ba77957a8c 100644 --- a/trunk/arch/arm/mach-omap2/board-ldp.c +++ b/trunk/arch/arm/mach-omap2/board-ldp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -42,19 +43,47 @@ #include #include -#include #include "board-flash.h" #include "mux.h" #include "hsmmc.h" #include "control.h" -#include "common-board-devices.h" #define LDP_SMSC911X_CS 1 #define LDP_SMSC911X_GPIO 152 #define DEBUG_BASE 0x08000000 #define LDP_ETHR_START DEBUG_BASE +static struct resource ldp_smsc911x_resources[] = { + [0] = { + .start = LDP_ETHR_START, + .end = LDP_ETHR_START + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config ldp_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device ldp_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(ldp_smsc911x_resources), + .resource = ldp_smsc911x_resources, + .dev = { + .platform_data = &ldp_smsc911x_config, + }, +}; + static uint32_t board_keymap[] = { KEY(0, 0, KEY_1), KEY(1, 0, KEY_2), @@ -168,16 +197,82 @@ static struct platform_device ldp_gpio_keys_device = { }, }; -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = LDP_SMSC911X_CS, - .gpio_irq = LDP_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT, +static int ts_gpio; + +/** + * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq + * + * @return - void. If request gpio fails then Flag KERN_ERR. + */ +static void ads7846_dev_init(void) +{ + if (gpio_request(ts_gpio, "ads7846 irq") < 0) { + printk(KERN_ERR "can't get ads746 pen down GPIO\n"); + return; + } + + gpio_direction_input(ts_gpio); + gpio_set_debounce(ts_gpio, 310); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(ts_gpio); +} + +static struct ads7846_platform_data tsc2046_config __initdata = { + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, +}; + +static struct omap2_mcspi_device_config tsc2046_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info ldp_spi_board_info[] __initdata = { + [0] = { + /* + * TSC2046 operates at a max freqency of 2MHz, so + * operate slightly below at 1.5MHz + */ + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &tsc2046_mcspi_config, + .irq = 0, + .platform_data = &tsc2046_config, + }, }; static inline void __init ldp_init_smsc911x(void) { - gpmc_smsc911x_init(&smsc911x_cfg); + int eth_cs; + unsigned long cs_mem_base; + int eth_gpio = 0; + + eth_cs = LDP_SMSC911X_CS; + + if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n"); + return; + } + + ldp_smsc911x_resources[0].start = cs_mem_base + 0x0; + ldp_smsc911x_resources[0].end = cs_mem_base + 0xff; + udelay(100); + + eth_gpio = LDP_SMSC911X_GPIO; + + ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio); + + if (gpio_request(eth_gpio, "smsc911x irq") < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", + eth_gpio); + return; + } + gpio_direction_input(eth_gpio); } static struct platform_device ldp_lcd_device = { @@ -265,9 +360,19 @@ static struct twl4030_platform_data ldp_twldata = { .keypad = &ldp_kp_twl4030_data, }; +static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &ldp_twldata, + }, +}; + static int __init omap_i2c_init(void) { - omap3_pmic_init("twl4030", &ldp_twldata); + omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo, + ARRAY_SIZE(ldp_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); return 0; @@ -284,6 +389,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { }; static struct platform_device *ldp_devices[] __initdata = { + &ldp_smsc911x_device, &ldp_lcd_device, &ldp_gpio_keys_device, }; @@ -294,6 +400,12 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static struct mtd_partition ldp_nand_partitions[] = { /* All the partition sizes are listed in terms of NAND block size */ { @@ -334,9 +446,13 @@ static void __init omap_ldp_init(void) ldp_init_smsc911x(); omap_i2c_init(); platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); - omap_ads7846_init(1, 54, 310, NULL); + ts_gpio = 54; + ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio); + spi_register_board_info(ldp_spi_board_info, + ARRAY_SIZE(ldp_spi_board_info)); + ads7846_dev_init(); omap_serial_init(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); board_nand_init(ldp_nand_partitions, ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); diff --git a/trunk/arch/arm/mach-omap2/board-n8x0.c b/trunk/arch/arm/mach-omap2/board-n8x0.c index 8d74318ed495..e710cd9e079b 100644 --- a/trunk/arch/arm/mach-omap2/board-n8x0.c +++ b/trunk/arch/arm/mach-omap2/board-n8x0.c @@ -106,13 +106,14 @@ static void __init n8x0_usb_init(void) static char announce[] __initdata = KERN_INFO "TUSB 6010\n"; /* PM companion chip power control pin */ - ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW, - "TUSB6010 enable"); + ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable"); if (ret != 0) { printk(KERN_ERR "Could not get TUSB power GPIO%i\n", TUSB6010_GPIO_ENABLE); return; } + gpio_direction_output(TUSB6010_GPIO_ENABLE, 0); + tusb_set_power(0); ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2, @@ -493,12 +494,8 @@ static struct omap_mmc_platform_data mmc1_data = { static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC]; -static struct gpio n810_emmc_gpios[] __initdata = { - { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" }, - { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" }, -}; - static void __init n8x0_mmc_init(void) + { int err; @@ -515,18 +512,27 @@ static void __init n8x0_mmc_init(void) mmc1_data.slots[1].ban_openended = 1; } - err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW, - "MMC slot switch"); + err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch"); if (err) return; + gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0); + if (machine_is_nokia_n810()) { - err = gpio_request_array(n810_emmc_gpios, - ARRAY_SIZE(n810_emmc_gpios)); + err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf"); + if (err) { + gpio_free(N8X0_SLOT_SWITCH_GPIO); + return; + } + gpio_direction_output(N810_EMMC_VSD_GPIO, 0); + + err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd"); if (err) { gpio_free(N8X0_SLOT_SWITCH_GPIO); + gpio_free(N810_EMMC_VSD_GPIO); return; } + gpio_direction_output(N810_EMMC_VIO_GPIO, 0); } mmc_data[0] = &mmc1_data; diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c index 3ff3a2c4b86e..33007fd4a083 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ b/trunk/arch/arm/mach-omap2/board-omap3beagle.c @@ -52,7 +52,6 @@ #include "hsmmc.h" #include "timer-gp.h" #include "pm.h" -#include "common-board-devices.h" #define NAND_BLOCK_SIZE SZ_128K @@ -80,12 +79,6 @@ static u8 omap3_beagle_get_rev(void) return omap3_beagle_version; } -static struct gpio omap3_beagle_rev_gpios[] __initdata = { - { 171, GPIOF_IN, "rev_id_0" }, - { 172, GPIOF_IN, "rev_id_1" }, - { 173, GPIOF_IN, "rev_id_2" }, -}; - static void __init omap3_beagle_init_rev(void) { int ret; @@ -95,13 +88,21 @@ static void __init omap3_beagle_init_rev(void) omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP); omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP); - ret = gpio_request_array(omap3_beagle_rev_gpios, - ARRAY_SIZE(omap3_beagle_rev_gpios)); - if (ret < 0) { - printk(KERN_ERR "Unable to get revision detection GPIO pins\n"); - omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; - return; - } + ret = gpio_request(171, "rev_id_0"); + if (ret < 0) + goto fail0; + + ret = gpio_request(172, "rev_id_1"); + if (ret < 0) + goto fail1; + + ret = gpio_request(173, "rev_id_2"); + if (ret < 0) + goto fail2; + + gpio_direction_input(171); + gpio_direction_input(172); + gpio_direction_input(173); beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1) | (gpio_get_value(173) << 2); @@ -127,6 +128,18 @@ static void __init omap3_beagle_init_rev(void) printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev); omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; } + + return; + +fail2: + gpio_free(172); +fail1: + gpio_free(171); +fail0: + printk(KERN_ERR "Unable to get revision detection GPIO pins\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; + + return; } static struct mtd_partition omap3beagle_nand_partitions[] = { @@ -160,6 +173,15 @@ static struct mtd_partition omap3beagle_nand_partitions[] = { }, }; +static struct omap_nand_platform_data omap3beagle_nand_data = { + .options = NAND_BUSWIDTH_16, + .parts = omap3beagle_nand_partitions, + .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions), + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ + .nand_setup = NULL, + .dev_ready = NULL, +}; + /* DSS */ static int beagle_enable_dvi(struct omap_dss_device *dssdev) @@ -221,10 +243,13 @@ static void __init beagle_display_init(void) { int r; - r = gpio_request_one(beagle_dvi_device.reset_gpio, GPIOF_OUT_INIT_LOW, - "DVI reset"); - if (r < 0) + r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset"); + if (r < 0) { printk(KERN_ERR "Unable to get DVI reset GPIO\n"); + return; + } + + gpio_direction_output(beagle_dvi_device.reset_gpio, 0); } #include "sdram-micron-mt46h32m32lf-6.h" @@ -251,7 +276,7 @@ static struct gpio_led gpio_leds[]; static int beagle_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - int r, usb_pwr_level; + int r; if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { mmc[0].gpio_wp = -EINVAL; @@ -270,46 +295,66 @@ static int beagle_twl_gpio_setup(struct device *dev, beagle_vmmc1_supply.dev = mmc[0].dev; beagle_vsim_supply.dev = mmc[0].dev; + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) { + r = gpio_request(gpio + 1, "EHCI_nOC"); + if (!r) { + r = gpio_direction_input(gpio + 1); + if (r) + gpio_free(gpio + 1); + } + if (r) + pr_err("%s: unable to configure EHCI_nOC\n", __func__); + } + /* * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active * high / others active low) - * DVI reset GPIO is different between beagle revisions */ - if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { - usb_pwr_level = GPIOF_OUT_INIT_HIGH; + gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); + else + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + + /* DVI reset GPIO is different between beagle revisions */ + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) beagle_dvi_device.reset_gpio = 129; - /* - * gpio + 1 on Xm controls the TFP410's enable line (active low) - * gpio + 2 control varies depending on the board rev as below: - * P7/P8 revisions(prototype): Camera EN - * A2+ revisions (production): LDO (DVI, serial, led blocks) - */ - r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW, - "nDVI_PWR_EN"); + else + beagle_dvi_device.reset_gpio = 170; + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + + /* + * gpio + 1 on Xm controls the TFP410's enable line (active low) + * gpio + 2 control varies depending on the board rev as follows: + * P7/P8 revisions(prototype): Camera EN + * A2+ revisions (production): LDO (supplies DVI, serial, led blocks) + */ + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { + r = gpio_request(gpio + 1, "nDVI_PWR_EN"); + if (!r) { + r = gpio_direction_output(gpio + 1, 0); + if (r) + gpio_free(gpio + 1); + } if (r) pr_err("%s: unable to configure nDVI_PWR_EN\n", __func__); - r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, - "DVI_LDO_EN"); + r = gpio_request(gpio + 2, "DVI_LDO_EN"); + if (!r) { + r = gpio_direction_output(gpio + 2, 1); + if (r) + gpio_free(gpio + 2); + } if (r) pr_err("%s: unable to configure DVI_LDO_EN\n", __func__); - } else { - usb_pwr_level = GPIOF_OUT_INIT_LOW; - beagle_dvi_device.reset_gpio = 170; - /* - * REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect - */ - if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC")) - pr_err("%s: unable to configure EHCI_nOC\n", __func__); } - gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR"); - - /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ - gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; - return 0; } @@ -408,6 +453,15 @@ static struct twl4030_platform_data beagle_twldata = { .vpll2 = &beagle_vpll2, }; +static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &beagle_twldata, + }, +}; + static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { { I2C_BOARD_INFO("eeprom", 0x50), @@ -416,7 +470,8 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { static int __init omap3_beagle_i2c_init(void) { - omap3_pmic_init("twl4030", &beagle_twldata); + omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, + ARRAY_SIZE(beagle_i2c_boardinfo)); /* Bus 3 is attached to the DVI port where devices like the pico DLP * projector don't work reliably with 400kHz */ omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom)); @@ -496,6 +551,39 @@ static struct platform_device *omap3_beagle_devices[] __initdata = { &keys_gpio, }; +static void __init omap3beagle_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + + /* find out the chip-select on which NAND exists */ + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + if ((ret & 0xC00) == 0x800) { + printk(KERN_INFO "Found NAND on CS%d\n", cs); + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + } + cs++; + } + + if (nandcs > GPMC_CS_NUM) { + printk(KERN_INFO "NAND: Unable to find configuration " + "in GPMC\n "); + return; + } + + if (nandcs < GPMC_CS_NUM) { + omap3beagle_nand_data.cs = nandcs; + + printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); + if (gpmc_nand_init(&omap3beagle_nand_data) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); + } +} + static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, @@ -514,6 +602,12 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void __init beagle_opp_init(void) { int r = 0; @@ -571,13 +665,13 @@ static void __init omap3_beagle_init(void) omap_serial_init(); omap_mux_init_gpio(170, OMAP_PIN_INPUT); + gpio_request(170, "DVI_nPD"); /* REVISIT leave DVI powered down until it's needed ... */ - gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); + gpio_direction_output(170, true); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); - omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions, - ARRAY_SIZE(omap3beagle_nand_partitions)); + omap3beagle_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); diff --git a/trunk/arch/arm/mach-omap2/board-omap3evm.c b/trunk/arch/arm/mach-omap2/board-omap3evm.c index 02e1ad29e1e8..5a1a916e5cc8 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3evm.c +++ b/trunk/arch/arm/mach-omap2/board-omap3evm.c @@ -50,7 +50,6 @@ #include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" -#include "common-board-devices.h" #define OMAP3_EVM_TS_GPIO 175 #define OMAP3_EVM_EHCI_VBUS 22 @@ -102,20 +101,49 @@ static void __init omap3_evm_get_revision(void) } #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) -#include +static struct resource omap3evm_smsc911x_resources[] = { + [0] = { + .start = OMAP3EVM_ETHR_START, + .end = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ), + .end = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ), + .flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW), + }, +}; -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = OMAP3EVM_SMSC911X_CS, - .gpio_irq = OMAP3EVM_ETHR_GPIO_IRQ, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS), +}; + +static struct platform_device omap3evm_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(omap3evm_smsc911x_resources), + .resource = &omap3evm_smsc911x_resources[0], + .dev = { + .platform_data = &smsc911x_config, + }, }; static inline void __init omap3evm_init_smsc911x(void) { + int eth_cs, eth_rst; struct clk *l3ck; unsigned int rate; + if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) + eth_rst = OMAP3EVM_GEN1_ETHR_GPIO_RST; + else + eth_rst = OMAP3EVM_GEN2_ETHR_GPIO_RST; + + eth_cs = OMAP3EVM_SMSC911X_CS; + l3ck = clk_get(NULL, "l3_ck"); if (IS_ERR(l3ck)) rate = 100000000; @@ -124,13 +152,33 @@ static inline void __init omap3evm_init_smsc911x(void) /* Configure ethernet controller reset gpio */ if (cpu_is_omap3430()) { - if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) - smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST; - else - smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST; + if (gpio_request(eth_rst, "SMSC911x gpio") < 0) { + pr_err(KERN_ERR "Failed to request %d for smsc911x\n", + eth_rst); + return; + } + + if (gpio_direction_output(eth_rst, 1) < 0) { + pr_err(KERN_ERR "Failed to set direction of %d for" \ + " smsc911x\n", eth_rst); + return; + } + /* reset pulse to ethernet controller*/ + usleep_range(150, 220); + gpio_set_value(eth_rst, 0); + usleep_range(150, 220); + gpio_set_value(eth_rst, 1); + usleep_range(1, 2); + } + + if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", + OMAP3EVM_ETHR_GPIO_IRQ); + return; } - gpmc_smsc911x_init(&smsc911x_cfg); + gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ); + platform_device_register(&omap3evm_smsc911x_device); } #else @@ -149,15 +197,6 @@ static inline void __init omap3evm_init_smsc911x(void) { return; } #define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO 210 #define OMAP3EVM_DVI_PANEL_EN_GPIO 199 -static struct gpio omap3_evm_dss_gpios[] __initdata = { - { OMAP3EVM_LCD_PANEL_RESB, GPIOF_OUT_INIT_HIGH, "lcd_panel_resb" }, - { OMAP3EVM_LCD_PANEL_INI, GPIOF_OUT_INIT_HIGH, "lcd_panel_ini" }, - { OMAP3EVM_LCD_PANEL_QVGA, GPIOF_OUT_INIT_LOW, "lcd_panel_qvga" }, - { OMAP3EVM_LCD_PANEL_LR, GPIOF_OUT_INIT_HIGH, "lcd_panel_lr" }, - { OMAP3EVM_LCD_PANEL_UD, GPIOF_OUT_INIT_HIGH, "lcd_panel_ud" }, - { OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW, "lcd_panel_envdd" }, -}; - static int lcd_enabled; static int dvi_enabled; @@ -165,10 +204,61 @@ static void __init omap3_evm_display_init(void) { int r; - r = gpio_request_array(omap3_evm_dss_gpios, - ARRAY_SIZE(omap3_evm_dss_gpios)); - if (r) - printk(KERN_ERR "failed to get lcd_panel_* gpios\n"); + r = gpio_request(OMAP3EVM_LCD_PANEL_RESB, "lcd_panel_resb"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_resb\n"); + return; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_RESB, 1); + + r = gpio_request(OMAP3EVM_LCD_PANEL_INI, "lcd_panel_ini"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_ini\n"); + goto err_1; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_INI, 1); + + r = gpio_request(OMAP3EVM_LCD_PANEL_QVGA, "lcd_panel_qvga"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_qvga\n"); + goto err_2; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_QVGA, 0); + + r = gpio_request(OMAP3EVM_LCD_PANEL_LR, "lcd_panel_lr"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_lr\n"); + goto err_3; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_LR, 1); + + r = gpio_request(OMAP3EVM_LCD_PANEL_UD, "lcd_panel_ud"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_ud\n"); + goto err_4; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_UD, 1); + + r = gpio_request(OMAP3EVM_LCD_PANEL_ENVDD, "lcd_panel_envdd"); + if (r) { + printk(KERN_ERR "failed to get lcd_panel_envdd\n"); + goto err_5; + } + gpio_direction_output(OMAP3EVM_LCD_PANEL_ENVDD, 0); + + return; + +err_5: + gpio_free(OMAP3EVM_LCD_PANEL_UD); +err_4: + gpio_free(OMAP3EVM_LCD_PANEL_LR); +err_3: + gpio_free(OMAP3EVM_LCD_PANEL_QVGA); +err_2: + gpio_free(OMAP3EVM_LCD_PANEL_INI); +err_1: + gpio_free(OMAP3EVM_LCD_PANEL_RESB); + } static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev) @@ -358,7 +448,7 @@ static struct platform_device leds_gpio = { static int omap3evm_twl_gpio_setup(struct device *dev, unsigned gpio, unsigned ngpio) { - int r, lcd_bl_en; + int r; /* gpio + 0 is "mmc0_cd" (input/IRQ) */ omap_mux_init_gpio(63, OMAP_PIN_INPUT); @@ -375,14 +465,16 @@ static int omap3evm_twl_gpio_setup(struct device *dev, */ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ - lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ? - GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; - r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL"); + r = gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); + if (!r) + r = gpio_direction_output(gpio + TWL4030_GPIO_MAX, + (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) ? 1 : 0); if (r) printk(KERN_ERR "failed to get/set lcd_bkl gpio\n"); /* gpio + 7 == DVI Enable */ - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI"); + gpio_request(gpio + 7, "EN_DVI"); + gpio_direction_output(gpio + 7, 0); /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -560,18 +652,78 @@ static struct twl4030_platform_data omap3evm_twldata = { .vdac = &omap3_evm_vdac, .vpll2 = &omap3_evm_vpll2, .vio = &omap3evm_vio, - .vmmc1 = &omap3evm_vmmc1, - .vsim = &omap3evm_vsim, +}; + +static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &omap3evm_twldata, + }, }; static int __init omap3_evm_i2c_init(void) { - omap3_pmic_init("twl4030", &omap3evm_twldata); + /* + * REVISIT: These entries can be set in omap3evm_twl_data + * after a merge with MFD tree + */ + omap3evm_twldata.vmmc1 = &omap3evm_vmmc1; + omap3evm_twldata.vsim = &omap3evm_vsim; + + omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo, + ARRAY_SIZE(omap3evm_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); return 0; } +static void ads7846_dev_init(void) +{ + if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0) + printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); + + gpio_direction_input(OMAP3_EVM_TS_GPIO); + gpio_set_debounce(OMAP3_EVM_TS_GPIO, 310); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OMAP3_EVM_TS_GPIO); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, + .settle_delay_usecs = 150, + .wakeup = true, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info omap3evm_spi_board_info[] = { + [0] = { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO), + .platform_data = &ads7846_config, + }, +}; + static struct omap_board_config_kernel omap3_evm_config[] __initdata = { }; @@ -673,11 +825,6 @@ static struct omap_musb_board_data musb_board_data = { .power = 100, }; -static struct gpio omap3_evm_ehci_gpios[] __initdata = { - { OMAP3_EVM_EHCI_VBUS, GPIOF_OUT_INIT_HIGH, "enable EHCI VBUS" }, - { OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW, "select EHCI port" }, -}; - static void __init omap3_evm_init(void) { omap3_evm_get_revision(); @@ -694,6 +841,9 @@ static void __init omap3_evm_init(void) omap_display_init(&omap3_evm_dss_data); + spi_register_board_info(omap3evm_spi_board_info, + ARRAY_SIZE(omap3evm_spi_board_info)); + omap_serial_init(); /* OMAP3EVM uses ISP1504 phy and so register nop transceiver */ @@ -701,12 +851,16 @@ static void __init omap3_evm_init(void) if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) { /* enable EHCI VBUS using GPIO22 */ - omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP); + omap_mux_init_gpio(22, OMAP_PIN_INPUT_PULLUP); + gpio_request(OMAP3_EVM_EHCI_VBUS, "enable EHCI VBUS"); + gpio_direction_output(OMAP3_EVM_EHCI_VBUS, 0); + gpio_set_value(OMAP3_EVM_EHCI_VBUS, 1); + /* Select EHCI port on main board */ - omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT, - OMAP_PIN_INPUT_PULLUP); - gpio_request_array(omap3_evm_ehci_gpios, - ARRAY_SIZE(omap3_evm_ehci_gpios)); + omap_mux_init_gpio(61, OMAP_PIN_INPUT_PULLUP); + gpio_request(OMAP3_EVM_EHCI_SELECT, "select EHCI port"); + gpio_direction_output(OMAP3_EVM_EHCI_SELECT, 0); + gpio_set_value(OMAP3_EVM_EHCI_SELECT, 0); /* setup EHCI phy reset config */ omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP); @@ -722,7 +876,7 @@ static void __init omap3_evm_init(void) } usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); - omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL); + ads7846_dev_init(); omap3evm_init_smsc911x(); omap3_evm_display_init(); diff --git a/trunk/arch/arm/mach-omap2/board-omap3logic.c b/trunk/arch/arm/mach-omap2/board-omap3logic.c index 60d9be49dbab..b726943d7c93 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3logic.c +++ b/trunk/arch/arm/mach-omap2/board-omap3logic.c @@ -37,7 +37,6 @@ #include "hsmmc.h" #include "timer-gp.h" #include "control.h" -#include "common-board-devices.h" #include #include @@ -94,9 +93,19 @@ static struct twl4030_platform_data omap3logic_twldata = { .vmmc1 = &omap3logic_vmmc1, }; +static struct i2c_board_info __initdata omap3logic_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &omap3logic_twldata, + }, +}; + static int __init omap3logic_i2c_init(void) { - omap3_pmic_init("twl4030", &omap3logic_twldata); + omap_register_i2c_bus(1, 2600, omap3logic_i2c_boardinfo, + ARRAY_SIZE(omap3logic_i2c_boardinfo)); return 0; } @@ -138,6 +147,7 @@ static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = { .cs = OMAP3LOGIC_SMSC911X_CS, .gpio_irq = -EINVAL, .gpio_reset = -EINVAL, + .flags = IORESOURCE_IRQ_LOWLEVEL, }; /* TODO/FIXME (comment by Peter Barada, LogicPD): diff --git a/trunk/arch/arm/mach-omap2/board-omap3pandora.c b/trunk/arch/arm/mach-omap2/board-omap3pandora.c index 78dd2a7fe6e6..07dba888f450 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3pandora.c +++ b/trunk/arch/arm/mach-omap2/board-omap3pandora.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -51,7 +52,6 @@ #include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" -#include "common-board-devices.h" #define PANDORA_WIFI_IRQ_GPIO 21 #define PANDORA_WIFI_NRESET_GPIO 23 @@ -305,13 +305,24 @@ static int omap3pandora_twl_gpio_setup(struct device *dev, /* gpio + 13 drives 32kHz buffer for wifi module */ gpio_32khz = gpio + 13; - ret = gpio_request_one(gpio_32khz, GPIOF_OUT_INIT_HIGH, "wifi 32kHz"); + ret = gpio_request(gpio_32khz, "wifi 32kHz"); if (ret < 0) { pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret); - return -ENODEV; + goto fail; + } + + ret = gpio_direction_output(gpio_32khz, 1); + if (ret < 0) { + pr_err("Cannot set GPIO line %d, ret=%d\n", gpio_32khz, ret); + goto fail_direction; } return 0; + +fail_direction: + gpio_free(gpio_32khz); +fail: + return -ENODEV; } static struct twl4030_gpio_platform_data omap3pandora_gpio_data = { @@ -533,6 +544,15 @@ static struct twl4030_platform_data omap3pandora_twldata = { .bci = &pandora_bci_data, }; +static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("tps65950", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &omap3pandora_twldata, + }, +}; + static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = { { I2C_BOARD_INFO("bq27500", 0x55), @@ -542,15 +562,61 @@ static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = { static int __init omap3pandora_i2c_init(void) { - omap3_pmic_init("tps65950", &omap3pandora_twldata); + omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo, + ARRAY_SIZE(omap3pandora_i2c_boardinfo)); /* i2c2 pins are not connected */ omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo, ARRAY_SIZE(omap3pandora_i2c3_boardinfo)); return 0; } +static void __init omap3pandora_ads7846_init(void) +{ + int gpio = OMAP3_PANDORA_TS_GPIO; + int ret; + + ret = gpio_request(gpio, "ads7846_pen_down"); + if (ret < 0) { + printk(KERN_ERR "Failed to request GPIO %d for " + "ads7846 pen down IRQ\n", gpio); + return; + } + + gpio_direction_input(gpio); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OMAP3_PANDORA_TS_GPIO); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + static struct spi_board_info omap3pandora_spi_board_info[] __initdata = { { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_PANDORA_TS_GPIO), + .platform_data = &ads7846_config, + }, { .modalias = "tpo_td043mtea1_panel_spi", .bus_num = 1, .chip_select = 1, @@ -573,10 +639,14 @@ static void __init pandora_wl1251_init(void) memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); - ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); + ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq"); if (ret < 0) goto fail; + ret = gpio_direction_input(PANDORA_WIFI_IRQ_GPIO); + if (ret < 0) + goto fail_irq; + pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); if (pandora_wl1251_pdata.irq < 0) goto fail_irq; @@ -618,6 +688,12 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void __init omap3pandora_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -629,9 +705,9 @@ static void __init omap3pandora_init(void) omap_serial_init(); spi_register_board_info(omap3pandora_spi_board_info, ARRAY_SIZE(omap3pandora_spi_board_info)); - omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL); + omap3pandora_ads7846_init(); usbhs_init(&usbhs_bdata); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); gpmc_nand_init(&pandora_nand_data); /* Ensure SDRC pins are mux'd for self-refresh */ diff --git a/trunk/arch/arm/mach-omap2/board-omap3stalker.c b/trunk/arch/arm/mach-omap2/board-omap3stalker.c index 085c60a7c47c..a6e0b9161c99 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3stalker.c +++ b/trunk/arch/arm/mach-omap2/board-omap3stalker.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -53,28 +54,52 @@ #include "mux.h" #include "hsmmc.h" #include "timer-gp.h" -#include "common-board-devices.h" #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) -#include - #define OMAP3STALKER_ETHR_START 0x2c000000 #define OMAP3STALKER_ETHR_SIZE 1024 #define OMAP3STALKER_ETHR_GPIO_IRQ 19 #define OMAP3STALKER_SMC911X_CS 5 -static struct omap_smsc911x_platform_data smsc911x_cfg = { - .cs = OMAP3STALKER_SMC911X_CS, - .gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ, - .gpio_reset = -EINVAL, +static struct resource omap3stalker_smsc911x_resources[] = { + [0] = { + .start = OMAP3STALKER_ETHR_START, + .end = + (OMAP3STALKER_ETHR_START + OMAP3STALKER_ETHR_SIZE - 1), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ), + .end = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ), + .flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW), + }, +}; + +static struct smsc911x_platform_config smsc911x_config = { + .phy_interface = PHY_INTERFACE_MODE_MII, + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS), }; +static struct platform_device omap3stalker_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(omap3stalker_smsc911x_resources), + .resource = &omap3stalker_smsc911x_resources[0], + .dev = { + .platform_data = &smsc911x_config, + }, +}; + static inline void __init omap3stalker_init_eth(void) { + int eth_cs; struct clk *l3ck; unsigned int rate; + eth_cs = OMAP3STALKER_SMC911X_CS; + l3ck = clk_get(NULL, "l3_ck"); if (IS_ERR(l3ck)) rate = 100000000; @@ -82,7 +107,16 @@ static inline void __init omap3stalker_init_eth(void) rate = clk_get_rate(l3ck); omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); - gpmc_smsc911x_init(&smsc911x_cfg); + if (gpio_request(OMAP3STALKER_ETHR_GPIO_IRQ, "SMC911x irq") < 0) { + printk(KERN_ERR + "Failed to request GPIO%d for smc911x IRQ\n", + OMAP3STALKER_ETHR_GPIO_IRQ); + return; + } + + gpio_direction_input(OMAP3STALKER_ETHR_GPIO_IRQ); + + platform_device_register(&omap3stalker_smsc911x_device); } #else @@ -331,11 +365,12 @@ omap3stalker_twl_gpio_setup(struct device *dev, */ /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ - gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW, - "EN_LCD_BKL"); + gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); /* gpio + 7 == DVI Enable */ - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI"); + gpio_request(gpio + 7, "EN_DVI"); + gpio_direction_output(gpio + 7, 0); /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -454,8 +489,15 @@ static struct twl4030_platform_data omap3stalker_twldata = { .codec = &omap3stalker_codec_data, .vdac = &omap3_stalker_vdac, .vpll2 = &omap3_stalker_vpll2, - .vmmc1 = &omap3stalker_vmmc1, - .vsim = &omap3stalker_vsim, +}; + +static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &omap3stalker_twldata, + }, }; static struct at24_platform_data fram_info = { @@ -474,7 +516,15 @@ static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = { static int __init omap3_stalker_i2c_init(void) { - omap3_pmic_init("twl4030", &omap3stalker_twldata); + /* + * REVISIT: These entries can be set in omap3evm_twl_data + * after a merge with MFD tree + */ + omap3stalker_twldata.vmmc1 = &omap3stalker_vmmc1; + omap3stalker_twldata.vsim = &omap3stalker_vsim; + + omap_register_i2c_bus(1, 2600, omap3stalker_i2c_boardinfo, + ARRAY_SIZE(omap3stalker_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3, ARRAY_SIZE(omap3stalker_i2c_boardinfo3)); @@ -482,6 +532,49 @@ static int __init omap3_stalker_i2c_init(void) } #define OMAP3_STALKER_TS_GPIO 175 +static void ads7846_dev_init(void) +{ + if (gpio_request(OMAP3_STALKER_TS_GPIO, "ADS7846 pendown") < 0) + printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); + + gpio_direction_input(OMAP3_STALKER_TS_GPIO); + gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310); +} + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OMAP3_STALKER_TS_GPIO); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, + .settle_delay_usecs = 150, +}; + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info omap3stalker_spi_board_info[] = { + [0] = { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_STALKER_TS_GPIO), + .platform_data = &ads7846_config, + }, +}; static struct omap_board_config_kernel omap3_stalker_config[] __initdata = { }; @@ -525,6 +618,12 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void __init omap3_stalker_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); @@ -537,11 +636,13 @@ static void __init omap3_stalker_init(void) ARRAY_SIZE(omap3_stalker_devices)); omap_display_init(&omap3_stalker_dss_data); + spi_register_board_info(omap3stalker_spi_board_info, + ARRAY_SIZE(omap3stalker_spi_board_info)); omap_serial_init(); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); - omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL); + ads7846_dev_init(); omap_mux_init_gpio(21, OMAP_PIN_OUTPUT); omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP); diff --git a/trunk/arch/arm/mach-omap2/board-omap3touchbook.c b/trunk/arch/arm/mach-omap2/board-omap3touchbook.c index 82872d7d313b..127cb1752bdd 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3touchbook.c +++ b/trunk/arch/arm/mach-omap2/board-omap3touchbook.c @@ -52,7 +52,6 @@ #include "mux.h" #include "hsmmc.h" #include "timer-gp.h" -#include "common-board-devices.h" #include @@ -96,6 +95,15 @@ static struct mtd_partition omap3touchbook_nand_partitions[] = { }, }; +static struct omap_nand_platform_data omap3touchbook_nand_data = { + .options = NAND_BUSWIDTH_16, + .parts = omap3touchbook_nand_partitions, + .nr_parts = ARRAY_SIZE(omap3touchbook_nand_partitions), + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ + .nand_setup = NULL, + .dev_ready = NULL, +}; + #include "sdram-micron-mt46h32m32lf-6.h" static struct omap2_hsmmc_info mmc[] = { @@ -146,11 +154,13 @@ static int touchbook_twl_gpio_setup(struct device *dev, /* REVISIT: need ehci-omap hooks for external VBUS * power switch and overcurrent detect */ - gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"); + + gpio_request(gpio + 1, "EHCI_nOC"); + gpio_direction_input(gpio + 1); /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ - gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW, - "nEN_USB_PWR"); + gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; @@ -263,6 +273,15 @@ static struct twl4030_platform_data touchbook_twldata = { .vpll2 = &touchbook_vpll2, }; +static struct i2c_board_info __initdata touchbook_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &touchbook_twldata, + }, +}; + static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = { { I2C_BOARD_INFO("bq27200", 0x55), @@ -272,7 +291,8 @@ static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = { static int __init omap3_touchbook_i2c_init(void) { /* Standard TouchBook bus */ - omap3_pmic_init("twl4030", &touchbook_twldata); + omap_register_i2c_bus(1, 2600, touchbook_i2c_boardinfo, + ARRAY_SIZE(touchbook_i2c_boardinfo)); /* Additional TouchBook bus */ omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo, @@ -281,7 +301,19 @@ static int __init omap3_touchbook_i2c_init(void) return 0; } -static struct ads7846_platform_data ads7846_pdata = { +static void __init omap3_ads7846_init(void) +{ + if (gpio_request(OMAP3_TS_GPIO, "ads7846_pen_down")) { + printk(KERN_ERR "Failed to request GPIO %d for " + "ads7846 pen down IRQ\n", OMAP3_TS_GPIO); + return; + } + + gpio_direction_input(OMAP3_TS_GPIO); + gpio_set_debounce(OMAP3_TS_GPIO, 310); +} + +static struct ads7846_platform_data ads7846_config = { .x_min = 100, .y_min = 265, .x_max = 3950, @@ -295,6 +327,23 @@ static struct ads7846_platform_data ads7846_pdata = { .keep_vref_on = 1, }; +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static struct spi_board_info omap3_ads7846_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 4, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OMAP3_TS_GPIO), + .platform_data = &ads7846_config, + } +}; + static struct gpio_led gpio_leds[] = { { .name = "touchbook::usr0", @@ -385,6 +434,39 @@ static struct platform_device *omap3_touchbook_devices[] __initdata = { &keys_gpio, }; +static void __init omap3touchbook_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + + /* find out the chip-select on which NAND exists */ + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + if ((ret & 0xC00) == 0x800) { + printk(KERN_INFO "Found NAND on CS%d\n", cs); + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + } + cs++; + } + + if (nandcs > GPMC_CS_NUM) { + printk(KERN_INFO "NAND: Unable to find configuration " + "in GPMC\n "); + return; + } + + if (nandcs < GPMC_CS_NUM) { + omap3touchbook_nand_data.cs = nandcs; + + printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); + if (gpmc_nand_init(&omap3touchbook_nand_data) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); + } +} + static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, @@ -399,10 +481,15 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { static void omap3_touchbook_poweroff(void) { - int pwr_off = TB_KILL_POWER_GPIO; + int r; - if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0) + r = gpio_request(TB_KILL_POWER_GPIO, "DVI reset"); + if (r < 0) { printk(KERN_ERR "Unable to get kill power GPIO\n"); + return; + } + + gpio_direction_output(TB_KILL_POWER_GPIO, 0); } static int __init early_touchbook_revision(char *p) @@ -414,6 +501,12 @@ static int __init early_touchbook_revision(char *p) } early_param("tbr", early_touchbook_revision); +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void __init omap3_touchbook_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); @@ -428,15 +521,17 @@ static void __init omap3_touchbook_init(void) omap_serial_init(); omap_mux_init_gpio(170, OMAP_PIN_INPUT); + gpio_request(176, "DVI_nPD"); /* REVISIT leave DVI powered down until it's needed ... */ - gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD"); + gpio_direction_output(176, true); /* Touchscreen and accelerometer */ - omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata); - usb_musb_init(NULL); + spi_register_board_info(omap3_ads7846_spi_board_info, + ARRAY_SIZE(omap3_ads7846_spi_board_info)); + omap3_ads7846_init(); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); - omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions, - ARRAY_SIZE(omap3touchbook_nand_partitions)); + omap3touchbook_flash_init(); /* Ensure SDRC pins are mux'd for self-refresh */ omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); diff --git a/trunk/arch/arm/mach-omap2/board-omap4panda.c b/trunk/arch/arm/mach-omap2/board-omap4panda.c index 5d7c0a313dc7..f3a7b1011914 100644 --- a/trunk/arch/arm/mach-omap2/board-omap4panda.c +++ b/trunk/arch/arm/mach-omap2/board-omap4panda.c @@ -46,7 +46,6 @@ #include "hsmmc.h" #include "control.h" #include "mux.h" -#include "common-board-devices.h" #define GPIO_HUB_POWER 1 #define GPIO_HUB_NRESET 62 @@ -112,11 +111,6 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .reset_gpio_port[2] = -EINVAL }; -static struct gpio panda_ehci_gpios[] __initdata = { - { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, "hub_power" }, - { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, "hub_nreset" }, -}; - static void __init omap4_ehci_init(void) { int ret; @@ -126,27 +120,44 @@ static void __init omap4_ehci_init(void) phy_ref_clk = clk_get(NULL, "auxclk3_ck"); if (IS_ERR(phy_ref_clk)) { pr_err("Cannot request auxclk3\n"); - return; + goto error1; } clk_set_rate(phy_ref_clk, 19200000); clk_enable(phy_ref_clk); - /* disable the power to the usb hub prior to init and reset phy+hub */ - ret = gpio_request_array(panda_ehci_gpios, - ARRAY_SIZE(panda_ehci_gpios)); + /* disable the power to the usb hub prior to init */ + ret = gpio_request(GPIO_HUB_POWER, "hub_power"); if (ret) { - pr_err("Unable to initialize EHCI power/reset\n"); - return; + pr_err("Cannot request GPIO %d\n", GPIO_HUB_POWER); + goto error1; } - gpio_export(GPIO_HUB_POWER, 0); + gpio_direction_output(GPIO_HUB_POWER, 0); + gpio_set_value(GPIO_HUB_POWER, 0); + + /* reset phy+hub */ + ret = gpio_request(GPIO_HUB_NRESET, "hub_nreset"); + if (ret) { + pr_err("Cannot request GPIO %d\n", GPIO_HUB_NRESET); + goto error2; + } gpio_export(GPIO_HUB_NRESET, 0); + gpio_direction_output(GPIO_HUB_NRESET, 0); + gpio_set_value(GPIO_HUB_NRESET, 0); gpio_set_value(GPIO_HUB_NRESET, 1); usbhs_init(&usbhs_bdata); /* enable power to hub */ gpio_set_value(GPIO_HUB_POWER, 1); + return; + +error2: + gpio_free(GPIO_HUB_POWER); +error1: + pr_err("Unable to initialize EHCI power/reset\n"); + return; + } static struct omap_musb_board_data musb_board_data = { @@ -397,6 +408,15 @@ static struct twl4030_platform_data omap4_panda_twldata = { .usb = &omap4_usbphy_data, }; +static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl6030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = OMAP44XX_IRQ_SYS_1N, + .platform_data = &omap4_panda_twldata, + }, +}; + /* * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM * is connected as I2C slave device, and can be accessed at address 0x50 @@ -409,7 +429,12 @@ static struct i2c_board_info __initdata panda_i2c_eeprom[] = { static int __init omap4_panda_i2c_init(void) { - omap4_pmic_init("twl6030", &omap4_panda_twldata); + /* + * Phoenix Audio IC needs I2C1 to + * start with 400 KHz or less + */ + omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo, + ARRAY_SIZE(omap4_panda_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); /* * Bus 3 is attached to the DVI port where devices like the pico DLP @@ -626,19 +651,27 @@ static void omap4_panda_hdmi_mux_init(void) OMAP_PIN_INPUT_PULLUP); } -static struct gpio panda_hdmi_gpios[] = { - { HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" }, - { HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" }, -}; - static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev) { int status; - status = gpio_request_array(panda_hdmi_gpios, - ARRAY_SIZE(panda_hdmi_gpios)); - if (status) - pr_err("Cannot request HDMI GPIOs\n"); + status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, + "hdmi_gpio_hpd"); + if (status) { + pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD); + return status; + } + status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, + "hdmi_gpio_ls_oe"); + if (status) { + pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE); + goto error1; + } + + return 0; + +error1: + gpio_free(HDMI_GPIO_HPD); return status; } diff --git a/trunk/arch/arm/mach-omap2/board-overo.c b/trunk/arch/arm/mach-omap2/board-overo.c index c03f92b14f9c..59ca33326b8c 100644 --- a/trunk/arch/arm/mach-omap2/board-overo.c +++ b/trunk/arch/arm/mach-omap2/board-overo.c @@ -56,7 +56,6 @@ #include "mux.h" #include "sdram-micron-mt46h32m32lf-6.h" #include "hsmmc.h" -#include "common-board-devices.h" #define OVERO_GPIO_BT_XGATE 15 #define OVERO_GPIO_W2W_NRESET 16 @@ -75,6 +74,30 @@ #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +#include + +static struct omap2_mcspi_device_config ads7846_mcspi_config = { + .turbo_mode = 0, + .single_channel = 1, /* 0: slave, 1: master */ +}; + +static int ads7846_get_pendown_state(void) +{ + return !gpio_get_value(OVERO_GPIO_PENDOWN); +} + +static struct ads7846_platform_data ads7846_config = { + .x_max = 0x0fff, + .y_max = 0x0fff, + .x_plate_ohms = 180, + .pressure_max = 255, + .debounce_max = 10, + .debounce_tol = 3, + .debounce_rep = 1, + .get_pendown_state = ads7846_get_pendown_state, + .keep_vref_on = 1, +}; + /* fixed regulator for ads7846 */ static struct regulator_consumer_supply ads7846_supply = REGULATOR_SUPPLY("vcc", "spi1.0"); @@ -105,7 +128,14 @@ static struct platform_device vads7846_device = { static void __init overo_ads7846_init(void) { - omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL); + if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) && + (gpio_direction_input(OVERO_GPIO_PENDOWN) == 0)) { + gpio_export(OVERO_GPIO_PENDOWN, 0); + } else { + printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n"); + return; + } + platform_device_register(&vads7846_device); } @@ -116,28 +146,106 @@ static inline void __init overo_ads7846_init(void) { return; } #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) #include -#include -static struct omap_smsc911x_platform_data smsc911x_cfg = { +static struct resource overo_smsc911x_resources[] = { + { + .name = "smsc911x-memory", + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct resource overo_smsc911x2_resources[] = { + { + .name = "smsc911x2-memory", + .flags = IORESOURCE_MEM, + }, + { + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config overo_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, + .flags = SMSC911X_USE_32BIT , + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device overo_smsc911x_device = { + .name = "smsc911x", .id = 0, - .cs = OVERO_SMSC911X_CS, - .gpio_irq = OVERO_SMSC911X_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT, + .num_resources = ARRAY_SIZE(overo_smsc911x_resources), + .resource = overo_smsc911x_resources, + .dev = { + .platform_data = &overo_smsc911x_config, + }, }; -static struct omap_smsc911x_platform_data smsc911x2_cfg = { +static struct platform_device overo_smsc911x2_device = { + .name = "smsc911x", .id = 1, - .cs = OVERO_SMSC911X2_CS, - .gpio_irq = OVERO_SMSC911X2_GPIO, - .gpio_reset = -EINVAL, - .flags = SMSC911X_USE_32BIT, + .num_resources = ARRAY_SIZE(overo_smsc911x2_resources), + .resource = overo_smsc911x2_resources, + .dev = { + .platform_data = &overo_smsc911x_config, + }, }; -static void __init overo_init_smsc911x(void) +static struct platform_device *smsc911x_devices[] = { + &overo_smsc911x_device, + &overo_smsc911x2_device, +}; + +static inline void __init overo_init_smsc911x(void) { - gpmc_smsc911x_init(&smsc911x_cfg); - gpmc_smsc911x_init(&smsc911x2_cfg); + unsigned long cs_mem_base, cs_mem_base2; + + /* set up first smsc911x chip */ + + if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n"); + return; + } + + overo_smsc911x_resources[0].start = cs_mem_base + 0x0; + overo_smsc911x_resources[0].end = cs_mem_base + 0xff; + + if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) && + (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) { + gpio_export(OVERO_SMSC911X_GPIO, 0); + } else { + printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n"); + return; + } + + overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO); + overo_smsc911x_resources[1].end = 0; + + /* set up second smsc911x chip */ + + if (gpmc_cs_request(OVERO_SMSC911X2_CS, SZ_16M, &cs_mem_base2) < 0) { + printk(KERN_ERR "Failed request for GPMC mem for smsc911x2\n"); + return; + } + + overo_smsc911x2_resources[0].start = cs_mem_base2 + 0x0; + overo_smsc911x2_resources[0].end = cs_mem_base2 + 0xff; + + if ((gpio_request(OVERO_SMSC911X2_GPIO, "SMSC911X2 IRQ") == 0) && + (gpio_direction_input(OVERO_SMSC911X2_GPIO) == 0)) { + gpio_export(OVERO_SMSC911X2_GPIO, 0); + } else { + printk(KERN_ERR "could not obtain gpio for SMSC911X2 IRQ\n"); + return; + } + + overo_smsc911x2_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X2_GPIO); + overo_smsc911x2_resources[1].end = 0; + + platform_add_devices(smsc911x_devices, ARRAY_SIZE(smsc911x_devices)); } #else @@ -151,20 +259,21 @@ static int dvi_enabled; #define OVERO_GPIO_LCD_EN 144 #define OVERO_GPIO_LCD_BL 145 -static struct gpio overo_dss_gpios[] __initdata = { - { OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" }, - { OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" }, -}; - static void __init overo_display_init(void) { - if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) { - printk(KERN_ERR "could not obtain DSS control GPIOs\n"); - return; - } + if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) && + (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0)) + gpio_export(OVERO_GPIO_LCD_EN, 0); + else + printk(KERN_ERR "could not obtain gpio for " + "OVERO_GPIO_LCD_EN\n"); - gpio_export(OVERO_GPIO_LCD_EN, 0); - gpio_export(OVERO_GPIO_LCD_BL, 0); + if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) && + (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0)) + gpio_export(OVERO_GPIO_LCD_BL, 0); + else + printk(KERN_ERR "could not obtain gpio for " + "OVERO_GPIO_LCD_BL\n"); } static int overo_panel_enable_dvi(struct omap_dss_device *dssdev) @@ -303,6 +412,45 @@ static struct mtd_partition overo_nand_partitions[] = { }, }; +static struct omap_nand_platform_data overo_nand_data = { + .parts = overo_nand_partitions, + .nr_parts = ARRAY_SIZE(overo_nand_partitions), + .dma_channel = -1, /* disable DMA in OMAP NAND driver */ +}; + +static void __init overo_flash_init(void) +{ + u8 cs = 0; + u8 nandcs = GPMC_CS_NUM + 1; + + /* find out the chip-select on which NAND exists */ + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + if ((ret & 0xC00) == 0x800) { + printk(KERN_INFO "Found NAND on CS%d\n", cs); + if (nandcs > GPMC_CS_NUM) + nandcs = cs; + } + cs++; + } + + if (nandcs > GPMC_CS_NUM) { + printk(KERN_INFO "NAND: Unable to find configuration " + "in GPMC\n "); + return; + } + + if (nandcs < GPMC_CS_NUM) { + overo_nand_data.cs = nandcs; + + printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); + if (gpmc_nand_init(&overo_nand_data) < 0) + printk(KERN_ERR "Unable to register NAND device\n"); + } +} + static struct omap2_hsmmc_info mmc[] = { { .mmc = 1, @@ -500,15 +648,37 @@ static struct twl4030_platform_data overo_twldata = { .vpll2 = &overo_vpll2, }; +static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("tps65950", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &overo_twldata, + }, +}; + static int __init overo_i2c_init(void) { - omap3_pmic_init("tps65950", &overo_twldata); + omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo, + ARRAY_SIZE(overo_i2c_boardinfo)); /* i2c2 pins are used for gpio */ omap_register_i2c_bus(3, 400, NULL, 0); return 0; } static struct spi_board_info overo_spi_board_info[] __initdata = { +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + { + .modalias = "ads7846", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 1500000, + .controller_data = &ads7846_mcspi_config, + .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), + .platform_data = &ads7846_config, + }, +#endif #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) { @@ -552,22 +722,20 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif -static struct gpio overo_bt_gpios[] __initdata = { - { OVERO_GPIO_BT_XGATE, GPIOF_OUT_INIT_LOW, "lcd enable" }, - { OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" }, +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, }; static void __init overo_init(void) { - int ret; - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); overo_i2c_init(); omap_display_init(&overo_dss_data); omap_serial_init(); - omap_nand_flash_init(0, overo_nand_partitions, - ARRAY_SIZE(overo_nand_partitions)); - usb_musb_init(NULL); + overo_flash_init(); + usb_musb_init(&musb_board_data); usbhs_init(&usbhs_bdata); overo_spi_init(); overo_ads7846_init(); @@ -580,9 +748,9 @@ static void __init overo_init(void) omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); - ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH, - "OVERO_GPIO_W2W_NRESET"); - if (ret == 0) { + if ((gpio_request(OVERO_GPIO_W2W_NRESET, + "OVERO_GPIO_W2W_NRESET") == 0) && + (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) { gpio_export(OVERO_GPIO_W2W_NRESET, 0); gpio_set_value(OVERO_GPIO_W2W_NRESET, 0); udelay(10); @@ -592,20 +760,25 @@ static void __init overo_init(void) "OVERO_GPIO_W2W_NRESET\n"); } - ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios)); - if (ret) { - pr_err("%s: could not obtain BT gpios\n", __func__); - } else { + if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) && + (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0)) gpio_export(OVERO_GPIO_BT_XGATE, 0); + else + printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n"); + + if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) && + (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) { gpio_export(OVERO_GPIO_BT_NRESET, 0); gpio_set_value(OVERO_GPIO_BT_NRESET, 0); mdelay(6); gpio_set_value(OVERO_GPIO_BT_NRESET, 1); + } else { + printk(KERN_ERR "could not obtain gpio for " + "OVERO_GPIO_BT_NRESET\n"); } - ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH, - "OVERO_GPIO_USBH_CPEN"); - if (ret == 0) + if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) && + (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0)) gpio_export(OVERO_GPIO_USBH_CPEN, 0); else printk(KERN_ERR "could not obtain gpio for " diff --git a/trunk/arch/arm/mach-omap2/board-rm680.c b/trunk/arch/arm/mach-omap2/board-rm680.c index 42d10b12da3c..2af8b05e786d 100644 --- a/trunk/arch/arm/mach-omap2/board-rm680.c +++ b/trunk/arch/arm/mach-omap2/board-rm680.c @@ -31,7 +31,6 @@ #include "mux.h" #include "hsmmc.h" #include "sdram-nokia.h" -#include "common-board-devices.h" static struct regulator_consumer_supply rm680_vemmc_consumers[] = { REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), @@ -91,9 +90,19 @@ static struct twl4030_platform_data rm680_twl_data = { /* add rest of the children here */ }; +static struct i2c_board_info __initdata rm680_twl_i2c_board_info[] = { + { + I2C_BOARD_INFO("twl5031", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &rm680_twl_data, + }, +}; + static void __init rm680_i2c_init(void) { - omap_pmic_init(1, 2900, "twl5031", INT_34XX_SYS_NIRQ, &rm680_twl_data); + omap_register_i2c_bus(1, 2900, rm680_twl_i2c_board_info, + ARRAY_SIZE(rm680_twl_i2c_board_info)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); } @@ -144,11 +153,17 @@ static struct omap_board_mux board_mux[] __initdata = { }; #endif +static struct omap_musb_board_data rm680_musb_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_PERIPHERAL, + .power = 100, +}; + static void __init rm680_init(void) { omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); omap_serial_init(); - usb_musb_init(NULL); + usb_musb_init(&rm680_musb_data); rm680_peripherals_init(); } diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index 2e509f9149e2..bbcb6775a6a3 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -43,7 +43,6 @@ #include "mux.h" #include "hsmmc.h" -#include "common-board-devices.h" #define SYSTEM_REV_B_USES_VAUX3 0x1699 #define SYSTEM_REV_S_USES_VAUX3 0x8 @@ -558,8 +557,10 @@ static __init void rx51_init_si4713(void) static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) { /* FIXME this gpio setup is just a placeholder for now */ - gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm"); - gpio_request_one(gpio + 7, GPIOF_OUT_INIT_HIGH, "speaker_en"); + gpio_request(gpio + 6, "backlight_pwm"); + gpio_direction_output(gpio + 6, 0); + gpio_request(gpio + 7, "speaker_en"); + gpio_direction_output(gpio + 7, 1); return 0; } @@ -776,6 +777,15 @@ static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = .power_gpio = 98, }; +static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = { + { + I2C_BOARD_INFO("twl5030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &rx51_twldata, + }, +}; + /* Audio setup data */ static struct aic3x_setup_data rx51_aic34_setup = { .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, @@ -823,7 +833,8 @@ static int __init rx51_i2c_init(void) rx51_twldata.vaux3 = &rx51_vaux3_cam; } rx51_twldata.vmmc2 = &rx51_vmmc2; - omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata); + omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1, + ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2, ARRAY_SIZE(rx51_peripherals_i2c_board_info_2)); omap_register_i2c_bus(3, 400, NULL, 0); @@ -910,20 +921,26 @@ static void rx51_wl1251_set_power(bool enable) gpio_set_value(RX51_WL1251_POWER_GPIO, enable); } -static struct gpio rx51_wl1251_gpios[] __initdata = { - { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" }, - { RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" }, -}; - static void __init rx51_init_wl1251(void) { int irq, ret; - ret = gpio_request_array(rx51_wl1251_gpios, - ARRAY_SIZE(rx51_wl1251_gpios)); + ret = gpio_request(RX51_WL1251_POWER_GPIO, "wl1251 power"); if (ret < 0) goto error; + ret = gpio_direction_output(RX51_WL1251_POWER_GPIO, 0); + if (ret < 0) + goto err_power; + + ret = gpio_request(RX51_WL1251_IRQ_GPIO, "wl1251 irq"); + if (ret < 0) + goto err_power; + + ret = gpio_direction_input(RX51_WL1251_IRQ_GPIO); + if (ret < 0) + goto err_irq; + irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO); if (irq < 0) goto err_irq; @@ -935,7 +952,10 @@ static void __init rx51_init_wl1251(void) err_irq: gpio_free(RX51_WL1251_IRQ_GPIO); + +err_power: gpio_free(RX51_WL1251_POWER_GPIO); + error: printk(KERN_ERR "wl1251 board initialisation failed\n"); wl1251_pdata.set_power = NULL; diff --git a/trunk/arch/arm/mach-omap2/board-rx51-video.c b/trunk/arch/arm/mach-omap2/board-rx51-video.c index 19777333aef8..89a66db8b77d 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-video.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-video.c @@ -76,12 +76,13 @@ static int __init rx51_video_init(void) return 0; } - if (gpio_request_one(RX51_LCD_RESET_GPIO, GPIOF_OUT_INIT_HIGH, - "LCD ACX565AKM reset")) { + if (gpio_request(RX51_LCD_RESET_GPIO, "LCD ACX565AKM reset")) { pr_err("%s failed to get LCD Reset GPIO\n", __func__); return 0; } + gpio_direction_output(RX51_LCD_RESET_GPIO, 1); + omap_display_init(&rx51_dss_board_info); return 0; } diff --git a/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c b/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c index 6402e781c458..007ebdc6c993 100644 --- a/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c +++ b/trunk/arch/arm/mach-omap2/board-zoom-debugboard.c @@ -15,7 +15,6 @@ #include #include -#include #include @@ -27,16 +26,60 @@ #define DEBUG_BASE 0x08000000 #define ZOOM_ETHR_START DEBUG_BASE -static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = { - .cs = ZOOM_SMSC911X_CS, - .gpio_irq = ZOOM_SMSC911X_GPIO, - .gpio_reset = -EINVAL, +static struct resource zoom_smsc911x_resources[] = { + [0] = { + .start = ZOOM_ETHR_START, + .end = ZOOM_ETHR_START + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + }, +}; + +static struct smsc911x_platform_config zoom_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, .flags = SMSC911X_USE_32BIT, + .phy_interface = PHY_INTERFACE_MODE_MII, +}; + +static struct platform_device zoom_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(zoom_smsc911x_resources), + .resource = zoom_smsc911x_resources, + .dev = { + .platform_data = &zoom_smsc911x_config, + }, }; static inline void __init zoom_init_smsc911x(void) { - gpmc_smsc911x_init(&zoom_smsc911x_cfg); + int eth_cs; + unsigned long cs_mem_base; + int eth_gpio = 0; + + eth_cs = ZOOM_SMSC911X_CS; + + if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n"); + return; + } + + zoom_smsc911x_resources[0].start = cs_mem_base + 0x0; + zoom_smsc911x_resources[0].end = cs_mem_base + 0xff; + + eth_gpio = ZOOM_SMSC911X_GPIO; + + zoom_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio); + + if (gpio_request(eth_gpio, "smsc911x irq") < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", + eth_gpio); + return; + } + gpio_direction_input(eth_gpio); } static struct plat_serial8250_port serial_platform_data[] = { @@ -77,9 +120,12 @@ static inline void __init zoom_init_quaduart(void) quart_gpio = ZOOM_QUADUART_GPIO; - if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0) + if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) { printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n", quart_gpio); + return; + } + gpio_direction_input(quart_gpio); } static inline int omap_zoom_debugboard_detect(void) @@ -89,12 +135,12 @@ static inline int omap_zoom_debugboard_detect(void) debug_board_detect = ZOOM_SMSC911X_GPIO; - if (gpio_request_one(debug_board_detect, GPIOF_IN, - "Zoom debug board detect") < 0) { + if (gpio_request(debug_board_detect, "Zoom debug board detect") < 0) { printk(KERN_ERR "Failed to request GPIO%d for Zoom debug" "board detect\n", debug_board_detect); return 0; } + gpio_direction_input(debug_board_detect); if (!gpio_get_value(debug_board_detect)) { ret = 0; @@ -104,6 +150,7 @@ static inline int omap_zoom_debugboard_detect(void) } static struct platform_device *zoom_devices[] __initdata = { + &zoom_smsc911x_device, &zoom_debugboard_serial_device, }; diff --git a/trunk/arch/arm/mach-omap2/board-zoom-display.c b/trunk/arch/arm/mach-omap2/board-zoom-display.c index ce53e82ba136..37b84c2b850f 100644 --- a/trunk/arch/arm/mach-omap2/board-zoom-display.c +++ b/trunk/arch/arm/mach-omap2/board-zoom-display.c @@ -21,19 +21,34 @@ #define LCD_PANEL_RESET_GPIO_PILOT 55 #define LCD_PANEL_QVGA_GPIO 56 -static struct gpio zoom_lcd_gpios[] __initdata = { - { -EINVAL, GPIOF_OUT_INIT_HIGH, "lcd reset" }, - { LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "lcd qvga" }, -}; - static void zoom_lcd_panel_init(void) { - zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? + int ret; + unsigned char lcd_panel_reset_gpio; + + lcd_panel_reset_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ? LCD_PANEL_RESET_GPIO_PROD : LCD_PANEL_RESET_GPIO_PILOT; - if (gpio_request_array(zoom_lcd_gpios, ARRAY_SIZE(zoom_lcd_gpios))) - pr_err("%s: Failed to get LCD GPIOs.\n", __func__); + ret = gpio_request(lcd_panel_reset_gpio, "lcd reset"); + if (ret) { + pr_err("Failed to get LCD reset GPIO (gpio%d).\n", + lcd_panel_reset_gpio); + return; + } + gpio_direction_output(lcd_panel_reset_gpio, 1); + + ret = gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga"); + if (ret) { + pr_err("Failed to get LCD_PANEL_QVGA_GPIO (gpio%d).\n", + LCD_PANEL_QVGA_GPIO); + goto err0; + } + gpio_direction_output(LCD_PANEL_QVGA_GPIO, 1); + + return; +err0: + gpio_free(lcd_panel_reset_gpio); } static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev) diff --git a/trunk/arch/arm/mach-omap2/board-zoom-peripherals.c b/trunk/arch/arm/mach-omap2/board-zoom-peripherals.c index 118c6f53c5eb..8dee7549fbdf 100644 --- a/trunk/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -31,7 +31,6 @@ #include "mux.h" #include "hsmmc.h" -#include "common-board-devices.h" #define OMAP_ZOOM_WLAN_PMENA_GPIO (101) #define OMAP_ZOOM_WLAN_IRQ_GPIO (162) @@ -277,11 +276,13 @@ static int zoom_twl_gpio_setup(struct device *dev, zoom_vsim_supply.dev = mmc[0].dev; zoom_vmmc2_supply.dev = mmc[1].dev; - ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, - "lcd enable"); - if (ret) + ret = gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd enable"); + if (ret) { pr_err("Failed to get LCD_PANEL_ENABLE_GPIO (gpio%d).\n", LCD_PANEL_ENABLE_GPIO); + return ret; + } + gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0); return ret; } @@ -348,6 +349,15 @@ static struct twl4030_platform_data zoom_twldata = { .vdac = &zoom_vdac, }; +static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl5030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &zoom_twldata, + }, +}; + static int __init omap_i2c_init(void) { if (machine_is_omap_zoom2()) { @@ -355,12 +365,19 @@ static int __init omap_i2c_init(void) zoom_audio_data.hs_extmute = 1; zoom_audio_data.set_hs_extmute = zoom2_set_hs_extmute; } - omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata); + omap_register_i2c_bus(1, 2400, zoom_i2c_boardinfo, + ARRAY_SIZE(zoom_i2c_boardinfo)); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, NULL, 0); return 0; } +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + static void enable_board_wakeup_source(void) { /* T2 interrupt line (keypad) */ @@ -375,7 +392,7 @@ void __init zoom_peripherals_init(void) omap_i2c_init(); platform_device_register(&omap_vwlan_device); - usb_musb_init(NULL); + usb_musb_init(&musb_board_data); enable_board_wakeup_source(); omap_serial_init(); } diff --git a/trunk/arch/arm/mach-omap2/common-board-devices.c b/trunk/arch/arm/mach-omap2/common-board-devices.c deleted file mode 100644 index e94903b2c65b..000000000000 --- a/trunk/arch/arm/mach-omap2/common-board-devices.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * common-board-devices.c - * - * Copyright (C) 2011 CompuLab, Ltd. - * Author: Mike Rapoport - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "common-board-devices.h" - -static struct i2c_board_info __initdata pmic_i2c_board_info = { - .addr = 0x48, - .flags = I2C_CLIENT_WAKE, -}; - -void __init omap_pmic_init(int bus, u32 clkrate, - const char *pmic_type, int pmic_irq, - struct twl4030_platform_data *pmic_data) -{ - strncpy(pmic_i2c_board_info.type, pmic_type, - sizeof(pmic_i2c_board_info.type)); - pmic_i2c_board_info.irq = pmic_irq; - pmic_i2c_board_info.platform_data = pmic_data; - - omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); -} - -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ - defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static struct omap2_mcspi_device_config ads7846_mcspi_config = { - .turbo_mode = 0, - .single_channel = 1, /* 0: slave, 1: master */ -}; - -static struct ads7846_platform_data ads7846_config = { - .x_max = 0x0fff, - .y_max = 0x0fff, - .x_plate_ohms = 180, - .pressure_max = 255, - .debounce_max = 10, - .debounce_tol = 3, - .debounce_rep = 1, - .gpio_pendown = -EINVAL, - .keep_vref_on = 1, -}; - -static struct spi_board_info ads7846_spi_board_info __initdata = { - .modalias = "ads7846", - .bus_num = -EINVAL, - .chip_select = 0, - .max_speed_hz = 1500000, - .controller_data = &ads7846_mcspi_config, - .irq = -EINVAL, - .platform_data = &ads7846_config, -}; - -void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, - struct ads7846_platform_data *board_pdata) -{ - struct spi_board_info *spi_bi = &ads7846_spi_board_info; - int err; - - err = gpio_request(gpio_pendown, "TS PenDown"); - if (err) { - pr_err("Could not obtain gpio for TS PenDown: %d\n", err); - return; - } - - gpio_direction_input(gpio_pendown); - gpio_export(gpio_pendown, 0); - - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); - - ads7846_config.gpio_pendown = gpio_pendown; - - spi_bi->bus_num = bus_num; - spi_bi->irq = OMAP_GPIO_IRQ(gpio_pendown); - - if (board_pdata) - spi_bi->platform_data = board_pdata; - - spi_register_board_info(&ads7846_spi_board_info, 1); -} -#else -void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, - struct ads7846_platform_data *board_pdata) -{ -} -#endif - -#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) -static struct omap_nand_platform_data nand_data = { - .dma_channel = -1, /* disable DMA in OMAP NAND driver */ -}; - -void __init omap_nand_flash_init(int options, struct mtd_partition *parts, - int nr_parts) -{ - u8 cs = 0; - u8 nandcs = GPMC_CS_NUM + 1; - - /* find out the chip-select on which NAND exists */ - while (cs < GPMC_CS_NUM) { - u32 ret = 0; - ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); - - if ((ret & 0xC00) == 0x800) { - printk(KERN_INFO "Found NAND on CS%d\n", cs); - if (nandcs > GPMC_CS_NUM) - nandcs = cs; - } - cs++; - } - - if (nandcs > GPMC_CS_NUM) { - printk(KERN_INFO "NAND: Unable to find configuration " - "in GPMC\n "); - return; - } - - if (nandcs < GPMC_CS_NUM) { - nand_data.cs = nandcs; - nand_data.parts = parts; - nand_data.nr_parts = nr_parts; - nand_data.options = options; - - printk(KERN_INFO "Registering NAND on CS%d\n", nandcs); - if (gpmc_nand_init(&nand_data) < 0) - printk(KERN_ERR "Unable to register NAND device\n"); - } -} -#else -void __init omap_nand_flash_init(int options, struct mtd_partition *parts, - int nr_parts) -{ -} -#endif diff --git a/trunk/arch/arm/mach-omap2/common-board-devices.h b/trunk/arch/arm/mach-omap2/common-board-devices.h deleted file mode 100644 index eb80b3b0ef47..000000000000 --- a/trunk/arch/arm/mach-omap2/common-board-devices.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __OMAP_COMMON_BOARD_DEVICES__ -#define __OMAP_COMMON_BOARD_DEVICES__ - -struct twl4030_platform_data; -struct mtd_partition; - -void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, - struct twl4030_platform_data *pmic_data); - -static inline void omap2_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data) -{ - omap_pmic_init(2, 2600, pmic_type, INT_24XX_SYS_NIRQ, pmic_data); -} - -static inline void omap3_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data) -{ - omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data); -} - -static inline void omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data) -{ - /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ - omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); -} - -struct ads7846_platform_data; - -void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, - struct ads7846_platform_data *board_pdata); -void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts); - -#endif /* __OMAP_COMMON_BOARD_DEVICES__ */ diff --git a/trunk/arch/arm/mach-omap2/gpmc-smc91x.c b/trunk/arch/arm/mach-omap2/gpmc-smc91x.c index ba10c24f3d8d..877c6f5807b7 100644 --- a/trunk/arch/arm/mach-omap2/gpmc-smc91x.c +++ b/trunk/arch/arm/mach-omap2/gpmc-smc91x.c @@ -147,24 +147,25 @@ void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data) goto free1; } - if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0) + if (gpio_request(gpmc_cfg->gpio_irq, "SMC91X irq") < 0) goto free1; + gpio_direction_input(gpmc_cfg->gpio_irq); gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); if (gpmc_cfg->gpio_pwrdwn) { - ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn, - GPIOF_OUT_INIT_LOW, "SMC91X powerdown"); + ret = gpio_request(gpmc_cfg->gpio_pwrdwn, "SMC91X powerdown"); if (ret) goto free2; + gpio_direction_output(gpmc_cfg->gpio_pwrdwn, 0); } if (gpmc_cfg->gpio_reset) { - ret = gpio_request_one(gpmc_cfg->gpio_reset, - GPIOF_OUT_INIT_LOW, "SMC91X reset"); + ret = gpio_request(gpmc_cfg->gpio_reset, "SMC91X reset"); if (ret) goto free3; + gpio_direction_output(gpmc_cfg->gpio_reset, 0); gpio_set_value(gpmc_cfg->gpio_reset, 1); msleep(100); gpio_set_value(gpmc_cfg->gpio_reset, 0); diff --git a/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c b/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c index 997033129d26..703f150dd01d 100644 --- a/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c +++ b/trunk/arch/arm/mach-omap2/gpmc-smsc911x.c @@ -10,7 +10,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define pr_fmt(fmt) "%s: " fmt, __func__ #include #include @@ -31,7 +30,7 @@ static struct resource gpmc_smsc911x_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, + .flags = IORESOURCE_IRQ, }, }; @@ -42,6 +41,16 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { .flags = SMSC911X_USE_16BIT, }; +static struct platform_device gpmc_smsc911x_device = { + .name = "smsc911x", + .id = -1, + .num_resources = ARRAY_SIZE(gpmc_smsc911x_resources), + .resource = gpmc_smsc911x_resources, + .dev = { + .platform_data = &gpmc_smsc911x_config, + }, +}; + /* * Initialize smsc911x device connected to the GPMC. Note that we * assume that pin multiplexing is done in the board-*.c file, @@ -49,49 +58,46 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = { */ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) { - struct platform_device *pdev; unsigned long cs_mem_base; int ret; gpmc_cfg = board_data; if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { - pr_err("Failed to request GPMC mem region\n"); + printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n"); return; } gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0; gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff; - if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) { - pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq); + if (gpio_request(gpmc_cfg->gpio_irq, "smsc911x irq") < 0) { + printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", + gpmc_cfg->gpio_irq); goto free1; } + gpio_direction_input(gpmc_cfg->gpio_irq); gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); + gpmc_smsc911x_resources[1].flags |= + (gpmc_cfg->flags & IRQF_TRIGGER_MASK); if (gpio_is_valid(gpmc_cfg->gpio_reset)) { - ret = gpio_request_one(gpmc_cfg->gpio_reset, - GPIOF_OUT_INIT_HIGH, "smsc911x reset"); + ret = gpio_request(gpmc_cfg->gpio_reset, "smsc911x reset"); if (ret) { - pr_err("Failed to request reset GPIO%d\n", - gpmc_cfg->gpio_reset); + printk(KERN_ERR "Failed to request GPIO%d for smsc911x reset\n", + gpmc_cfg->gpio_reset); goto free2; } + gpio_direction_output(gpmc_cfg->gpio_reset, 1); gpio_set_value(gpmc_cfg->gpio_reset, 0); msleep(100); gpio_set_value(gpmc_cfg->gpio_reset, 1); } - if (gpmc_cfg->flags) - gpmc_smsc911x_config.flags = gpmc_cfg->flags; - - pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, - gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), - &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config)); - if (!pdev) { - pr_err("Unable to register platform device\n"); + if (platform_device_register(&gpmc_smsc911x_device) < 0) { + printk(KERN_ERR "Unable to register smsc911x device\n"); gpio_free(gpmc_cfg->gpio_reset); goto free2; } @@ -103,5 +109,5 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) free1: gpmc_cs_free(gpmc_cfg->cs); - pr_err("Could not initialize smsc911x device\n"); + printk(KERN_ERR "Could not initialize smsc911x\n"); } diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index 3af2b7a1045e..237e4530abf2 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -73,18 +73,83 @@ static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) return __raw_readl(bank->base_reg + reg); } +static int previous_irq; + +/* + * On 34xx we can get occasional spurious interrupts if the ack from + * an interrupt handler does not get posted before we unmask. Warn about + * the interrupt handlers that need to flush posted writes. + */ +static int omap_check_spurious(unsigned int irq) +{ + u32 sir, spurious; + + sir = intc_bank_read_reg(&irq_banks[0], INTC_SIR); + spurious = sir >> 7; + + if (spurious) { + printk(KERN_WARNING "Spurious irq %i: 0x%08x, please flush " + "posted write for irq %i\n", + irq, sir, previous_irq); + return spurious; + } + + return 0; +} + /* XXX: FIQ and additional INTC support (only MPU at the moment) */ static void omap_ack_irq(struct irq_data *d) { intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL); } +static void omap_mask_irq(struct irq_data *d) +{ + unsigned int irq = d->irq; + int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + + if (cpu_is_omap34xx() && !cpu_is_ti816x()) { + int spurious = 0; + + /* + * INT_34XX_GPT12_IRQ is also the spurious irq. Maybe because + * it is the highest irq number? + */ + if (irq == INT_34XX_GPT12_IRQ) + spurious = omap_check_spurious(irq); + + if (!spurious) + previous_irq = irq; + } + + irq &= (IRQ_BITS_PER_REG - 1); + + intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset); +} + +static void omap_unmask_irq(struct irq_data *d) +{ + unsigned int irq = d->irq; + int offset = irq & (~(IRQ_BITS_PER_REG - 1)); + + irq &= (IRQ_BITS_PER_REG - 1); + + intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset); +} + static void omap_mask_ack_irq(struct irq_data *d) { - irq_gc_mask_disable_reg(d); + omap_mask_irq(d); omap_ack_irq(d); } +static struct irq_chip omap_irq_chip = { + .name = "INTC", + .irq_ack = omap_mask_ack_irq, + .irq_mask = omap_mask_irq, + .irq_unmask = omap_unmask_irq, +}; + static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank) { unsigned long tmp; @@ -121,31 +186,11 @@ int omap_irq_pending(void) return 0; } -static __init void -omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) -{ - struct irq_chip_generic *gc; - struct irq_chip_type *ct; - - gc = irq_alloc_generic_chip("INTC", 1, irq_start, base, - handle_level_irq); - ct = gc->chip_types; - ct->chip.irq_ack = omap_mask_ack_irq; - ct->chip.irq_mask = irq_gc_mask_disable_reg; - ct->chip.irq_unmask = irq_gc_unmask_enable_reg; - - ct->regs.ack = INTC_CONTROL; - ct->regs.enable = INTC_MIR_CLEAR0; - ct->regs.disable = INTC_MIR_SET0; - irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, - IRQ_NOREQUEST | IRQ_NOPROBE, 0); -} - void __init omap_init_irq(void) { unsigned long nr_of_irqs = 0; unsigned int nr_banks = 0; - int i, j; + int i; for (i = 0; i < ARRAY_SIZE(irq_banks); i++) { unsigned long base = 0; @@ -170,15 +215,17 @@ void __init omap_init_irq(void) omap_irq_bank_init_one(bank); - for (i = 0, j = 0; i < bank->nr_irqs; i += 32, j += 0x20) - omap_alloc_gc(bank->base_reg + j, i, 32); - nr_of_irqs += bank->nr_irqs; nr_banks++; } printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n", nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : ""); + + for (i = 0; i < nr_of_irqs; i++) { + irq_set_chip_and_handler(i, &omap_irq_chip, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } } #ifdef CONFIG_ARCH_OMAP3 diff --git a/trunk/arch/arm/mach-omap2/omap_l3_noc.c b/trunk/arch/arm/mach-omap2/omap_l3_noc.c index 7b9f1909ddb2..82632c24076f 100644 --- a/trunk/arch/arm/mach-omap2/omap_l3_noc.c +++ b/trunk/arch/arm/mach-omap2/omap_l3_noc.c @@ -63,7 +63,10 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) char *source_name; /* Get the Type of interrupt */ - inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; + if (irq == l3->app_irq) + inttype = L3_APPLICATION_ERROR; + else + inttype = L3_DEBUG_ERROR; for (i = 0; i < L3_MODULES; i++) { /* @@ -81,10 +84,10 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) err_src = j; /* Read the stderrlog_main_source from clk domain */ - std_err_main_addr = base + *(l3_targ[i] + err_src); - std_err_main = readl(std_err_main_addr); + std_err_main_addr = base + (*(l3_targ[i] + err_src)); + std_err_main = readl(std_err_main_addr); - switch (std_err_main & CUSTOM_ERROR) { + switch ((std_err_main & CUSTOM_ERROR)) { case STANDARD_ERROR: source_name = l3_targ_stderrlog_main_name[i][err_src]; @@ -129,49 +132,49 @@ static int __init omap4_l3_probe(struct platform_device *pdev) l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) - return -ENOMEM; + ret = -ENOMEM; platform_set_drvdata(pdev, l3); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "couldn't find resource 0\n"); ret = -ENODEV; - goto err0; + goto err1; } l3->l3_base[0] = ioremap(res->start, resource_size(res)); - if (!l3->l3_base[0]) { + if (!(l3->l3_base[0])) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err0; + goto err2; } res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, "couldn't find resource 1\n"); ret = -ENODEV; - goto err1; + goto err3; } l3->l3_base[1] = ioremap(res->start, resource_size(res)); - if (!l3->l3_base[1]) { + if (!(l3->l3_base[1])) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err1; + goto err4; } res = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (!res) { dev_err(&pdev->dev, "couldn't find resource 2\n"); ret = -ENODEV; - goto err2; + goto err5; } l3->l3_base[2] = ioremap(res->start, resource_size(res)); - if (!l3->l3_base[2]) { + if (!(l3->l3_base[2])) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err2; + goto err6; } /* @@ -184,7 +187,7 @@ static int __init omap4_l3_probe(struct platform_device *pdev) if (ret) { pr_crit("L3: request_irq failed to register for 0x%x\n", OMAP44XX_IRQ_L3_DBG); - goto err3; + goto err7; } l3->debug_irq = irq; @@ -195,22 +198,24 @@ static int __init omap4_l3_probe(struct platform_device *pdev) if (ret) { pr_crit("L3: request_irq failed to register for 0x%x\n", OMAP44XX_IRQ_L3_APP); - goto err4; + goto err8; } l3->app_irq = irq; - return 0; - + goto err0; +err8: +err7: + iounmap(l3->l3_base[2]); +err6: +err5: + iounmap(l3->l3_base[1]); err4: - free_irq(l3->debug_irq, l3); err3: - iounmap(l3->l3_base[2]); + iounmap(l3->l3_base[0]); err2: - iounmap(l3->l3_base[1]); err1: - iounmap(l3->l3_base[0]); -err0: kfree(l3); +err0: return ret; } diff --git a/trunk/arch/arm/mach-omap2/omap_l3_smx.c b/trunk/arch/arm/mach-omap2/omap_l3_smx.c index 873c0e33b512..4321e7938929 100644 --- a/trunk/arch/arm/mach-omap2/omap_l3_smx.c +++ b/trunk/arch/arm/mach-omap2/omap_l3_smx.c @@ -155,7 +155,7 @@ static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, u8 multi = error & L3_ERROR_LOG_MULTI; u32 address = omap3_l3_decode_addr(error_addr); - WARN(true, "%s seen by %s %s at address %x\n", + WARN(true, "%s Error seen by %s %s at address %x\n", omap3_l3_code_string(code), omap3_l3_initiator_string(initid), multi ? "Multiple Errors" : "", @@ -167,15 +167,21 @@ static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) { struct omap3_l3 *l3 = _l3; + u64 status, clear; u64 error; u64 error_addr; u64 err_source = 0; void __iomem *base; int int_type; + irqreturn_t ret = IRQ_NONE; - int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; + if (irq == l3->app_irq) + int_type = L3_APPLICATION_ERROR; + else + int_type = L3_DEBUG_ERROR; + if (!int_type) { status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_0); /* @@ -196,6 +202,7 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) base = l3->rt + *(omap3_l3_bases[int_type] + err_source); error = omap3_l3_readll(base, L3_ERROR_LOG); + if (error) { error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR); @@ -203,8 +210,9 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) } /* Clear the status register */ - clear = (L3_AGENT_STATUS_CLEAR_IA << int_type) | - L3_AGENT_STATUS_CLEAR_TA; + clear = ((L3_AGENT_STATUS_CLEAR_IA << int_type) | + (L3_AGENT_STATUS_CLEAR_TA)); + omap3_l3_writell(base, L3_AGENT_STATUS, clear); /* clear the error log register */ @@ -220,8 +228,10 @@ static int __init omap3_l3_probe(struct platform_device *pdev) int ret; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); - if (!l3) - return -ENOMEM; + if (!l3) { + ret = -ENOMEM; + goto err0; + } platform_set_drvdata(pdev, l3); @@ -229,13 +239,13 @@ static int __init omap3_l3_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "couldn't find resource\n"); ret = -ENODEV; - goto err0; + goto err1; } l3->rt = ioremap(res->start, resource_size(res)); - if (!l3->rt) { + if (!(l3->rt)) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err0; + goto err2; } l3->debug_irq = platform_get_irq(pdev, 0); @@ -244,26 +254,28 @@ static int __init omap3_l3_probe(struct platform_device *pdev) "l3-debug-irq", l3); if (ret) { dev_err(&pdev->dev, "couldn't request debug irq\n"); - goto err1; + goto err3; } l3->app_irq = platform_get_irq(pdev, 1); ret = request_irq(l3->app_irq, omap3_l3_app_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING, "l3-app-irq", l3); + if (ret) { dev_err(&pdev->dev, "couldn't request app irq\n"); - goto err2; + goto err4; } - return 0; + goto err0; +err4: +err3: + iounmap(l3->rt); err2: - free_irq(l3->debug_irq, l3); err1: - iounmap(l3->rt); -err0: kfree(l3); +err0: return ret; } diff --git a/trunk/arch/arm/mach-omap2/omap_phy_internal.c b/trunk/arch/arm/mach-omap2/omap_phy_internal.c index f47813edd951..05f6abc96b0d 100644 --- a/trunk/arch/arm/mach-omap2/omap_phy_internal.c +++ b/trunk/arch/arm/mach-omap2/omap_phy_internal.c @@ -50,16 +50,13 @@ int omap4430_phy_init(struct device *dev) { ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K); if (!ctrl_base) { - pr_err("control module ioremap failed\n"); + dev_err(dev, "control module ioremap failed\n"); return -ENOMEM; } /* Power down the phy */ __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF); - - if (!dev) - return 0; - phyclk = clk_get(dev, "ocp2scp_usb_phy_ick"); + if (IS_ERR(phyclk)) { dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n"); iounmap(ctrl_base); @@ -231,7 +228,7 @@ void am35x_musb_clear_irq(void) regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); } -void am35x_set_mode(u8 musb_mode) +void am35x_musb_set_mode(u8 musb_mode) { u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); diff --git a/trunk/arch/arm/mach-omap2/pm44xx.c b/trunk/arch/arm/mach-omap2/pm44xx.c index 59a870be8390..76cfff2db514 100644 --- a/trunk/arch/arm/mach-omap2/pm44xx.c +++ b/trunk/arch/arm/mach-omap2/pm44xx.c @@ -105,11 +105,13 @@ static int __init omap4_pm_init(void) pr_err("Power Management for TI OMAP4.\n"); +#ifdef CONFIG_PM ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { pr_err("Failed to setup powerdomains\n"); goto err2; } +#endif #ifdef CONFIG_SUSPEND suspend_set_ops(&omap_pm_ops); diff --git a/trunk/arch/arm/mach-omap2/smartreflex.c b/trunk/arch/arm/mach-omap2/smartreflex.c index fb7dc52394a8..13e24f913dd4 100644 --- a/trunk/arch/arm/mach-omap2/smartreflex.c +++ b/trunk/arch/arm/mach-omap2/smartreflex.c @@ -847,14 +847,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) goto err_free_devinfo; } - mem = request_mem_region(mem->start, resource_size(mem), - dev_name(&pdev->dev)); - if (!mem) { - dev_err(&pdev->dev, "%s: no mem region\n", __func__); - ret = -EBUSY; - goto err_free_devinfo; - } - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(&pdev->dev); @@ -891,7 +883,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) ret = sr_late_init(sr_info); if (ret) { pr_warning("%s: Error in SR late init\n", __func__); - return ret; + goto err_release_region; } } @@ -904,7 +896,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm); if (!vdd_dbg_dir) { ret = -EINVAL; - goto err_iounmap; + goto err_release_region; } sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); @@ -912,7 +904,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", __func__); ret = PTR_ERR(sr_info->dbg_dir); - goto err_iounmap; + goto err_release_region; } (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, @@ -929,7 +921,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) dev_err(&pdev->dev, "%s: Unable to create debugfs directory" "for n-values\n", __func__); ret = PTR_ERR(nvalue_dir); - goto err_debugfs; + goto err_release_region; } omap_voltage_get_volttable(sr_info->voltdm, &volt_data); @@ -939,7 +931,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) "entries for n-values\n", __func__, sr_info->voltdm->name); ret = -ENODATA; - goto err_debugfs; + goto err_release_region; } for (i = 0; i < sr_info->nvalue_count; i++) { @@ -953,11 +945,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) return ret; -err_debugfs: - debugfs_remove_recursive(sr_info->dbg_dir); -err_iounmap: - list_del(&sr_info->node); - iounmap(sr_info->base); err_release_region: release_mem_region(mem->start, resource_size(mem)); err_free_devinfo: diff --git a/trunk/arch/arm/mach-omap2/usb-musb.c b/trunk/arch/arm/mach-omap2/usb-musb.c index c7ed540d868d..35559f77e2de 100644 --- a/trunk/arch/arm/mach-omap2/usb-musb.c +++ b/trunk/arch/arm/mach-omap2/usb-musb.c @@ -108,13 +108,7 @@ static void usb_musb_mux_init(struct omap_musb_board_data *board_data) } } -static struct omap_musb_board_data musb_default_board_data = { - .interface_type = MUSB_INTERFACE_ULPI, - .mode = MUSB_OTG, - .power = 100, -}; - -void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) +void __init usb_musb_init(struct omap_musb_board_data *board_data) { struct omap_hwmod *oh; struct omap_device *od; @@ -122,12 +116,11 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) struct device *dev; int bus_id = -1; const char *oh_name, *name; - struct omap_musb_board_data *board_data; - if (musb_board_data) - board_data = musb_board_data; - else - board_data = &musb_default_board_data; + if (cpu_is_omap3517() || cpu_is_omap3505()) { + } else if (cpu_is_omap44xx()) { + usb_musb_mux_init(board_data); + } /* * REVISIT: This line can be removed once all the platforms using @@ -171,15 +164,10 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) dev->dma_mask = &musb_dmamask; dev->coherent_dma_mask = musb_dmamask; put_device(dev); - - if (cpu_is_omap44xx()) - omap4430_phy_init(dev); } #else void __init usb_musb_init(struct omap_musb_board_data *board_data) { - if (cpu_is_omap44xx()) - omap4430_phy_init(NULL); } #endif /* CONFIG_USB_MUSB_SOC */ diff --git a/trunk/arch/arm/mach-omap2/usb-tusb6010.c b/trunk/arch/arm/mach-omap2/usb-tusb6010.c index 8dd26b765b7d..8a3c05f3c1d6 100644 --- a/trunk/arch/arm/mach-omap2/usb-tusb6010.c +++ b/trunk/arch/arm/mach-omap2/usb-tusb6010.c @@ -293,11 +293,12 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data, ); /* IRQ */ - status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); + status = gpio_request(irq, "TUSB6010 irq"); if (status < 0) { printk(error, 3, status); return status; } + gpio_direction_input(irq); tusb_resources[2].start = irq + IH_GPIO_BASE; /* set up memory timings ... can speed them up later */ diff --git a/trunk/arch/arm/mach-omap2/voltage.c b/trunk/arch/arm/mach-omap2/voltage.c index 9ef3789ded4b..0c1552d9d995 100644 --- a/trunk/arch/arm/mach-omap2/voltage.c +++ b/trunk/arch/arm/mach-omap2/voltage.c @@ -148,6 +148,7 @@ static int vp_volt_debug_get(void *data, u64 *val) } vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage); + pr_notice("curr_vsel = %x\n", vsel); if (!vdd->pmic_info->vsel_to_uv) { pr_warning("PMIC function to convert vsel to voltage" diff --git a/trunk/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h b/trunk/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h index ea6c9c88c725..872de0bf1e6b 100644 --- a/trunk/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h +++ b/trunk/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h @@ -14,14 +14,14 @@ #ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__ struct omap_smsc911x_platform_data { - int id; int cs; int gpio_irq; int gpio_reset; u32 flags; }; -#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +#if defined(CONFIG_SMSC911X) || \ + defined(CONFIG_SMSC911X_MODULE) extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d); diff --git a/trunk/arch/arm/plat-omap/include/plat/uncompress.h b/trunk/arch/arm/plat-omap/include/plat/uncompress.h index 2b576f1ab647..30b891c4a93f 100644 --- a/trunk/arch/arm/plat-omap/include/plat/uncompress.h +++ b/trunk/arch/arm/plat-omap/include/plat/uncompress.h @@ -129,6 +129,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_OMAP1(3, sx1); /* omap2 based boards using UART1 */ + DEBUG_LL_OMAP2(1, omap2evm); DEBUG_LL_OMAP2(1, omap_2430sdp); DEBUG_LL_OMAP2(1, omap_apollon); DEBUG_LL_OMAP2(1, omap_h4); diff --git a/trunk/arch/arm/plat-omap/include/plat/usb.h b/trunk/arch/arm/plat-omap/include/plat/usb.h index 17d3c939775c..02b96c8f6a17 100644 --- a/trunk/arch/arm/plat-omap/include/plat/usb.h +++ b/trunk/arch/arm/plat-omap/include/plat/usb.h @@ -113,7 +113,7 @@ extern int omap4430_phy_suspend(struct device *dev, int suspend); extern void am35x_musb_reset(void); extern void am35x_musb_phy_power(u8 on); extern void am35x_musb_clear_irq(void); -extern void am35x_set_mode(u8 musb_mode); +extern void am35x_musb_set_mode(u8 musb_mode); /* * FIXME correct answer depends on hmc_mode, diff --git a/trunk/arch/mips/ar7/gpio.c b/trunk/arch/mips/ar7/gpio.c index 425dfa5d6e12..bb571bcdb8f2 100644 --- a/trunk/arch/mips/ar7/gpio.c +++ b/trunk/arch/mips/ar7/gpio.c @@ -325,9 +325,7 @@ int __init ar7_gpio_init(void) size = 0x1f; } - gpch->regs = ioremap_nocache(AR7_REGS_GPIO, - AR7_REGS_GPIO + 0x10); - + gpch->regs = ioremap_nocache(AR7_REGS_GPIO, size); if (!gpch->regs) { printk(KERN_ERR "%s: failed to ioremap regs\n", gpch->chip.label); diff --git a/trunk/arch/mips/include/asm/dma-mapping.h b/trunk/arch/mips/include/asm/dma-mapping.h index 655f849bd08d..7aa37ddfca4b 100644 --- a/trunk/arch/mips/include/asm/dma-mapping.h +++ b/trunk/arch/mips/include/asm/dma-mapping.h @@ -5,7 +5,9 @@ #include #include +#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */ #include +#endif extern struct dma_map_ops *mips_dma_map_ops; diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index 71350f7f2d88..e9b3af27d844 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -374,7 +374,8 @@ void __noreturn die(const char *str, struct pt_regs *regs) unsigned long dvpret = dvpe(); #endif /* CONFIG_MIPS_MT_SMTC */ - notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV); + if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) + sig = 0; console_verbose(); spin_lock_irq(&die_lock); @@ -383,9 +384,6 @@ void __noreturn die(const char *str, struct pt_regs *regs) mips_mt_regdump(dvpret); #endif /* CONFIG_MIPS_MT_SMTC */ - if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) - sig = 0; - printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); add_taint(TAINT_DIE); diff --git a/trunk/arch/mips/rb532/gpio.c b/trunk/arch/mips/rb532/gpio.c index 37de05d595e7..6c47dfeb7be3 100644 --- a/trunk/arch/mips/rb532/gpio.c +++ b/trunk/arch/mips/rb532/gpio.c @@ -185,7 +185,7 @@ int __init rb532_gpio_init(void) struct resource *r; r = rb532_gpio_reg0_res; - rb532_gpio_chip->regbase = ioremap_nocache(r->start, r->end - r->start); + rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r)); if (!rb532_gpio_chip->regbase) { printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); diff --git a/trunk/arch/powerpc/platforms/83xx/suspend.c b/trunk/arch/powerpc/platforms/83xx/suspend.c index 188272934cfb..104faa8aa23c 100644 --- a/trunk/arch/powerpc/platforms/83xx/suspend.c +++ b/trunk/arch/powerpc/platforms/83xx/suspend.c @@ -318,17 +318,20 @@ static const struct platform_suspend_ops mpc83xx_suspend_ops = { .end = mpc83xx_suspend_end, }; +static struct of_device_id pmc_match[]; static int pmc_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct resource res; struct pmc_type *type; int ret = 0; - if (!ofdev->dev.of_match) + match = of_match_device(pmc_match, &ofdev->dev); + if (!match) return -EINVAL; - type = ofdev->dev.of_match->data; + type = match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/trunk/arch/powerpc/sysdev/fsl_msi.c b/trunk/arch/powerpc/sysdev/fsl_msi.c index d5679dc1e20f..01cd2f089512 100644 --- a/trunk/arch/powerpc/sysdev/fsl_msi.c +++ b/trunk/arch/powerpc/sysdev/fsl_msi.c @@ -304,8 +304,10 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, return 0; } +static const struct of_device_id fsl_of_msi_ids[]; static int __devinit fsl_of_msi_probe(struct platform_device *dev) { + const struct of_device_id *match; struct fsl_msi *msi; struct resource res; int err, i, j, irq_index, count; @@ -316,9 +318,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) u32 offset; static const u32 all_avail[] = { 0, NR_MSI_IRQS }; - if (!dev->dev.of_match) + match = of_match_device(fsl_of_msi_ids, &dev->dev); + if (!match) return -EINVAL; - features = dev->dev.of_match->data; + features = match->data; printk(KERN_DEBUG "Setting up Freescale MSI support\n"); diff --git a/trunk/arch/sparc/kernel/apc.c b/trunk/arch/sparc/kernel/apc.c index f679c57644d5..1e34f29e58bb 100644 --- a/trunk/arch/sparc/kernel/apc.c +++ b/trunk/arch/sparc/kernel/apc.c @@ -165,7 +165,7 @@ static int __devinit apc_probe(struct platform_device *op) return 0; } -static struct of_device_id __initdata apc_match[] = { +static struct of_device_id apc_match[] = { { .name = APC_OBPNAME, }, diff --git a/trunk/arch/sparc/kernel/pci_sabre.c b/trunk/arch/sparc/kernel/pci_sabre.c index 948068a083fc..d1840dbdaa2f 100644 --- a/trunk/arch/sparc/kernel/pci_sabre.c +++ b/trunk/arch/sparc/kernel/pci_sabre.c @@ -452,8 +452,10 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, sabre_scan_bus(pbm, &op->dev); } +static const struct of_device_id sabre_match[]; static int __devinit sabre_probe(struct platform_device *op) { + const struct of_device_id *match; const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->dev.of_node; struct pci_pbm_info *pbm; @@ -463,7 +465,8 @@ static int __devinit sabre_probe(struct platform_device *op) const u32 *vdma; u64 clear_irq; - hummingbird_p = op->dev.of_match && (op->dev.of_match->data != NULL); + match = of_match_device(sabre_match, &op->dev); + hummingbird_p = match && (match->data != NULL); if (!hummingbird_p) { struct device_node *cpu_dp; diff --git a/trunk/arch/sparc/kernel/pci_schizo.c b/trunk/arch/sparc/kernel/pci_schizo.c index fecfcb2063c8..283fbc329a43 100644 --- a/trunk/arch/sparc/kernel/pci_schizo.c +++ b/trunk/arch/sparc/kernel/pci_schizo.c @@ -1458,11 +1458,15 @@ static int __devinit __schizo_init(struct platform_device *op, unsigned long chi return err; } +static const struct of_device_id schizo_match[]; static int __devinit schizo_probe(struct platform_device *op) { - if (!op->dev.of_match) + const struct of_device_id *match; + + match = of_match_device(schizo_match, &op->dev); + if (!match) return -EINVAL; - return __schizo_init(op, (unsigned long) op->dev.of_match->data); + return __schizo_init(op, (unsigned long)match->data); } /* The ordering of this table is very important. Some Tomatillo diff --git a/trunk/arch/sparc/kernel/pmc.c b/trunk/arch/sparc/kernel/pmc.c index 93d7b4465f8d..6a585d393580 100644 --- a/trunk/arch/sparc/kernel/pmc.c +++ b/trunk/arch/sparc/kernel/pmc.c @@ -69,7 +69,7 @@ static int __devinit pmc_probe(struct platform_device *op) return 0; } -static struct of_device_id __initdata pmc_match[] = { +static struct of_device_id pmc_match[] = { { .name = PMC_OBPNAME, }, diff --git a/trunk/arch/sparc/kernel/smp_32.c b/trunk/arch/sparc/kernel/smp_32.c index 91c10fb70858..850a1360c0d6 100644 --- a/trunk/arch/sparc/kernel/smp_32.c +++ b/trunk/arch/sparc/kernel/smp_32.c @@ -53,6 +53,7 @@ cpumask_t smp_commenced_mask = CPU_MASK_NONE; void __cpuinit smp_store_cpu_info(int id) { int cpu_node; + int mid; cpu_data(id).udelay_val = loops_per_jiffy; @@ -60,10 +61,13 @@ void __cpuinit smp_store_cpu_info(int id) cpu_data(id).clock_tick = prom_getintdefault(cpu_node, "clock-frequency", 0); cpu_data(id).prom_node = cpu_node; - cpu_data(id).mid = cpu_get_hwmid(cpu_node); + mid = cpu_get_hwmid(cpu_node); - if (cpu_data(id).mid < 0) - panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); + if (mid < 0) { + printk(KERN_NOTICE "No MID found for CPU%d at node 0x%08d", id, cpu_node); + mid = 0; + } + cpu_data(id).mid = mid; } void __init smp_cpus_done(unsigned int max_cpus) diff --git a/trunk/arch/sparc/kernel/time_32.c b/trunk/arch/sparc/kernel/time_32.c index 4e236391b635..96046a4024c2 100644 --- a/trunk/arch/sparc/kernel/time_32.c +++ b/trunk/arch/sparc/kernel/time_32.c @@ -168,7 +168,7 @@ static int __devinit clock_probe(struct platform_device *op) return 0; } -static struct of_device_id __initdata clock_match[] = { +static struct of_device_id clock_match[] = { { .name = "eeprom", }, diff --git a/trunk/arch/sparc/lib/checksum_32.S b/trunk/arch/sparc/lib/checksum_32.S index 3632cb34e914..0084c3361e15 100644 --- a/trunk/arch/sparc/lib/checksum_32.S +++ b/trunk/arch/sparc/lib/checksum_32.S @@ -289,10 +289,16 @@ cc_end_cruft: /* Also, handle the alignment code out of band. */ cc_dword_align: - cmp %g1, 6 - bl,a ccte + cmp %g1, 16 + bge 1f + srl %g1, 1, %o3 +2: cmp %o3, 0 + be,a ccte andcc %g1, 0xf, %o3 - andcc %o0, 0x1, %g0 + andcc %o3, %o0, %g0 ! Check %o0 only (%o1 has the same last 2 bits) + be,a 2b + srl %o3, 1, %o3 +1: andcc %o0, 0x1, %g0 bne ccslow andcc %o0, 0x2, %g0 be 1f diff --git a/trunk/arch/um/os-Linux/util.c b/trunk/arch/um/os-Linux/util.c index 6ea77979531c..42827cafa6af 100644 --- a/trunk/arch/um/os-Linux/util.c +++ b/trunk/arch/um/os-Linux/util.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len) host.release, host.version, host.machine); } +/* + * We cannot use glibc's abort(). It makes use of tgkill() which + * has no effect within UML's kernel threads. + * After that glibc would execute an invalid instruction to kill + * the calling process and UML crashes with SIGSEGV. + */ +static inline void __attribute__ ((noreturn)) uml_abort(void) +{ + sigset_t sig; + + fflush(NULL); + + if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT)) + sigprocmask(SIG_UNBLOCK, &sig, 0); + + for (;;) + if (kill(getpid(), SIGABRT) < 0) + exit(127); +} + void os_dump_core(void) { int pid; @@ -116,5 +137,5 @@ void os_dump_core(void) while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0) os_kill_ptraced_process(pid, 0); - abort(); + uml_abort(); } diff --git a/trunk/arch/x86/include/asm/apicdef.h b/trunk/arch/x86/include/asm/apicdef.h index d87988bacf3e..34595d5e1038 100644 --- a/trunk/arch/x86/include/asm/apicdef.h +++ b/trunk/arch/x86/include/asm/apicdef.h @@ -78,6 +78,7 @@ #define APIC_DEST_LOGICAL 0x00800 #define APIC_DEST_PHYSICAL 0x00000 #define APIC_DM_FIXED 0x00000 +#define APIC_DM_FIXED_MASK 0x00700 #define APIC_DM_LOWEST 0x00100 #define APIC_DM_SMI 0x00200 #define APIC_DM_REMRD 0x00300 diff --git a/trunk/arch/x86/include/asm/pgtable_types.h b/trunk/arch/x86/include/asm/pgtable_types.h index 7db7723d1f32..d56187c6b838 100644 --- a/trunk/arch/x86/include/asm/pgtable_types.h +++ b/trunk/arch/x86/include/asm/pgtable_types.h @@ -299,6 +299,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, /* Install a pte for a particular vaddr in kernel space. */ void set_pte_vaddr(unsigned long vaddr, pte_t pte); +extern void native_pagetable_reserve(u64 start, u64 end); #ifdef CONFIG_X86_32 extern void native_pagetable_setup_start(pgd_t *base); extern void native_pagetable_setup_done(pgd_t *base); diff --git a/trunk/arch/x86/include/asm/uv/uv_bau.h b/trunk/arch/x86/include/asm/uv/uv_bau.h index 3e094af443c3..130f1eeee5fe 100644 --- a/trunk/arch/x86/include/asm/uv/uv_bau.h +++ b/trunk/arch/x86/include/asm/uv/uv_bau.h @@ -94,6 +94,8 @@ /* after this # consecutive successes, bump up the throttle if it was lowered */ #define COMPLETE_THRESHOLD 5 +#define UV_LB_SUBNODEID 0x10 + /* * number of entries in the destination side payload queue */ @@ -124,7 +126,7 @@ * The distribution specification (32 bytes) is interpreted as a 256-bit * distribution vector. Adjacent bits correspond to consecutive even numbered * nodeIDs. The result of adding the index of a given bit to the 15-bit - * 'base_dest_nodeid' field of the header corresponds to the + * 'base_dest_nasid' field of the header corresponds to the * destination nodeID associated with that specified bit. */ struct bau_target_uvhubmask { @@ -176,7 +178,7 @@ struct bau_msg_payload { struct bau_msg_header { unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ /* bits 5:0 */ - unsigned int base_dest_nodeid:15; /* nasid of the */ + unsigned int base_dest_nasid:15; /* nasid of the */ /* bits 20:6 */ /* first bit in uvhub map */ unsigned int command:8; /* message type */ /* bits 28:21 */ @@ -378,6 +380,10 @@ struct ptc_stats { unsigned long d_rcanceled; /* number of messages canceled by resets */ }; +struct hub_and_pnode { + short uvhub; + short pnode; +}; /* * one per-cpu; to locate the software tables */ @@ -399,10 +405,12 @@ struct bau_control { int baudisabled; int set_bau_off; short cpu; + short osnode; short uvhub_cpu; short uvhub; short cpus_in_socket; short cpus_in_uvhub; + short partition_base_pnode; unsigned short message_number; unsigned short uvhub_quiesce; short socket_acknowledge_count[DEST_Q_SIZE]; @@ -422,15 +430,16 @@ struct bau_control { int congested_period; cycles_t period_time; long period_requests; + struct hub_and_pnode *target_hub_and_pnode; }; static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) { return constant_test_bit(uvhub, &dstp->bits[0]); } -static inline void bau_uvhub_set(int uvhub, struct bau_target_uvhubmask *dstp) +static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp) { - __set_bit(uvhub, &dstp->bits[0]); + __set_bit(pnode, &dstp->bits[0]); } static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, int nbits) diff --git a/trunk/arch/x86/include/asm/uv/uv_hub.h b/trunk/arch/x86/include/asm/uv/uv_hub.h index a501741c2335..4298002d0c83 100644 --- a/trunk/arch/x86/include/asm/uv/uv_hub.h +++ b/trunk/arch/x86/include/asm/uv/uv_hub.h @@ -398,6 +398,8 @@ struct uv_blade_info { unsigned short nr_online_cpus; unsigned short pnode; short memory_nid; + spinlock_t nmi_lock; + unsigned long nmi_count; }; extern struct uv_blade_info *uv_blade_info; extern short *uv_node_to_blade; diff --git a/trunk/arch/x86/include/asm/uv/uv_mmrs.h b/trunk/arch/x86/include/asm/uv/uv_mmrs.h index 20cafeac7455..f5bb64a823d7 100644 --- a/trunk/arch/x86/include/asm/uv/uv_mmrs.h +++ b/trunk/arch/x86/include/asm/uv/uv_mmrs.h @@ -5,7 +5,7 @@ * * SGI UV MMR definitions * - * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2007-2011 Silicon Graphics, Inc. All rights reserved. */ #ifndef _ASM_X86_UV_UV_MMRS_H @@ -1099,5 +1099,19 @@ union uvh_rtc1_int_config_u { } s; }; +/* ========================================================================= */ +/* UVH_SCRATCH5 */ +/* ========================================================================= */ +#define UVH_SCRATCH5 0x2d0200UL +#define UVH_SCRATCH5_32 0x00778 + +#define UVH_SCRATCH5_SCRATCH5_SHFT 0 +#define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL +union uvh_scratch5_u { + unsigned long v; + struct uvh_scratch5_s { + unsigned long scratch5 : 64; /* RW, W1CS */ + } s; +}; #endif /* __ASM_UV_MMRS_X86_H__ */ diff --git a/trunk/arch/x86/include/asm/x86_init.h b/trunk/arch/x86/include/asm/x86_init.h index 643ebf2e2ad8..d3d859035af9 100644 --- a/trunk/arch/x86/include/asm/x86_init.h +++ b/trunk/arch/x86/include/asm/x86_init.h @@ -67,6 +67,17 @@ struct x86_init_oem { void (*banner)(void); }; +/** + * struct x86_init_mapping - platform specific initial kernel pagetable setup + * @pagetable_reserve: reserve a range of addresses for kernel pagetable usage + * + * For more details on the purpose of this hook, look in + * init_memory_mapping and the commit that added it. + */ +struct x86_init_mapping { + void (*pagetable_reserve)(u64 start, u64 end); +}; + /** * struct x86_init_paging - platform specific paging functions * @pagetable_setup_start: platform specific pre paging_init() call @@ -123,6 +134,7 @@ struct x86_init_ops { struct x86_init_mpparse mpparse; struct x86_init_irqs irqs; struct x86_init_oem oem; + struct x86_init_mapping mapping; struct x86_init_paging paging; struct x86_init_timers timers; struct x86_init_iommu iommu; diff --git a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c index 33b10a0fc095..7acd2d2ac965 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/trunk/arch/x86/kernel/apic/x2apic_uv_x.c @@ -37,6 +37,13 @@ #include #include #include +#include + +/* BMC sets a bit this MMR non-zero before sending an NMI */ +#define UVH_NMI_MMR UVH_SCRATCH5 +#define UVH_NMI_MMR_CLEAR (UVH_NMI_MMR + 8) +#define UV_NMI_PENDING_MASK (1UL << 63) +DEFINE_PER_CPU(unsigned long, cpu_last_nmi_count); DEFINE_PER_CPU(int, x2apic_extra_bits); @@ -642,18 +649,46 @@ void __cpuinit uv_cpu_init(void) */ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) { + unsigned long real_uv_nmi; + int bid; + if (reason != DIE_NMIUNKNOWN) return NOTIFY_OK; if (in_crash_kexec) /* do nothing if entering the crash kernel */ return NOTIFY_OK; + /* - * Use a lock so only one cpu prints at a time - * to prevent intermixed output. + * Each blade has an MMR that indicates when an NMI has been sent + * to cpus on the blade. If an NMI is detected, atomically + * clear the MMR and update a per-blade NMI count used to + * cause each cpu on the blade to notice a new NMI. + */ + bid = uv_numa_blade_id(); + real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); + + if (unlikely(real_uv_nmi)) { + spin_lock(&uv_blade_info[bid].nmi_lock); + real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); + if (real_uv_nmi) { + uv_blade_info[bid].nmi_count++; + uv_write_local_mmr(UVH_NMI_MMR_CLEAR, UV_NMI_PENDING_MASK); + } + spin_unlock(&uv_blade_info[bid].nmi_lock); + } + + if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count)) + return NOTIFY_DONE; + + __get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count; + + /* + * Use a lock so only one cpu prints at a time. + * This prevents intermixed output. */ spin_lock(&uv_nmi_lock); - pr_info("NMI stack dump cpu %u:\n", smp_processor_id()); + pr_info("UV NMI stack dump cpu %u:\n", smp_processor_id()); dump_stack(); spin_unlock(&uv_nmi_lock); @@ -661,7 +696,8 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) } static struct notifier_block uv_dump_stack_nmi_nb = { - .notifier_call = uv_handle_nmi + .notifier_call = uv_handle_nmi, + .priority = NMI_LOCAL_LOW_PRIOR - 1, }; void uv_register_nmi_notifier(void) @@ -720,8 +756,9 @@ void __init uv_system_init(void) printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); - uv_blade_info = kmalloc(bytes, GFP_KERNEL); + uv_blade_info = kzalloc(bytes, GFP_KERNEL); BUG_ON(!uv_blade_info); + for (blade = 0; blade < uv_num_possible_blades(); blade++) uv_blade_info[blade].memory_nid = -1; @@ -747,6 +784,7 @@ void __init uv_system_init(void) uv_blade_info[blade].pnode = pnode; uv_blade_info[blade].nr_possible_cpus = 0; uv_blade_info[blade].nr_online_cpus = 0; + spin_lock_init(&uv_blade_info[blade].nmi_lock); max_pnode = max(pnode, max_pnode); blade++; } diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index bb9eb29a52dd..6f9d1f6063e9 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -613,7 +613,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) #endif /* As a rule processors have APIC timer running in deep C states */ - if (c->x86 >= 0xf && !cpu_has_amd_erratum(amd_erratum_400)) + if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400)) set_cpu_cap(c, X86_FEATURE_ARAT); /* @@ -698,7 +698,7 @@ cpu_dev_register(amd_cpu_dev); */ const int amd_erratum_400[] = - AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0x0f, 0x4, 0x2, 0xff, 0xf), + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); EXPORT_SYMBOL_GPL(amd_erratum_400); diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c index 167f97b5596e..bb0adad35143 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -509,6 +509,7 @@ static __cpuinit int allocate_threshold_blocks(unsigned int cpu, out_free: if (b) { kobject_put(&b->kobj); + list_del(&b->miscj); kfree(b); } return err; diff --git a/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c index 6f8c5e9da97f..0f034460260d 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -446,18 +446,20 @@ void intel_init_thermal(struct cpuinfo_x86 *c) */ rdmsr(MSR_IA32_MISC_ENABLE, l, h); + h = lvtthmr_init; /* * The initial value of thermal LVT entries on all APs always reads * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI * sequence to them and LVT registers are reset to 0s except for * the mask bits which are set to 1s when APs receive INIT IPI. - * Always restore the value that BIOS has programmed on AP based on - * BSP's info we saved since BIOS is always setting the same value - * for all threads/cores + * If BIOS takes over the thermal interrupt and sets its interrupt + * delivery mode to SMI (not fixed), it restores the value that the + * BIOS has programmed on AP based on BSP's info we saved since BIOS + * is always setting the same value for all threads/cores. */ - apic_write(APIC_LVTTHMR, lvtthmr_init); + if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED) + apic_write(APIC_LVTTHMR, lvtthmr_init); - h = lvtthmr_init; if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { printk(KERN_DEBUG diff --git a/trunk/arch/x86/kernel/kprobes.c b/trunk/arch/x86/kernel/kprobes.c index c969fd9d1566..f1a6244d7d93 100644 --- a/trunk/arch/x86/kernel/kprobes.c +++ b/trunk/arch/x86/kernel/kprobes.c @@ -1183,12 +1183,13 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + unsigned long flags; /* This is possible if op is under delayed unoptimizing */ if (kprobe_disabled(&op->kp)) return; - preempt_disable(); + local_irq_save(flags); if (kprobe_running()) { kprobes_inc_nmissed_count(&op->kp); } else { @@ -1207,7 +1208,7 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op, opt_pre_handler(&op->kp, regs); __this_cpu_write(current_kprobe, NULL); } - preempt_enable_no_resched(); + local_irq_restore(flags); } static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src) diff --git a/trunk/arch/x86/kernel/x86_init.c b/trunk/arch/x86/kernel/x86_init.c index c11514e9128b..75ef4b18e9b7 100644 --- a/trunk/arch/x86/kernel/x86_init.c +++ b/trunk/arch/x86/kernel/x86_init.c @@ -61,6 +61,10 @@ struct x86_init_ops x86_init __initdata = { .banner = default_banner, }, + .mapping = { + .pagetable_reserve = native_pagetable_reserve, + }, + .paging = { .pagetable_setup_start = native_pagetable_setup_start, .pagetable_setup_done = native_pagetable_setup_done, diff --git a/trunk/arch/x86/mm/init.c b/trunk/arch/x86/mm/init.c index 286d289b039b..37b8b0fe8320 100644 --- a/trunk/arch/x86/mm/init.c +++ b/trunk/arch/x86/mm/init.c @@ -81,6 +81,11 @@ static void __init find_early_table_space(unsigned long end, int use_pse, end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); } +void __init native_pagetable_reserve(u64 start, u64 end) +{ + memblock_x86_reserve_range(start, end, "PGTABLE"); +} + struct map_range { unsigned long start; unsigned long end; @@ -272,9 +277,24 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, __flush_tlb_all(); + /* + * Reserve the kernel pagetable pages we used (pgt_buf_start - + * pgt_buf_end) and free the other ones (pgt_buf_end - pgt_buf_top) + * so that they can be reused for other purposes. + * + * On native it just means calling memblock_x86_reserve_range, on Xen it + * also means marking RW the pagetable pages that we allocated before + * but that haven't been used. + * + * In fact on xen we mark RO the whole range pgt_buf_start - + * pgt_buf_top, because we have to make sure that when + * init_memory_mapping reaches the pagetable pages area, it maps + * RO all the pagetable pages, including the ones that are beyond + * pgt_buf_end at that time. + */ if (!after_bootmem && pgt_buf_end > pgt_buf_start) - memblock_x86_reserve_range(pgt_buf_start << PAGE_SHIFT, - pgt_buf_end << PAGE_SHIFT, "PGTABLE"); + x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start), + PFN_PHYS(pgt_buf_end)); if (!after_bootmem) early_memtest(start, end); diff --git a/trunk/arch/x86/platform/uv/tlb_uv.c b/trunk/arch/x86/platform/uv/tlb_uv.c index 7cb6424317f6..c58e0ea39ef5 100644 --- a/trunk/arch/x86/platform/uv/tlb_uv.c +++ b/trunk/arch/x86/platform/uv/tlb_uv.c @@ -699,16 +699,17 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, struct mm_struct *mm, unsigned long va, unsigned int cpu) { - int tcpu; - int uvhub; int locals = 0; int remotes = 0; int hubs = 0; + int tcpu; + int tpnode; struct bau_desc *bau_desc; struct cpumask *flush_mask; struct ptc_stats *stat; struct bau_control *bcp; struct bau_control *tbcp; + struct hub_and_pnode *hpp; /* kernel was booted 'nobau' */ if (nobau) @@ -750,11 +751,18 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu; bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); - /* cpu statistics */ for_each_cpu(tcpu, flush_mask) { - uvhub = uv_cpu_to_blade_id(tcpu); - bau_uvhub_set(uvhub, &bau_desc->distribution); - if (uvhub == bcp->uvhub) + /* + * The distribution vector is a bit map of pnodes, relative + * to the partition base pnode (and the partition base nasid + * in the header). + * Translate cpu to pnode and hub using an array stored + * in local memory. + */ + hpp = &bcp->socket_master->target_hub_and_pnode[tcpu]; + tpnode = hpp->pnode - bcp->partition_base_pnode; + bau_uvhub_set(tpnode, &bau_desc->distribution); + if (hpp->uvhub == bcp->uvhub) locals++; else remotes++; @@ -855,7 +863,7 @@ void uv_bau_message_interrupt(struct pt_regs *regs) * an interrupt, but causes an error message to be returned to * the sender. */ -static void uv_enable_timeouts(void) +static void __init uv_enable_timeouts(void) { int uvhub; int nuvhubs; @@ -1326,10 +1334,10 @@ static int __init uv_ptc_init(void) } /* - * initialize the sending side's sending buffers + * Initialize the sending side's sending buffers. */ static void -uv_activation_descriptor_init(int node, int pnode) +uv_activation_descriptor_init(int node, int pnode, int base_pnode) { int i; int cpu; @@ -1352,11 +1360,11 @@ uv_activation_descriptor_init(int node, int pnode) n = pa >> uv_nshift; m = pa & uv_mmask; + /* the 14-bit pnode */ uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, (n << UV_DESC_BASE_PNODE_SHIFT | m)); - /* - * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each + * Initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each * cpu even though we only use the first one; one descriptor can * describe a broadcast to 256 uv hubs. */ @@ -1365,12 +1373,13 @@ uv_activation_descriptor_init(int node, int pnode) memset(bd2, 0, sizeof(struct bau_desc)); bd2->header.sw_ack_flag = 1; /* - * base_dest_nodeid is the nasid of the first uvhub - * in the partition. The bit map will indicate uvhub numbers, - * which are 0-N in a partition. Pnodes are unique system-wide. + * The base_dest_nasid set in the message header is the nasid + * of the first uvhub in the partition. The bit map will + * indicate destination pnode numbers relative to that base. + * They may not be consecutive if nasid striding is being used. */ - bd2->header.base_dest_nodeid = UV_PNODE_TO_NASID(uv_partition_base_pnode); - bd2->header.dest_subnodeid = 0x10; /* the LB */ + bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); + bd2->header.dest_subnodeid = UV_LB_SUBNODEID; bd2->header.command = UV_NET_ENDPOINT_INTD; bd2->header.int_both = 1; /* @@ -1442,7 +1451,7 @@ uv_payload_queue_init(int node, int pnode) /* * Initialization of each UV hub's structures */ -static void __init uv_init_uvhub(int uvhub, int vector) +static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) { int node; int pnode; @@ -1450,11 +1459,11 @@ static void __init uv_init_uvhub(int uvhub, int vector) node = uvhub_to_first_node(uvhub); pnode = uv_blade_to_pnode(uvhub); - uv_activation_descriptor_init(node, pnode); + uv_activation_descriptor_init(node, pnode, base_pnode); uv_payload_queue_init(node, pnode); /* - * the below initialization can't be in firmware because the - * messaging IRQ will be determined by the OS + * The below initialization can't be in firmware because the + * messaging IRQ will be determined by the OS. */ apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, @@ -1491,10 +1500,11 @@ calculate_destination_timeout(void) /* * initialize the bau_control structure for each cpu */ -static int __init uv_init_per_cpu(int nuvhubs) +static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) { int i; int cpu; + int tcpu; int pnode; int uvhub; int have_hmaster; @@ -1528,6 +1538,15 @@ static int __init uv_init_per_cpu(int nuvhubs) bcp = &per_cpu(bau_control, cpu); memset(bcp, 0, sizeof(struct bau_control)); pnode = uv_cpu_hub_info(cpu)->pnode; + if ((pnode - base_part_pnode) >= UV_DISTRIBUTION_SIZE) { + printk(KERN_EMERG + "cpu %d pnode %d-%d beyond %d; BAU disabled\n", + cpu, pnode, base_part_pnode, + UV_DISTRIBUTION_SIZE); + return 1; + } + bcp->osnode = cpu_to_node(cpu); + bcp->partition_base_pnode = uv_partition_base_pnode; uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); bdp = &uvhub_descs[uvhub]; @@ -1536,7 +1555,7 @@ static int __init uv_init_per_cpu(int nuvhubs) bdp->pnode = pnode; /* kludge: 'assuming' one node per socket, and assuming that disabling a socket just leaves a gap in node numbers */ - socket = (cpu_to_node(cpu) & 1); + socket = bcp->osnode & 1; bdp->socket_mask |= (1 << socket); sdp = &bdp->socket[socket]; sdp->cpu_number[sdp->num_cpus] = cpu; @@ -1585,6 +1604,20 @@ static int __init uv_init_per_cpu(int nuvhubs) nextsocket: socket++; socket_mask = (socket_mask >> 1); + /* each socket gets a local array of pnodes/hubs */ + bcp = smaster; + bcp->target_hub_and_pnode = kmalloc_node( + sizeof(struct hub_and_pnode) * + num_possible_cpus(), GFP_KERNEL, bcp->osnode); + memset(bcp->target_hub_and_pnode, 0, + sizeof(struct hub_and_pnode) * + num_possible_cpus()); + for_each_present_cpu(tcpu) { + bcp->target_hub_and_pnode[tcpu].pnode = + uv_cpu_hub_info(tcpu)->pnode; + bcp->target_hub_and_pnode[tcpu].uvhub = + uv_cpu_hub_info(tcpu)->numa_blade_id; + } } } kfree(uvhub_descs); @@ -1637,21 +1670,22 @@ static int __init uv_bau_init(void) spin_lock_init(&disable_lock); congested_cycles = microsec_2_cycles(congested_response_us); - if (uv_init_per_cpu(nuvhubs)) { - nobau = 1; - return 0; - } - uv_partition_base_pnode = 0x7fffffff; - for (uvhub = 0; uvhub < nuvhubs; uvhub++) + for (uvhub = 0; uvhub < nuvhubs; uvhub++) { if (uv_blade_nr_possible_cpus(uvhub) && (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode)) uv_partition_base_pnode = uv_blade_to_pnode(uvhub); + } + + if (uv_init_per_cpu(nuvhubs, uv_partition_base_pnode)) { + nobau = 1; + return 0; + } vector = UV_BAU_MESSAGE; for_each_possible_blade(uvhub) if (uv_blade_nr_possible_cpus(uvhub)) - uv_init_uvhub(uvhub, vector); + uv_init_uvhub(uvhub, vector, uv_partition_base_pnode); uv_enable_timeouts(); alloc_intr_gate(vector, uv_bau_message_intr1); diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 55c965b38c27..0684f3c74d53 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1275,6 +1275,20 @@ static __init void xen_pagetable_setup_start(pgd_t *base) { } +static __init void xen_mapping_pagetable_reserve(u64 start, u64 end) +{ + /* reserve the range used */ + native_pagetable_reserve(start, end); + + /* set as RW the rest */ + printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", end, + PFN_PHYS(pgt_buf_top)); + while (end < PFN_PHYS(pgt_buf_top)) { + make_lowmem_page_readwrite(__va(end)); + end += PAGE_SIZE; + } +} + static void xen_post_allocator_init(void); static __init void xen_pagetable_setup_done(pgd_t *base) @@ -1463,119 +1477,6 @@ static int xen_pgd_alloc(struct mm_struct *mm) return ret; } -#ifdef CONFIG_X86_64 -static __initdata u64 __last_pgt_set_rw = 0; -static __initdata u64 __pgt_buf_start = 0; -static __initdata u64 __pgt_buf_end = 0; -static __initdata u64 __pgt_buf_top = 0; -/* - * As a consequence of the commit: - * - * commit 4b239f458c229de044d6905c2b0f9fe16ed9e01e - * Author: Yinghai Lu - * Date: Fri Dec 17 16:58:28 2010 -0800 - * - * x86-64, mm: Put early page table high - * - * at some point init_memory_mapping is going to reach the pagetable pages - * area and map those pages too (mapping them as normal memory that falls - * in the range of addresses passed to init_memory_mapping as argument). - * Some of those pages are already pagetable pages (they are in the range - * pgt_buf_start-pgt_buf_end) therefore they are going to be mapped RO and - * everything is fine. - * Some of these pages are not pagetable pages yet (they fall in the range - * pgt_buf_end-pgt_buf_top; for example the page at pgt_buf_end) so they - * are going to be mapped RW. When these pages become pagetable pages and - * are hooked into the pagetable, xen will find that the guest has already - * a RW mapping of them somewhere and fail the operation. - * The reason Xen requires pagetables to be RO is that the hypervisor needs - * to verify that the pagetables are valid before using them. The validation - * operations are called "pinning". - * - * In order to fix the issue we mark all the pages in the entire range - * pgt_buf_start-pgt_buf_top as RO, however when the pagetable allocation - * is completed only the range pgt_buf_start-pgt_buf_end is reserved by - * init_memory_mapping. Hence the kernel is going to crash as soon as one - * of the pages in the range pgt_buf_end-pgt_buf_top is reused (b/c those - * ranges are RO). - * - * For this reason, 'mark_rw_past_pgt' is introduced which is called _after_ - * the init_memory_mapping has completed (in a perfect world we would - * call this function from init_memory_mapping, but lets ignore that). - * - * Because we are called _after_ init_memory_mapping the pgt_buf_[start, - * end,top] have all changed to new values (b/c init_memory_mapping - * is called and setting up another new page-table). Hence, the first time - * we enter this function, we save away the pgt_buf_start value and update - * the pgt_buf_[end,top]. - * - * When we detect that the "old" pgt_buf_start through pgt_buf_end - * PFNs have been reserved (so memblock_x86_reserve_range has been called), - * we immediately set out to RW the "old" pgt_buf_end through pgt_buf_top. - * - * And then we update those "old" pgt_buf_[end|top] with the new ones - * so that we can redo this on the next pagetable. - */ -static __init void mark_rw_past_pgt(void) { - - if (pgt_buf_end > pgt_buf_start) { - u64 addr, size; - - /* Save it away. */ - if (!__pgt_buf_start) { - __pgt_buf_start = pgt_buf_start; - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - return; - } - /* If we get the range that starts at __pgt_buf_end that means - * the range is reserved, and that in 'init_memory_mapping' - * the 'memblock_x86_reserve_range' has been called with the - * outdated __pgt_buf_start, __pgt_buf_end (the "new" - * pgt_buf_[start|end|top] refer now to a new pagetable. - * Note: we are called _after_ the pgt_buf_[..] have been - * updated.*/ - - addr = memblock_x86_find_in_range_size(PFN_PHYS(__pgt_buf_start), - &size, PAGE_SIZE); - - /* Still not reserved, meaning 'memblock_x86_reserve_range' - * hasn't been called yet. Update the _end and _top.*/ - if (addr == PFN_PHYS(__pgt_buf_start)) { - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - return; - } - - /* OK, the area is reserved, meaning it is time for us to - * set RW for the old end->top PFNs. */ - - /* ..unless we had already done this. */ - if (__pgt_buf_end == __last_pgt_set_rw) - return; - - addr = PFN_PHYS(__pgt_buf_end); - - /* set as RW the rest */ - printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", - PFN_PHYS(__pgt_buf_end), PFN_PHYS(__pgt_buf_top)); - - while (addr < PFN_PHYS(__pgt_buf_top)) { - make_lowmem_page_readwrite(__va(addr)); - addr += PAGE_SIZE; - } - /* And update everything so that we are ready for the next - * pagetable (the one created for regions past 4GB) */ - __last_pgt_set_rw = __pgt_buf_end; - __pgt_buf_start = pgt_buf_start; - __pgt_buf_end = pgt_buf_end; - __pgt_buf_top = pgt_buf_top; - } - return; -} -#else -static __init void mark_rw_past_pgt(void) { } -#endif static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) { #ifdef CONFIG_X86_64 @@ -1601,14 +1502,6 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) { unsigned long pfn = pte_pfn(pte); - /* - * A bit of optimization. We do not need to call the workaround - * when xen_set_pte_init is called with a PTE with 0 as PFN. - * That is b/c the pagetable at that point are just being populated - * with empty values and we can save some cycles by not calling - * the 'memblock' code.*/ - if (pfn) - mark_rw_past_pgt(); /* * If the new pfn is within the range of the newly allocated * kernel pagetable, and it isn't being mapped into an @@ -2118,8 +2011,6 @@ __init void xen_ident_map_ISA(void) static __init void xen_post_allocator_init(void) { - mark_rw_past_pgt(); - #ifdef CONFIG_XEN_DEBUG pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); #endif @@ -2228,6 +2119,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { void __init xen_init_mmu_ops(void) { + x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve; x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done; pv_mmu_ops = xen_mmu_ops; diff --git a/trunk/block/blk-cgroup.c b/trunk/block/blk-cgroup.c index f0605ab2a761..471fdcc5df85 100644 --- a/trunk/block/blk-cgroup.c +++ b/trunk/block/blk-cgroup.c @@ -114,6 +114,13 @@ struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) } EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup); +struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk) +{ + return container_of(task_subsys_state(tsk, blkio_subsys_id), + struct blkio_cgroup, css); +} +EXPORT_SYMBOL_GPL(task_blkio_cgroup); + static inline void blkio_update_group_weight(struct blkio_group *blkg, unsigned int weight) { diff --git a/trunk/block/blk-cgroup.h b/trunk/block/blk-cgroup.h index 10919fae2d3a..c774930cc206 100644 --- a/trunk/block/blk-cgroup.h +++ b/trunk/block/blk-cgroup.h @@ -291,6 +291,7 @@ static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg) {} #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE) extern struct blkio_cgroup blkio_root_cgroup; extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup); +extern struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk); extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, struct blkio_group *blkg, void *key, dev_t dev, enum blkio_policy_id plid); @@ -314,6 +315,8 @@ void blkiocg_update_io_remove_stats(struct blkio_group *blkg, struct cgroup; static inline struct blkio_cgroup * cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; } +static inline struct blkio_cgroup * +task_blkio_cgroup(struct task_struct *tsk) { return NULL; } static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, struct blkio_group *blkg, void *key, dev_t dev, diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index a2e58eeb3549..3fe00a14822a 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -316,8 +316,10 @@ EXPORT_SYMBOL(__blk_run_queue); */ void blk_run_queue_async(struct request_queue *q) { - if (likely(!blk_queue_stopped(q))) + if (likely(!blk_queue_stopped(q))) { + __cancel_delayed_work(&q->delay_work); queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); + } } EXPORT_SYMBOL(blk_run_queue_async); diff --git a/trunk/block/blk-throttle.c b/trunk/block/blk-throttle.c index 0475a22a420d..252a81a306f7 100644 --- a/trunk/block/blk-throttle.c +++ b/trunk/block/blk-throttle.c @@ -160,9 +160,8 @@ static void throtl_put_tg(struct throtl_grp *tg) } static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, - struct cgroup *cgroup) + struct blkio_cgroup *blkcg) { - struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); struct throtl_grp *tg = NULL; void *key = td; struct backing_dev_info *bdi = &td->queue->backing_dev_info; @@ -229,12 +228,12 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, static struct throtl_grp * throtl_get_tg(struct throtl_data *td) { - struct cgroup *cgroup; struct throtl_grp *tg = NULL; + struct blkio_cgroup *blkcg; rcu_read_lock(); - cgroup = task_cgroup(current, blkio_subsys_id); - tg = throtl_find_alloc_tg(td, cgroup); + blkcg = task_blkio_cgroup(current); + tg = throtl_find_alloc_tg(td, blkcg); if (!tg) tg = &td->root_tg; rcu_read_unlock(); diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 5b52011e3a40..ab7a9e6a9b1c 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1014,10 +1014,9 @@ void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg, cfqg->needs_update = true; } -static struct cfq_group * -cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) +static struct cfq_group * cfq_find_alloc_cfqg(struct cfq_data *cfqd, + struct blkio_cgroup *blkcg, int create) { - struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); struct cfq_group *cfqg = NULL; void *key = cfqd; int i, j; @@ -1079,12 +1078,12 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) */ static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create) { - struct cgroup *cgroup; + struct blkio_cgroup *blkcg; struct cfq_group *cfqg = NULL; rcu_read_lock(); - cgroup = task_cgroup(current, blkio_subsys_id); - cfqg = cfq_find_alloc_cfqg(cfqd, cgroup, create); + blkcg = task_blkio_cgroup(current); + cfqg = cfq_find_alloc_cfqg(cfqd, blkcg, create); if (!cfqg && create) cfqg = &cfqd->root_group; rcu_read_unlock(); diff --git a/trunk/drivers/ata/libahci.c b/trunk/drivers/ata/libahci.c index ff9d832a163d..d38c40fe4ddb 100644 --- a/trunk/drivers/ata/libahci.c +++ b/trunk/drivers/ata/libahci.c @@ -561,27 +561,6 @@ void ahci_start_engine(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); u32 tmp; - u8 status; - - status = readl(port_mmio + PORT_TFDATA) & 0xFF; - - /* - * At end of section 10.1 of AHCI spec (rev 1.3), it states - * Software shall not set PxCMD.ST to 1 until it is determined - * that a functoinal device is present on the port as determined by - * PxTFD.STS.BSY=0, PxTFD.STS.DRQ=0 and PxSSTS.DET=3h - * - * Even though most AHCI host controllers work without this check, - * specific controller will fail under this condition - */ - if (status & (ATA_BUSY | ATA_DRQ)) - return; - else { - ahci_scr_read(&ap->link, SCR_STATUS, &tmp); - - if ((tmp & 0xf) != 0x3) - return; - } /* start DMA */ tmp = readl(port_mmio + PORT_CMD); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index f26f2fe3480a..dad9fd660f37 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -3316,7 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, struct ata_eh_context *ehc = &link->eh_context; struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; enum ata_lpm_policy old_policy = link->lpm_policy; - bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM; + bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM; unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; unsigned int err_mask; int rc; diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index bdd2719f3f68..bc9e702186dd 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -2643,16 +2643,19 @@ fore200e_init(struct fore200e* fore200e, struct device *parent) } #ifdef CONFIG_SBUS +static const struct of_device_id fore200e_sba_match[]; static int __devinit fore200e_sba_probe(struct platform_device *op) { + const struct of_device_id *match; const struct fore200e_bus *bus; struct fore200e *fore200e; static int index = 0; int err; - if (!op->dev.of_match) + match = of_match_device(fore200e_sba_match, &op->dev); + if (!match) return -EINVAL; - bus = op->dev.of_match->data; + bus = match->data; fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); if (!fore200e) diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 8066d086578a..e086fbbbe853 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -2547,7 +2547,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) disk->major = MajorNumber; disk->first_minor = n << DAC960_MaxPartitionsBits; disk->fops = &DAC960_BlockDeviceOperations; - disk->events = DISK_EVENT_MEDIA_CHANGE; } /* Indicate the Block Device Registration completed successfully, diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 456c0cc90dcf..8eba86bba599 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -1736,7 +1736,6 @@ static int __init fd_probe_drives(void) disk->major = FLOPPY_MAJOR; disk->first_minor = drive; disk->fops = &floppy_fops; - disk->events = DISK_EVENT_MEDIA_CHANGE; sprintf(disk->disk_name, "fd%d", drive); disk->private_data = &unit[drive]; set_capacity(disk, 880*2); diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index c871eae14120..ede16c64ff07 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -1964,7 +1964,6 @@ static int __init atari_floppy_init (void) unit[i].disk->first_minor = i; sprintf(unit[i].disk->disk_name, "fd%d", i); unit[i].disk->fops = &floppy_fops; - unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE; unit[i].disk->private_data = &unit[i]; unit[i].disk->queue = blk_init_queue(do_fd_request, &ataflop_lock); diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 301d7a9a41a6..db8f88586c8d 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4205,7 +4205,6 @@ static int __init floppy_init(void) disks[dr]->major = FLOPPY_MAJOR; disks[dr]->first_minor = TOMINOR(dr); disks[dr]->fops = &floppy_fops; - disks[dr]->events = DISK_EVENT_MEDIA_CHANGE; sprintf(disks[dr]->disk_name, "fd%d", dr); init_timer(&motor_off_timer[dr]); diff --git a/trunk/drivers/block/paride/pcd.c b/trunk/drivers/block/paride/pcd.c index 2f2ccf686251..8690e31d9932 100644 --- a/trunk/drivers/block/paride/pcd.c +++ b/trunk/drivers/block/paride/pcd.c @@ -320,7 +320,6 @@ static void pcd_init_units(void) disk->first_minor = unit; strcpy(disk->disk_name, cd->name); /* umm... */ disk->fops = &pcd_bdops; - disk->events = DISK_EVENT_MEDIA_CHANGE; } } diff --git a/trunk/drivers/block/paride/pd.c b/trunk/drivers/block/paride/pd.c index 21dfdb776869..869e7676d46f 100644 --- a/trunk/drivers/block/paride/pd.c +++ b/trunk/drivers/block/paride/pd.c @@ -837,7 +837,6 @@ static void pd_probe_drive(struct pd_unit *disk) p->fops = &pd_fops; p->major = major; p->first_minor = (disk - pd) << PD_BITS; - p->events = DISK_EVENT_MEDIA_CHANGE; disk->gd = p; p->private_data = disk; p->queue = pd_queue; diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index 7adeb1edbf43..f21b520ef419 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -294,7 +294,6 @@ static void __init pf_init_units(void) disk->first_minor = unit; strcpy(disk->disk_name, pf->name); disk->fops = &pf_fops; - disk->events = DISK_EVENT_MEDIA_CHANGE; if (!(*drives[unit])[D_PRT]) pf_drive_count++; } diff --git a/trunk/drivers/block/rbd.c b/trunk/drivers/block/rbd.c index 3e904717c1c0..9712fad82bc6 100644 --- a/trunk/drivers/block/rbd.c +++ b/trunk/drivers/block/rbd.c @@ -92,6 +92,8 @@ struct rbd_client { struct list_head node; }; +struct rbd_req_coll; + /* * a single io request */ @@ -100,6 +102,24 @@ struct rbd_request { struct bio *bio; /* cloned bio */ struct page **pages; /* list of used pages */ u64 len; + int coll_index; + struct rbd_req_coll *coll; +}; + +struct rbd_req_status { + int done; + int rc; + u64 bytes; +}; + +/* + * a collection of requests + */ +struct rbd_req_coll { + int total; + int num_done; + struct kref kref; + struct rbd_req_status status[0]; }; struct rbd_snap { @@ -416,6 +436,17 @@ static void rbd_put_client(struct rbd_device *rbd_dev) rbd_dev->client = NULL; } +/* + * Destroy requests collection + */ +static void rbd_coll_release(struct kref *kref) +{ + struct rbd_req_coll *coll = + container_of(kref, struct rbd_req_coll, kref); + + dout("rbd_coll_release %p\n", coll); + kfree(coll); +} /* * Create a new header structure, translate header format from the on-disk @@ -590,6 +621,14 @@ static u64 rbd_get_segment(struct rbd_image_header *header, return len; } +static int rbd_get_num_segments(struct rbd_image_header *header, + u64 ofs, u64 len) +{ + u64 start_seg = ofs >> header->obj_order; + u64 end_seg = (ofs + len - 1) >> header->obj_order; + return end_seg - start_seg + 1; +} + /* * bio helpers */ @@ -735,6 +774,50 @@ static void rbd_destroy_ops(struct ceph_osd_req_op *ops) kfree(ops); } +static void rbd_coll_end_req_index(struct request *rq, + struct rbd_req_coll *coll, + int index, + int ret, u64 len) +{ + struct request_queue *q; + int min, max, i; + + dout("rbd_coll_end_req_index %p index %d ret %d len %lld\n", + coll, index, ret, len); + + if (!rq) + return; + + if (!coll) { + blk_end_request(rq, ret, len); + return; + } + + q = rq->q; + + spin_lock_irq(q->queue_lock); + coll->status[index].done = 1; + coll->status[index].rc = ret; + coll->status[index].bytes = len; + max = min = coll->num_done; + while (max < coll->total && coll->status[max].done) + max++; + + for (i = min; istatus[i].rc, + coll->status[i].bytes); + coll->num_done++; + kref_put(&coll->kref, rbd_coll_release); + } + spin_unlock_irq(q->queue_lock); +} + +static void rbd_coll_end_req(struct rbd_request *req, + int ret, u64 len) +{ + rbd_coll_end_req_index(req->rq, req->coll, req->coll_index, ret, len); +} + /* * Send ceph osd request */ @@ -749,6 +832,8 @@ static int rbd_do_request(struct request *rq, int flags, struct ceph_osd_req_op *ops, int num_reply, + struct rbd_req_coll *coll, + int coll_index, void (*rbd_cb)(struct ceph_osd_request *req, struct ceph_msg *msg), struct ceph_osd_request **linger_req, @@ -763,12 +848,20 @@ static int rbd_do_request(struct request *rq, struct ceph_osd_request_head *reqhead; struct rbd_image_header *header = &dev->header; - ret = -ENOMEM; req_data = kzalloc(sizeof(*req_data), GFP_NOIO); - if (!req_data) - goto done; + if (!req_data) { + if (coll) + rbd_coll_end_req_index(rq, coll, coll_index, + -ENOMEM, len); + return -ENOMEM; + } - dout("rbd_do_request len=%lld ofs=%lld\n", len, ofs); + if (coll) { + req_data->coll = coll; + req_data->coll_index = coll_index; + } + + dout("rbd_do_request obj=%s ofs=%lld len=%lld\n", obj, len, ofs); down_read(&header->snap_rwsem); @@ -828,7 +921,8 @@ static int rbd_do_request(struct request *rq, ret = ceph_osdc_wait_request(&dev->client->osdc, req); if (ver) *ver = le64_to_cpu(req->r_reassert_version.version); - dout("reassert_ver=%lld\n", le64_to_cpu(req->r_reassert_version.version)); + dout("reassert_ver=%lld\n", + le64_to_cpu(req->r_reassert_version.version)); ceph_osdc_put_request(req); } return ret; @@ -837,10 +931,8 @@ static int rbd_do_request(struct request *rq, bio_chain_put(req_data->bio); ceph_osdc_put_request(req); done_pages: + rbd_coll_end_req(req_data, ret, len); kfree(req_data); -done: - if (rq) - blk_end_request(rq, ret, len); return ret; } @@ -874,7 +966,7 @@ static void rbd_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg) bytes = req_data->len; } - blk_end_request(req_data->rq, rc, bytes); + rbd_coll_end_req(req_data, rc, bytes); if (req_data->bio) bio_chain_put(req_data->bio); @@ -934,6 +1026,7 @@ static int rbd_req_sync_op(struct rbd_device *dev, flags, ops, 2, + NULL, 0, NULL, linger_req, ver); if (ret < 0) @@ -959,7 +1052,9 @@ static int rbd_do_op(struct request *rq, u64 snapid, int opcode, int flags, int num_reply, u64 ofs, u64 len, - struct bio *bio) + struct bio *bio, + struct rbd_req_coll *coll, + int coll_index) { char *seg_name; u64 seg_ofs; @@ -995,7 +1090,10 @@ static int rbd_do_op(struct request *rq, flags, ops, num_reply, + coll, coll_index, rbd_req_cb, 0, NULL); + + rbd_destroy_ops(ops); done: kfree(seg_name); return ret; @@ -1008,13 +1106,15 @@ static int rbd_req_write(struct request *rq, struct rbd_device *rbd_dev, struct ceph_snap_context *snapc, u64 ofs, u64 len, - struct bio *bio) + struct bio *bio, + struct rbd_req_coll *coll, + int coll_index) { return rbd_do_op(rq, rbd_dev, snapc, CEPH_NOSNAP, CEPH_OSD_OP_WRITE, CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, 2, - ofs, len, bio); + ofs, len, bio, coll, coll_index); } /* @@ -1024,14 +1124,16 @@ static int rbd_req_read(struct request *rq, struct rbd_device *rbd_dev, u64 snapid, u64 ofs, u64 len, - struct bio *bio) + struct bio *bio, + struct rbd_req_coll *coll, + int coll_index) { return rbd_do_op(rq, rbd_dev, NULL, (snapid ? snapid : CEPH_NOSNAP), CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, 2, - ofs, len, bio); + ofs, len, bio, coll, coll_index); } /* @@ -1063,7 +1165,9 @@ static int rbd_req_sync_notify_ack(struct rbd_device *dev, { struct ceph_osd_req_op *ops; struct page **pages = NULL; - int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_NOTIFY_ACK, 0); + int ret; + + ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_NOTIFY_ACK, 0); if (ret < 0) return ret; @@ -1077,6 +1181,7 @@ static int rbd_req_sync_notify_ack(struct rbd_device *dev, CEPH_OSD_FLAG_READ, ops, 1, + NULL, 0, rbd_simple_req_cb, 0, NULL); rbd_destroy_ops(ops); @@ -1274,6 +1379,20 @@ static int rbd_req_sync_exec(struct rbd_device *dev, return ret; } +static struct rbd_req_coll *rbd_alloc_coll(int num_reqs) +{ + struct rbd_req_coll *coll = + kzalloc(sizeof(struct rbd_req_coll) + + sizeof(struct rbd_req_status) * num_reqs, + GFP_ATOMIC); + + if (!coll) + return NULL; + coll->total = num_reqs; + kref_init(&coll->kref); + return coll; +} + /* * block device queue callback */ @@ -1291,6 +1410,8 @@ static void rbd_rq_fn(struct request_queue *q) bool do_write; int size, op_size = 0; u64 ofs; + int num_segs, cur_seg = 0; + struct rbd_req_coll *coll; /* peek at request from block layer */ if (!rq) @@ -1321,6 +1442,14 @@ static void rbd_rq_fn(struct request_queue *q) do_write ? "write" : "read", size, blk_rq_pos(rq) * 512ULL); + num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size); + coll = rbd_alloc_coll(num_segs); + if (!coll) { + spin_lock_irq(q->queue_lock); + __blk_end_request_all(rq, -ENOMEM); + goto next; + } + do { /* a bio clone to be passed down to OSD req */ dout("rq->bio->bi_vcnt=%d\n", rq->bio->bi_vcnt); @@ -1328,35 +1457,41 @@ static void rbd_rq_fn(struct request_queue *q) rbd_dev->header.block_name, ofs, size, NULL, NULL); + kref_get(&coll->kref); bio = bio_chain_clone(&rq_bio, &next_bio, &bp, op_size, GFP_ATOMIC); if (!bio) { - spin_lock_irq(q->queue_lock); - __blk_end_request_all(rq, -ENOMEM); - goto next; + rbd_coll_end_req_index(rq, coll, cur_seg, + -ENOMEM, op_size); + goto next_seg; } + /* init OSD command: write or read */ if (do_write) rbd_req_write(rq, rbd_dev, rbd_dev->header.snapc, ofs, - op_size, bio); + op_size, bio, + coll, cur_seg); else rbd_req_read(rq, rbd_dev, cur_snap_id(rbd_dev), ofs, - op_size, bio); + op_size, bio, + coll, cur_seg); +next_seg: size -= op_size; ofs += op_size; + cur_seg++; rq_bio = next_bio; } while (size > 0); + kref_put(&coll->kref, rbd_coll_release); if (bp) bio_pair_release(bp); - spin_lock_irq(q->queue_lock); next: rq = blk_fetch_request(q); diff --git a/trunk/drivers/block/swim.c b/trunk/drivers/block/swim.c index 24a482f2fbd6..fd5adcd55944 100644 --- a/trunk/drivers/block/swim.c +++ b/trunk/drivers/block/swim.c @@ -858,7 +858,6 @@ static int __devinit swim_floppy_init(struct swim_priv *swd) swd->unit[drive].disk->first_minor = drive; sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); swd->unit[drive].disk->fops = &floppy_fops; - swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; swd->unit[drive].disk->private_data = &swd->unit[drive]; swd->unit[drive].disk->queue = swd->queue; set_capacity(swd->unit[drive].disk, 2880); diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index 4c10f56facbf..773bfa792777 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -1163,7 +1163,6 @@ static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device disk->major = FLOPPY_MAJOR; disk->first_minor = i; disk->fops = &floppy_fops; - disk->events = DISK_EVENT_MEDIA_CHANGE; disk->private_data = &floppy_states[i]; disk->queue = swim3_queue; disk->flags |= GENHD_FL_REMOVABLE; diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 68b9430c7cfe..0e376d46bdd1 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -2334,7 +2334,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) disk->major = UB_MAJOR; disk->first_minor = lun->id * UB_PARTS_PER_LUN; disk->fops = &ub_bd_fops; - disk->events = DISK_EVENT_MEDIA_CHANGE; disk->private_data = lun; disk->driverfs_dev = &sc->intf->dev; diff --git a/trunk/drivers/block/xsysace.c b/trunk/drivers/block/xsysace.c index 645ff765cd12..6c7fd7db6dff 100644 --- a/trunk/drivers/block/xsysace.c +++ b/trunk/drivers/block/xsysace.c @@ -1005,7 +1005,6 @@ static int __devinit ace_setup(struct ace_device *ace) ace->gd->major = ace_major; ace->gd->first_minor = ace->id * ACE_NUM_MINORS; ace->gd->fops = &ace_fops; - ace->gd->events = DISK_EVENT_MEDIA_CHANGE; ace->gd->queue = ace->queue; ace->gd->private_data = ace; snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a'); diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index 514dd8efaf73..75fb965b8f72 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -986,6 +986,9 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t cdinfo(CD_OPEN, "entering cdrom_open\n"); + /* open is event synchronization point, check events first */ + check_disk_change(bdev); + /* if this was a O_NONBLOCK open and we should honor the flags, * do a quick open without drive/disc integrity checks. */ cdi->use_count++; @@ -1012,9 +1015,6 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count); - /* Do this on open. Don't wait for mount, because they might - not be mounting, but opening with O_NONBLOCK */ - check_disk_change(bdev); return 0; err_release: if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) { diff --git a/trunk/drivers/cdrom/gdrom.c b/trunk/drivers/cdrom/gdrom.c index b2b034fea34e..3ceaf006e7f0 100644 --- a/trunk/drivers/cdrom/gdrom.c +++ b/trunk/drivers/cdrom/gdrom.c @@ -803,7 +803,6 @@ static int __devinit probe_gdrom(struct platform_device *devptr) goto probe_fail_cdrom_register; } gd.disk->fops = &gdrom_bdops; - gd.disk->events = DISK_EVENT_MEDIA_CHANGE; /* latch on to the interrupt */ err = gdrom_set_interrupt_handlers(); if (err) diff --git a/trunk/drivers/cdrom/viocd.c b/trunk/drivers/cdrom/viocd.c index 4e874c5fa605..e427fbe45999 100644 --- a/trunk/drivers/cdrom/viocd.c +++ b/trunk/drivers/cdrom/viocd.c @@ -626,7 +626,6 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) gendisk->queue = q; gendisk->fops = &viocd_fops; gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; - gendisk->events = DISK_EVENT_MEDIA_CHANGE; set_capacity(gendisk, 0); gendisk->private_data = d; d->viocd_disk = gendisk; diff --git a/trunk/drivers/char/hw_random/n2-drv.c b/trunk/drivers/char/hw_random/n2-drv.c index 43ac61978d8b..ac6739e085e3 100644 --- a/trunk/drivers/char/hw_random/n2-drv.c +++ b/trunk/drivers/char/hw_random/n2-drv.c @@ -619,15 +619,18 @@ static void __devinit n2rng_driver_version(void) pr_info("%s", version); } +static const struct of_device_id n2rng_match[]; static int __devinit n2rng_probe(struct platform_device *op) { + const struct of_device_id *match; int victoria_falls; int err = -ENOMEM; struct n2rng *np; - if (!op->dev.of_match) + match = of_match_device(n2rng_match, &op->dev); + if (!match) return -EINVAL; - victoria_falls = (op->dev.of_match->data != NULL); + victoria_falls = (match->data != NULL); n2rng_driver_version(); np = kzalloc(sizeof(*np), GFP_KERNEL); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index cc6c9b2546a3..64c6b8530615 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -2554,9 +2554,11 @@ static struct pci_driver ipmi_pci_driver = { }; #endif /* CONFIG_PCI */ +static struct of_device_id ipmi_match[]; static int __devinit ipmi_probe(struct platform_device *dev) { #ifdef CONFIG_OF + const struct of_device_id *match; struct smi_info *info; struct resource resource; const __be32 *regsize, *regspacing, *regshift; @@ -2566,7 +2568,8 @@ static int __devinit ipmi_probe(struct platform_device *dev) dev_info(&dev->dev, "probing via device tree\n"); - if (!dev->dev.of_match) + match = of_match_device(ipmi_match, &dev->dev); + if (!match) return -EINVAL; ret = of_address_to_resource(np, 0, &resource); @@ -2601,7 +2604,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) return -ENOMEM; } - info->si_type = (enum si_type) dev->dev.of_match->data; + info->si_type = (enum si_type) match->data; info->addr_source = SI_DEVICETREE; info->irq_setup = std_irq_setup; diff --git a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c index d6412c16385f..39ccdeada791 100644 --- a/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/trunk/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -715,13 +715,13 @@ static int __devexit hwicap_remove(struct device *dev) } #ifdef CONFIG_OF -static int __devinit hwicap_of_probe(struct platform_device *op) +static int __devinit hwicap_of_probe(struct platform_device *op, + const struct hwicap_driver_config *config) { struct resource res; const unsigned int *id; const char *family; int rc; - const struct hwicap_driver_config *config = op->dev.of_match->data; const struct config_registers *regs; @@ -751,20 +751,24 @@ static int __devinit hwicap_of_probe(struct platform_device *op) regs); } #else -static inline int hwicap_of_probe(struct platform_device *op) +static inline int hwicap_of_probe(struct platform_device *op, + const struct hwicap_driver_config *config) { return -EINVAL; } #endif /* CONFIG_OF */ +static const struct of_device_id __devinitconst hwicap_of_match[]; static int __devinit hwicap_drv_probe(struct platform_device *pdev) { + const struct of_device_id *match; struct resource *res; const struct config_registers *regs; const char *family; - if (pdev->dev.of_match) - return hwicap_of_probe(pdev); + match = of_match_device(hwicap_of_match, &pdev->dev); + if (match) + return hwicap_of_probe(pdev, match->data); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) diff --git a/trunk/drivers/edac/ppc4xx_edac.c b/trunk/drivers/edac/ppc4xx_edac.c index c1f0045ceb8e..af8e7b1aa290 100644 --- a/trunk/drivers/edac/ppc4xx_edac.c +++ b/trunk/drivers/edac/ppc4xx_edac.c @@ -1019,7 +1019,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, struct ppc4xx_edac_pdata *pdata = NULL; const struct device_node *np = op->dev.of_node; - if (op->dev.of_match == NULL) + if (of_match_device(ppc4xx_edac_match, &op->dev) == NULL) return -EINVAL; /* Initial driver pointers and private data */ diff --git a/trunk/drivers/gpu/drm/drm_fb_helper.c b/trunk/drivers/gpu/drm/drm_fb_helper.c index 11d7a72c22d9..140b9525b48a 100644 --- a/trunk/drivers/gpu/drm/drm_fb_helper.c +++ b/trunk/drivers/gpu/drm/drm_fb_helper.c @@ -1516,17 +1516,33 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) } EXPORT_SYMBOL(drm_fb_helper_initial_config); -bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) +/** + * drm_fb_helper_hotplug_event - respond to a hotplug notification by + * probing all the outputs attached to the fb. + * @fb_helper: the drm_fb_helper + * + * LOCKING: + * Called at runtime, must take mode config lock. + * + * Scan the connectors attached to the fb_helper and try to put together a + * setup after *notification of a change in output configuration. + * + * RETURNS: + * 0 on success and a non-zero error code otherwise. + */ +int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) { + struct drm_device *dev = fb_helper->dev; int count = 0; u32 max_width, max_height, bpp_sel; bool bound = false, crtcs_bound = false; struct drm_crtc *crtc; if (!fb_helper->fb) - return false; + return 0; - list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) { + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (crtc->fb) crtcs_bound = true; if (crtc->fb == fb_helper->fb) @@ -1535,7 +1551,8 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) if (!bound && crtcs_bound) { fb_helper->delayed_hotplug = true; - return false; + mutex_unlock(&dev->mode_config.mutex); + return 0; } DRM_DEBUG_KMS("\n"); @@ -1546,6 +1563,7 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height); drm_setup_crtcs(fb_helper); + mutex_unlock(&dev->mode_config.mutex); return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index c34a8dd31d02..32d1b3e829c8 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -49,7 +49,7 @@ module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600); unsigned int i915_powersave = 1; module_param_named(powersave, i915_powersave, int, 0600); -unsigned int i915_semaphores = 1; +unsigned int i915_semaphores = 0; module_param_named(semaphores, i915_semaphores, int, 0600); unsigned int i915_enable_rc6 = 0; diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 373c2a005ec1..2166ee071ddb 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -5154,6 +5154,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); + if (!HAS_PCH_SPLIT(dev)) + intel_enable_plane(dev_priv, plane, pipe); ret = intel_pipe_set_base(crtc, x, y, old_fb); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index c20eac3379e6..9073e3bfb08c 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -1780,7 +1780,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) mc_shared_chmap = RREG32(MC_SHARED_CHMAP); - mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); + if (rdev->flags & RADEON_IS_IGP) + mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); + else + mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); switch (rdev->config.evergreen.max_tile_pipes) { case 1: diff --git a/trunk/drivers/gpu/drm/radeon/evergreend.h b/trunk/drivers/gpu/drm/radeon/evergreend.h index 94533849927e..fc40e0cc3451 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreend.h +++ b/trunk/drivers/gpu/drm/radeon/evergreend.h @@ -200,6 +200,7 @@ #define BURSTLENGTH_SHIFT 9 #define BURSTLENGTH_MASK 0x00000200 #define CHANSIZE_OVERRIDE (1 << 11) +#define FUS_MC_ARB_RAMCFG 0x2768 #define MC_VM_AGP_TOP 0x2028 #define MC_VM_AGP_BOT 0x202C #define MC_VM_AGP_BASE 0x2030 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index dd881d035f09..90dfb2b8cf03 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1574,9 +1574,17 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; bool bad_record = false; - u8 *record = (u8 *)(mode_info->atom_context->bios + - data_offset + - le16_to_cpu(lvds_info->info.usModePatchTableOffset)); + u8 *record; + + if ((frev == 1) && (crev < 2)) + /* absolute */ + record = (u8 *)(mode_info->atom_context->bios + + le16_to_cpu(lvds_info->info.usModePatchTableOffset)); + else + /* relative */ + record = (u8 *)(mode_info->atom_context->bios + + data_offset + + le16_to_cpu(lvds_info->info.usModePatchTableOffset)); while (*record != ATOM_RECORD_END_TYPE) { switch (*record) { case LCD_MODE_PATCH_RECORD_MODE_TYPE: diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/cayman b/trunk/drivers/gpu/drm/radeon/reg_srcs/cayman index 6334f8ac1209..0aa8e85a9457 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/cayman @@ -33,6 +33,7 @@ cayman 0x9400 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS 0x00009100 SPI_CONFIG_CNTL 0x0000913C SPI_CONFIG_CNTL_1 +0x00009508 TA_CNTL_AUX 0x00009830 DB_DEBUG 0x00009834 DB_DEBUG2 0x00009838 DB_DEBUG3 diff --git a/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen b/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen index 7e1637176e08..0e28cae7ea43 100644 --- a/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ b/trunk/drivers/gpu/drm/radeon/reg_srcs/evergreen @@ -46,6 +46,7 @@ evergreen 0x9400 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS 0x00009100 SPI_CONFIG_CNTL 0x0000913C SPI_CONFIG_CNTL_1 +0x00009508 TA_CNTL_AUX 0x00009700 VC_CNTL 0x00009714 VC_ENHANCE 0x00009830 DB_DEBUG diff --git a/trunk/drivers/gpu/vga/vga_switcheroo.c b/trunk/drivers/gpu/vga/vga_switcheroo.c index e01cacba685f..498b284e5ef9 100644 --- a/trunk/drivers/gpu/vga/vga_switcheroo.c +++ b/trunk/drivers/gpu/vga/vga_switcheroo.c @@ -219,9 +219,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) int i; struct vga_switcheroo_client *active = NULL; - if (new_client->active == true) - return 0; - for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { if (vgasr_priv.clients[i].active == true) { active = &vgasr_priv.clients[i]; @@ -372,6 +369,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, goto out; } + if (client->active == true) + goto out; + /* okay we want a switch - test if devices are willing to switch */ can_switch = true; for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index 75b984c519ac..107397a606b4 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -560,15 +560,18 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; +static const struct of_device_id mpc_i2c_of_match[]; static int __devinit fsl_i2c_probe(struct platform_device *op) { + const struct of_device_id *match; struct mpc_i2c *i2c; const u32 *prop; u32 clock = MPC_I2C_CLOCK_LEGACY; int result = 0; int plen; - if (!op->dev.of_match) + match = of_match_device(mpc_i2c_of_match, &op->dev); + if (!match) return -EINVAL; i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); @@ -605,8 +608,8 @@ static int __devinit fsl_i2c_probe(struct platform_device *op) clock = *prop; } - if (op->dev.of_match->data) { - struct mpc_i2c_data *data = op->dev.of_match->data; + if (match->data) { + struct mpc_i2c_data *data = match->data; data->setup(op->dev.of_node, i2c, clock, data->prescaler); } else { /* Backwards compatibility */ diff --git a/trunk/drivers/i2c/busses/i2c-pnx.c b/trunk/drivers/i2c/busses/i2c-pnx.c index a97e3fec8148..04be9f82e14b 100644 --- a/trunk/drivers/i2c/busses/i2c-pnx.c +++ b/trunk/drivers/i2c/busses/i2c-pnx.c @@ -65,7 +65,7 @@ static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) jiffies, expires); timer->expires = jiffies + expires; - timer->data = (unsigned long)&alg_data; + timer->data = (unsigned long)alg_data; add_timer(timer); } diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index c24946f51256..1de1c19dad30 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -281,17 +281,24 @@ struct ser_req { u8 command; u8 ref_off; u16 scratch; - __be16 sample; struct spi_message msg; struct spi_transfer xfer[6]; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be16 sample ____cacheline_aligned; }; struct ads7845_ser_req { u8 command[3]; - u8 pwrdown[3]; - u8 sample[3]; struct spi_message msg; struct spi_transfer xfer[2]; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 sample[3] ____cacheline_aligned; }; static int ads7846_read12_ser(struct device *dev, unsigned command) diff --git a/trunk/drivers/leds/leds-lm3530.c b/trunk/drivers/leds/leds-lm3530.c index e7089a1f6cb6..b37e6186d0fa 100644 --- a/trunk/drivers/leds/leds-lm3530.c +++ b/trunk/drivers/leds/leds-lm3530.c @@ -349,6 +349,7 @@ static const struct i2c_device_id lm3530_id[] = { {LM3530_NAME, 0}, {} }; +MODULE_DEVICE_TABLE(i2c, lm3530_id); static struct i2c_driver lm3530_i2c_driver = { .probe = lm3530_probe, diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index c820e2f53527..3f442003623d 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -524,7 +524,7 @@ void cx88_ir_irq(struct cx88_core *core) for (todo = 32; todo > 0; todo -= bits) { ev.pulse = samples & 0x80000000 ? false : true; bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); - ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate); + ev.duration = (bits * (NSEC_PER_SEC / 1000)) / ir_samplerate; ir_raw_event_store_with_filter(ir->dev, &ev); samples <<= bits; } diff --git a/trunk/drivers/media/video/soc_camera.c b/trunk/drivers/media/video/soc_camera.c index 3973f9a94753..ddb4c091dedc 100644 --- a/trunk/drivers/media/video/soc_camera.c +++ b/trunk/drivers/media/video/soc_camera.c @@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, } EXPORT_SYMBOL(soc_camera_apply_sensor_flags); +#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ + ((x) >> 24) & 0xff + +static int soc_camera_try_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct v4l2_pix_format *pix = &f->fmt.pix; + int ret; + + dev_dbg(&icd->dev, "TRY_FMT(%c%c%c%c, %ux%u)\n", + pixfmtstr(pix->pixelformat), pix->width, pix->height); + + pix->bytesperline = 0; + pix->sizeimage = 0; + + ret = ici->ops->try_fmt(icd, f); + if (ret < 0) + return ret; + + if (!pix->sizeimage) { + if (!pix->bytesperline) { + const struct soc_camera_format_xlate *xlate; + + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); + if (!xlate) + return -EINVAL; + + ret = soc_mbus_bytes_per_line(pix->width, + xlate->host_fmt); + if (ret > 0) + pix->bytesperline = ret; + } + if (pix->bytesperline) + pix->sizeimage = pix->bytesperline * pix->height; + } + + return 0; +} + static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct soc_camera_device *icd = file->private_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); WARN_ON(priv != file->private_data); @@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; /* limit format to hardware capabilities */ - return ici->ops->try_fmt(icd, f); + return soc_camera_try_fmt(icd, f); } static int soc_camera_enum_input(struct file *file, void *priv, @@ -362,9 +401,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) icd->user_formats = NULL; } -#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ - ((x) >> 24) & 0xff - /* Called with .vb_lock held, or from the first open(2), see comment there */ static int soc_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) @@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd, pixfmtstr(pix->pixelformat), pix->width, pix->height); /* We always call try_fmt() before set_fmt() or set_crop() */ - ret = ici->ops->try_fmt(icd, f); + ret = soc_camera_try_fmt(icd, f); if (ret < 0) return ret; diff --git a/trunk/drivers/media/video/v4l2-device.c b/trunk/drivers/media/video/v4l2-device.c index 5aeaf876ba9b..4aae501f02d0 100644 --- a/trunk/drivers/media/video/v4l2-device.c +++ b/trunk/drivers/media/video/v4l2-device.c @@ -155,8 +155,10 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, sd->v4l2_dev = v4l2_dev; if (sd->internal_ops && sd->internal_ops->registered) { err = sd->internal_ops->registered(sd); - if (err) + if (err) { + module_put(sd->owner); return err; + } } /* This just returns 0 if either of the two args is NULL */ @@ -164,6 +166,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, if (err) { if (sd->internal_ops && sd->internal_ops->unregistered) sd->internal_ops->unregistered(sd); + module_put(sd->owner); return err; } diff --git a/trunk/drivers/media/video/v4l2-subdev.c b/trunk/drivers/media/video/v4l2-subdev.c index 0b8064490676..812729ebf09e 100644 --- a/trunk/drivers/media/video/v4l2-subdev.c +++ b/trunk/drivers/media/video/v4l2-subdev.c @@ -155,25 +155,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) switch (cmd) { case VIDIOC_QUERYCTRL: - return v4l2_subdev_queryctrl(sd, arg); + return v4l2_queryctrl(sd->ctrl_handler, arg); case VIDIOC_QUERYMENU: - return v4l2_subdev_querymenu(sd, arg); + return v4l2_querymenu(sd->ctrl_handler, arg); case VIDIOC_G_CTRL: - return v4l2_subdev_g_ctrl(sd, arg); + return v4l2_g_ctrl(sd->ctrl_handler, arg); case VIDIOC_S_CTRL: - return v4l2_subdev_s_ctrl(sd, arg); + return v4l2_s_ctrl(sd->ctrl_handler, arg); case VIDIOC_G_EXT_CTRLS: - return v4l2_subdev_g_ext_ctrls(sd, arg); + return v4l2_g_ext_ctrls(sd->ctrl_handler, arg); case VIDIOC_S_EXT_CTRLS: - return v4l2_subdev_s_ext_ctrls(sd, arg); + return v4l2_s_ext_ctrls(sd->ctrl_handler, arg); case VIDIOC_TRY_EXT_CTRLS: - return v4l2_subdev_try_ext_ctrls(sd, arg); + return v4l2_try_ext_ctrls(sd->ctrl_handler, arg); case VIDIOC_DQEVENT: if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) diff --git a/trunk/drivers/message/i2o/i2o_block.c b/trunk/drivers/message/i2o/i2o_block.c index 643ad52e3ca2..4796bbf0ae4e 100644 --- a/trunk/drivers/message/i2o/i2o_block.c +++ b/trunk/drivers/message/i2o/i2o_block.c @@ -1000,7 +1000,6 @@ static struct i2o_block_device *i2o_block_device_alloc(void) gd->major = I2O_MAJOR; gd->queue = queue; gd->fops = &i2o_block_fops; - gd->events = DISK_EVENT_MEDIA_CHANGE; gd->private_data = dev; dev->gd = gd; diff --git a/trunk/drivers/mmc/core/host.c b/trunk/drivers/mmc/core/host.c index 2b200c1cfbba..461e6a17fb90 100644 --- a/trunk/drivers/mmc/core/host.c +++ b/trunk/drivers/mmc/core/host.c @@ -94,7 +94,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) spin_unlock_irqrestore(&host->clk_lock, flags); return; } - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (!host->clk_requests) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -104,7 +104,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); } spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /* @@ -130,7 +130,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) { unsigned long flags; - mmc_claim_host(host); + mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (host->clk_gated) { spin_unlock_irqrestore(&host->clk_lock, flags); @@ -140,7 +140,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) } host->clk_requests++; spin_unlock_irqrestore(&host->clk_lock, flags); - mmc_release_host(host); + mutex_unlock(&host->clk_gate_mutex); } /** @@ -215,6 +215,7 @@ static inline void mmc_host_clk_init(struct mmc_host *host) host->clk_gated = false; INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); spin_lock_init(&host->clk_lock); + mutex_init(&host->clk_gate_mutex); } /** diff --git a/trunk/drivers/mmc/host/sdhci-of-core.c b/trunk/drivers/mmc/host/sdhci-of-core.c index f9b611fc773e..60e4186a4345 100644 --- a/trunk/drivers/mmc/host/sdhci-of-core.c +++ b/trunk/drivers/mmc/host/sdhci-of-core.c @@ -124,8 +124,10 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) #endif } +static const struct of_device_id sdhci_of_match[]; static int __devinit sdhci_of_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct sdhci_of_data *sdhci_of_data; struct sdhci_host *host; @@ -134,9 +136,10 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) int size; int ret; - if (!ofdev->dev.of_match) + match = of_match_device(sdhci_of_match, &ofdev->dev); + if (!match) return -EINVAL; - sdhci_of_data = ofdev->dev.of_match->data; + sdhci_of_data = match->data; if (!of_device_is_available(np)) return -ENODEV; diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index bd483f0c57e1..c1d33464aee8 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -214,11 +214,13 @@ static void __devinit of_free_probes(const char **probes) } #endif +static struct of_device_id of_flash_match[]; static int __devinit of_flash_probe(struct platform_device *dev) { #ifdef CONFIG_MTD_PARTITIONS const char **part_probe_types; #endif + const struct of_device_id *match; struct device_node *dp = dev->dev.of_node; struct resource res; struct of_flash *info; @@ -232,9 +234,10 @@ static int __devinit of_flash_probe(struct platform_device *dev) struct mtd_info **mtd_list = NULL; resource_size_t res_size; - if (!dev->dev.of_match) + match = of_match_device(of_flash_match, &dev->dev); + if (!match) return -EINVAL; - probe_type = dev->dev.of_match->data; + probe_type = match->data; reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index 01b604ad155e..e5a7375685ad 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -144,7 +144,7 @@ obj-$(CONFIG_NE3210) += ne3210.o 8390.o obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o obj-$(CONFIG_B44) += b44.o obj-$(CONFIG_FORCEDETH) += forcedeth.o -obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o +obj-$(CONFIG_NE_H8300) += ne-h8300.o obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o obj-$(CONFIG_FTMAC100) += ftmac100.o @@ -219,7 +219,7 @@ obj-$(CONFIG_SC92031) += sc92031.o obj-$(CONFIG_LP486E) += lp486e.o obj-$(CONFIG_ETH16I) += eth16i.o -obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o +obj-$(CONFIG_ZORRO8390) += zorro8390.o obj-$(CONFIG_HPLANCE) += hplance.o 7990.o obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o obj-$(CONFIG_EQUALIZER) += eql.o @@ -231,7 +231,7 @@ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o obj-$(CONFIG_DECLANCE) += declance.o obj-$(CONFIG_ATARILANCE) += atarilance.o obj-$(CONFIG_A2065) += a2065.o -obj-$(CONFIG_HYDRA) += hydra.o 8390.o +obj-$(CONFIG_HYDRA) += hydra.o obj-$(CONFIG_ARIADNE) += ariadne.o obj-$(CONFIG_CS89x0) += cs89x0.o obj-$(CONFIG_MACSONIC) += macsonic.o diff --git a/trunk/drivers/net/bonding/bond_3ad.h b/trunk/drivers/net/bonding/bond_3ad.h index b28baff70864..01b8a6af275b 100644 --- a/trunk/drivers/net/bonding/bond_3ad.h +++ b/trunk/drivers/net/bonding/bond_3ad.h @@ -39,7 +39,7 @@ typedef struct mac_addr { u8 mac_addr_value[ETH_ALEN]; -} mac_addr_t; +} __packed mac_addr_t; enum { BOND_AD_STABLE = 0, @@ -134,12 +134,12 @@ typedef struct lacpdu { u8 tlv_type_terminator; // = terminator u8 terminator_length; // = 0 u8 reserved_50[50]; // = 0 -} lacpdu_t; +} __packed lacpdu_t; typedef struct lacpdu_header { struct ethhdr hdr; struct lacpdu lacpdu; -} lacpdu_header_t; +} __packed lacpdu_header_t; // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) typedef struct bond_marker { @@ -155,12 +155,12 @@ typedef struct bond_marker { u8 tlv_type_terminator; // = 0x00 u8 terminator_length; // = 0x00 u8 reserved_90[90]; // = 0 -} bond_marker_t; +} __packed bond_marker_t; typedef struct bond_marker_header { struct ethhdr hdr; struct bond_marker marker; -} bond_marker_header_t; +} __packed bond_marker_header_t; #pragma pack() diff --git a/trunk/drivers/net/can/mscan/mpc5xxx_can.c b/trunk/drivers/net/can/mscan/mpc5xxx_can.c index bd1d811c204f..5fedc3375562 100644 --- a/trunk/drivers/net/can/mscan/mpc5xxx_can.c +++ b/trunk/drivers/net/can/mscan/mpc5xxx_can.c @@ -247,8 +247,10 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, } #endif /* CONFIG_PPC_MPC512x */ +static struct of_device_id mpc5xxx_can_table[]; static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct mpc5xxx_can_data *data; struct device_node *np = ofdev->dev.of_node; struct net_device *dev; @@ -258,9 +260,10 @@ static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) int irq, mscan_clksrc = 0; int err = -ENOMEM; - if (!ofdev->dev.of_match) + match = of_match_device(mpc5xxx_can_table, &ofdev->dev); + if (!match) return -EINVAL; - data = (struct mpc5xxx_can_data *)ofdev->dev.of_match->data; + data = match->data; base = of_iomap(np, 0); if (!base) { diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 53c0f04b1b23..cf79cf759e13 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -2688,9 +2688,6 @@ static int ehea_open(struct net_device *dev) netif_start_queue(dev); } - init_waitqueue_head(&port->swqe_avail_wq); - init_waitqueue_head(&port->restart_wq); - mutex_unlock(&port->port_lock); return ret; @@ -3276,6 +3273,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, INIT_WORK(&port->reset_task, ehea_reset_port); + init_waitqueue_head(&port->swqe_avail_wq); + init_waitqueue_head(&port->restart_wq); + ret = register_netdev(dev); if (ret) { pr_err("register_netdev failed. ret=%d\n", ret); diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index 24cb953900dd..5131e61c358c 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -998,8 +998,10 @@ static const struct net_device_ops fs_enet_netdev_ops = { #endif }; +static struct of_device_id fs_enet_match[]; static int __devinit fs_enet_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; @@ -1007,14 +1009,15 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) const u8 *mac_addr; int privsize, len, ret = -ENODEV; - if (!ofdev->dev.of_match) + match = of_match_device(fs_enet_match, &ofdev->dev); + if (!match) return -EINVAL; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; - if (!IS_FEC(ofdev->dev.of_match)) { + if (!IS_FEC(match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; @@ -1049,7 +1052,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; - fep->ops = ofdev->dev.of_match->data; + fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) diff --git a/trunk/drivers/net/fs_enet/mii-fec.c b/trunk/drivers/net/fs_enet/mii-fec.c index 7e840d373ab3..6a2e150e75bb 100644 --- a/trunk/drivers/net/fs_enet/mii-fec.c +++ b/trunk/drivers/net/fs_enet/mii-fec.c @@ -101,17 +101,20 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) return 0; } +static struct of_device_id fs_enet_mdio_fec_match[]; static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct resource res; struct mii_bus *new_bus; struct fec_info *fec; int (*get_bus_freq)(struct device_node *); int ret = -ENOMEM, clock, speed; - if (!ofdev->dev.of_match) + match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); + if (!match) return -EINVAL; - get_bus_freq = ofdev->dev.of_match->data; + get_bus_freq = match->data; new_bus = mdiobus_alloc(); if (!new_bus) diff --git a/trunk/drivers/net/hydra.c b/trunk/drivers/net/hydra.c index c5ef62ceb840..1cd481c04202 100644 --- a/trunk/drivers/net/hydra.c +++ b/trunk/drivers/net/hydra.c @@ -98,15 +98,15 @@ static const struct net_device_ops hydra_netdev_ops = { .ndo_open = hydra_open, .ndo_stop = hydra_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_start_xmit = __ei_start_xmit, + .ndo_tx_timeout = __ei_tx_timeout, + .ndo_get_stats = __ei_get_stats, + .ndo_set_multicast_list = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, + .ndo_poll_controller = __ei_poll, #endif }; @@ -125,7 +125,7 @@ static int __devinit hydra_init(struct zorro_dev *z) 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, }; - dev = alloc_ei_netdev(); + dev = ____alloc_ei_netdev(0); if (!dev) return -ENOMEM; diff --git a/trunk/drivers/net/ne-h8300.c b/trunk/drivers/net/ne-h8300.c index 30be8c634ebd..7298a34bc795 100644 --- a/trunk/drivers/net/ne-h8300.c +++ b/trunk/drivers/net/ne-h8300.c @@ -167,7 +167,7 @@ static void cleanup_card(struct net_device *dev) #ifndef MODULE struct net_device * __init ne_probe(int unit) { - struct net_device *dev = alloc_ei_netdev(); + struct net_device *dev = ____alloc_ei_netdev(0); int err; if (!dev) @@ -197,15 +197,15 @@ static const struct net_device_ops ne_netdev_ops = { .ndo_open = ne_open, .ndo_stop = ne_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_start_xmit = __ei_start_xmit, + .ndo_tx_timeout = __ei_tx_timeout, + .ndo_get_stats = __ei_get_stats, + .ndo_set_multicast_list = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, + .ndo_poll_controller = __ei_poll, #endif }; @@ -637,7 +637,7 @@ int init_module(void) int err; for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = alloc_ei_netdev(); + struct net_device *dev = ____alloc_ei_netdev(0); if (!dev) break; if (io[this_dev]) { diff --git a/trunk/drivers/net/sfc/mcdi.c b/trunk/drivers/net/sfc/mcdi.c index d98479030ef2..3dd45ed61f0a 100644 --- a/trunk/drivers/net/sfc/mcdi.c +++ b/trunk/drivers/net/sfc/mcdi.c @@ -50,6 +50,20 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) return &nic_data->mcdi; } +static inline void +efx_mcdi_readd(struct efx_nic *efx, efx_dword_t *value, unsigned reg) +{ + struct siena_nic_data *nic_data = efx->nic_data; + value->u32[0] = (__force __le32)__raw_readl(nic_data->mcdi_smem + reg); +} + +static inline void +efx_mcdi_writed(struct efx_nic *efx, const efx_dword_t *value, unsigned reg) +{ + struct siena_nic_data *nic_data = efx->nic_data; + __raw_writel((__force u32)value->u32[0], nic_data->mcdi_smem + reg); +} + void efx_mcdi_init(struct efx_nic *efx) { struct efx_mcdi_iface *mcdi; @@ -70,8 +84,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, const u8 *inbuf, size_t inlen) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); - unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); - unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx); + unsigned pdu = MCDI_PDU(efx); + unsigned doorbell = MCDI_DOORBELL(efx); unsigned int i; efx_dword_t hdr; u32 xflags, seqno; @@ -92,30 +106,28 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, MCDI_HEADER_SEQ, seqno, MCDI_HEADER_XFLAGS, xflags); - efx_writed(efx, &hdr, pdu); + efx_mcdi_writed(efx, &hdr, pdu); - for (i = 0; i < inlen; i += 4) { - _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); - /* use wmb() within loop to inhibit write combining */ - wmb(); - } + for (i = 0; i < inlen; i += 4) + efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i), + pdu + 4 + i); /* ring the doorbell with a distinctive value */ - _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); - wmb(); + EFX_POPULATE_DWORD_1(hdr, EFX_DWORD_0, 0x45789abc); + efx_mcdi_writed(efx, &hdr, doorbell); } static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); - unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); + unsigned int pdu = MCDI_PDU(efx); int i; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); BUG_ON(outlen & 3 || outlen >= 0x100); for (i = 0; i < outlen; i += 4) - *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); + efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i); } static int efx_mcdi_poll(struct efx_nic *efx) @@ -123,7 +135,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) struct efx_mcdi_iface *mcdi = efx_mcdi(efx); unsigned int time, finish; unsigned int respseq, respcmd, error; - unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); + unsigned int pdu = MCDI_PDU(efx); unsigned int rc, spins; efx_dword_t reg; @@ -149,8 +161,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) time = get_seconds(); - rmb(); - efx_readd(efx, ®, pdu); + efx_mcdi_readd(efx, ®, pdu); /* All 1's indicates that shared memory is in reset (and is * not a valid header). Wait for it to come out reset before @@ -177,7 +188,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) respseq, mcdi->seqno); rc = EIO; } else if (error) { - efx_readd(efx, ®, pdu + 4); + efx_mcdi_readd(efx, ®, pdu + 4); switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) { #define TRANSLATE_ERROR(name) \ case MC_CMD_ERR_ ## name: \ @@ -211,21 +222,21 @@ static int efx_mcdi_poll(struct efx_nic *efx) /* Test and clear MC-rebooted flag for this port/function */ int efx_mcdi_poll_reboot(struct efx_nic *efx) { - unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); + unsigned int addr = MCDI_REBOOT_FLAG(efx); efx_dword_t reg; uint32_t value; if (efx_nic_rev(efx) < EFX_REV_SIENA_A0) return false; - efx_readd(efx, ®, addr); + efx_mcdi_readd(efx, ®, addr); value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); if (value == 0) return 0; EFX_ZERO_DWORD(reg); - efx_writed(efx, ®, addr); + efx_mcdi_writed(efx, ®, addr); if (value == MC_STATUS_DWORD_ASSERT) return -EINTR; diff --git a/trunk/drivers/net/sfc/nic.c b/trunk/drivers/net/sfc/nic.c index 10f1cb79c147..9b29a8d7c449 100644 --- a/trunk/drivers/net/sfc/nic.c +++ b/trunk/drivers/net/sfc/nic.c @@ -1937,6 +1937,13 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf) size = min_t(size_t, table->step, 16); + if (table->offset >= efx->type->mem_map_size) { + /* No longer mapped; return dummy data */ + memcpy(buf, "\xde\xc0\xad\xde", 4); + buf += table->rows * size; + continue; + } + for (i = 0; i < table->rows; i++) { switch (table->step) { case 4: /* 32-bit register or SRAM */ diff --git a/trunk/drivers/net/sfc/nic.h b/trunk/drivers/net/sfc/nic.h index a42db6e35be3..d91701abd331 100644 --- a/trunk/drivers/net/sfc/nic.h +++ b/trunk/drivers/net/sfc/nic.h @@ -143,10 +143,12 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) /** * struct siena_nic_data - Siena NIC state * @mcdi: Management-Controller-to-Driver Interface + * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable. * @wol_filter_id: Wake-on-LAN packet filter id */ struct siena_nic_data { struct efx_mcdi_iface mcdi; + void __iomem *mcdi_smem; int wol_filter_id; }; diff --git a/trunk/drivers/net/sfc/siena.c b/trunk/drivers/net/sfc/siena.c index e4dd8986b1fe..837869b71db9 100644 --- a/trunk/drivers/net/sfc/siena.c +++ b/trunk/drivers/net/sfc/siena.c @@ -220,12 +220,26 @@ static int siena_probe_nic(struct efx_nic *efx) efx_reado(efx, ®, FR_AZ_CS_DEBUG); efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; + /* Initialise MCDI */ + nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys + + FR_CZ_MC_TREG_SMEM, + FR_CZ_MC_TREG_SMEM_STEP * + FR_CZ_MC_TREG_SMEM_ROWS); + if (!nic_data->mcdi_smem) { + netif_err(efx, probe, efx->net_dev, + "could not map MCDI at %llx+%x\n", + (unsigned long long)efx->membase_phys + + FR_CZ_MC_TREG_SMEM, + FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); + rc = -ENOMEM; + goto fail1; + } efx_mcdi_init(efx); /* Recover from a failed assertion before probing */ rc = efx_mcdi_handle_assertion(efx); if (rc) - goto fail1; + goto fail2; /* Let the BMC know that the driver is now in charge of link and * filter settings. We must do this before we reset the NIC */ @@ -280,6 +294,7 @@ static int siena_probe_nic(struct efx_nic *efx) fail3: efx_mcdi_drv_attach(efx, false, NULL); fail2: + iounmap(nic_data->mcdi_smem); fail1: kfree(efx->nic_data); return rc; @@ -359,6 +374,8 @@ static int siena_init_nic(struct efx_nic *efx) static void siena_remove_nic(struct efx_nic *efx) { + struct siena_nic_data *nic_data = efx->nic_data; + efx_nic_free_buffer(efx, &efx->irq_status); siena_reset_hw(efx, RESET_TYPE_ALL); @@ -368,7 +385,8 @@ static void siena_remove_nic(struct efx_nic *efx) efx_mcdi_drv_attach(efx, false, NULL); /* Tear down the private nic state */ - kfree(efx->nic_data); + iounmap(nic_data->mcdi_smem); + kfree(nic_data); efx->nic_data = NULL; } @@ -606,8 +624,7 @@ struct efx_nic_type siena_a0_nic_type = { .default_mac_ops = &efx_mcdi_mac_operations, .revision = EFX_REV_SIENA_A0, - .mem_map_size = (FR_CZ_MC_TREG_SMEM + - FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS), + .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */ .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, .buf_tbl_base = FR_BZ_BUF_FULL_TBL, diff --git a/trunk/drivers/net/sunhme.c b/trunk/drivers/net/sunhme.c index eb4f59fb01e9..bff2f7999ff0 100644 --- a/trunk/drivers/net/sunhme.c +++ b/trunk/drivers/net/sunhme.c @@ -3237,15 +3237,18 @@ static void happy_meal_pci_exit(void) #endif #ifdef CONFIG_SBUS +static const struct of_device_id hme_sbus_match[]; static int __devinit hme_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; struct device_node *dp = op->dev.of_node; const char *model = of_get_property(dp, "model", NULL); int is_qfe; - if (!op->dev.of_match) + match = of_match_device(hme_sbus_match, &op->dev); + if (!match) return -EINVAL; - is_qfe = (op->dev.of_match->data != NULL); + is_qfe = (match->data != NULL); if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) is_qfe = 1; diff --git a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c index 51f2ef142a5b..976467253d20 100644 --- a/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/trunk/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -311,6 +311,9 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data) /* toggle the LRO feature*/ netdev->features ^= NETIF_F_LRO; + /* Update private LRO flag */ + adapter->lro = lro_requested; + /* update harware LRO capability accordingly */ if (lro_requested) adapter->shared->devRead.misc.uptFeatures |= diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 17d04ff8d678..1482fa650833 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -2141,6 +2141,8 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) static void ath9k_flush(struct ieee80211_hw *hw, bool drop) { struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); int timeout = 200; /* ms */ int i, j; @@ -2149,6 +2151,12 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) cancel_delayed_work_sync(&sc->tx_complete_work); + if (sc->sc_flags & SC_OP_INVALID) { + ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); + mutex_unlock(&sc->mutex); + return; + } + if (drop) timeout = 1; diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c index c1511b14b239..42db0fc8b921 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-core.c @@ -2155,6 +2155,13 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) goto set_ch_out; } + if (priv->iw_mode == NL80211_IFTYPE_ADHOC && + !iwl_legacy_is_channel_ibss(ch_info)) { + IWL_DEBUG_MAC80211(priv, "leave - not IBSS channel\n"); + ret = -EINVAL; + goto set_ch_out; + } + spin_lock_irqsave(&priv->lock, flags); for_each_context(priv, ctx) { diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h b/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h index 9ee849d669f3..f43ac1eb9014 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-dev.h @@ -1411,6 +1411,12 @@ iwl_legacy_is_channel_passive(const struct iwl_channel_info *ch) return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; } +static inline int +iwl_legacy_is_channel_ibss(const struct iwl_channel_info *ch) +{ + return (ch->flags & EEPROM_CHANNEL_IBSS) ? 1 : 0; +} + static inline void __iwl_legacy_free_pages(struct iwl_priv *priv, struct page *page) { diff --git a/trunk/drivers/net/wireless/libertas/cmd.c b/trunk/drivers/net/wireless/libertas/cmd.c index 7e8a658b7670..f3ac62431a30 100644 --- a/trunk/drivers/net/wireless/libertas/cmd.c +++ b/trunk/drivers/net/wireless/libertas/cmd.c @@ -1339,8 +1339,8 @@ int lbs_execute_next_command(struct lbs_private *priv) cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); - list_del(&cmdnode->list); spin_lock_irqsave(&priv->driver_lock, flags); + list_del(&cmdnode->list); lbs_complete_command(priv, cmdnode, 0); spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -1352,8 +1352,8 @@ int lbs_execute_next_command(struct lbs_private *priv) (priv->psstate == PS_STATE_PRE_SLEEP)) { lbs_deb_host( "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); - list_del(&cmdnode->list); spin_lock_irqsave(&priv->driver_lock, flags); + list_del(&cmdnode->list); lbs_complete_command(priv, cmdnode, 0); spin_unlock_irqrestore(&priv->driver_lock, flags); priv->needtowakeup = 1; @@ -1366,7 +1366,9 @@ int lbs_execute_next_command(struct lbs_private *priv) "EXEC_NEXT_CMD: sending EXIT_PS\n"); } } + spin_lock_irqsave(&priv->driver_lock, flags); list_del(&cmdnode->list); + spin_unlock_irqrestore(&priv->driver_lock, flags); lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", le16_to_cpu(cmd->command)); lbs_submit_command(priv, cmdnode); diff --git a/trunk/drivers/net/zorro8390.c b/trunk/drivers/net/zorro8390.c index b78a38d9172a..8c7c522a056a 100644 --- a/trunk/drivers/net/zorro8390.c +++ b/trunk/drivers/net/zorro8390.c @@ -126,7 +126,7 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z, board = z->resource.start; ioaddr = board+cards[i].offset; - dev = alloc_ei_netdev(); + dev = ____alloc_ei_netdev(0); if (!dev) return -ENOMEM; if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) { @@ -146,15 +146,15 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z, static const struct net_device_ops zorro8390_netdev_ops = { .ndo_open = zorro8390_open, .ndo_stop = zorro8390_close, - .ndo_start_xmit = ei_start_xmit, - .ndo_tx_timeout = ei_tx_timeout, - .ndo_get_stats = ei_get_stats, - .ndo_set_multicast_list = ei_set_multicast_list, + .ndo_start_xmit = __ei_start_xmit, + .ndo_tx_timeout = __ei_tx_timeout, + .ndo_get_stats = __ei_get_stats, + .ndo_set_multicast_list = __ei_set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = ei_poll, + .ndo_poll_controller = __ei_poll, #endif }; diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index ebf51ad1b714..a806cb321d2e 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -579,7 +579,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), 4096); - size1 = !add_size? size0: + size1 = (!add_head || (add_head && !add_size)) ? size0 : calculate_iosize(size, min_size+add_size, size1, resource_size(b_res), 4096); if (!size0 && !size1) { @@ -677,7 +677,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, align += aligns[order]; } size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); - size1 = !add_size ? size : + size1 = (!add_head || (add_head && !add_size)) ? size0 : calculate_memsize(size, min_size+add_size, 0, resource_size(b_res), min_align); if (!size0 && !size1) { diff --git a/trunk/drivers/rapidio/switches/idt_gen2.c b/trunk/drivers/rapidio/switches/idt_gen2.c index ac2701b22e71..043ee3136e40 100644 --- a/trunk/drivers/rapidio/switches/idt_gen2.c +++ b/trunk/drivers/rapidio/switches/idt_gen2.c @@ -95,6 +95,9 @@ idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, else table++; + if (route_port == RIO_INVALID_ROUTE) + route_port = IDT_DEFAULT_ROUTE; + rio_mport_write_config_32(mport, destid, hopcount, LOCAL_RTE_CONF_DESTID_SEL, table); @@ -411,6 +414,12 @@ static int idtg2_switch_init(struct rio_dev *rdev, int do_enum) rdev->rswitch->em_handle = idtg2_em_handler; rdev->rswitch->sw_sysfs = idtg2_sysfs; + if (do_enum) { + /* Ensure that default routing is disabled on startup */ + rio_write_config_32(rdev, + RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE); + } + return 0; } diff --git a/trunk/drivers/rapidio/switches/idtcps.c b/trunk/drivers/rapidio/switches/idtcps.c index 3a971077e7bf..d06ee2d44b44 100644 --- a/trunk/drivers/rapidio/switches/idtcps.c +++ b/trunk/drivers/rapidio/switches/idtcps.c @@ -26,6 +26,9 @@ idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, { u32 result; + if (route_port == RIO_INVALID_ROUTE) + route_port = CPS_DEFAULT_ROUTE; + if (table == RIO_GLOBAL_TABLE) { rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); @@ -130,6 +133,9 @@ static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) /* set TVAL = ~50us */ rio_write_config_32(rdev, rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); + /* Ensure that default routing is disabled on startup */ + rio_write_config_32(rdev, + RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE); } return 0; diff --git a/trunk/drivers/rapidio/switches/tsi57x.c b/trunk/drivers/rapidio/switches/tsi57x.c index 1a62934bfebc..db8b8028988d 100644 --- a/trunk/drivers/rapidio/switches/tsi57x.c +++ b/trunk/drivers/rapidio/switches/tsi57x.c @@ -303,6 +303,12 @@ static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum) rdev->rswitch->em_init = tsi57x_em_init; rdev->rswitch->em_handle = tsi57x_em_handler; + if (do_enum) { + /* Ensure that default routing is disabled on startup */ + rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT, + RIO_INVALID_ROUTE); + } + return 0; } diff --git a/trunk/drivers/rtc/rtc-davinci.c b/trunk/drivers/rtc/rtc-davinci.c index 8d46838dff8a..755e1fe914af 100644 --- a/trunk/drivers/rtc/rtc-davinci.c +++ b/trunk/drivers/rtc/rtc-davinci.c @@ -524,6 +524,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) goto fail2; } + platform_set_drvdata(pdev, davinci_rtc); + davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &davinci_rtc_ops, THIS_MODULE); if (IS_ERR(davinci_rtc->rtc)) { @@ -553,8 +555,6 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); - platform_set_drvdata(pdev, davinci_rtc); - device_init_wakeup(&pdev->dev, 0); return 0; @@ -562,6 +562,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) fail4: rtc_device_unregister(davinci_rtc->rtc); fail3: + platform_set_drvdata(pdev, NULL); iounmap(davinci_rtc->base); fail2: release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); diff --git a/trunk/drivers/rtc/rtc-ds1286.c b/trunk/drivers/rtc/rtc-ds1286.c index 60ce69600828..47e681df31e2 100644 --- a/trunk/drivers/rtc/rtc-ds1286.c +++ b/trunk/drivers/rtc/rtc-ds1286.c @@ -355,6 +355,7 @@ static int __devinit ds1286_probe(struct platform_device *pdev) goto out; } spin_lock_init(&priv->lock); + platform_set_drvdata(pdev, priv); rtc = rtc_device_register("ds1286", &pdev->dev, &ds1286_ops, THIS_MODULE); if (IS_ERR(rtc)) { @@ -362,7 +363,6 @@ static int __devinit ds1286_probe(struct platform_device *pdev) goto out; } priv->rtc = rtc; - platform_set_drvdata(pdev, priv); return 0; out: diff --git a/trunk/drivers/rtc/rtc-ep93xx.c b/trunk/drivers/rtc/rtc-ep93xx.c index 11ae64dcbf3c..335551d333b2 100644 --- a/trunk/drivers/rtc/rtc-ep93xx.c +++ b/trunk/drivers/rtc/rtc-ep93xx.c @@ -151,6 +151,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return -ENXIO; pdev->dev.platform_data = ep93xx_rtc; + platform_set_drvdata(pdev, rtc); rtc = rtc_device_register(pdev->name, &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); @@ -159,8 +160,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) goto exit; } - platform_set_drvdata(pdev, rtc); - err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); if (err) goto fail; @@ -168,9 +167,9 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) return 0; fail: - platform_set_drvdata(pdev, NULL); rtc_device_unregister(rtc); exit: + platform_set_drvdata(pdev, NULL); pdev->dev.platform_data = NULL; return err; } diff --git a/trunk/drivers/rtc/rtc-m41t80.c b/trunk/drivers/rtc/rtc-m41t80.c index 69fe664a2228..eda128fc1d38 100644 --- a/trunk/drivers/rtc/rtc-m41t80.c +++ b/trunk/drivers/rtc/rtc-m41t80.c @@ -783,6 +783,9 @@ static int m41t80_probe(struct i2c_client *client, goto exit; } + clientdata->features = id->driver_data; + i2c_set_clientdata(client, clientdata); + rtc = rtc_device_register(client->name, &client->dev, &m41t80_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { @@ -792,8 +795,6 @@ static int m41t80_probe(struct i2c_client *client, } clientdata->rtc = rtc; - clientdata->features = id->driver_data; - i2c_set_clientdata(client, clientdata); /* Make sure HT (Halt Update) bit is cleared */ rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); diff --git a/trunk/drivers/rtc/rtc-max8925.c b/trunk/drivers/rtc/rtc-max8925.c index 20494b5edc3c..3bc046f427e0 100644 --- a/trunk/drivers/rtc/rtc-max8925.c +++ b/trunk/drivers/rtc/rtc-max8925.c @@ -258,6 +258,8 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) } dev_set_drvdata(&pdev->dev, info); + /* XXX - isn't this redundant? */ + platform_set_drvdata(pdev, info); info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, &max8925_rtc_ops, THIS_MODULE); @@ -267,10 +269,9 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) goto out_rtc; } - platform_set_drvdata(pdev, info); - return 0; out_rtc: + platform_set_drvdata(pdev, NULL); free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); out_irq: kfree(info); diff --git a/trunk/drivers/rtc/rtc-max8998.c b/trunk/drivers/rtc/rtc-max8998.c index 3f7bc6b9fefa..2e48aa604273 100644 --- a/trunk/drivers/rtc/rtc-max8998.c +++ b/trunk/drivers/rtc/rtc-max8998.c @@ -265,6 +265,8 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) info->rtc = max8998->rtc; info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0; + platform_set_drvdata(pdev, info); + info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev, &max8998_rtc_ops, THIS_MODULE); @@ -274,8 +276,6 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) goto out_rtc; } - platform_set_drvdata(pdev, info); - ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, "rtc-alarm0", info); @@ -293,6 +293,7 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) return 0; out_rtc: + platform_set_drvdata(pdev, NULL); kfree(info); return ret; } diff --git a/trunk/drivers/rtc/rtc-mc13xxx.c b/trunk/drivers/rtc/rtc-mc13xxx.c index c5ac03793e79..a1a278bc340d 100644 --- a/trunk/drivers/rtc/rtc-mc13xxx.c +++ b/trunk/drivers/rtc/rtc-mc13xxx.c @@ -349,11 +349,15 @@ static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) if (ret) goto err_alarm_irq_request; + mc13xxx_unlock(mc13xxx); + priv->rtc = rtc_device_register(pdev->name, &pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE); if (IS_ERR(priv->rtc)) { ret = PTR_ERR(priv->rtc); + mc13xxx_lock(mc13xxx); + mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); err_alarm_irq_request: @@ -365,12 +369,12 @@ static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); err_reset_irq_request: + mc13xxx_unlock(mc13xxx); + platform_set_drvdata(pdev, NULL); kfree(priv); } - mc13xxx_unlock(mc13xxx); - return ret; } diff --git a/trunk/drivers/rtc/rtc-msm6242.c b/trunk/drivers/rtc/rtc-msm6242.c index 67820626e18f..fcb113c11122 100644 --- a/trunk/drivers/rtc/rtc-msm6242.c +++ b/trunk/drivers/rtc/rtc-msm6242.c @@ -214,6 +214,7 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) error = -ENOMEM; goto out_free_priv; } + platform_set_drvdata(dev, priv); rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops, THIS_MODULE); @@ -223,10 +224,10 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) } priv->rtc = rtc; - platform_set_drvdata(dev, priv); return 0; out_unmap: + platform_set_drvdata(dev, NULL); iounmap(priv->regs); out_free_priv: kfree(priv); diff --git a/trunk/drivers/rtc/rtc-mxc.c b/trunk/drivers/rtc/rtc-mxc.c index 826ab64a8fa9..d814417bee8c 100644 --- a/trunk/drivers/rtc/rtc-mxc.c +++ b/trunk/drivers/rtc/rtc-mxc.c @@ -418,14 +418,6 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) goto exit_put_clk; } - rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto exit_put_clk; - } - - pdata->rtc = rtc; platform_set_drvdata(pdev, pdata); /* Configure and enable the RTC */ @@ -438,8 +430,19 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) pdata->irq = -1; } + rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, + THIS_MODULE); + if (IS_ERR(rtc)) { + ret = PTR_ERR(rtc); + goto exit_clr_drvdata; + } + + pdata->rtc = rtc; + return 0; +exit_clr_drvdata: + platform_set_drvdata(pdev, NULL); exit_put_clk: clk_disable(pdata->clk); clk_put(pdata->clk); diff --git a/trunk/drivers/rtc/rtc-pcap.c b/trunk/drivers/rtc/rtc-pcap.c index a633abc42896..cd4f198cc2ef 100644 --- a/trunk/drivers/rtc/rtc-pcap.c +++ b/trunk/drivers/rtc/rtc-pcap.c @@ -151,6 +151,8 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) pcap_rtc->pcap = dev_get_drvdata(pdev->dev.parent); + platform_set_drvdata(pdev, pcap_rtc); + pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, &pcap_rtc_ops, THIS_MODULE); if (IS_ERR(pcap_rtc->rtc)) { @@ -158,7 +160,6 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) goto fail_rtc; } - platform_set_drvdata(pdev, pcap_rtc); timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); @@ -177,6 +178,7 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) fail_timer: rtc_device_unregister(pcap_rtc->rtc); fail_rtc: + platform_set_drvdata(pdev, NULL); kfree(pcap_rtc); return err; } diff --git a/trunk/drivers/rtc/rtc-rp5c01.c b/trunk/drivers/rtc/rtc-rp5c01.c index 694da39b6dd2..359da6d020b9 100644 --- a/trunk/drivers/rtc/rtc-rp5c01.c +++ b/trunk/drivers/rtc/rtc-rp5c01.c @@ -249,15 +249,15 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) spin_lock_init(&priv->lock); + platform_set_drvdata(dev, priv); + rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { error = PTR_ERR(rtc); goto out_unmap; } - priv->rtc = rtc; - platform_set_drvdata(dev, priv); error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); if (error) @@ -268,6 +268,7 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) out_unregister: rtc_device_unregister(rtc); out_unmap: + platform_set_drvdata(dev, NULL); iounmap(priv->regs); out_free_priv: kfree(priv); diff --git a/trunk/drivers/s390/char/tape_block.c b/trunk/drivers/s390/char/tape_block.c index 83cea9a55e2f..1b3924c2fffd 100644 --- a/trunk/drivers/s390/char/tape_block.c +++ b/trunk/drivers/s390/char/tape_block.c @@ -236,7 +236,6 @@ tapeblock_setup_device(struct tape_device * device) disk->major = tapeblock_major; disk->first_minor = device->first_minor; disk->fops = &tapeblock_fops; - disk->events = DISK_EVENT_MEDIA_CHANGE; disk->private_data = tape_get_device(device); disk->queue = blkdat->request_queue; set_capacity(disk, 0); diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index e2d45c91b8e8..9689d41c7888 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -1292,8 +1292,10 @@ static struct scsi_host_template qpti_template = { .use_clustering = ENABLE_CLUSTERING, }; +static const struct of_device_id qpti_match[]; static int __devinit qpti_sbus_probe(struct platform_device *op) { + const struct of_device_id *match; struct scsi_host_template *tpnt; struct device_node *dp = op->dev.of_node; struct Scsi_Host *host; @@ -1301,9 +1303,10 @@ static int __devinit qpti_sbus_probe(struct platform_device *op) static int nqptis; const char *fcode; - if (!op->dev.of_match) + match = of_match_device(qpti_match, &op->dev); + if (!match) return -EINVAL; - tpnt = op->dev.of_match->data; + tpnt = match->data; /* Sometimes Antares cards come up not completely * setup, and we get a report of a zero IRQ. diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 0bac91e72370..ec1803a48723 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -74,8 +74,6 @@ struct kmem_cache *scsi_sdb_cache; */ #define SCSI_QUEUE_DELAY 3 -static void scsi_run_queue(struct request_queue *q); - /* * Function: scsi_unprep_request() * @@ -161,7 +159,7 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy) blk_requeue_request(q, cmd->request); spin_unlock_irqrestore(q->queue_lock, flags); - scsi_run_queue(q); + kblockd_schedule_work(q, &device->requeue_work); return 0; } @@ -438,7 +436,11 @@ static void scsi_run_queue(struct request_queue *q) continue; } - blk_run_queue_async(sdev->request_queue); + spin_unlock(shost->host_lock); + spin_lock(sdev->request_queue->queue_lock); + __blk_run_queue(sdev->request_queue); + spin_unlock(sdev->request_queue->queue_lock); + spin_lock(shost->host_lock); } /* put any unprocessed entries back */ list_splice(&starved_list, &shost->starved_list); @@ -447,6 +449,16 @@ static void scsi_run_queue(struct request_queue *q) blk_run_queue(q); } +void scsi_requeue_run_queue(struct work_struct *work) +{ + struct scsi_device *sdev; + struct request_queue *q; + + sdev = container_of(work, struct scsi_device, requeue_work); + q = sdev->request_queue; + scsi_run_queue(q); +} + /* * Function: scsi_requeue_command() * diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 087821fac8fe..58584dc0724a 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -242,6 +242,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, int display_failure_msg = 1, ret; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); extern void scsi_evt_thread(struct work_struct *work); + extern void scsi_requeue_run_queue(struct work_struct *work); sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size, GFP_ATOMIC); @@ -264,6 +265,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, INIT_LIST_HEAD(&sdev->event_list); spin_lock_init(&sdev->list_lock); INIT_WORK(&sdev->event_work, scsi_evt_thread); + INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue); sdev->sdev_gendev.parent = get_device(&starget->dev); sdev->sdev_target = starget; diff --git a/trunk/drivers/tty/serial/of_serial.c b/trunk/drivers/tty/serial/of_serial.c index 0e8eec516df4..c911b2419abb 100644 --- a/trunk/drivers/tty/serial/of_serial.c +++ b/trunk/drivers/tty/serial/of_serial.c @@ -80,14 +80,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* * Try to register a serial port */ +static struct of_device_id of_platform_serial_table[]; static int __devinit of_platform_serial_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct of_serial_info *info; struct uart_port port; int port_type; int ret; - if (!ofdev->dev.of_match) + match = of_match_device(of_platform_serial_table, &ofdev->dev); + if (!match) return -EINVAL; if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) @@ -97,7 +100,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) if (info == NULL) return -ENOMEM; - port_type = (unsigned long)ofdev->dev.of_match->data; + port_type = (unsigned long)match->data; ret = of_platform_serial_setup(ofdev, port_type, &port); if (ret) goto out; diff --git a/trunk/drivers/usb/gadget/fsl_qe_udc.c b/trunk/drivers/usb/gadget/fsl_qe_udc.c index 36613b37c504..3a68e09309f7 100644 --- a/trunk/drivers/usb/gadget/fsl_qe_udc.c +++ b/trunk/drivers/usb/gadget/fsl_qe_udc.c @@ -2539,15 +2539,18 @@ static void qe_udc_release(struct device *dev) } /* Driver probe functions */ +static const struct of_device_id qe_udc_match[]; static int __devinit qe_udc_probe(struct platform_device *ofdev) { + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct qe_ep *ep; unsigned int ret = 0; unsigned int i; const void *prop; - if (!ofdev->dev.of_match) + match = of_match_device(qe_udc_match, &ofdev->dev); + if (!match) return -EINVAL; prop = of_get_property(np, "mode", NULL); @@ -2561,7 +2564,7 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev) return -ENOMEM; } - udc_controller->soc_type = (unsigned long)ofdev->dev.of_match->data; + udc_controller->soc_type = (unsigned long)match->data; udc_controller->usb_regs = of_iomap(np, 0); if (!udc_controller->usb_regs) { ret = -ENOMEM; diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index e0c2284924b6..5aac00eb1830 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -42,9 +42,34 @@ #define FBPIXMAPSIZE (1024 * 8) +static DEFINE_MUTEX(registration_lock); struct fb_info *registered_fb[FB_MAX] __read_mostly; int num_registered_fb __read_mostly; +static struct fb_info *get_fb_info(unsigned int idx) +{ + struct fb_info *fb_info; + + if (idx >= FB_MAX) + return ERR_PTR(-ENODEV); + + mutex_lock(®istration_lock); + fb_info = registered_fb[idx]; + if (fb_info) + atomic_inc(&fb_info->count); + mutex_unlock(®istration_lock); + + return fb_info; +} + +static void put_fb_info(struct fb_info *fb_info) +{ + if (!atomic_dec_and_test(&fb_info->count)) + return; + if (fb_info->fbops->fb_destroy) + fb_info->fbops->fb_destroy(fb_info); +} + int lock_fb_info(struct fb_info *info) { mutex_lock(&info->lock); @@ -647,6 +672,7 @@ int fb_show_logo(struct fb_info *info, int rotate) { return 0; } static void *fb_seq_start(struct seq_file *m, loff_t *pos) { + mutex_lock(®istration_lock); return (*pos < FB_MAX) ? pos : NULL; } @@ -658,6 +684,7 @@ static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos) static void fb_seq_stop(struct seq_file *m, void *v) { + mutex_unlock(®istration_lock); } static int fb_seq_show(struct seq_file *m, void *v) @@ -690,13 +717,30 @@ static const struct file_operations fb_proc_fops = { .release = seq_release, }; -static ssize_t -fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +/* + * We hold a reference to the fb_info in file->private_data, + * but if the current registered fb has changed, we don't + * actually want to use it. + * + * So look up the fb_info using the inode minor number, + * and just verify it against the reference we have. + */ +static struct fb_info *file_fb_info(struct file *file) { - unsigned long p = *ppos; struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; + + if (info != file->private_data) + info = NULL; + return info; +} + +static ssize_t +fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + struct fb_info *info = file_fb_info(file); u8 *buffer, *dst; u8 __iomem *src; int c, cnt = 0, err = 0; @@ -761,9 +805,7 @@ static ssize_t fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file_fb_info(file); u8 *buffer, *src; u8 __iomem *dst; int c, cnt = 0, err = 0; @@ -1141,10 +1183,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; + struct fb_info *info = file_fb_info(file); + if (!info) + return -ENODEV; return do_fb_ioctl(info, cmd, arg); } @@ -1265,12 +1307,13 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, static long fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct inode *inode = file->f_path.dentry->d_inode; - int fbidx = iminor(inode); - struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; + struct fb_info *info = file_fb_info(file); + struct fb_ops *fb; long ret = -ENOIOCTLCMD; + if (!info) + return -ENODEV; + fb = info->fbops; switch(cmd) { case FBIOGET_VSCREENINFO: case FBIOPUT_VSCREENINFO: @@ -1303,16 +1346,18 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, static int fb_mmap(struct file *file, struct vm_area_struct * vma) { - int fbidx = iminor(file->f_path.dentry->d_inode); - struct fb_info *info = registered_fb[fbidx]; - struct fb_ops *fb = info->fbops; + struct fb_info *info = file_fb_info(file); + struct fb_ops *fb; unsigned long off; unsigned long start; u32 len; + if (!info) + return -ENODEV; if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) return -EINVAL; off = vma->vm_pgoff << PAGE_SHIFT; + fb = info->fbops; if (!fb) return -ENODEV; mutex_lock(&info->mm_lock); @@ -1361,14 +1406,16 @@ __releases(&info->lock) struct fb_info *info; int res = 0; - if (fbidx >= FB_MAX) - return -ENODEV; - info = registered_fb[fbidx]; - if (!info) + info = get_fb_info(fbidx); + if (!info) { request_module("fb%d", fbidx); - info = registered_fb[fbidx]; - if (!info) - return -ENODEV; + info = get_fb_info(fbidx); + if (!info) + return -ENODEV; + } + if (IS_ERR(info)) + return PTR_ERR(info); + mutex_lock(&info->lock); if (!try_module_get(info->fbops->owner)) { res = -ENODEV; @@ -1386,6 +1433,8 @@ __releases(&info->lock) #endif out: mutex_unlock(&info->lock); + if (res) + put_fb_info(info); return res; } @@ -1401,6 +1450,7 @@ __releases(&info->lock) info->fbops->fb_release(info,1); module_put(info->fbops->owner); mutex_unlock(&info->lock); + put_fb_info(info); return 0; } @@ -1487,8 +1537,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, return false; } +static int do_unregister_framebuffer(struct fb_info *fb_info); + #define VGA_FB_PHYS 0xA0000 -void remove_conflicting_framebuffers(struct apertures_struct *a, +static void do_remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { int i; @@ -1510,43 +1562,32 @@ void remove_conflicting_framebuffers(struct apertures_struct *a, printk(KERN_INFO "fb: conflicting fb hw usage " "%s vs %s - removing generic driver\n", name, registered_fb[i]->fix.id); - unregister_framebuffer(registered_fb[i]); + do_unregister_framebuffer(registered_fb[i]); } } } -EXPORT_SYMBOL(remove_conflicting_framebuffers); -/** - * register_framebuffer - registers a frame buffer device - * @fb_info: frame buffer info structure - * - * Registers a frame buffer device @fb_info. - * - * Returns negative errno on error, or zero for success. - * - */ - -int -register_framebuffer(struct fb_info *fb_info) +static int do_register_framebuffer(struct fb_info *fb_info) { int i; struct fb_event event; struct fb_videomode mode; - if (num_registered_fb == FB_MAX) - return -ENXIO; - if (fb_check_foreignness(fb_info)) return -ENOSYS; - remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, + do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, fb_is_primary_device(fb_info)); + if (num_registered_fb == FB_MAX) + return -ENXIO; + num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) if (!registered_fb[i]) break; fb_info->node = i; + atomic_set(&fb_info->count, 1); mutex_init(&fb_info->lock); mutex_init(&fb_info->mm_lock); @@ -1592,36 +1633,14 @@ register_framebuffer(struct fb_info *fb_info) return 0; } - -/** - * unregister_framebuffer - releases a frame buffer device - * @fb_info: frame buffer info structure - * - * Unregisters a frame buffer device @fb_info. - * - * Returns negative errno on error, or zero for success. - * - * This function will also notify the framebuffer console - * to release the driver. - * - * This is meant to be called within a driver's module_exit() - * function. If this is called outside module_exit(), ensure - * that the driver implements fb_open() and fb_release() to - * check that no processes are using the device. - */ - -int -unregister_framebuffer(struct fb_info *fb_info) +static int do_unregister_framebuffer(struct fb_info *fb_info) { struct fb_event event; int i, ret = 0; i = fb_info->node; - if (!registered_fb[i]) { - ret = -EINVAL; - goto done; - } - + if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) + return -EINVAL; if (!lock_fb_info(fb_info)) return -ENODEV; @@ -1629,16 +1648,14 @@ unregister_framebuffer(struct fb_info *fb_info) ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); unlock_fb_info(fb_info); - if (ret) { - ret = -EINVAL; - goto done; - } + if (ret) + return -EINVAL; if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); fb_destroy_modelist(&fb_info->modelist); - registered_fb[i]=NULL; + registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); device_destroy(fb_class, MKDEV(FB_MAJOR, i)); @@ -1646,9 +1663,65 @@ unregister_framebuffer(struct fb_info *fb_info) fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); /* this may free fb info */ - if (fb_info->fbops->fb_destroy) - fb_info->fbops->fb_destroy(fb_info); -done: + put_fb_info(fb_info); + return 0; +} + +void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ + mutex_lock(®istration_lock); + do_remove_conflicting_framebuffers(a, name, primary); + mutex_unlock(®istration_lock); +} +EXPORT_SYMBOL(remove_conflicting_framebuffers); + +/** + * register_framebuffer - registers a frame buffer device + * @fb_info: frame buffer info structure + * + * Registers a frame buffer device @fb_info. + * + * Returns negative errno on error, or zero for success. + * + */ +int +register_framebuffer(struct fb_info *fb_info) +{ + int ret; + + mutex_lock(®istration_lock); + ret = do_register_framebuffer(fb_info); + mutex_unlock(®istration_lock); + + return ret; +} + +/** + * unregister_framebuffer - releases a frame buffer device + * @fb_info: frame buffer info structure + * + * Unregisters a frame buffer device @fb_info. + * + * Returns negative errno on error, or zero for success. + * + * This function will also notify the framebuffer console + * to release the driver. + * + * This is meant to be called within a driver's module_exit() + * function. If this is called outside module_exit(), ensure + * that the driver implements fb_open() and fb_release() to + * check that no processes are using the device. + */ +int +unregister_framebuffer(struct fb_info *fb_info) +{ + int ret; + + mutex_lock(®istration_lock); + ret = do_unregister_framebuffer(fb_info); + mutex_unlock(®istration_lock); + return ret; } diff --git a/trunk/drivers/video/omap/Makefile b/trunk/drivers/video/omap/Makefile index 25db55696e14..49226a1b909e 100644 --- a/trunk/drivers/video/omap/Makefile +++ b/trunk/drivers/video/omap/Makefile @@ -30,6 +30,7 @@ objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o +objs-y$(CONFIG_MACH_OMAP2EVM) += lcd_omap2evm.o objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o diff --git a/trunk/drivers/video/omap/lcd_omap2evm.c b/trunk/drivers/video/omap/lcd_omap2evm.c new file mode 100644 index 000000000000..7e7a65c08452 --- /dev/null +++ b/trunk/drivers/video/omap/lcd_omap2evm.c @@ -0,0 +1,192 @@ +/* + * LCD panel support for the MISTRAL OMAP2EVM board + * + * Author: Arun C + * + * Derived from drivers/video/omap/lcd_omap3evm.c + * Derived from drivers/video/omap/lcd-apollon.c + * + * 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 "omapfb.h" + +#define LCD_PANEL_ENABLE_GPIO 154 +#define LCD_PANEL_LR 128 +#define LCD_PANEL_UD 129 +#define LCD_PANEL_INI 152 +#define LCD_PANEL_QVGA 148 +#define LCD_PANEL_RESB 153 + +#define TWL_LED_LEDEN 0x00 +#define TWL_PWMA_PWMAON 0x00 +#define TWL_PWMA_PWMAOFF 0x01 + +static unsigned int bklight_level; + +static int omap2evm_panel_init(struct lcd_panel *panel, + struct omapfb_device *fbdev) +{ + gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable"); + gpio_request(LCD_PANEL_LR, "LCD lr"); + gpio_request(LCD_PANEL_UD, "LCD ud"); + gpio_request(LCD_PANEL_INI, "LCD ini"); + gpio_request(LCD_PANEL_QVGA, "LCD qvga"); + gpio_request(LCD_PANEL_RESB, "LCD resb"); + + gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1); + gpio_direction_output(LCD_PANEL_RESB, 1); + gpio_direction_output(LCD_PANEL_INI, 1); + gpio_direction_output(LCD_PANEL_QVGA, 0); + gpio_direction_output(LCD_PANEL_LR, 1); + gpio_direction_output(LCD_PANEL_UD, 1); + + twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON); + twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF); + bklight_level = 100; + + return 0; +} + +static void omap2evm_panel_cleanup(struct lcd_panel *panel) +{ + gpio_free(LCD_PANEL_RESB); + gpio_free(LCD_PANEL_QVGA); + gpio_free(LCD_PANEL_INI); + gpio_free(LCD_PANEL_UD); + gpio_free(LCD_PANEL_LR); + gpio_free(LCD_PANEL_ENABLE_GPIO); +} + +static int omap2evm_panel_enable(struct lcd_panel *panel) +{ + gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0); + return 0; +} + +static void omap2evm_panel_disable(struct lcd_panel *panel) +{ + gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1); +} + +static unsigned long omap2evm_panel_get_caps(struct lcd_panel *panel) +{ + return 0; +} + +static int omap2evm_bklight_setlevel(struct lcd_panel *panel, + unsigned int level) +{ + u8 c; + if ((level >= 0) && (level <= 100)) { + c = (125 * (100 - level)) / 100 + 2; + twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF); + bklight_level = level; + } + return 0; +} + +static unsigned int omap2evm_bklight_getlevel(struct lcd_panel *panel) +{ + return bklight_level; +} + +static unsigned int omap2evm_bklight_getmaxlevel(struct lcd_panel *panel) +{ + return 100; +} + +struct lcd_panel omap2evm_panel = { + .name = "omap2evm", + .config = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC | + OMAP_LCDC_INV_HSYNC, + + .bpp = 16, + .data_lines = 18, + .x_res = 480, + .y_res = 640, + .hsw = 3, + .hfp = 0, + .hbp = 28, + .vsw = 2, + .vfp = 1, + .vbp = 0, + + .pixel_clock = 20000, + + .init = omap2evm_panel_init, + .cleanup = omap2evm_panel_cleanup, + .enable = omap2evm_panel_enable, + .disable = omap2evm_panel_disable, + .get_caps = omap2evm_panel_get_caps, + .set_bklight_level = omap2evm_bklight_setlevel, + .get_bklight_level = omap2evm_bklight_getlevel, + .get_bklight_max = omap2evm_bklight_getmaxlevel, +}; + +static int omap2evm_panel_probe(struct platform_device *pdev) +{ + omapfb_register_panel(&omap2evm_panel); + return 0; +} + +static int omap2evm_panel_remove(struct platform_device *pdev) +{ + return 0; +} + +static int omap2evm_panel_suspend(struct platform_device *pdev, + pm_message_t mesg) +{ + return 0; +} + +static int omap2evm_panel_resume(struct platform_device *pdev) +{ + return 0; +} + +struct platform_driver omap2evm_panel_driver = { + .probe = omap2evm_panel_probe, + .remove = omap2evm_panel_remove, + .suspend = omap2evm_panel_suspend, + .resume = omap2evm_panel_resume, + .driver = { + .name = "omap2evm_lcd", + .owner = THIS_MODULE, + }, +}; + +static int __init omap2evm_panel_drv_init(void) +{ + return platform_driver_register(&omap2evm_panel_driver); +} + +static void __exit omap2evm_panel_drv_exit(void) +{ + platform_driver_unregister(&omap2evm_panel_driver); +} + +module_init(omap2evm_panel_drv_init); +module_exit(omap2evm_panel_drv_exit); diff --git a/trunk/drivers/watchdog/mpc8xxx_wdt.c b/trunk/drivers/watchdog/mpc8xxx_wdt.c index 528bceb220fd..eed5436ffb51 100644 --- a/trunk/drivers/watchdog/mpc8xxx_wdt.c +++ b/trunk/drivers/watchdog/mpc8xxx_wdt.c @@ -185,17 +185,20 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { .fops = &mpc8xxx_wdt_fops, }; +static const struct of_device_id mpc8xxx_wdt_match[]; static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) { int ret; + const struct of_device_id *match; struct device_node *np = ofdev->dev.of_node; struct mpc8xxx_wdt_type *wdt_type; u32 freq = fsl_get_sys_freq(); bool enabled; - if (!ofdev->dev.of_match) + match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); + if (!match) return -EINVAL; - wdt_type = ofdev->dev.of_match->data; + wdt_type = match->data; if (!freq || freq == -1) return -EINVAL; diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 5147bdd3b8e1..257b00e98428 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -1102,6 +1102,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) if (!bdev->bd_part) goto out_clear; + ret = 0; if (disk->fops->open) { ret = disk->fops->open(bdev, mode); if (ret == -ERESTARTSYS) { @@ -1118,9 +1119,18 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) put_disk(disk); goto restart; } - if (ret) - goto out_clear; } + /* + * If the device is invalidated, rescan partition + * if open succeeded or failed with -ENOMEDIUM. + * The latter is necessary to prevent ghost + * partitions on a removed medium. + */ + if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) + rescan_partitions(disk, bdev); + if (ret) + goto out_clear; + if (!bdev->bd_openers) { bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); bdi = blk_get_backing_dev_info(bdev); @@ -1128,8 +1138,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) bdi = &default_backing_dev_info; bdev_inode_switch_bdi(bdev->bd_inode, bdi); } - if (bdev->bd_invalidated) - rescan_partitions(disk, bdev); } else { struct block_device *whole; whole = bdget_disk(disk, 0); @@ -1153,13 +1161,14 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) } } else { if (bdev->bd_contains == bdev) { - if (bdev->bd_disk->fops->open) { + ret = 0; + if (bdev->bd_disk->fops->open) ret = bdev->bd_disk->fops->open(bdev, mode); - if (ret) - goto out_unlock_bdev; - } - if (bdev->bd_invalidated) + /* the same as first opener case, read comment there */ + if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) rescan_partitions(bdev->bd_disk, bdev); + if (ret) + goto out_unlock_bdev; } /* only one opener holds refs to the module and disk */ module_put(disk->fops->owner); diff --git a/trunk/fs/btrfs/acl.c b/trunk/fs/btrfs/acl.c index 5d505aaa72fb..44ea5b92e1ba 100644 --- a/trunk/fs/btrfs/acl.c +++ b/trunk/fs/btrfs/acl.c @@ -178,12 +178,13 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, if (value) { acl = posix_acl_from_xattr(value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { ret = posix_acl_valid(acl); if (ret) goto out; - } else if (IS_ERR(acl)) { - return PTR_ERR(acl); } } diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index cd52f7f556ef..9ee6bd55e16c 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -8856,23 +8856,38 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, int btrfs_init_space_info(struct btrfs_fs_info *fs_info) { struct btrfs_space_info *space_info; + struct btrfs_super_block *disk_super; + u64 features; + u64 flags; + int mixed = 0; int ret; - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, - &space_info); - if (ret) - return ret; + disk_super = &fs_info->super_copy; + if (!btrfs_super_root(disk_super)) + return 1; - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, - &space_info); - if (ret) - return ret; + features = btrfs_super_incompat_flags(disk_super); + if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) + mixed = 1; - ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, - &space_info); + flags = BTRFS_BLOCK_GROUP_SYSTEM; + ret = update_space_info(fs_info, flags, 0, 0, &space_info); if (ret) - return ret; + goto out; + if (mixed) { + flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; + ret = update_space_info(fs_info, flags, 0, 0, &space_info); + } else { + flags = BTRFS_BLOCK_GROUP_METADATA; + ret = update_space_info(fs_info, flags, 0, 0, &space_info); + if (ret) + goto out; + + flags = BTRFS_BLOCK_GROUP_DATA; + ret = update_space_info(fs_info, flags, 0, 0, &space_info); + } +out: return ret; } diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index ffb48d6c5433..2616f7ed4799 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -81,6 +81,13 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) iflags |= FS_NOATIME_FL; if (flags & BTRFS_INODE_DIRSYNC) iflags |= FS_DIRSYNC_FL; + if (flags & BTRFS_INODE_NODATACOW) + iflags |= FS_NOCOW_FL; + + if ((flags & BTRFS_INODE_COMPRESS) && !(flags & BTRFS_INODE_NOCOMPRESS)) + iflags |= FS_COMPR_FL; + else if (flags & BTRFS_INODE_NOCOMPRESS) + iflags |= FS_NOCOMP_FL; return iflags; } @@ -144,16 +151,13 @@ static int check_flags(unsigned int flags) if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NOATIME_FL | FS_NODUMP_FL | \ FS_SYNC_FL | FS_DIRSYNC_FL | \ - FS_NOCOMP_FL | FS_COMPR_FL | \ - FS_NOCOW_FL | FS_COW_FL)) + FS_NOCOMP_FL | FS_COMPR_FL | + FS_NOCOW_FL)) return -EOPNOTSUPP; if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) return -EINVAL; - if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL)) - return -EINVAL; - return 0; } @@ -218,6 +222,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) ip->flags |= BTRFS_INODE_DIRSYNC; else ip->flags &= ~BTRFS_INODE_DIRSYNC; + if (flags & FS_NOCOW_FL) + ip->flags |= BTRFS_INODE_NODATACOW; + else + ip->flags &= ~BTRFS_INODE_NODATACOW; /* * The COMPRESS flag can only be changed by users, while the NOCOMPRESS @@ -230,11 +238,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) } else if (flags & FS_COMPR_FL) { ip->flags |= BTRFS_INODE_COMPRESS; ip->flags &= ~BTRFS_INODE_NOCOMPRESS; + } else { + ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); } - if (flags & FS_NOCOW_FL) - ip->flags |= BTRFS_INODE_NODATACOW; - else if (flags & FS_COW_FL) - ip->flags &= ~BTRFS_INODE_NODATACOW; trans = btrfs_join_transaction(root, 1); BUG_ON(IS_ERR(trans)); diff --git a/trunk/fs/cifs/cifs_unicode.c b/trunk/fs/cifs/cifs_unicode.c index 23d43cde4306..1b2e180b018d 100644 --- a/trunk/fs/cifs/cifs_unicode.c +++ b/trunk/fs/cifs/cifs_unicode.c @@ -277,6 +277,7 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen, for (i = 0, j = 0; i < srclen; j++) { src_char = source[i]; + charlen = 1; switch (src_char) { case 0: put_unaligned(0, &target[j]); @@ -316,16 +317,13 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen, dst_char = cpu_to_le16(0x003f); charlen = 1; } - /* - * character may take more than one byte in the source - * string, but will take exactly two bytes in the - * target string - */ - i += charlen; - continue; } + /* + * character may take more than one byte in the source string, + * but will take exactly two bytes in the target string + */ + i += charlen; put_unaligned(dst_char, &target[j]); - i++; /* move to next char in source string */ } ctoUCS_out: diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 05f1dcf7d79a..277262a8e82f 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -2673,6 +2673,11 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon, 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); + + if (rc == -EOPNOTSUPP || rc == -EINVAL) + rc = SMBQueryInformation(xid, tcon, full_path, pfile_info, + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); kfree(pfile_info); return rc; } diff --git a/trunk/fs/configfs/dir.c b/trunk/fs/configfs/dir.c index 3313dd19f543..9a37a9b6de3a 100644 --- a/trunk/fs/configfs/dir.c +++ b/trunk/fs/configfs/dir.c @@ -53,11 +53,14 @@ DEFINE_SPINLOCK(configfs_dirent_lock); static void configfs_d_iput(struct dentry * dentry, struct inode * inode) { - struct configfs_dirent * sd = dentry->d_fsdata; + struct configfs_dirent *sd = dentry->d_fsdata; if (sd) { BUG_ON(sd->s_dentry != dentry); + /* Coordinate with configfs_readdir */ + spin_lock(&configfs_dirent_lock); sd->s_dentry = NULL; + spin_unlock(&configfs_dirent_lock); configfs_put(sd); } iput(inode); @@ -689,7 +692,8 @@ static int create_default_group(struct config_group *parent_group, sd = child->d_fsdata; sd->s_type |= CONFIGFS_USET_DEFAULT; } else { - d_delete(child); + BUG_ON(child->d_inode); + d_drop(child); dput(child); } } @@ -1545,7 +1549,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir struct configfs_dirent * parent_sd = dentry->d_fsdata; struct configfs_dirent *cursor = filp->private_data; struct list_head *p, *q = &cursor->s_sibling; - ino_t ino; + ino_t ino = 0; int i = filp->f_pos; switch (i) { @@ -1573,6 +1577,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir struct configfs_dirent *next; const char * name; int len; + struct inode *inode = NULL; next = list_entry(p, struct configfs_dirent, s_sibling); @@ -1581,9 +1586,28 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir name = configfs_get_name(next); len = strlen(name); - if (next->s_dentry) - ino = next->s_dentry->d_inode->i_ino; - else + + /* + * We'll have a dentry and an inode for + * PINNED items and for open attribute + * files. We lock here to prevent a race + * with configfs_d_iput() clearing + * s_dentry before calling iput(). + * + * Why do we go to the trouble? If + * someone has an attribute file open, + * the inode number should match until + * they close it. Beyond that, we don't + * care. + */ + spin_lock(&configfs_dirent_lock); + dentry = next->s_dentry; + if (dentry) + inode = dentry->d_inode; + if (inode) + ino = inode->i_ino; + spin_unlock(&configfs_dirent_lock); + if (!inode) ino = iunique(configfs_sb, 2); if (filldir(dirent, name, len, filp->f_pos, ino, @@ -1683,7 +1707,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) err = configfs_attach_group(sd->s_element, &group->cg_item, dentry); if (err) { - d_delete(dentry); + BUG_ON(dentry->d_inode); + d_drop(dentry); dput(dentry); } else { spin_lock(&configfs_dirent_lock); diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index c6ba49bd95b3..b32eb29a4e6f 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -174,7 +174,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (!inode) return 0; - if (nd->flags & LOOKUP_RCU) + if (nd && (nd->flags & LOOKUP_RCU)) return -ECHILD; fc = get_fuse_conn(inode); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 54fc993e3027..e3c4f112ebf7 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -179,7 +179,7 @@ EXPORT_SYMBOL(putname); static int acl_permission_check(struct inode *inode, int mask, unsigned int flags, int (*check_acl)(struct inode *inode, int mask, unsigned int flags)) { - umode_t mode = inode->i_mode; + unsigned int mode = inode->i_mode; mask &= MAY_READ | MAY_WRITE | MAY_EXEC; diff --git a/trunk/fs/nfs/nfs4filelayout.c b/trunk/fs/nfs/nfs4filelayout.c index 6f8192f4cfc7..be79dc9f386d 100644 --- a/trunk/fs/nfs/nfs4filelayout.c +++ b/trunk/fs/nfs/nfs4filelayout.c @@ -117,6 +117,8 @@ static int filelayout_async_handle_error(struct rpc_task *task, case -EKEYEXPIRED: rpc_delay(task, FILELAYOUT_POLL_RETRY_MAX); break; + case -NFS4ERR_RETRY_UNCACHED_REP: + break; default: dprintk("%s DS error. Retry through MDS %d\n", __func__, task->tk_status); @@ -416,7 +418,8 @@ static int filelayout_check_layout(struct pnfs_layout_hdr *lo, struct nfs4_filelayout_segment *fl, struct nfs4_layoutget_res *lgr, - struct nfs4_deviceid *id) + struct nfs4_deviceid *id, + gfp_t gfp_flags) { struct nfs4_file_layout_dsaddr *dsaddr; int status = -EINVAL; @@ -439,7 +442,7 @@ filelayout_check_layout(struct pnfs_layout_hdr *lo, /* find and reference the deviceid */ dsaddr = nfs4_fl_find_get_deviceid(id); if (dsaddr == NULL) { - dsaddr = get_device_info(lo->plh_inode, id); + dsaddr = get_device_info(lo->plh_inode, id, gfp_flags); if (dsaddr == NULL) goto out; } @@ -500,7 +503,8 @@ static int filelayout_decode_layout(struct pnfs_layout_hdr *flo, struct nfs4_filelayout_segment *fl, struct nfs4_layoutget_res *lgr, - struct nfs4_deviceid *id) + struct nfs4_deviceid *id, + gfp_t gfp_flags) { struct xdr_stream stream; struct xdr_buf buf = { @@ -516,7 +520,7 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, dprintk("%s: set_layout_map Begin\n", __func__); - scratch = alloc_page(GFP_KERNEL); + scratch = alloc_page(gfp_flags); if (!scratch) return -ENOMEM; @@ -554,13 +558,13 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, goto out_err; fl->fh_array = kzalloc(fl->num_fh * sizeof(struct nfs_fh *), - GFP_KERNEL); + gfp_flags); if (!fl->fh_array) goto out_err; for (i = 0; i < fl->num_fh; i++) { /* Do we want to use a mempool here? */ - fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags); if (!fl->fh_array[i]) goto out_err_free; @@ -605,19 +609,20 @@ filelayout_free_lseg(struct pnfs_layout_segment *lseg) static struct pnfs_layout_segment * filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, - struct nfs4_layoutget_res *lgr) + struct nfs4_layoutget_res *lgr, + gfp_t gfp_flags) { struct nfs4_filelayout_segment *fl; int rc; struct nfs4_deviceid id; dprintk("--> %s\n", __func__); - fl = kzalloc(sizeof(*fl), GFP_KERNEL); + fl = kzalloc(sizeof(*fl), gfp_flags); if (!fl) return NULL; - rc = filelayout_decode_layout(layoutid, fl, lgr, &id); - if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id)) { + rc = filelayout_decode_layout(layoutid, fl, lgr, &id, gfp_flags); + if (rc != 0 || filelayout_check_layout(layoutid, fl, lgr, &id, gfp_flags)) { _filelayout_free_lseg(fl); return NULL; } @@ -633,7 +638,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, int size = (fl->stripe_type == STRIPE_SPARSE) ? fl->dsaddr->ds_num : fl->dsaddr->stripe_count; - fl->commit_buckets = kcalloc(size, sizeof(struct list_head), GFP_KERNEL); + fl->commit_buckets = kcalloc(size, sizeof(struct list_head), gfp_flags); if (!fl->commit_buckets) { filelayout_free_lseg(&fl->generic_hdr); return NULL; diff --git a/trunk/fs/nfs/nfs4filelayout.h b/trunk/fs/nfs/nfs4filelayout.h index 7c44579f5832..2b461d77b43a 100644 --- a/trunk/fs/nfs/nfs4filelayout.h +++ b/trunk/fs/nfs/nfs4filelayout.h @@ -104,6 +104,6 @@ extern struct nfs4_file_layout_dsaddr * nfs4_fl_find_get_deviceid(struct nfs4_deviceid *dev_id); extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr); struct nfs4_file_layout_dsaddr * -get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id); +get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags); #endif /* FS_NFS_NFS4FILELAYOUT_H */ diff --git a/trunk/fs/nfs/nfs4filelayoutdev.c b/trunk/fs/nfs/nfs4filelayoutdev.c index de5350f2b249..db07c7af1395 100644 --- a/trunk/fs/nfs/nfs4filelayoutdev.c +++ b/trunk/fs/nfs/nfs4filelayoutdev.c @@ -225,11 +225,11 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr) } static struct nfs4_pnfs_ds * -nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port) +nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port, gfp_t gfp_flags) { struct nfs4_pnfs_ds *tmp_ds, *ds; - ds = kzalloc(sizeof(*tmp_ds), GFP_KERNEL); + ds = kzalloc(sizeof(*tmp_ds), gfp_flags); if (!ds) goto out; @@ -261,7 +261,7 @@ nfs4_pnfs_ds_add(struct inode *inode, u32 ip_addr, u32 port) * Currently only support ipv4, and one multi-path address. */ static struct nfs4_pnfs_ds * -decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) +decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode, gfp_t gfp_flags) { struct nfs4_pnfs_ds *ds = NULL; char *buf; @@ -303,7 +303,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) rlen); goto out_err; } - buf = kmalloc(rlen + 1, GFP_KERNEL); + buf = kmalloc(rlen + 1, gfp_flags); if (!buf) { dprintk("%s: Not enough memory\n", __func__); goto out_err; @@ -333,7 +333,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) sscanf(pstr, "-%d-%d", &tmp[0], &tmp[1]); port = htons((tmp[0] << 8) | (tmp[1])); - ds = nfs4_pnfs_ds_add(inode, ip_addr, port); + ds = nfs4_pnfs_ds_add(inode, ip_addr, port, gfp_flags); dprintk("%s: Decoded address and port %s\n", __func__, buf); out_free: kfree(buf); @@ -343,7 +343,7 @@ decode_and_add_ds(struct xdr_stream *streamp, struct inode *inode) /* Decode opaque device data and return the result */ static struct nfs4_file_layout_dsaddr* -decode_device(struct inode *ino, struct pnfs_device *pdev) +decode_device(struct inode *ino, struct pnfs_device *pdev, gfp_t gfp_flags) { int i; u32 cnt, num; @@ -362,7 +362,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) struct page *scratch; /* set up xdr stream */ - scratch = alloc_page(GFP_KERNEL); + scratch = alloc_page(gfp_flags); if (!scratch) goto out_err; @@ -384,7 +384,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) } /* read stripe indices */ - stripe_indices = kcalloc(cnt, sizeof(u8), GFP_KERNEL); + stripe_indices = kcalloc(cnt, sizeof(u8), gfp_flags); if (!stripe_indices) goto out_err_free_scratch; @@ -423,7 +423,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) dsaddr = kzalloc(sizeof(*dsaddr) + (sizeof(struct nfs4_pnfs_ds *) * (num - 1)), - GFP_KERNEL); + gfp_flags); if (!dsaddr) goto out_err_free_stripe_indices; @@ -452,7 +452,7 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) for (j = 0; j < mp_count; j++) { if (j == 0) { dsaddr->ds_list[i] = decode_and_add_ds(&stream, - ino); + ino, gfp_flags); if (dsaddr->ds_list[i] == NULL) goto out_err_free_deviceid; } else { @@ -503,12 +503,12 @@ decode_device(struct inode *ino, struct pnfs_device *pdev) * available devices. */ static struct nfs4_file_layout_dsaddr * -decode_and_add_device(struct inode *inode, struct pnfs_device *dev) +decode_and_add_device(struct inode *inode, struct pnfs_device *dev, gfp_t gfp_flags) { struct nfs4_file_layout_dsaddr *d, *new; long hash; - new = decode_device(inode, dev); + new = decode_device(inode, dev, gfp_flags); if (!new) { printk(KERN_WARNING "%s: Could not decode or add device\n", __func__); @@ -537,7 +537,7 @@ decode_and_add_device(struct inode *inode, struct pnfs_device *dev) * of available devices, and return it. */ struct nfs4_file_layout_dsaddr * -get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) +get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags) { struct pnfs_device *pdev = NULL; u32 max_resp_sz; @@ -556,17 +556,17 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) dprintk("%s inode %p max_resp_sz %u max_pages %d\n", __func__, inode, max_resp_sz, max_pages); - pdev = kzalloc(sizeof(struct pnfs_device), GFP_KERNEL); + pdev = kzalloc(sizeof(struct pnfs_device), gfp_flags); if (pdev == NULL) return NULL; - pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL); + pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags); if (pages == NULL) { kfree(pdev); return NULL; } for (i = 0; i < max_pages; i++) { - pages[i] = alloc_page(GFP_KERNEL); + pages[i] = alloc_page(gfp_flags); if (!pages[i]) goto out_free; } @@ -587,7 +587,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id) * Found new device, need to decode it and then add it to the * list of known devices for this mountpoint. */ - dsaddr = decode_and_add_device(inode, pdev); + dsaddr = decode_and_add_device(inode, pdev, gfp_flags); out_free: for (i = 0; i < max_pages; i++) __free_page(pages[i]); diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 69c0f3c5ee7a..cf1b339c3937 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -300,6 +300,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc ret = nfs4_delay(server->client, &exception->timeout); if (ret != 0) break; + case -NFS4ERR_RETRY_UNCACHED_REP: case -NFS4ERR_OLD_STATEID: exception->retry = 1; break; @@ -3695,6 +3696,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, rpc_delay(task, NFS4_POLL_RETRY_MAX); task->tk_status = 0; return -EAGAIN; + case -NFS4ERR_RETRY_UNCACHED_REP: case -NFS4ERR_OLD_STATEID: task->tk_status = 0; return -EAGAIN; @@ -4844,6 +4846,8 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata) dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); rpc_delay(task, NFS4_POLL_RETRY_MIN); task->tk_status = 0; + /* fall through */ + case -NFS4ERR_RETRY_UNCACHED_REP: nfs_restart_rpc(task, data->clp); return; } @@ -5479,6 +5483,8 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf break; case -NFS4ERR_DELAY: rpc_delay(task, NFS4_POLL_RETRY_MAX); + /* fall through */ + case -NFS4ERR_RETRY_UNCACHED_REP: return -EAGAIN; default: nfs4_schedule_lease_recovery(clp); diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index ff681ab65d31..f57f5281a520 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -383,6 +383,7 @@ pnfs_destroy_all_layouts(struct nfs_client *clp) plh_layouts); dprintk("%s freeing layout for inode %lu\n", __func__, lo->plh_inode->i_ino); + list_del_init(&lo->plh_layouts); pnfs_destroy_layout(NFS_I(lo->plh_inode)); } } @@ -466,7 +467,8 @@ pnfs_choose_layoutget_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo, static struct pnfs_layout_segment * send_layoutget(struct pnfs_layout_hdr *lo, struct nfs_open_context *ctx, - u32 iomode) + u32 iomode, + gfp_t gfp_flags) { struct inode *ino = lo->plh_inode; struct nfs_server *server = NFS_SERVER(ino); @@ -479,7 +481,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, dprintk("--> %s\n", __func__); BUG_ON(ctx == NULL); - lgp = kzalloc(sizeof(*lgp), GFP_KERNEL); + lgp = kzalloc(sizeof(*lgp), gfp_flags); if (lgp == NULL) return NULL; @@ -487,12 +489,12 @@ send_layoutget(struct pnfs_layout_hdr *lo, max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; max_pages = max_resp_sz >> PAGE_SHIFT; - pages = kzalloc(max_pages * sizeof(struct page *), GFP_KERNEL); + pages = kzalloc(max_pages * sizeof(struct page *), gfp_flags); if (!pages) goto out_err_free; for (i = 0; i < max_pages; i++) { - pages[i] = alloc_page(GFP_KERNEL); + pages[i] = alloc_page(gfp_flags); if (!pages[i]) goto out_err_free; } @@ -508,6 +510,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, lgp->args.layout.pages = pages; lgp->args.layout.pglen = max_pages * PAGE_SIZE; lgp->lsegpp = &lseg; + lgp->gfp_flags = gfp_flags; /* Synchronously retrieve layout information from server and * store in lseg. @@ -665,11 +668,11 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo, } static struct pnfs_layout_hdr * -alloc_init_layout_hdr(struct inode *ino) +alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags) { struct pnfs_layout_hdr *lo; - lo = kzalloc(sizeof(struct pnfs_layout_hdr), GFP_KERNEL); + lo = kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags); if (!lo) return NULL; atomic_set(&lo->plh_refcount, 1); @@ -681,7 +684,7 @@ alloc_init_layout_hdr(struct inode *ino) } static struct pnfs_layout_hdr * -pnfs_find_alloc_layout(struct inode *ino) +pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags) { struct nfs_inode *nfsi = NFS_I(ino); struct pnfs_layout_hdr *new = NULL; @@ -696,7 +699,7 @@ pnfs_find_alloc_layout(struct inode *ino) return nfsi->layout; } spin_unlock(&ino->i_lock); - new = alloc_init_layout_hdr(ino); + new = alloc_init_layout_hdr(ino, gfp_flags); spin_lock(&ino->i_lock); if (likely(nfsi->layout == NULL)) /* Won the race? */ @@ -756,7 +759,8 @@ pnfs_find_lseg(struct pnfs_layout_hdr *lo, u32 iomode) struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode iomode) + enum pnfs_iomode iomode, + gfp_t gfp_flags) { struct nfs_inode *nfsi = NFS_I(ino); struct nfs_client *clp = NFS_SERVER(ino)->nfs_client; @@ -767,7 +771,7 @@ pnfs_update_layout(struct inode *ino, if (!pnfs_enabled_sb(NFS_SERVER(ino))) return NULL; spin_lock(&ino->i_lock); - lo = pnfs_find_alloc_layout(ino); + lo = pnfs_find_alloc_layout(ino, gfp_flags); if (lo == NULL) { dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__); goto out_unlock; @@ -807,7 +811,7 @@ pnfs_update_layout(struct inode *ino, spin_unlock(&clp->cl_lock); } - lseg = send_layoutget(lo, ctx, iomode); + lseg = send_layoutget(lo, ctx, iomode, gfp_flags); if (!lseg && first) { spin_lock(&clp->cl_lock); list_del_init(&lo->plh_layouts); @@ -846,7 +850,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out; } /* Inject layout blob into I/O device driver */ - lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res); + lseg = NFS_SERVER(ino)->pnfs_curr_ld->alloc_lseg(lo, res, lgp->gfp_flags); if (!lseg || IS_ERR(lseg)) { if (!lseg) status = -ENOMEM; @@ -899,7 +903,8 @@ static int pnfs_read_pg_test(struct nfs_pageio_descriptor *pgio, /* This is first coelesce call for a series of nfs_pages */ pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, prev->wb_context, - IOMODE_READ); + IOMODE_READ, + GFP_KERNEL); } return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); } @@ -921,7 +926,8 @@ static int pnfs_write_pg_test(struct nfs_pageio_descriptor *pgio, /* This is first coelesce call for a series of nfs_pages */ pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, prev->wb_context, - IOMODE_RW); + IOMODE_RW, + GFP_NOFS); } return NFS_SERVER(pgio->pg_inode)->pnfs_curr_ld->pg_test(pgio, prev, req); } diff --git a/trunk/fs/nfs/pnfs.h b/trunk/fs/nfs/pnfs.h index bc4827202e7a..0c015bad9e7a 100644 --- a/trunk/fs/nfs/pnfs.h +++ b/trunk/fs/nfs/pnfs.h @@ -70,7 +70,7 @@ struct pnfs_layoutdriver_type { const u32 id; const char *name; struct module *owner; - struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr); + struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr, gfp_t gfp_flags); void (*free_lseg) (struct pnfs_layout_segment *lseg); /* test for nfs page cache coalescing */ @@ -126,7 +126,7 @@ void get_layout_hdr(struct pnfs_layout_hdr *lo); void put_lseg(struct pnfs_layout_segment *lseg); struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode access_type); + enum pnfs_iomode access_type, gfp_t gfp_flags); void set_pnfs_layoutdriver(struct nfs_server *, u32 id); void unset_pnfs_layoutdriver(struct nfs_server *); enum pnfs_try_status pnfs_try_to_write_data(struct nfs_write_data *, @@ -245,7 +245,7 @@ static inline void put_lseg(struct pnfs_layout_segment *lseg) static inline struct pnfs_layout_segment * pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx, - enum pnfs_iomode access_type) + enum pnfs_iomode access_type, gfp_t gfp_flags) { return NULL; } diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 7cded2b12a05..2bcf0dc306a1 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -288,7 +288,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc) atomic_set(&req->wb_complete, requests); BUG_ON(desc->pg_lseg != NULL); - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); ClearPageError(page); offset = 0; nbytes = desc->pg_count; @@ -351,7 +351,7 @@ static int nfs_pagein_one(struct nfs_pageio_descriptor *desc) } req = nfs_list_entry(data->pages.next); if ((!lseg) && list_is_singular(&data->pages)) - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_READ, GFP_KERNEL); ret = nfs_read_rpcsetup(req, data, &nfs_read_full_ops, desc->pg_count, 0, lseg); diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 3bd5d7e80f6c..49c715b4ac92 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -939,7 +939,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc) atomic_set(&req->wb_complete, requests); BUG_ON(desc->pg_lseg); - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); ClearPageError(page); offset = 0; nbytes = desc->pg_count; @@ -1013,7 +1013,7 @@ static int nfs_flush_one(struct nfs_pageio_descriptor *desc) } req = nfs_list_entry(data->pages.next); if ((!lseg) && list_is_singular(&data->pages)) - lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW); + lseg = pnfs_update_layout(desc->pg_inode, req->wb_context, IOMODE_RW, GFP_NOFS); if ((desc->pg_ioflags & FLUSH_COND_STABLE) && (desc->pg_moreio || NFS_I(desc->pg_inode)->ncommit)) diff --git a/trunk/fs/ocfs2/cluster/heartbeat.c b/trunk/fs/ocfs2/cluster/heartbeat.c index 643720209a98..9a3e6bbff27b 100644 --- a/trunk/fs/ocfs2/cluster/heartbeat.c +++ b/trunk/fs/ocfs2/cluster/heartbeat.c @@ -539,25 +539,41 @@ static int o2hb_verify_crc(struct o2hb_region *reg, /* We want to make sure that nobody is heartbeating on top of us -- * this will help detect an invalid configuration. */ -static int o2hb_check_last_timestamp(struct o2hb_region *reg) +static void o2hb_check_last_timestamp(struct o2hb_region *reg) { - int node_num, ret; struct o2hb_disk_slot *slot; struct o2hb_disk_heartbeat_block *hb_block; + char *errstr; - node_num = o2nm_this_node(); - - ret = 1; - slot = ®->hr_slots[node_num]; + slot = ®->hr_slots[o2nm_this_node()]; /* Don't check on our 1st timestamp */ - if (slot->ds_last_time) { - hb_block = slot->ds_raw_block; + if (!slot->ds_last_time) + return; - if (le64_to_cpu(hb_block->hb_seq) != slot->ds_last_time) - ret = 0; - } + hb_block = slot->ds_raw_block; + if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && + le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && + hb_block->hb_node == slot->ds_node_num) + return; - return ret; +#define ERRSTR1 "Another node is heartbeating on device" +#define ERRSTR2 "Heartbeat generation mismatch on device" +#define ERRSTR3 "Heartbeat sequence mismatch on device" + + if (hb_block->hb_node != slot->ds_node_num) + errstr = ERRSTR1; + else if (le64_to_cpu(hb_block->hb_generation) != + slot->ds_last_generation) + errstr = ERRSTR2; + else + errstr = ERRSTR3; + + mlog(ML_ERROR, "%s (%s): expected(%u:0x%llx, 0x%llx), " + "ondisk(%u:0x%llx, 0x%llx)\n", errstr, reg->hr_dev_name, + slot->ds_node_num, (unsigned long long)slot->ds_last_generation, + (unsigned long long)slot->ds_last_time, hb_block->hb_node, + (unsigned long long)le64_to_cpu(hb_block->hb_generation), + (unsigned long long)le64_to_cpu(hb_block->hb_seq)); } static inline void o2hb_prepare_block(struct o2hb_region *reg, @@ -983,9 +999,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) /* With an up to date view of the slots, we can check that no * other node has been improperly configured to heartbeat in * our slot. */ - if (!o2hb_check_last_timestamp(reg)) - mlog(ML_ERROR, "Device \"%s\": another node is heartbeating " - "in our slot!\n", reg->hr_dev_name); + o2hb_check_last_timestamp(reg); /* fill in the proper info for our next heartbeat */ o2hb_prepare_block(reg, reg->hr_generation); @@ -999,8 +1013,8 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) } i = -1; - while((i = find_next_bit(configured_nodes, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { - + while((i = find_next_bit(configured_nodes, + O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { change |= o2hb_check_slot(reg, ®->hr_slots[i]); } @@ -1690,6 +1704,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, struct file *filp = NULL; struct inode *inode = NULL; ssize_t ret = -EINVAL; + int live_threshold; if (reg->hr_bdev) goto out; @@ -1766,8 +1781,18 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, * A node is considered live after it has beat LIVE_THRESHOLD * times. We're not steady until we've given them a chance * _after_ our first read. + * The default threshold is bare minimum so as to limit the delay + * during mounts. For global heartbeat, the threshold doubled for the + * first region. */ - atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); + live_threshold = O2HB_LIVE_THRESHOLD; + if (o2hb_global_heartbeat_active()) { + spin_lock(&o2hb_live_lock); + if (o2hb_pop_count(&o2hb_region_bitmap, O2NM_MAX_REGIONS) == 1) + live_threshold <<= 1; + spin_unlock(&o2hb_live_lock); + } + atomic_set(®->hr_steady_iterations, live_threshold + 1); hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", reg->hr_item.ci_name); diff --git a/trunk/fs/ocfs2/dir.c b/trunk/fs/ocfs2/dir.c index 9fe5b8fd658f..8582e3f4f120 100644 --- a/trunk/fs/ocfs2/dir.c +++ b/trunk/fs/ocfs2/dir.c @@ -2868,7 +2868,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh, bytes = blocks_wanted << sb->s_blocksize_bits; struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); struct ocfs2_inode_info *oi = OCFS2_I(dir); - struct ocfs2_alloc_context *data_ac; + struct ocfs2_alloc_context *data_ac = NULL; struct ocfs2_alloc_context *meta_ac = NULL; struct buffer_head *dirdata_bh = NULL; struct buffer_head *dx_root_bh = NULL; diff --git a/trunk/fs/ocfs2/dlm/dlmdomain.c b/trunk/fs/ocfs2/dlm/dlmdomain.c index 7540a492eaba..3b179d6cbde0 100644 --- a/trunk/fs/ocfs2/dlm/dlmdomain.c +++ b/trunk/fs/ocfs2/dlm/dlmdomain.c @@ -1614,7 +1614,8 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) spin_unlock(&dlm->spinlock); /* Support for global heartbeat and node info was added in 1.1 */ - if (dlm_protocol.pv_major > 1 || dlm_protocol.pv_minor > 0) { + if (dlm->dlm_locking_proto.pv_major > 1 || + dlm->dlm_locking_proto.pv_minor > 0) { status = dlm_send_nodeinfo(dlm, ctxt->yes_resp_map); if (status) { mlog_errno(status); diff --git a/trunk/fs/ocfs2/dlm/dlmmaster.c b/trunk/fs/ocfs2/dlm/dlmmaster.c index fede57ed005f..84d166328cf7 100644 --- a/trunk/fs/ocfs2/dlm/dlmmaster.c +++ b/trunk/fs/ocfs2/dlm/dlmmaster.c @@ -2574,6 +2574,9 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, res->state &= ~DLM_LOCK_RES_MIGRATING; wake = 1; spin_unlock(&res->spinlock); + if (dlm_is_host_down(ret)) + dlm_wait_for_node_death(dlm, target, + DLM_NODE_DEATH_WAIT_MAX); goto leave; } diff --git a/trunk/fs/ocfs2/file.c b/trunk/fs/ocfs2/file.c index 41565ae52856..89659d6dc206 100644 --- a/trunk/fs/ocfs2/file.c +++ b/trunk/fs/ocfs2/file.c @@ -1607,6 +1607,9 @@ static void ocfs2_calc_trunc_pos(struct inode *inode, range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec); if (le32_to_cpu(rec->e_cpos) >= trunc_start) { + /* + * remove an entire extent record. + */ *trunc_cpos = le32_to_cpu(rec->e_cpos); /* * Skip holes if any. @@ -1617,7 +1620,16 @@ static void ocfs2_calc_trunc_pos(struct inode *inode, *blkno = le64_to_cpu(rec->e_blkno); *trunc_end = le32_to_cpu(rec->e_cpos); } else if (range > trunc_start) { + /* + * remove a partial extent record, which means we're + * removing the last extent record. + */ *trunc_cpos = trunc_start; + /* + * skip hole if any. + */ + if (range < *trunc_end) + *trunc_end = range; *trunc_len = *trunc_end - trunc_start; coff = trunc_start - le32_to_cpu(rec->e_cpos); *blkno = le64_to_cpu(rec->e_blkno) + diff --git a/trunk/fs/ocfs2/journal.c b/trunk/fs/ocfs2/journal.c index b141a44605ca..295d56454e8b 100644 --- a/trunk/fs/ocfs2/journal.c +++ b/trunk/fs/ocfs2/journal.c @@ -1260,6 +1260,9 @@ void ocfs2_complete_mount_recovery(struct ocfs2_super *osb) { struct ocfs2_journal *journal = osb->journal; + if (ocfs2_is_hard_readonly(osb)) + return; + /* No need to queue up our truncate_log as regular cleanup will catch * that */ ocfs2_queue_recovery_completion(journal, osb->slot_num, diff --git a/trunk/include/drm/drm_fb_helper.h b/trunk/include/drm/drm_fb_helper.h index ade09d7b4271..c99c3d3e7811 100644 --- a/trunk/include/drm/drm_fb_helper.h +++ b/trunk/include/drm/drm_fb_helper.h @@ -127,7 +127,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); -bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); +int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper); bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel); int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper); int drm_fb_helper_debug_enter(struct fb_info *info); diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index 16ee8b49a200..d4675af963fa 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -546,18 +546,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap); extern bool capable(int cap); extern bool ns_capable(struct user_namespace *ns, int cap); extern bool task_ns_capable(struct task_struct *t, int cap); - -/** - * nsown_capable - Check superior capability to one's own user_ns - * @cap: The capability in question - * - * Return true if the current task has the given superior capability - * targeted at its own user namespace. - */ -static inline bool nsown_capable(int cap) -{ - return ns_capable(current_user_ns(), cap); -} +extern bool nsown_capable(int cap); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); diff --git a/trunk/include/linux/cred.h b/trunk/include/linux/cred.h index 9aeeb0ba2003..be16b61283cc 100644 --- a/trunk/include/linux/cred.h +++ b/trunk/include/linux/cred.h @@ -146,6 +146,7 @@ struct cred { void *security; /* subjective LSM security */ #endif struct user_struct *user; /* real user ID subscription */ + struct user_namespace *user_ns; /* cached user->user_ns */ struct group_info *group_info; /* supplementary groups for euid/fsgid */ struct rcu_head rcu; /* RCU deletion hook */ }; @@ -354,10 +355,15 @@ static inline void put_cred(const struct cred *_cred) #define current_fsgid() (current_cred_xxx(fsgid)) #define current_cap() (current_cred_xxx(cap_effective)) #define current_user() (current_cred_xxx(user)) -#define _current_user_ns() (current_cred_xxx(user)->user_ns) #define current_security() (current_cred_xxx(security)) -extern struct user_namespace *current_user_ns(void); +#ifdef CONFIG_USER_NS +#define current_user_ns() (current_cred_xxx(user_ns)) +#else +extern struct user_namespace init_user_ns; +#define current_user_ns() (&init_user_ns) +#endif + #define current_uid_gid(_uid, _gid) \ do { \ diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index ab8dfc095709..d08399db6e2c 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -442,7 +442,6 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ - const struct of_device_id *of_match; /* matching of_device_id from driver */ dev_t devt; /* dev_t, creates the sysfs "dev" */ diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index df728c1c29ed..6a8274877171 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -832,6 +832,7 @@ struct fb_tile_ops { #define FBINFO_CAN_FORCE_OUTPUT 0x200000 struct fb_info { + atomic_t count; int node; int flags; struct mutex lock; /* Lock for open/release/ioctl funcs */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index dbd860af0804..cdf9495df204 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -358,7 +358,6 @@ struct inodes_stat_t { #define FS_EXTENT_FL 0x00080000 /* Extents */ #define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */ #define FS_NOCOW_FL 0x00800000 /* Do not cow file */ -#define FS_COW_FL 0x02000000 /* Cow file */ #define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */ #define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */ diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 8b4538446636..09a308072f56 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -53,13 +53,12 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * Bits which can be modified via irq_set/clear/modify_status_flags() * IRQ_LEVEL - Interrupt is level type. Will be also * updated in the code when the above trigger - * bits are modified via irq_set_irq_type() + * bits are modified via set_irq_type() * IRQ_PER_CPU - Mark an interrupt PER_CPU. Will protect * it from affinity setting * IRQ_NOPROBE - Interrupt cannot be probed by autoprobing * IRQ_NOREQUEST - Interrupt cannot be requested via * request_irq() - * IRQ_NOTHREAD - Interrupt cannot be threaded * IRQ_NOAUTOEN - Interrupt is not automatically enabled in * request/setup_irq() * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) @@ -86,7 +85,6 @@ enum { IRQ_NO_BALANCING = (1 << 13), IRQ_MOVE_PCNTXT = (1 << 14), IRQ_NESTED_THREAD = (1 << 15), - IRQ_NOTHREAD = (1 << 16), }; #define IRQF_MODIFY_MASK \ @@ -263,6 +261,23 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) * struct irq_chip - hardware interrupt chip descriptor * * @name: name for /proc/interrupts + * @startup: deprecated, replaced by irq_startup + * @shutdown: deprecated, replaced by irq_shutdown + * @enable: deprecated, replaced by irq_enable + * @disable: deprecated, replaced by irq_disable + * @ack: deprecated, replaced by irq_ack + * @mask: deprecated, replaced by irq_mask + * @mask_ack: deprecated, replaced by irq_mask_ack + * @unmask: deprecated, replaced by irq_unmask + * @eoi: deprecated, replaced by irq_eoi + * @end: deprecated, will go away with __do_IRQ() + * @set_affinity: deprecated, replaced by irq_set_affinity + * @retrigger: deprecated, replaced by irq_retrigger + * @set_type: deprecated, replaced by irq_set_type + * @set_wake: deprecated, replaced by irq_wake + * @bus_lock: deprecated, replaced by irq_bus_lock + * @bus_sync_unlock: deprecated, replaced by irq_bus_sync_unlock + * * @irq_startup: start up the interrupt (defaults to ->enable if NULL) * @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL) * @irq_enable: enable the interrupt (defaults to chip->unmask if NULL) @@ -280,9 +295,6 @@ static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d) * @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips * @irq_cpu_online: configure an interrupt source for a secondary CPU * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU - * @irq_suspend: function called from core code on suspend once per chip - * @irq_resume: function called from core code on resume once per chip - * @irq_pm_shutdown: function called from core code on shutdown once per chip * @irq_print_chip: optional to print special chip info in show_interrupts * @flags: chip specific flags * @@ -312,10 +324,6 @@ struct irq_chip { void (*irq_cpu_online)(struct irq_data *data); void (*irq_cpu_offline)(struct irq_data *data); - void (*irq_suspend)(struct irq_data *data); - void (*irq_resume)(struct irq_data *data); - void (*irq_pm_shutdown)(struct irq_data *data); - void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); unsigned long flags; @@ -431,7 +439,7 @@ irq_set_handler(unsigned int irq, irq_flow_handler_t handle) /* * Set a highlevel chained flow handler for a given IRQ. * (a chained handler is automatically enabled and set to - * IRQ_NOREQUEST, IRQ_NOPROBE, and IRQ_NOTHREAD) + * IRQ_NOREQUEST and IRQ_NOPROBE) */ static inline void irq_set_chained_handler(unsigned int irq, irq_flow_handler_t handle) @@ -461,16 +469,6 @@ static inline void irq_set_probe(unsigned int irq) irq_modify_status(irq, IRQ_NOPROBE, 0); } -static inline void irq_set_nothread(unsigned int irq) -{ - irq_modify_status(irq, 0, IRQ_NOTHREAD); -} - -static inline void irq_set_thread(unsigned int irq) -{ - irq_modify_status(irq, IRQ_NOTHREAD, 0); -} - static inline void irq_set_nested_thread(unsigned int irq, bool nest) { if (nest) @@ -575,145 +573,6 @@ static inline int irq_reserve_irq(unsigned int irq) return irq_reserve_irqs(irq, 1); } -#ifndef irq_reg_writel -# define irq_reg_writel(val, addr) writel(val, addr) -#endif -#ifndef irq_reg_readl -# define irq_reg_readl(addr) readl(addr) -#endif - -/** - * struct irq_chip_regs - register offsets for struct irq_gci - * @enable: Enable register offset to reg_base - * @disable: Disable register offset to reg_base - * @mask: Mask register offset to reg_base - * @ack: Ack register offset to reg_base - * @eoi: Eoi register offset to reg_base - * @type: Type configuration register offset to reg_base - * @polarity: Polarity configuration register offset to reg_base - */ -struct irq_chip_regs { - unsigned long enable; - unsigned long disable; - unsigned long mask; - unsigned long ack; - unsigned long eoi; - unsigned long type; - unsigned long polarity; -}; - -/** - * struct irq_chip_type - Generic interrupt chip instance for a flow type - * @chip: The real interrupt chip which provides the callbacks - * @regs: Register offsets for this chip - * @handler: Flow handler associated with this chip - * @type: Chip can handle these flow types - * - * A irq_generic_chip can have several instances of irq_chip_type when - * it requires different functions and register offsets for different - * flow types. - */ -struct irq_chip_type { - struct irq_chip chip; - struct irq_chip_regs regs; - irq_flow_handler_t handler; - u32 type; -}; - -/** - * struct irq_chip_generic - Generic irq chip data structure - * @lock: Lock to protect register and cache data access - * @reg_base: Register base address (virtual) - * @irq_base: Interrupt base nr for this chip - * @irq_cnt: Number of interrupts handled by this chip - * @mask_cache: Cached mask register - * @type_cache: Cached type register - * @polarity_cache: Cached polarity register - * @wake_enabled: Interrupt can wakeup from suspend - * @wake_active: Interrupt is marked as an wakeup from suspend source - * @num_ct: Number of available irq_chip_type instances (usually 1) - * @private: Private data for non generic chip callbacks - * @list: List head for keeping track of instances - * @chip_types: Array of interrupt irq_chip_types - * - * Note, that irq_chip_generic can have multiple irq_chip_type - * implementations which can be associated to a particular irq line of - * an irq_chip_generic instance. That allows to share and protect - * state in an irq_chip_generic instance when we need to implement - * different flow mechanisms (level/edge) for it. - */ -struct irq_chip_generic { - raw_spinlock_t lock; - void __iomem *reg_base; - unsigned int irq_base; - unsigned int irq_cnt; - u32 mask_cache; - u32 type_cache; - u32 polarity_cache; - u32 wake_enabled; - u32 wake_active; - unsigned int num_ct; - void *private; - struct list_head list; - struct irq_chip_type chip_types[0]; -}; - -/** - * enum irq_gc_flags - Initialization flags for generic irq chips - * @IRQ_GC_INIT_MASK_CACHE: Initialize the mask_cache by reading mask reg - * @IRQ_GC_INIT_NESTED_LOCK: Set the lock class of the irqs to nested for - * irq chips which need to call irq_set_wake() on - * the parent irq. Usually GPIO implementations - */ -enum irq_gc_flags { - IRQ_GC_INIT_MASK_CACHE = 1 << 0, - IRQ_GC_INIT_NESTED_LOCK = 1 << 1, -}; - -/* Generic chip callback functions */ -void irq_gc_noop(struct irq_data *d); -void irq_gc_mask_disable_reg(struct irq_data *d); -void irq_gc_mask_set_bit(struct irq_data *d); -void irq_gc_mask_clr_bit(struct irq_data *d); -void irq_gc_unmask_enable_reg(struct irq_data *d); -void irq_gc_ack(struct irq_data *d); -void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); -void irq_gc_eoi(struct irq_data *d); -int irq_gc_set_wake(struct irq_data *d, unsigned int on); - -/* Setup functions for irq_chip_generic */ -struct irq_chip_generic * -irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base, - void __iomem *reg_base, irq_flow_handler_t handler); -void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, - enum irq_gc_flags flags, unsigned int clr, - unsigned int set); -int irq_setup_alt_chip(struct irq_data *d, unsigned int type); -void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, - unsigned int clr, unsigned int set); - -static inline struct irq_chip_type *irq_data_get_chip_type(struct irq_data *d) -{ - return container_of(d->chip, struct irq_chip_type, chip); -} - -#define IRQ_MSK(n) (u32)((n) < 32 ? ((1 << (n)) - 1) : UINT_MAX) - -#ifdef CONFIG_SMP -static inline void irq_gc_lock(struct irq_chip_generic *gc) -{ - raw_spin_lock(&gc->lock); -} - -static inline void irq_gc_unlock(struct irq_chip_generic *gc) -{ - raw_spin_unlock(&gc->lock); -} -#else -static inline void irq_gc_lock(struct irq_chip_generic *gc) { } -static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } -#endif - #endif /* CONFIG_GENERIC_HARDIRQS */ #endif /* !CONFIG_S390 */ diff --git a/trunk/include/linux/irqdesc.h b/trunk/include/linux/irqdesc.h index c70b1aa4b93a..a082905b5ebe 100644 --- a/trunk/include/linux/irqdesc.h +++ b/trunk/include/linux/irqdesc.h @@ -16,18 +16,16 @@ struct timer_rand_state; * @irq_data: per irq and chip data passed down to chip functions * @timer_rand_state: pointer to timer rand state struct * @kstat_irqs: irq stats per cpu - * @handle_irq: highlevel irq-events handler - * @preflow_handler: handler called before the flow handler (currently used by sparc) + * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] * @action: the irq action chain * @status: status information * @core_internal_state__do_not_mess_with_it: core internal status information * @depth: disable-depth, for nested irq_disable() calls - * @wake_depth: enable depth, for multiple irq_set_irq_wake() callers + * @wake_depth: enable depth, for multiple set_irq_wake() callers * @irq_count: stats field to detect stalled irqs * @last_unhandled: aging timer for unhandled count * @irqs_unhandled: stats field for spurious unhandled interrupts * @lock: locking for SMP - * @affinity_hint: hint to user space for preferred irq affinity * @affinity_notify: context for notification of affinity changes * @pending_mask: pending rebalanced interrupts * @threads_oneshot: bitfield to handle shared oneshot threads diff --git a/trunk/include/linux/mmc/host.h b/trunk/include/linux/mmc/host.h index eb792cb6d745..bcb793ec7374 100644 --- a/trunk/include/linux/mmc/host.h +++ b/trunk/include/linux/mmc/host.h @@ -183,6 +183,7 @@ struct mmc_host { struct work_struct clk_gate_work; /* delayed clock gate */ unsigned int clk_old; /* old clock value cache */ spinlock_t clk_lock; /* lock for clk fields */ + struct mutex clk_gate_mutex; /* mutex for clock gating */ #endif /* host specific block data */ diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 890dce242639..7e371f7df9c4 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -233,6 +233,7 @@ struct nfs4_layoutget { struct nfs4_layoutget_args args; struct nfs4_layoutget_res res; struct pnfs_layout_segment **lsegpp; + gfp_t gfp_flags; }; struct nfs4_getdeviceinfo_args { diff --git a/trunk/include/linux/of_device.h b/trunk/include/linux/of_device.h index 8bfe6c1d4365..ae5638480ef2 100644 --- a/trunk/include/linux/of_device.h +++ b/trunk/include/linux/of_device.h @@ -21,8 +21,7 @@ extern void of_device_make_bus_id(struct device *dev); static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv) { - dev->of_match = of_match_device(drv->of_match_table, dev); - return dev->of_match != NULL; + return of_match_device(drv->of_match_table, dev) != NULL; } extern struct platform_device *of_dev_get(struct platform_device *dev); @@ -58,6 +57,11 @@ static inline int of_device_uevent(struct device *dev, static inline void of_device_node_put(struct device *dev) { } +static inline const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct device *dev) +{ + return NULL; +} #endif /* CONFIG_OF_DEVICE */ #endif /* _LINUX_OF_DEVICE_H */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index 838c1149251a..eaf4350c0f90 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -208,6 +208,8 @@ static inline struct proc_dir_entry *proc_symlink(const char *name, struct proc_dir_entry *parent,const char *dest) {return NULL;} static inline struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent) {return NULL;} +static inline struct proc_dir_entry *proc_mkdir_mode(const char *name, + mode_t mode, struct proc_dir_entry *parent) { return NULL; } static inline struct proc_dir_entry *create_proc_read_entry(const char *name, mode_t mode, struct proc_dir_entry *base, diff --git a/trunk/include/net/inet_ecn.h b/trunk/include/net/inet_ecn.h index 88bdd010d65d..2fa8d1341a0a 100644 --- a/trunk/include/net/inet_ecn.h +++ b/trunk/include/net/inet_ecn.h @@ -38,9 +38,19 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) return outer; } -#define INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0) -#define INET_ECN_dontxmit(sk) \ - do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0) +static inline void INET_ECN_xmit(struct sock *sk) +{ + inet_sk(sk)->tos |= INET_ECN_ECT_0; + if (inet6_sk(sk) != NULL) + inet6_sk(sk)->tclass |= INET_ECN_ECT_0; +} + +static inline void INET_ECN_dontxmit(struct sock *sk) +{ + inet_sk(sk)->tos &= ~INET_ECN_MASK; + if (inet6_sk(sk) != NULL) + inet6_sk(sk)->tclass &= ~INET_ECN_MASK; +} #define IP6_ECN_flow_init(label) do { \ (label) &= ~htonl(INET_ECN_MASK << 20); \ diff --git a/trunk/include/net/llc_pdu.h b/trunk/include/net/llc_pdu.h index 75b8e2968c9b..f57e7d46a453 100644 --- a/trunk/include/net/llc_pdu.h +++ b/trunk/include/net/llc_pdu.h @@ -199,7 +199,7 @@ struct llc_pdu_sn { u8 ssap; u8 ctrl_1; u8 ctrl_2; -}; +} __packed; static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb) { @@ -211,7 +211,7 @@ struct llc_pdu_un { u8 dsap; u8 ssap; u8 ctrl_1; -}; +} __packed; static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb) { @@ -359,7 +359,7 @@ struct llc_xid_info { u8 fmt_id; /* always 0x81 for LLC */ u8 type; /* different if NULL/non-NULL LSAP */ u8 rw; /* sender receive window */ -}; +} __packed; /** * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID @@ -415,7 +415,7 @@ struct llc_frmr_info { u8 curr_ssv; /* current send state variable val */ u8 curr_rsv; /* current receive state variable */ u8 ind_bits; /* indicator bits set with macro */ -}; +} __packed; extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type); extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value); diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index 2d3ec5094685..dd82e02ddde3 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -169,6 +169,7 @@ struct scsi_device { sdev_dev; struct execute_work ew; /* used to get process context on put */ + struct work_struct requeue_work; struct scsi_dh_data *scsi_dh_data; enum scsi_device_state sdev_state; diff --git a/trunk/kernel/capability.c b/trunk/kernel/capability.c index bf0c734d0c12..32a80e08ff4b 100644 --- a/trunk/kernel/capability.c +++ b/trunk/kernel/capability.c @@ -399,3 +399,15 @@ bool task_ns_capable(struct task_struct *t, int cap) return ns_capable(task_cred_xxx(t, user)->user_ns, cap); } EXPORT_SYMBOL(task_ns_capable); + +/** + * nsown_capable - Check superior capability to one's own user_ns + * @cap: The capability in question + * + * Return true if the current task has the given superior capability + * targeted at its own user namespace. + */ +bool nsown_capable(int cap) +{ + return ns_capable(current_user_ns(), cap); +} diff --git a/trunk/kernel/cred.c b/trunk/kernel/cred.c index 5557b55048df..8093c16b84b1 100644 --- a/trunk/kernel/cred.c +++ b/trunk/kernel/cred.c @@ -54,6 +54,7 @@ struct cred init_cred = { .cap_effective = CAP_INIT_EFF_SET, .cap_bset = CAP_INIT_BSET, .user = INIT_USER, + .user_ns = &init_user_ns, .group_info = &init_groups, #ifdef CONFIG_KEYS .tgcred = &init_tgcred, @@ -410,6 +411,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) goto error_put; } + /* cache user_ns in cred. Doesn't need a refcount because it will + * stay pinned by cred->user + */ + new->user_ns = new->user->user_ns; + #ifdef CONFIG_KEYS /* new threads get their own thread keyrings if their parent already * had one */ @@ -741,12 +747,6 @@ int set_create_files_as(struct cred *new, struct inode *inode) } EXPORT_SYMBOL(set_create_files_as); -struct user_namespace *current_user_ns(void) -{ - return _current_user_ns(); -} -EXPORT_SYMBOL(current_user_ns); - #ifdef CONFIG_DEBUG_CREDENTIALS bool creds_are_invalid(const struct cred *cred) diff --git a/trunk/kernel/irq/Makefile b/trunk/kernel/irq/Makefile index e7a13bd3316a..54329cd7b3ee 100644 --- a/trunk/kernel/irq/Makefile +++ b/trunk/kernel/irq/Makefile @@ -1,6 +1,5 @@ obj-y := irqdesc.o handle.o manage.o spurious.o resend.o chip.o dummychip.o devres.o -obj-y += generic-chip.o obj-$(CONFIG_GENERIC_IRQ_PROBE) += autoprobe.o obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_GENERIC_PENDING_IRQ) += migration.o diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 52d856d513ff..4af1e2b244cb 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -573,7 +573,6 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, if (handle != handle_bad_irq && is_chained) { irq_settings_set_noprobe(desc); irq_settings_set_norequest(desc); - irq_settings_set_nothread(desc); irq_startup(desc); } out: diff --git a/trunk/kernel/irq/debug.h b/trunk/kernel/irq/debug.h index 97a8bfadc88a..306cba37e9a5 100644 --- a/trunk/kernel/irq/debug.h +++ b/trunk/kernel/irq/debug.h @@ -27,7 +27,6 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) P(IRQ_PER_CPU); P(IRQ_NOPROBE); P(IRQ_NOREQUEST); - P(IRQ_NOTHREAD); P(IRQ_NOAUTOEN); PS(IRQS_AUTODETECT); diff --git a/trunk/kernel/irq/generic-chip.c b/trunk/kernel/irq/generic-chip.c deleted file mode 100644 index 31a9db711906..000000000000 --- a/trunk/kernel/irq/generic-chip.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Library implementing the most common irq chip callback functions - * - * Copyright (C) 2011, Thomas Gleixner - */ -#include -#include -#include -#include -#include -#include - -#include "internals.h" - -static LIST_HEAD(gc_list); -static DEFINE_RAW_SPINLOCK(gc_lock); - -static inline struct irq_chip_regs *cur_regs(struct irq_data *d) -{ - return &container_of(d->chip, struct irq_chip_type, chip)->regs; -} - -/** - * irq_gc_noop - NOOP function - * @d: irq_data - */ -void irq_gc_noop(struct irq_data *d) -{ -} - -/** - * irq_gc_mask_disable_reg - Mask chip via disable register - * @d: irq_data - * - * Chip has separate enable/disable registers instead of a single mask - * register. - */ -void irq_gc_mask_disable_reg(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->disable); - gc->mask_cache &= ~mask; - irq_gc_unlock(gc); -} - -/** - * irq_gc_mask_set_mask_bit - Mask chip via setting bit in mask register - * @d: irq_data - * - * Chip has a single mask register. Values of this register are cached - * and protected by gc->lock - */ -void irq_gc_mask_set_bit(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - gc->mask_cache |= mask; - irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); - irq_gc_unlock(gc); -} - -/** - * irq_gc_mask_set_mask_bit - Mask chip via clearing bit in mask register - * @d: irq_data - * - * Chip has a single mask register. Values of this register are cached - * and protected by gc->lock - */ -void irq_gc_mask_clr_bit(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - gc->mask_cache &= ~mask; - irq_reg_writel(gc->mask_cache, gc->reg_base + cur_regs(d)->mask); - irq_gc_unlock(gc); -} - -/** - * irq_gc_unmask_enable_reg - Unmask chip via enable register - * @d: irq_data - * - * Chip has separate enable/disable registers instead of a single mask - * register. - */ -void irq_gc_unmask_enable_reg(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->enable); - gc->mask_cache |= mask; - irq_gc_unlock(gc); -} - -/** - * irq_gc_ack - Ack pending interrupt - * @d: irq_data - */ -void irq_gc_ack(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); - irq_gc_unlock(gc); -} - -/** - * irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt - * @d: irq_data - */ -void irq_gc_mask_disable_reg_and_ack(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->mask); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); - irq_gc_unlock(gc); -} - -/** - * irq_gc_eoi - EOI interrupt - * @d: irq_data - */ -void irq_gc_eoi(struct irq_data *d) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - irq_gc_lock(gc); - irq_reg_writel(mask, gc->reg_base + cur_regs(d)->eoi); - irq_gc_unlock(gc); -} - -/** - * irq_gc_set_wake - Set/clr wake bit for an interrupt - * @d: irq_data - * - * For chips where the wake from suspend functionality is not - * configured in a separate register and the wakeup active state is - * just stored in a bitmask. - */ -int irq_gc_set_wake(struct irq_data *d, unsigned int on) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - u32 mask = 1 << (d->irq - gc->irq_base); - - if (!(mask & gc->wake_enabled)) - return -EINVAL; - - irq_gc_lock(gc); - if (on) - gc->wake_active |= mask; - else - gc->wake_active &= ~mask; - irq_gc_unlock(gc); - return 0; -} - -/** - * irq_alloc_generic_chip - Allocate a generic chip and initialize it - * @name: Name of the irq chip - * @num_ct: Number of irq_chip_type instances associated with this - * @irq_base: Interrupt base nr for this chip - * @reg_base: Register base address (virtual) - * @handler: Default flow handler associated with this chip - * - * Returns an initialized irq_chip_generic structure. The chip defaults - * to the primary (index 0) irq_chip_type and @handler - */ -struct irq_chip_generic * -irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base, - void __iomem *reg_base, irq_flow_handler_t handler) -{ - struct irq_chip_generic *gc; - unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type); - - gc = kzalloc(sz, GFP_KERNEL); - if (gc) { - raw_spin_lock_init(&gc->lock); - gc->num_ct = num_ct; - gc->irq_base = irq_base; - gc->reg_base = reg_base; - gc->chip_types->chip.name = name; - gc->chip_types->handler = handler; - } - return gc; -} - -/* - * Separate lockdep class for interrupt chip which can nest irq_desc - * lock. - */ -static struct lock_class_key irq_nested_lock_class; - -/** - * irq_setup_generic_chip - Setup a range of interrupts with a generic chip - * @gc: Generic irq chip holding all data - * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base - * @flags: Flags for initialization - * @clr: IRQ_* bits to clear - * @set: IRQ_* bits to set - * - * Set up max. 32 interrupts starting from gc->irq_base. Note, this - * initializes all interrupts to the primary irq_chip_type and its - * associated handler. - */ -void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk, - enum irq_gc_flags flags, unsigned int clr, - unsigned int set) -{ - struct irq_chip_type *ct = gc->chip_types; - unsigned int i; - - raw_spin_lock(&gc_lock); - list_add_tail(&gc->list, &gc_list); - raw_spin_unlock(&gc_lock); - - /* Init mask cache ? */ - if (flags & IRQ_GC_INIT_MASK_CACHE) - gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask); - - for (i = gc->irq_base; msk; msk >>= 1, i++) { - if (!msk & 0x01) - continue; - - if (flags & IRQ_GC_INIT_NESTED_LOCK) - irq_set_lockdep_class(i, &irq_nested_lock_class); - - irq_set_chip_and_handler(i, &ct->chip, ct->handler); - irq_set_chip_data(i, gc); - irq_modify_status(i, clr, set); - } - gc->irq_cnt = i - gc->irq_base; -} - -/** - * irq_setup_alt_chip - Switch to alternative chip - * @d: irq_data for this interrupt - * @type Flow type to be initialized - * - * Only to be called from chip->irq_set_type() callbacks. - */ -int irq_setup_alt_chip(struct irq_data *d, unsigned int type) -{ - struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - struct irq_chip_type *ct = gc->chip_types; - unsigned int i; - - for (i = 0; i < gc->num_ct; i++, ct++) { - if (ct->type & type) { - d->chip = &ct->chip; - irq_data_to_desc(d)->handle_irq = ct->handler; - return 0; - } - } - return -EINVAL; -} - -/** - * irq_remove_generic_chip - Remove a chip - * @gc: Generic irq chip holding all data - * @msk: Bitmask holding the irqs to initialize relative to gc->irq_base - * @clr: IRQ_* bits to clear - * @set: IRQ_* bits to set - * - * Remove up to 32 interrupts starting from gc->irq_base. - */ -void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk, - unsigned int clr, unsigned int set) -{ - unsigned int i = gc->irq_base; - - raw_spin_lock(&gc_lock); - list_del(&gc->list); - raw_spin_unlock(&gc_lock); - - for (; msk; msk >>= 1, i++) { - if (!msk & 0x01) - continue; - - /* Remove handler first. That will mask the irq line */ - irq_set_handler(i, NULL); - irq_set_chip(i, &no_irq_chip); - irq_set_chip_data(i, NULL); - irq_modify_status(i, clr, set); - } -} - -#ifdef CONFIG_PM -static int irq_gc_suspend(void) -{ - struct irq_chip_generic *gc; - - list_for_each_entry(gc, &gc_list, list) { - struct irq_chip_type *ct = gc->chip_types; - - if (ct->chip.irq_suspend) - ct->chip.irq_suspend(irq_get_irq_data(gc->irq_base)); - } - return 0; -} - -static void irq_gc_resume(void) -{ - struct irq_chip_generic *gc; - - list_for_each_entry(gc, &gc_list, list) { - struct irq_chip_type *ct = gc->chip_types; - - if (ct->chip.irq_resume) - ct->chip.irq_resume(irq_get_irq_data(gc->irq_base)); - } -} -#else -#define irq_gc_suspend NULL -#define irq_gc_resume NULL -#endif - -static void irq_gc_shutdown(void) -{ - struct irq_chip_generic *gc; - - list_for_each_entry(gc, &gc_list, list) { - struct irq_chip_type *ct = gc->chip_types; - - if (ct->chip.irq_pm_shutdown) - ct->chip.irq_pm_shutdown(irq_get_irq_data(gc->irq_base)); - } -} - -static struct syscore_ops irq_gc_syscore_ops = { - .suspend = irq_gc_suspend, - .resume = irq_gc_resume, - .shutdown = irq_gc_shutdown, -}; - -static int __init irq_gc_init_ops(void) -{ - register_syscore_ops(&irq_gc_syscore_ops); - return 0; -} -device_initcall(irq_gc_init_ops); diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index f7ce0021e1c4..07c1611f3899 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -900,8 +900,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ new->handler = irq_nested_primary_handler; } else { - if (irq_settings_can_thread(desc)) - irq_setup_forced_threading(new); + irq_setup_forced_threading(new); } /* diff --git a/trunk/kernel/irq/settings.h b/trunk/kernel/irq/settings.h index f1667833d444..0d91730b6330 100644 --- a/trunk/kernel/irq/settings.h +++ b/trunk/kernel/irq/settings.h @@ -8,7 +8,6 @@ enum { _IRQ_LEVEL = IRQ_LEVEL, _IRQ_NOPROBE = IRQ_NOPROBE, _IRQ_NOREQUEST = IRQ_NOREQUEST, - _IRQ_NOTHREAD = IRQ_NOTHREAD, _IRQ_NOAUTOEN = IRQ_NOAUTOEN, _IRQ_MOVE_PCNTXT = IRQ_MOVE_PCNTXT, _IRQ_NO_BALANCING = IRQ_NO_BALANCING, @@ -21,7 +20,6 @@ enum { #define IRQ_LEVEL GOT_YOU_MORON #define IRQ_NOPROBE GOT_YOU_MORON #define IRQ_NOREQUEST GOT_YOU_MORON -#define IRQ_NOTHREAD GOT_YOU_MORON #define IRQ_NOAUTOEN GOT_YOU_MORON #define IRQ_NESTED_THREAD GOT_YOU_MORON #undef IRQF_MODIFY_MASK @@ -96,21 +94,6 @@ static inline void irq_settings_set_norequest(struct irq_desc *desc) desc->status_use_accessors |= _IRQ_NOREQUEST; } -static inline bool irq_settings_can_thread(struct irq_desc *desc) -{ - return !(desc->status_use_accessors & _IRQ_NOTHREAD); -} - -static inline void irq_settings_clr_nothread(struct irq_desc *desc) -{ - desc->status_use_accessors &= ~_IRQ_NOTHREAD; -} - -static inline void irq_settings_set_nothread(struct irq_desc *desc) -{ - desc->status_use_accessors |= _IRQ_NOTHREAD; -} - static inline bool irq_settings_can_probe(struct irq_desc *desc) { return !(desc->status_use_accessors & _IRQ_NOPROBE); diff --git a/trunk/kernel/time/clocksource.c b/trunk/kernel/time/clocksource.c index 6519cf62d9cd..0e17c10f8a9d 100644 --- a/trunk/kernel/time/clocksource.c +++ b/trunk/kernel/time/clocksource.c @@ -685,8 +685,8 @@ int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) /* Add clocksource to the clcoksource list */ mutex_lock(&clocksource_mutex); clocksource_enqueue(cs); - clocksource_select(); clocksource_enqueue_watchdog(cs); + clocksource_select(); mutex_unlock(&clocksource_mutex); return 0; } @@ -706,8 +706,8 @@ int clocksource_register(struct clocksource *cs) mutex_lock(&clocksource_mutex); clocksource_enqueue(cs); - clocksource_select(); clocksource_enqueue_watchdog(cs); + clocksource_select(); mutex_unlock(&clocksource_mutex); return 0; } diff --git a/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index da800ffa810c..723c7637e55a 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/kernel/time/tick-broadcast.c @@ -522,10 +522,11 @@ static void tick_broadcast_init_next_event(struct cpumask *mask, */ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { + int cpu = smp_processor_id(); + /* Set it up only once ! */ if (bc->event_handler != tick_handle_oneshot_broadcast) { int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; - int cpu = smp_processor_id(); bc->event_handler = tick_handle_oneshot_broadcast; clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); @@ -551,6 +552,15 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) tick_broadcast_set_event(tick_next_period, 1); } else bc->next_event.tv64 = KTIME_MAX; + } else { + /* + * The first cpu which switches to oneshot mode sets + * the bit for all other cpus which are in the general + * (periodic) broadcast mask. So the bit is set and + * would prevent the first broadcast enter after this + * to program the bc device. + */ + tick_broadcast_clear_oneshot(cpu); } } diff --git a/trunk/lib/vsprintf.c b/trunk/lib/vsprintf.c index bc0ac6b333dc..dfd60192bc2e 100644 --- a/trunk/lib/vsprintf.c +++ b/trunk/lib/vsprintf.c @@ -797,7 +797,7 @@ char *uuid_string(char *buf, char *end, const u8 *addr, return string(buf, end, uuid, spec); } -int kptr_restrict = 1; +int kptr_restrict __read_mostly; /* * Show a '%p' thing. A kernel extension is that the '%p' is followed diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 570d944daeb5..3f8bce264df6 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -2358,6 +2358,7 @@ EXPORT_SYMBOL(alloc_pages_exact); /** * alloc_pages_exact_nid - allocate an exact number of physically-contiguous * pages on a node. + * @nid: the preferred node ID where memory should be allocated * @size: the number of bytes to allocate * @gfp_mask: GFP flags for the allocation * diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 9e755c166cc5..dfc7069102ee 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -1037,7 +1037,6 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) struct address_space *mapping; unsigned long index; struct inode *inode; - bool unlock_mutex = false; BUG_ON(!PageLocked(page)); mapping = page->mapping; @@ -1072,15 +1071,14 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) * we've taken the spinlock, because shmem_unuse_inode() will * prune a !swapped inode from the swaplist under both locks. */ - if (swap.val && list_empty(&info->swaplist)) { + if (swap.val) { mutex_lock(&shmem_swaplist_mutex); - /* move instead of add in case we're racing */ - list_move_tail(&info->swaplist, &shmem_swaplist); - unlock_mutex = true; + if (list_empty(&info->swaplist)) + list_add_tail(&info->swaplist, &shmem_swaplist); } spin_lock(&info->lock); - if (unlock_mutex) + if (swap.val) mutex_unlock(&shmem_swaplist_mutex); if (index >= info->next_index) { diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index f6b435c80079..8bfd45050a61 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -937,7 +937,7 @@ static unsigned long shrink_page_list(struct list_head *page_list, * back off and wait for congestion to clear because further reclaim * will encounter the same problem */ - if (nr_dirty == nr_congested && nr_dirty != 0) + if (nr_dirty && nr_dirty == nr_congested && scanning_global_lru(sc)) zone_set_flag(zone, ZONE_CONGESTED); free_page_list(&free_pages); diff --git a/trunk/net/9p/protocol.c b/trunk/net/9p/protocol.c index b58a501cf3d1..a873277cb996 100644 --- a/trunk/net/9p/protocol.c +++ b/trunk/net/9p/protocol.c @@ -674,6 +674,7 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, } strcpy(dirent->d_name, nameptr); + kfree(nameptr); out: return fake_pdu.offset; diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index f3bc322c5891..74ef4d4846a4 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -737,7 +737,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, nf_bridge->mask |= BRNF_PKT_TYPE; } - if (br_parse_ip_options(skb)) + if (pf == PF_INET && br_parse_ip_options(skb)) return NF_DROP; /* The physdev module checks on this */ diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 92009440d28b..b624fe4d9bd7 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -5186,27 +5186,27 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) /* Fix illegal checksum combinations */ if ((features & NETIF_F_HW_CSUM) && (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - netdev_info(dev, "mixed HW and IP checksum settings.\n"); + netdev_warn(dev, "mixed HW and IP checksum settings.\n"); features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); } if ((features & NETIF_F_NO_CSUM) && (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - netdev_info(dev, "mixed no checksumming and other settings.\n"); + netdev_warn(dev, "mixed no checksumming and other settings.\n"); features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); } /* Fix illegal SG+CSUM combinations. */ if ((features & NETIF_F_SG) && !(features & NETIF_F_ALL_CSUM)) { - netdev_info(dev, - "Dropping NETIF_F_SG since no checksum feature.\n"); + netdev_dbg(dev, + "Dropping NETIF_F_SG since no checksum feature.\n"); features &= ~NETIF_F_SG; } /* TSO requires that SG is present as well. */ if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { - netdev_info(dev, "Dropping TSO features since no SG feature.\n"); + netdev_dbg(dev, "Dropping TSO features since no SG feature.\n"); features &= ~NETIF_F_ALL_TSO; } @@ -5216,7 +5216,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) /* Software GSO depends on SG. */ if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { - netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); + netdev_dbg(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); features &= ~NETIF_F_GSO; } @@ -5226,13 +5226,13 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) if (!((features & NETIF_F_GEN_CSUM) || (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { - netdev_info(dev, + netdev_dbg(dev, "Dropping NETIF_F_UFO since no checksum offload features.\n"); features &= ~NETIF_F_UFO; } if (!(features & NETIF_F_SG)) { - netdev_info(dev, + netdev_dbg(dev, "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); features &= ~NETIF_F_UFO; } @@ -5414,12 +5414,6 @@ int register_netdevice(struct net_device *dev) dev->features |= NETIF_F_SOFT_FEATURES; dev->wanted_features = dev->features & dev->hw_features; - /* Avoid warning from netdev_fix_features() for GSO without SG */ - if (!(dev->wanted_features & NETIF_F_SG)) { - dev->wanted_features &= ~NETIF_F_GSO; - dev->features &= ~NETIF_F_GSO; - } - /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, * vlan_dev_init() will do the dev->features check, so these features * are enabled only if supported by underlying device. diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index ce4596ed1268..bd1224fd216a 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -237,6 +237,10 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) &local->dynamic_ps_disable_work); } + /* Don't restart the timer if we're not disassociated */ + if (!ifmgd->associated) + return TX_CONTINUE; + mod_timer(&local->dynamic_ps_timer, jiffies + msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); diff --git a/trunk/net/netfilter/ipvs/ip_vs_app.c b/trunk/net/netfilter/ipvs/ip_vs_app.c index 51f3af7c4743..059af3120be7 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_app.c +++ b/trunk/net/netfilter/ipvs/ip_vs_app.c @@ -572,7 +572,7 @@ static const struct file_operations ip_vs_app_fops = { .open = ip_vs_app_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; #endif diff --git a/trunk/net/netfilter/ipvs/ip_vs_conn.c b/trunk/net/netfilter/ipvs/ip_vs_conn.c index d3fd91bbba49..bf28ac2fc99b 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_conn.c +++ b/trunk/net/netfilter/ipvs/ip_vs_conn.c @@ -1046,7 +1046,7 @@ static const struct file_operations ip_vs_conn_fops = { .open = ip_vs_conn_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; static const char *ip_vs_origin_name(unsigned flags) @@ -1114,7 +1114,7 @@ static const struct file_operations ip_vs_conn_sync_fops = { .open = ip_vs_conn_sync_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; #endif diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index ea722810faf3..37890f228b19 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -2066,7 +2066,7 @@ static const struct file_operations ip_vs_info_fops = { .open = ip_vs_info_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release_private, + .release = seq_release_net, }; #endif @@ -2109,7 +2109,7 @@ static const struct file_operations ip_vs_stats_fops = { .open = ip_vs_stats_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) @@ -2178,7 +2178,7 @@ static const struct file_operations ip_vs_stats_percpu_fops = { .open = ip_vs_stats_percpu_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; #endif diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index e6e7ce0d3d55..7102457661d6 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -1819,8 +1819,6 @@ static int filename_trans_read(struct policydb *p, void *fp) goto out; nel = le32_to_cpu(buf[0]); - printk(KERN_ERR "%s: nel=%d\n", __func__, nel); - last = p->filename_trans; while (last && last->next) last = last->next; @@ -1857,8 +1855,6 @@ static int filename_trans_read(struct policydb *p, void *fp) goto out; name[len] = 0; - printk(KERN_ERR "%s: ft=%p ft->name=%p ft->name=%s\n", __func__, ft, ft->name, ft->name); - rc = next_entry(buf, fp, sizeof(u32) * 4); if (rc) goto out; diff --git a/trunk/sound/soc/codecs/ssm2602.c b/trunk/sound/soc/codecs/ssm2602.c index 2727befd158e..b04d28039c16 100644 --- a/trunk/sound/soc/codecs/ssm2602.c +++ b/trunk/sound/soc/codecs/ssm2602.c @@ -139,7 +139,7 @@ SOC_DOUBLE_R("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 31, 0), SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0), -SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 7, 1, 0), +SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0), SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1), SOC_SINGLE("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1), @@ -602,7 +602,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { .read = ssm2602_read_reg_cache, .write = ssm2602_write, .set_bias_level = ssm2602_set_bias_level, - .reg_cache_size = sizeof(ssm2602_reg), + .reg_cache_size = ARRAY_SIZE(ssm2602_reg), .reg_word_size = sizeof(u16), .reg_cache_default = ssm2602_reg, }; @@ -614,7 +614,7 @@ static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { * low = 0x1a * high = 0x1b */ -static int ssm2602_i2c_probe(struct i2c_client *i2c, +static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct ssm2602_priv *ssm2602; @@ -635,7 +635,7 @@ static int ssm2602_i2c_probe(struct i2c_client *i2c, return ret; } -static int ssm2602_i2c_remove(struct i2c_client *client) +static int __devexit ssm2602_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); kfree(i2c_get_clientdata(client)); @@ -655,7 +655,7 @@ static struct i2c_driver ssm2602_i2c_driver = { .owner = THIS_MODULE, }, .probe = ssm2602_i2c_probe, - .remove = ssm2602_i2c_remove, + .remove = __devexit_p(ssm2602_i2c_remove), .id_table = ssm2602_i2c_id, }; #endif diff --git a/trunk/sound/soc/codecs/uda134x.c b/trunk/sound/soc/codecs/uda134x.c index 48ffd406a71d..a7b8f301bad3 100644 --- a/trunk/sound/soc/codecs/uda134x.c +++ b/trunk/sound/soc/codecs/uda134x.c @@ -601,9 +601,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .reg_cache_step = 1, .read = uda134x_read_reg_cache, .write = uda134x_write, -#ifdef POWER_OFF_ON_STANDBY .set_bias_level = uda134x_set_bias_level, -#endif }; static int __devinit uda134x_codec_probe(struct platform_device *pdev) diff --git a/trunk/sound/soc/codecs/wm8903.c b/trunk/sound/soc/codecs/wm8903.c index f52b623bb692..824d1c8c8a35 100644 --- a/trunk/sound/soc/codecs/wm8903.c +++ b/trunk/sound/soc/codecs/wm8903.c @@ -692,7 +692,7 @@ SOC_ENUM("DRC Smoothing Threshold", drc_smoothing), SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, - WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), + WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), SOC_ENUM("ADC Companding Mode", adc_companding), SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), diff --git a/trunk/sound/soc/jz4740/jz4740-i2s.c b/trunk/sound/soc/jz4740/jz4740-i2s.c index 419bf4f5534a..cd22a54b2f14 100644 --- a/trunk/sound/soc/jz4740/jz4740-i2s.c +++ b/trunk/sound/soc/jz4740/jz4740-i2s.c @@ -133,7 +133,7 @@ static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream, struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; - if (!dai->active) + if (dai->active) return; conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); diff --git a/trunk/sound/soc/mid-x86/sst_platform.c b/trunk/sound/soc/mid-x86/sst_platform.c index d567c322a2fb..6b1f9d3bf34e 100644 --- a/trunk/sound/soc/mid-x86/sst_platform.c +++ b/trunk/sound/soc/mid-x86/sst_platform.c @@ -376,6 +376,11 @@ static int sst_platform_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } +static int sst_platform_pcm_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + static struct snd_pcm_ops sst_platform_ops = { .open = sst_platform_open, .close = sst_platform_close, @@ -384,6 +389,7 @@ static struct snd_pcm_ops sst_platform_ops = { .trigger = sst_platform_pcm_trigger, .pointer = sst_platform_pcm_pointer, .hw_params = sst_platform_pcm_hw_params, + .hw_free = sst_platform_pcm_hw_free, }; static void sst_pcm_free(struct snd_pcm *pcm) diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index 99054cf1f68f..b5922984eac6 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -65,6 +65,14 @@ config SND_OMAP_SOC_OVERO Say Y if you want to add support for SoC audio on the Gumstix Overo or CompuLab CM-T35 +config SND_OMAP_SOC_OMAP2EVM + tristate "SoC Audio support for OMAP2EVM board" + depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM + select SND_OMAP_SOC_MCBSP + select SND_SOC_TWL4030 + help + Say Y if you want to add support for SoC audio on the omap2evm board. + config SND_OMAP_SOC_OMAP3EVM tristate "SoC Audio support for OMAP3EVM board" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM diff --git a/trunk/sound/soc/omap/Makefile b/trunk/sound/soc/omap/Makefile index 6c2c87eed5bb..ba9fc650db28 100644 --- a/trunk/sound/soc/omap/Makefile +++ b/trunk/sound/soc/omap/Makefile @@ -13,6 +13,7 @@ snd-soc-rx51-objs := rx51.o snd-soc-ams-delta-objs := ams-delta.o snd-soc-osk5912-objs := osk5912.o snd-soc-overo-objs := overo.o +snd-soc-omap2evm-objs := omap2evm.o snd-soc-omap3evm-objs := omap3evm.o snd-soc-am3517evm-objs := am3517evm.o snd-soc-sdp3430-objs := sdp3430.o diff --git a/trunk/sound/soc/omap/omap2evm.c b/trunk/sound/soc/omap/omap2evm.c new file mode 100644 index 000000000000..29b60d6796e7 --- /dev/null +++ b/trunk/sound/soc/omap/omap2evm.c @@ -0,0 +1,139 @@ +/* + * omap2evm.c -- SoC audio machine driver for omap2evm board + * + * Author: Arun KS + * + * Based on sound/soc/omap/overo.c by Steve Sakoman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "omap-mcbsp.h" +#include "omap-pcm.h" + +static int omap2evm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + + /* Set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) { + printk(KERN_ERR "can't set codec DAI configuration\n"); + return ret; + } + + /* Set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) { + printk(KERN_ERR "can't set cpu DAI configuration\n"); + return ret; + } + + /* Set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, + SND_SOC_CLOCK_IN); + if (ret < 0) { + printk(KERN_ERR "can't set codec system clock\n"); + return ret; + } + + return 0; +} + +static struct snd_soc_ops omap2evm_ops = { + .hw_params = omap2evm_hw_params, +}; + +/* Digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link omap2evm_dai = { + .name = "TWL4030", + .stream_name = "TWL4030", + .cpu_dai_name = "omap-mcbsp-dai.1", + .codec_dai_name = "twl4030-hifi", + .platform_name = "omap-pcm-audio", + .codec_name = "twl4030-codec", + .ops = &omap2evm_ops, +}; + +/* Audio machine driver */ +static struct snd_soc_card snd_soc_omap2evm = { + .name = "omap2evm", + .dai_link = &omap2evm_dai, + .num_links = 1, +}; + +static struct platform_device *omap2evm_snd_device; + +static int __init omap2evm_soc_init(void) +{ + int ret; + + if (!machine_is_omap2evm()) + return -ENODEV; + printk(KERN_INFO "omap2evm SoC init\n"); + + omap2evm_snd_device = platform_device_alloc("soc-audio", -1); + if (!omap2evm_snd_device) { + printk(KERN_ERR "Platform device allocation failed\n"); + return -ENOMEM; + } + + platform_set_drvdata(omap2evm_snd_device, &snd_soc_omap2evm); + + ret = platform_device_add(omap2evm_snd_device); + if (ret) + goto err1; + + return 0; + +err1: + printk(KERN_ERR "Unable to add platform device\n"); + platform_device_put(omap2evm_snd_device); + + return ret; +} +module_init(omap2evm_soc_init); + +static void __exit omap2evm_soc_exit(void) +{ + platform_device_unregister(omap2evm_snd_device); +} +module_exit(omap2evm_soc_exit); + +MODULE_AUTHOR("Arun KS "); +MODULE_DESCRIPTION("ALSA SoC omap2evm"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index d8562ce4de7a..dd55d1069468 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -3291,6 +3291,8 @@ int snd_soc_register_card(struct snd_soc_card *card) if (!card->name || !card->dev) return -EINVAL; + dev_set_drvdata(card->dev, card); + snd_soc_initialize_card_lists(card); soc_init_card_debugfs(card); diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index 416538248a4b..0974f957b8fa 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -427,7 +427,7 @@ static void mmap_read_all(void) { int i; - for (i = 0; i < evsel_list->cpus->nr; i++) { + for (i = 0; i < evsel_list->nr_mmaps; i++) { if (evsel_list->mmap[i].base) mmap_read(&evsel_list->mmap[i]); } diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 11e3c8458362..2f9a337b182f 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -549,7 +549,7 @@ static int test__basic_mmap(void) ++foo; } - while ((event = perf_evlist__read_on_cpu(evlist, 0)) != NULL) { + while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { struct perf_sample sample; if (event->header.type != PERF_RECORD_SAMPLE) { diff --git a/trunk/tools/perf/builtin-top.c b/trunk/tools/perf/builtin-top.c index 7e3d6e310bf8..ebfc7cf5f63b 100644 --- a/trunk/tools/perf/builtin-top.c +++ b/trunk/tools/perf/builtin-top.c @@ -801,12 +801,12 @@ static void perf_event__process_sample(const union perf_event *event, } } -static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu) +static void perf_session__mmap_read_idx(struct perf_session *self, int idx) { struct perf_sample sample; union perf_event *event; - while ((event = perf_evlist__read_on_cpu(top.evlist, cpu)) != NULL) { + while ((event = perf_evlist__mmap_read(top.evlist, idx)) != NULL) { perf_session__parse_sample(self, event, &sample); if (event->header.type == PERF_RECORD_SAMPLE) @@ -820,8 +820,8 @@ static void perf_session__mmap_read(struct perf_session *self) { int i; - for (i = 0; i < top.evlist->cpus->nr; i++) - perf_session__mmap_read_cpu(self, i); + for (i = 0; i < top.evlist->nr_mmaps; i++) + perf_session__mmap_read_idx(self, i); } static void start_counters(struct perf_evlist *evlist) diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index 45da8d186b49..23eb22b05d27 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -166,11 +166,11 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) return NULL; } -union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) +union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) { /* XXX Move this to perf.c, making it generally available */ unsigned int page_size = sysconf(_SC_PAGE_SIZE); - struct perf_mmap *md = &evlist->mmap[cpu]; + struct perf_mmap *md = &evlist->mmap[idx]; unsigned int head = perf_mmap__read_head(md); unsigned int old = md->prev; unsigned char *data = md->base + page_size; @@ -235,31 +235,37 @@ union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) void perf_evlist__munmap(struct perf_evlist *evlist) { - int cpu; + int i; - for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { - if (evlist->mmap[cpu].base != NULL) { - munmap(evlist->mmap[cpu].base, evlist->mmap_len); - evlist->mmap[cpu].base = NULL; + for (i = 0; i < evlist->nr_mmaps; i++) { + if (evlist->mmap[i].base != NULL) { + munmap(evlist->mmap[i].base, evlist->mmap_len); + evlist->mmap[i].base = NULL; } } + + free(evlist->mmap); + evlist->mmap = NULL; } int perf_evlist__alloc_mmap(struct perf_evlist *evlist) { - evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); + evlist->nr_mmaps = evlist->cpus->nr; + if (evlist->cpus->map[0] == -1) + evlist->nr_mmaps = evlist->threads->nr; + evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); return evlist->mmap != NULL ? 0 : -ENOMEM; } static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel, - int cpu, int prot, int mask, int fd) + int idx, int prot, int mask, int fd) { - evlist->mmap[cpu].prev = 0; - evlist->mmap[cpu].mask = mask; - evlist->mmap[cpu].base = mmap(NULL, evlist->mmap_len, prot, + evlist->mmap[idx].prev = 0; + evlist->mmap[idx].mask = mask; + evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, MAP_SHARED, fd, 0); - if (evlist->mmap[cpu].base == MAP_FAILED) { - if (evlist->cpus->map[cpu] == -1 && evsel->attr.inherit) + if (evlist->mmap[idx].base == MAP_FAILED) { + if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit) ui__warning("Inherit is not allowed on per-task " "events using mmap.\n"); return -1; @@ -269,6 +275,86 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *ev return 0; } +static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask) +{ + struct perf_evsel *evsel; + int cpu, thread; + + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { + int output = -1; + + for (thread = 0; thread < evlist->threads->nr; thread++) { + list_for_each_entry(evsel, &evlist->entries, node) { + int fd = FD(evsel, cpu, thread); + + if (output == -1) { + output = fd; + if (__perf_evlist__mmap(evlist, evsel, cpu, + prot, mask, output) < 0) + goto out_unmap; + } else { + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) + goto out_unmap; + } + + if ((evsel->attr.read_format & PERF_FORMAT_ID) && + perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) + goto out_unmap; + } + } + } + + return 0; + +out_unmap: + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { + if (evlist->mmap[cpu].base != NULL) { + munmap(evlist->mmap[cpu].base, evlist->mmap_len); + evlist->mmap[cpu].base = NULL; + } + } + return -1; +} + +static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask) +{ + struct perf_evsel *evsel; + int thread; + + for (thread = 0; thread < evlist->threads->nr; thread++) { + int output = -1; + + list_for_each_entry(evsel, &evlist->entries, node) { + int fd = FD(evsel, 0, thread); + + if (output == -1) { + output = fd; + if (__perf_evlist__mmap(evlist, evsel, thread, + prot, mask, output) < 0) + goto out_unmap; + } else { + if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) + goto out_unmap; + } + + if ((evsel->attr.read_format & PERF_FORMAT_ID) && + perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0) + goto out_unmap; + } + } + + return 0; + +out_unmap: + for (thread = 0; thread < evlist->threads->nr; thread++) { + if (evlist->mmap[thread].base != NULL) { + munmap(evlist->mmap[thread].base, evlist->mmap_len); + evlist->mmap[thread].base = NULL; + } + } + return -1; +} + /** perf_evlist__mmap - Create per cpu maps to receive events * * @evlist - list of events @@ -287,11 +373,11 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *ev int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) { unsigned int page_size = sysconf(_SC_PAGE_SIZE); - int mask = pages * page_size - 1, cpu; - struct perf_evsel *first_evsel, *evsel; + int mask = pages * page_size - 1; + struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; - int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); + int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) return -ENOMEM; @@ -301,43 +387,18 @@ int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) evlist->overwrite = overwrite; evlist->mmap_len = (pages + 1) * page_size; - first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node); list_for_each_entry(evsel, &evlist->entries, node) { if ((evsel->attr.read_format & PERF_FORMAT_ID) && evsel->sample_id == NULL && perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) return -ENOMEM; - - for (cpu = 0; cpu < cpus->nr; cpu++) { - for (thread = 0; thread < threads->nr; thread++) { - int fd = FD(evsel, cpu, thread); - - if (evsel->idx || thread) { - if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, - FD(first_evsel, cpu, 0)) != 0) - goto out_unmap; - } else if (__perf_evlist__mmap(evlist, evsel, cpu, - prot, mask, fd) < 0) - goto out_unmap; - - if ((evsel->attr.read_format & PERF_FORMAT_ID) && - perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) - goto out_unmap; - } - } } - return 0; + if (evlist->cpus->map[0] == -1) + return perf_evlist__mmap_per_thread(evlist, prot, mask); -out_unmap: - for (cpu = 0; cpu < cpus->nr; cpu++) { - if (evlist->mmap[cpu].base != NULL) { - munmap(evlist->mmap[cpu].base, evlist->mmap_len); - evlist->mmap[cpu].base = NULL; - } - } - return -1; + return perf_evlist__mmap_per_cpu(evlist, prot, mask); } int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, @@ -348,7 +409,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, if (evlist->threads == NULL) return -1; - if (target_tid != -1) + if (cpu_list == NULL && target_tid != -1) evlist->cpus = cpu_map__dummy_new(); else evlist->cpus = cpu_map__new(cpu_list); diff --git a/trunk/tools/perf/util/evlist.h b/trunk/tools/perf/util/evlist.h index 8b1cb7a4c5f1..7109d7add14e 100644 --- a/trunk/tools/perf/util/evlist.h +++ b/trunk/tools/perf/util/evlist.h @@ -17,6 +17,7 @@ struct perf_evlist { struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; int nr_entries; int nr_fds; + int nr_mmaps; int mmap_len; bool overwrite; union perf_event event_copy; @@ -46,7 +47,7 @@ void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); -union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); +union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); int perf_evlist__alloc_mmap(struct perf_evlist *evlist); int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); diff --git a/trunk/tools/perf/util/python.c b/trunk/tools/perf/util/python.c index f5e38451fdc5..99c722672f84 100644 --- a/trunk/tools/perf/util/python.c +++ b/trunk/tools/perf/util/python.c @@ -680,7 +680,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, &cpu, &sample_id_all)) return NULL; - event = perf_evlist__read_on_cpu(evlist, cpu); + event = perf_evlist__mmap_read(evlist, cpu); if (event != NULL) { struct perf_evsel *first; PyObject *pyevent = pyrf_event__new(event);