From fbda9468360f184fe2161a3170968b936f29de1c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 19 Sep 2012 15:10:41 +0100 Subject: [PATCH] open up the 3.4 LTSI branch. Only thing left from 3.0 is pramfs and lttng. I have no idea if they really work (or build) at this time. Signed-off-by: Greg Kroah-Hartman --- KERNEL_VERSION | 2 +- ...aging-android-delete-android-drivers.patch | 5904 ----------------- ...002-staging-android-fix-build-issues.patch | 46 - ...-android-common-include-linux-slab.h.patch | 21 - ...n-Fix-slab.h-includes-for-2.6.34-rc4.patch | 33 - ...ing-android-mark-subsystem-as-broken.patch | 30 - ...le-Ensure-ramconsole-does-not-get-cl.patch | 35 - ...am_console-Start-ram-console-earlier.patch | 26 - ...ing-android-timed_gpio-Request-gpios.patch | 49 - ...ystem-log-for-framework-system-log-m.patch | 55 - ...der-Use-seq_file-for-debug-interface.patch | 835 --- ...ove-debugging-information-from-procf.patch | 151 - ...io-Properly-discard-invalid-timeout-.patch | 30 - ...reate-dedicated-workqueue-for-binder.patch | 49 - ...ykiller-Don-t-try-to-kill-the-same-p.patch | 42 - ...ller-Substantially-reduce-overhead-d.patch | 99 - ...-memory-corruption-via-page-aliasing.patch | 48 - ...morykiller-Remove-bitrotted-codepath.patch | 32 - ...ykiller-Update-arguments-of-shrinker.patch | 24 - ...ykiller-Ignore-shmem-pages-in-page-c.patch | 28 - ...iller-Fix-arguments-to-lowmem_shrink.patch | 61 - ...gger-bump-up-the-logger-buffer-sizes.patch | 36 - ...m_console-pass-in-a-boot-info-string.patch | 166 - ...ite-spaces-coding-style-issue-in-log.patch | 52 - ...switch-switch-class-and-GPIO-drivers.patch | 499 -- ...witch-minor-code-formatting-cleanups.patch | 55 - ...0026-staging-android-add-pmem-driver.patch | 1499 ----- ...em-Anonymous-shared-memory-subsystem.patch | 829 --- ...em-Implement-read-2-in-ashmem-driver.patch | 65 - ...0029-ashmem-Fix-ASHMEM_SET_PROT_MASK.patch | 51 - ...ate-arguments-of-shrinker-for-2.6.35.patch | 43 - ...mem-Support-lseek-2-in-ashmem-driver.patch | 84 - ...shmem-Fix-arguments-to-ashmem_shrink.patch | 72 - ...roid-0033-ashmem-Whitespace-cleanups.patch | 142 - ...id-fixed-a-space-warning-in-binder.h.patch | 25 - ...-characters-warnings-in-lowmemorykil.patch | 43 - ...on-t-call-dump_stack-in-binder_vma_o.patch | 32 - ...7-Staging-android-Remove-pmem-driver.patch | 1490 ----- ...ix-crashes-when-sharing-a-binder-fil.patch | 87 - ...ykiller-Don-t-wait-more-than-one-sec.patch | 49 - ...ole-Don-t-build-on-arches-w-o-iorema.patch | 33 - ...droid-add-the-code-back-to-the-build.patch | 36 - ...-out-the-EXPORT_SYMBOL-into-export.h.patch | 247 - ....h-to-ARM-specific-files-as-required.patch | 460 -- ...e-cpuidle-single-global-and-last_sta.patch | 177 - ...ocate-registers-in-irq-entry-assembl.patch | 92 - ...e-rename-clk_init-to-shmobile_clk_in.patch | 108 - ...hmobile-add-shmobile_earlytimer_init.patch | 55 - ...ch-shmobile-default-to-no-earlytimer.patch | 34 - ...solidate-time-keeping-and-irq-enable.patch | 79 - ...sh-pfc-get_config_reg-shift-clean-up.patch | 33 - ...pfc-Remove-unused-gpio_in_use-member.patch | 31 - .../0011-sh-pfc-Add-GPIO-IRQ-support.patch | 101 - ...e-move-helper-macro-PORT_DATA_xx-to-.patch | 443 -- ...e-move-helper-macro-PORT_xx-to-sh_pf.patch | 509 -- ...e-move-helper-macro-PORTCR-to-sh_pfc.patch | 153 - .../0015-sh-pfc-ioremap-support.patch | 350 - ...io_read_bit-for-data-register-access.patch | 56 - ...onvert-index-to-field-and-value-pair.patch | 133 - ...h-pfc-Add-config_reg_helper-function.patch | 140 - ...bitfield-width-config-register-suppo.patch | 121 - .../0020-sh-pfc-Unlock-register-support.patch | 74 - ...ach-shmobile-Break-out-INTC-IRQ-code.patch | 223 - ...both-edges-GPIO-interrupts-on-sh7372.patch | 35 - ...intc-Add-IRQ-trigger-bit-field-check.patch | 45 - ...24-sh-userimask.c-needs-linux-stat.h.patch | 41 - ...use-of-stat.h-in-arch-sh-specific-fi.patch | 41 - ...to-arch-sh-specific-files-as-require.patch | 32 - ...to-arch-sh-specific-files-as-require.patch | 36 - ...xport.h-for-EXPORT_SYMBOL-to-intc-vi.patch | 31 - ...ement-sysdev-functionality-for-regul.patch | 892 --- ...riggering-on-both-edges-for-ARM-SoCs.patch | 34 - ...-sysdev_class-to-a-regular-subsystem.patch | 183 - ...t-include-SH7372-s-INTCS-in-syscore-.patch | 103 - ...vt2irq-irq2evt-macros-for-sh-and-arm.patch | 103 - ...lobal-intc-controller-counter-static.patch | 44 - ...enirq-Add-IRQCHIP_SKIP_SET_WAKE-flag.patch | 56 - ...RQCHIP_SKIP_SET_WAKE-over-a-dummy-se.patch | 47 - ...off-superfluous-irq_shutdown-hooking.patch | 30 - ...SET_MASK_OK_NOCOPY-for-intc_set_affi.patch | 32 - ...039-sh-intc-optimize-intc-IRQ-lookup.patch | 135 - ...sh-intc-remove-dependency-on-NR_IRQS.patch | 93 - ...p-section-mismatch-for-intc_ack_data.patch | 44 - ...ivers-sh-late-disabling-of-clocks-V2.patch | 80 - ...-sh-clkfwk-Convert-to-IS_ERR_OR_NULL.patch | 31 - ...move-CLKDEV_xxx_ID-macro-to-sh_clk.h.patch | 174 - ...clock-drivers-to-debugfs_remove_recu.patch | 193 - ...clkfwk-add-clk_rate_mult_range_round.patch | 67 - ...fwk-Kill-off-remaining-debugfs-cruft.patch | 146 - ...clock-parent-from-current-register-v.patch | 143 - ...-clock-struct-with-mapped_reg-member.patch | 70 - ...-iowrite32-and-mapped_reg-for-mstp32.patch | 44 - ...32-iowrite32-and-mapped_reg-for-div4.patch | 81 - ...32-iowrite32-and-mapped_reg-for-div6.patch | 93 - ..._init_parent-should-be-called-after-.patch | 39 - ...fix-use-clk_reparent-for-div6-clocks.patch | 33 - ...-sh_clk_ops-in-parallel-with-clk_ops.patch | 32 - ...56-sh-convert-cpg-code-to-sh_clk_ops.patch | 93 - ...RM-mach-shmobile-R-Mobile-A1-support.patch | 1378 ---- ...ach-shmobile-r8a7740-add-PFC-support.patch | 2602 -------- ...ach-shmobile-r8a7740-add-i2c-support.patch | 151 - ...ch-shmobile-r8a7740-add-INTC-support.patch | 804 --- ...ch-shmobile-bonito-Add-LCDC0-support.patch | 56 - ...h-shmobile-r8a7740-sh_clk_ops-rename.patch | 50 - ...e-r8a7740-map_io-and-init_early-upda.patch | 91 - ...e-rename-clk_init-to-shmobile_clk_in.patch | 37 - ...bile-r8a7740-and-Bonito-timer-rework.patch | 59 - ...ile-pfc-r8a7740-add-gpio_irq-support.patch | 82 - ...67-net-sh_eth-tidyup-compile-warning.patch | 45 - ...t-sh_eth-remove-__flush_purge_region.patch | 58 - ...h_eth-Move-the-Renesas-SuperH-driver.patch | 290 - ...uild-by-forgot-including-linux-inter.patch | 43 - ...of-ndo_set_multicast_list-in-drivers.patch | 283 - ...072-net-sh_eth-fix-the-compile-error.patch | 45 - .../0073-net-sh_eth-use-ioremap.patch | 172 - ...0074-sh-modify-prototype-in-sh_eth.h.patch | 30 - ...ve-the-asm-sh_eth.h-to-include-linux.patch | 55 - ...m-sh_eth.h-to-linux-sh_eth.h-in-some.patch | 86 - ...m-sh_eth.h-to-linux-sh_eth.h-in-sh77.patch | 31 - .../0078-net-sh_eth-fix-build-failure.patch | 55 - ...vert-drivers-net-ethernet-to-use-mod.patch | 101 - .../0080-net-make-ethtool_ops-const.patch | 49 - ...1-sh-eth-use-an-unique-MDIO-bus-name.patch | 31 - ...uild-error-by-the-value-which-is-not.patch | 38 - ...Remove-alloc_etherdev-error-messages.patch | 120 - ...net-sh_eth-fix-skb_over_panic-happen.patch | 64 - ...v-stats-structure-and-fix-dma_map_si.patch | 229 - ...et-dev_alloc_skb-to-netdev_alloc_skb.patch | 89 - ...-fix-linux-interrupt.h-included-twic.patch | 31 - ...he-value-of-tsu-to-the-SH7757-s-GETH.patch | 32 - ...ange-the-condition-of-initialization.patch | 50 - ...odify-a-condition-of-ioremap-for-TSU.patch | 65 - ...-add-support-for-multicast-filtering.patch | 362 - ...h-add-support-for-VLAN-tag-filtering.patch | 130 - .../0093-net-sh_eth-Add-support-SH7734.patch | 163 - ...ndian-check-for-architecture-indepen.patch | 56 - .../0095-net-sh_eth-add-support-R8A7740.patch | 211 - .../0096-atomic-use-linux-atomic.h.patch | 480 -- ...ev-sh_mobile_meram-Enable-runtime-PM.patch | 46 - ...meram-Enable-disable-MERAM-along-wit.patch | 41 - ...meram-Move-private-data-from-.h-to-..patch | 58 - ...meram-Backup-restore-device-register.patch | 122 - ...elper-macro-for-platform_driver-boil.patch | 83 - ...re-Generalize-module_platform_driver.patch | 85 - ...lcdc-Turn-dot-clock-on-before-resumi.patch | 53 - ...lcdc-Replace-hardcoded-register-valu.patch | 573 -- ...lcdc-Don-t-acknowlege-interrupts-uni.patch | 73 - ...lcdc-Compute-clock-pattern-using-div.patch | 50 - ...lcdc-Split-LCDC-start-code-from-sh_m.patch | 443 -- ...lcdc-Store-the-frame-buffer-base-add.patch | 67 - ...lcdc-Restart-LCDC-in-runtime-PM-resu.patch | 120 - ...meram-Replace-hardcoded-register-val.patch | 162 - ...meram-Validate-ICB-configuration-out.patch | 56 - ...meram-Fix-MExxCTL-register-save-on-r.patch | 36 - ...meram-Remove-unneeded-sh_mobile_mera.patch | 101 - ...am-Reset-ICBs-at-unregistration-time.patch | 38 - ...lcdc-Adjust-requested-parameters-in-.patch | 142 - ...lcdc-Add-support-for-format-changes-.patch | 51 - ...lcdc-use-display-information-in-info.patch | 71 - ...lcdc-Update-fix.line_length-in-.fb_s.patch | 61 - ...bile_lcdc-Avoid-forward-declarations.patch | 139 - ...lcdc-Split-channel-initialization-fr.patch | 332 - ...e_lcdc-Remove-sh_mobile_lcdc_set_bpp.patch | 169 - .../0122-video-irq-Remove-IRQF_DISABLED.patch | 59 - ....h-to-drivers-video-files-who-really.patch | 72 - ...lcdcfb-fixup-LDHAJR-HSYNPAJ-needs-ma.patch | 33 - ...25-fbdev-sh_mipi_dsi-tidyup-dsip_clk.patch | 75 - ...pi_dsi-typo-fix-of-SH_MIPI_DSI_HBPBM.patch | 45 - ...i-tidyup-VMCTR2-parameter-expression.patch | 37 - ..._mipi_dsi-add-SH_MIPI_DSI_HFPBM-flag.patch | 44 - ...h_mipi_dsi-add-SH_MIPI_DSI_BL2E-flag.patch | 44 - ...sh_mipi_dsi-add-lane-control-support.patch | 101 - ...i-add-sync_pulses-sync_events-burst-.patch | 94 - ...pi_dsi-add-VMLEN1-VMLEN2-calculation.patch | 106 - ...i-add-set_dot_clock-for-each-platfor.patch | 147 - ...bdev-sh_mipi_dsi-add-HSxxCLK-support.patch | 84 - ...dsi-sh_mipi-has-pdata-instead-of-dev.patch | 58 - ...i-fixup-setup-timing-of-sh_mipi_setu.patch | 138 - ...pi_dsi-fixup-setup-timing-of-SYSCONF.patch | 61 - ..._mipi_dsi-fixup-setup-timing-DSICTRL.patch | 43 - ...ivers-video-to-use-module_platform_d.patch | 386 -- ...OURCC-based-format-configuration-API.patch | 423 -- ..._FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch | 35 - ...failure-in-mach-shmobile-board-ag5ev.patch | 33 - .../0143-sh-se7724-fix-compile-breakage.patch | 99 - ...lcdc-Support-FOURCC-based-format-API.patch | 731 -- ...bile_lcdc-Reorder-code-into-sections.patch | 547 -- ...lcdc-Mark-init-only-symbols-with-__d.patch | 42 - ...lcdc-Move-pm-runtime-enable-to-probe.patch | 96 - ...lcdc-Don-t-pass-struct-device-around.patch | 149 - ...lcdc-Create-functions-to-turn-the-di.patch | 144 - ...hdmi-Don-t-access-LCDC-channel-in-no.patch | 47 - ...i-Remove-platform-data-lcd_dev-field.patch | 112 - ...lcdc-Add-sh_mobile_lcdc_entity-defin.patch | 49 - ...hdmi-Implement-sh_mobile_lcdc_entity.patch | 134 - ...i-Implement-sh_mobile_lcdc_entity-in.patch | 173 - ...lcdc-Handle-HDMI-MIPI-transmitter-de.patch | 118 - ...i-Don-t-hook-up-into-board_cfg-displ.patch | 129 - ...hdmi-Don-t-hook-up-into-board_cfg-di.patch | 120 - ...e-Don-t-initialize-the-hdmi_info-lcd.patch | 47 - ...hdmi-Remove-sh_mobile_hdmi_info-lcd_.patch | 30 - ...lcdc-Remove-board-configuration-owne.patch | 60 - ...lcdc-Remove-board-configuration-boar.patch | 344 - ...lcdc-Move-brightness-ops-to-sh_mobil.patch | 132 - ...lcdc-Merge-board_cfg-and-lcd_size_cf.patch | 314 - ...dd-an-lcdc-channel-pointer-to-sh_mob.patch | 64 - ...se-sh_mobile_lcdc_entity-channel-to-.patch | 240 - ...lcdc-Remove-fb_info-parameter-to-dis.patch | 95 - ...lcdc-Return-display-connection-state.patch | 102 - ...dd-display-notify-callback-to-sh_mob.patch | 156 - ..._hdmi-Use-LCDC-notification-callback.patch | 158 - ...lcdc-Pass-a-video-mode-to-the-notify.patch | 296 - ...hdmi-Don-t-set-sh_hdmi-mode-in-the-d.patch | 50 - ...obile_hdmi-Don-t-access-LCDC-fb_info.patch | 145 - ...lcdc-Store-display-mode-in-a-struct-.patch | 193 - ...lcdc-Rename-lcd-num-_cfg-lcd-num-_mo.patch | 405 -- ...lcdc-Reorganize-the-sh_mobile_lcdc_c.patch | 84 - ...lcdc-Add-sh_mobile_format_info-funct.patch | 277 - ...lcdc-Store-the-format-in-struct-sh_m.patch | 126 - ...lcdc-Split-fb-init-cleanup-from-chan.patch | 396 -- ...lcdc-Pass-physical-device-pointer-to.patch | 38 - ...lcdc-Store-configuration-in-channel-.patch | 278 - ...lcdc-Pass-channel-pointer-to-sh_mobi.patch | 100 - ...meram-Request-memory-regions-for-mem.patch | 127 - ...meram-Add-_cfg-suffix-to-struct-sh_m.patch | 102 - ...meram-Make-variables-unsigned-where-.patch | 219 - ...meram-Make-current_reg-field-store-t.patch | 34 - ...meram-Add-struct-sh_mobile_meram_icb.patch | 444 -- ...mobile_meram-Don-t-inline-everything.patch | 108 - ..._meram-Divide-the-code-into-sections.patch | 263 - ...meram-Use-genalloc-to-manage-MERAM-a.patch | 366 - ...le_meram-Allocate-ICBs-automatically.patch | 740 --- ...e-Don-t-set-MERAM-ICB-numbers-in-pla.patch | 88 - ...meram-Remove-unused-sh_mobile_meram_.patch | 31 - ...lcdc-Don-t-store-copy-of-platform-da.patch | 315 - ...meram-Don-t-perform-update-in-regist.patch | 97 - ..._meram-Remove-unneeded-sanity-checks.patch | 155 - ...meram-Implement-system-suspend-resum.patch | 56 - ...i-add-extra-phyctrl-for-sh_mipi_dsi_.patch | 64 - ...ci-Kill-off-bitrotted-H8-300-support.patch | 263 - ...dy-up-ioread-write-wrappers-kill-off.patch | 87 - ...ill-off-some-more-unused-definitions.patch | 38 - ...l-sh-sci-Generalize-overrun-handling.patch | 304 - ...-sh-sci-Consolidate-RXD-pin-handling.patch | 108 - ...al-sh-sci-More-unused-define-purging.patch | 80 - ...serial-sh-sci-Abstract-register-maps.patch | 766 --- ...sci-FIFO-sizing-helper-consolidation.patch | 255 - ...pport-generic-SCLSR-overrun-detectio.patch | 44 - ...gtype-probing-doesn-t-need-to-be-fat.patch | 45 - ...d-missing-module-description-author-.patch | 26 - ...ll-off-per-port-enable-disable-callb.patch | 194 - ...x-up-pretty-name-printing-for-port-I.patch | 203 - ...h-sci-Fix-up-default-regtype-probing.patch | 34 - ...x-DMA-build-by-including-dma-mapping.patch | 46 - ...al-sh-sci-console-Runtime-PM-support.patch | 145 - .../0214-sh-sci-PM-Use-power.irq_safe.patch | 35 - ...i-report-CTS-as-active-for-get_mctrl.patch | 43 - ...n-t-filter-on-DMA-device-use-only-ch.patch | 108 - .../0217-TTY-irq-Remove-IRQF_DISABLED.patch | 60 - ...ial-sh-sci-Fix-up-SH-2A-SCIF-support.patch | 71 - ...-serial-sh-sci-Fix-up-SCFCR-handling.patch | 111 - ...pport-icount-statistics-for-error-ca.patch | 99 - ...Clarify-enable_ms-break_ctl-comments.patch | 44 - ...sh-sci-Fix-up-modem-control-handling.patch | 60 - ...sh-sci-Add-support-for-loopback-mode.patch | 48 - ...serial-sh-sci-per-port-modem-control.patch | 110 - ...-sci-Avoid-FIFO-clear-for-MCE-toggle.patch | 56 - ...sh-sci-Handle-GPIO-function-requests.patch | 177 - ...o_keys-switch-to-using-threaded-IRQs.patch | 42 - ...nput-gpio_keys-move-to-late_initcall.patch | 38 - ...29-Input-gpio_keys-fix-a-memory-leak.patch | 29 - ...add-support-for-device-tree-platform.patch | 305 - ...ys-switch-to-using-SIMPLE_DEV_PM_OPS.patch | 56 - ...return-proper-error-code-if-memory-a.patch | 33 - ...fix-two-typos-in-devicetree-document.patch | 30 - ...t-gpio_keys-use-of_property_read_u32.patch | 78 - ...fix-struct-device-declared-inside-pa.patch | 36 - ...put-gpio_keys-constify-platform-data.patch | 139 - ...o_keys-switch-to-using-threaded-IRQs.patch | 33 - ...keys-consolidate-key-destructor-code.patch | 78 - ...-add-support-for-interrupt-only-keys.patch | 395 -- ...0-Input-sh_keysc-fix-compile-warning.patch | 36 - ...ard-use-macro-module_platform_driver.patch | 73 - ...r-machine-3284-to-common-Encore-name.patch | 34 - ...-cpuimx-boards-fix-mach-types-errors.patch | 90 - ...dd-a-few-machine-types-to-mach-types.patch | 122 - ...mach-types-to-fix-mxs-build-breakage.patch | 41 - ...achine_is_xxx-naming-for-eSata-Sheev.patch | 90 - .../0247-ARM-Update-mach-types.patch | 828 --- ...le-add-armadillo800eva-board-support.patch | 235 - ...mobile-armadillo800eva-add-defconfig.patch | 168 - ...le-armadillo800eva-add-support-LCDC0.patch | 159 - ...e-armadillo800eva-add-support-ST1232.patch | 58 - ...e-armadillo800eva-add-support-gpio_k.patch | 69 - ...e-armadillo800eva-add-support-sh_eth.patch | 108 - ...fconfig-allow-use-of-armhf-userspace.patch | 45 - ...nfig-disable-config_sysfs_deprecated.patch | 38 - ...ile-armadillo800eva-defconfig-update.patch | 95 - ...372-ap4evb-and-mackerel-timer-rework.patch | 67 - ..._eth-needs-net_ethernet-on-defconfig.patch | 36 - ...move-mm.h-inclusion-from-netdevice.h.patch | 167 - ...ow-ports-to-override-the-irq-handler.patch | 36 - ...x-dma-mapping.h-in-linux-dmaengine.h.patch | 35 - ...ntroduce-generic-port-in-out-helpers.patch | 53 - ...e-to-get-a-specific-DMA-channel-is-n.patch | 53 - ...0003-serial-8250-increase-PASS_LIMIT.patch | 39 - ...lave-cyclic-DMA-engine-documentation.patch | 279 - ...akeup-init-logic-to-speed-up-startup.patch | 60 - ...DEFINE_IDR-for-static-initialization.patch | 47 - ...llow-platforms-to-override-irq-handl.patch | 140 - ...add-helper-function-for-slave_single.patch | 51 - ...-tty-serial8250-remove-UPIO_DWAPB-32.patch | 167 - ...remove-struct-scatterlist-for-header.patch | 37 - ...ty-8250-export-serial8250_handle_irq.patch | 32 - ...-add-new-enum-dma_transfer_direction.patch | 83 - ...serial-8250-Move-UPIO_TSI-to-powerpc.patch | 129 - ...h-fix-implicit-use-of-bitmap.h-and-a.patch | 45 - ...rt-the-EFR-register-of-XR1715x-uarts.patch | 159 - ...shmobile-kzm9g-add-smsc-9221-support.patch | 96 - ...mit-LSR-safety-check-engaged-warning.patch | 44 - ...ine-interleaved-transfer-request-api.patch | 192 - ...A_TRANS_NONE-to-dma_transfer_directi.patch | 60 - ...0-replace-hardcoded-0xbf-with-define.patch | 33 - ...ow-controller-information-to-dma_sla.patch | 59 - ...ct-uart_8250_port-from-8250.c-to-825.patch | 98 - ...stinguish-between-dmaengine-failed-t.patch | 49 - ...parameter-passing-for-8250-Rx-IRQ-ha.patch | 79 - ...14-dmaengine-add-private-header-file.patch | 87 - ...e-key-functions-for-an-8250-IRQ-hand.patch | 161 - ...-dma_slave-introduce-inline-wrappers.patch | 79 - ...-timeout-use-the-specified-IRQ-handl.patch | 51 - ...016-ARM-Add-init_consistent_dma_size.patch | 195 - ...nually-inline-serial8250_handle_port.patch | 77 - ...c-add-a-card-hotplug-handler-context.patch | 55 - ...p-all-the-8250-related-code-together.patch | 746 --- ...dd-a-generic-GPIO-card-detect-helper.patch | 144 - .../0018-serial-Kill-off-NO_IRQ.patch | 361 - ..._cd_gpio_request-by-removing-two-par.patch | 71 - ...019-tty-fix-a-build-failure-on-sparc.patch | 42 - ...-kzm9g-add-external-usb-host-support.patch | 82 - ...dardize-header-file-inclusion-checks.patch | 65 - ...-drivers-tty-serial-suncore.h-includ.patch | 199 - ...mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch | 48 - ...st-unused-traces-of-pausing-I-O-in-8.patch | 732 -- ...tmio-Share-register-access-functions.patch | 130 - ...-s-serial_in-shareable-to-other-driv.patch | 73 - .../0023-mmc-sdhi-Add-write16_hook.patch | 149 - ...-delete-useless-void-casts-in-8250.c.patch | 84 - ...e-condition-resulting-in-spurious-in.patch | 132 - ...-number-of-indirections-in-8250-code.patch | 958 --- ...ursive-spinlock-don-t-schedule-with-.patch | 167 - ...l_port_in-out-vs-serial_in-out-in-82.patch | 455 -- .../0026-mmc-tmio-maximize-power-saving.patch | 172 - ...ck-and-forth-conversions-in-serial_o.patch | 56 - ...-recently-introduced-bug-in-DMA-code.patch | 34 - ...add-a-force-background-timer-flag-an.patch | 118 - .../0028-8250.c-less-than-2400-baud-fix.patch | 51 - .../0028-mmc-tmio-fix-a-deadlock.patch | 85 - ...move-mm.h-inclusion-from-netdevice.h.patch | 109 - ...l8250-Add-dl_read-dl_write-callbacks.patch | 203 - ...lost-clk_enable_on_init-for-div6_zb1.patch | 52 - ...ld-issue-related-to-struct-scatterli.patch | 32 - ...8250-Use-dl_read-dl_write-on-Alchemy.patch | 138 - ...liminate-unused-variable-mmc-warning.patch | 45 - ...ial8250-Use-dl_read-dl_write-on-RM9K.patch | 139 - ...initialise-mmc_data-flags-before-use.patch | 39 - ...250-Clean-up-default-map-and-dl-code.patch | 134 - .../0033-mmc-tmio-Cache-interrupt-masks.patch | 131 - ...roduce-serial8250_register_8250_port.patch | 169 - ...-Provide-separate-interrupt-handlers.patch | 215 - ...al8250-em-Emma-Mobile-UART-driver-V2.patch | 254 - ...-named-IRQs-to-use-specific-handlers.patch | 180 - ...em-clk_get-IS_ERR-error-handling-fix.patch | 38 - ...uidle-create-bootparam-cpuidle.off-1.patch | 116 - .../0036-mmc-irq-Remove-IRQF_DISABLED.patch | 46 - ...xen-access-to-x86-pm_idle-and-defaul.patch | 85 - ...-to-drivers-mmc-users-assuming-impli.patch | 36 - ...38-cpuidle-stop-depending-on-pm_idle.patch | 254 - ...rintk-with-appropriate-display-macro.patch | 36 - ...istent-spelling-of-cpuidle_idle_call.patch | 53 - ...ck-gating-on-platforms-with-a-.set_p.patch | 33 - ...mach_shmobile-kzm9g-update-defconfig.patch | 48 - ...ers-mmc-host-to-use-module_platform_.patch | 103 - ...-Fix-up-fallout-from-cpuidle-changes.patch | 32 - ...le.h-to-drivers-cpuidle-files-as-req.patch | 41 - ...e-second-argument-of-k-un-map_atomic.patch | 46 - ...-last_residency-update-to-driver-ent.patch | 868 --- ...mmc-tmio_mmc-Hotplug-code-regrouping.patch | 84 - ...-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch | 89 - ...-host-move-to-dma_transfer_direction.patch | 54 - ...uidle_state-structure-and-move-per-c.patch | 531 -- ...mc-fix-card-eject-during-IO-with-DMA.patch | 111 - ...e-Global-registration-of-idle-states.patch | 1520 ----- ...not-enable-card-hotplug-interrupts-i.patch | 53 - ...common-time-keeping-and-irq-enabling.patch | 285 - ...te-the-native-hotplug-condition-only.patch | 71 - .../0047-mm-add-vm_area_add_early.patch | 92 - ...port-the-generic-MMC-GPIO-card-hotpl.patch | 255 - ...e-clockevents_config-a-global-symbol.patch | 46 - ...hi-pass-card-hotplug-GPIO-number-to-.patch | 55 - ...rce-em_sti-Emma-Mobile-STI-driver-V2.patch | 484 -- ...er-status-flag-doesn-t-have-to-be-ex.patch | 101 - ...ization-of-the-high_memory-variable-.patch | 63 - ...-remove-unused-sdio_irq_enabled-flag.patch | 54 - ...e-mappings-within-the-vmalloc-region.patch | 207 - ...dhi-do-not-manage-PM-clocks-manually.patch | 52 - ...ounmap-when-dealing-with-section-bas.patch | 66 - ...c-prettify-the-tmio_mmc_set_ios-func.patch | 63 - ...ioremap-optimization-by-reusing-stat.patch | 177 - ...hi-add-a-callback-for-board-specific.patch | 74 - ...obile-Introduce-shmobile_setup_delay.patch | 72 - ...hi-support-modular-mmc-core-with-non.patch | 85 - ...ile-Allow-SoC-specific-CPU-kill-code.patch | 67 - ...dardize-header-file-inclusion-checks.patch | 61 - ...e-Use-preset_lpj-with-calibrate_dela.patch | 46 - ...6-mmc-sh_mmcif-maximize-power-saving.patch | 82 - .../0057-ARM-Undelete-KZM9D-mach-type.patch | 32 - ...-mmc-sh_mmcif-simplify-platform-data.patch | 89 - .../0058-gpio-Emma-Mobile-GPIO-driver.patch | 481 -- ...-to-drivers-mmc-users-assuming-impli.patch | 52 - ...-Emma-Mobile-EV2-SoC-base-support-V3.patch | 493 -- ...-host-move-to-dma_transfer_direction.patch | 54 - ...mach-shmobile-KZM9D-board-support-V3.patch | 110 - ...-clock-gating-on-platforms-with-a-.d.patch | 34 - ...obile-Emma-Mobile-EV2-SMP-support-V3.patch | 329 - ...f-simplify-clock-divisor-calculation.patch | 42 - ...bile-Emma-Mobile-EV2-GPIO-support-V3.patch | 280 - ...ers-mmc-host-to-use-module_platform_.patch | 79 - ...bile-KZM9D-board-Ethernet-support-V3.patch | 82 - ...mmcif-process-error-interrupts-first.patch | 53 - .../0064-mmc-sh_mmcif-cosmetic-clean-up.patch | 211 - ...mcif-process-requests-asynchronously.patch | 788 --- ...ove-now-superfluous-sh_mmcif_host-da.patch | 319 - ...mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch | 40 - ...mmc-sh_mmcif-simplify-bitmask-macros.patch | 51 - ...0069-mmc-sh_mmcif-double-clock-speed.patch | 41 - ...-f_max-should-be-half-of-the-bus-clo.patch | 49 - ...if-Simplify-calculation-of-mmc-f_min.patch | 44 - ...shmobile-clock-r8a7740-add-USB-clock.patch | 203 - ...change-the-timing-of-alsa_sound_last.patch | 38 - ...se-and-refactor-pcm_new-to-pass-only.patch | 529 -- ...components-to-probe-remove-in-sequen.patch | 249 - ...ate-out-PCM-operations-into-new-file.patch | 1333 ---- .../0077-ASoC-core-PCM-mutex-per-rtd.patch | 203 - ...ormats-to-be-specified-in-the-dai_li.patch | 148 - ...e-PM-references-to-components-of-act.patch | 78 - ...-tidyup-parameter-of-fsi_stream_push.patch | 64 - ...1-ASoC-sh-fsi-add-fsi_set_master_clk.patch | 273 - ...control-moves-to-fsi_port_start-stop.patch | 74 - ...h-fsi-tidyup-unclear-variable-naming.patch | 344 - ...move-pm_runtime-from-fsi_dai_set_fmt.patch | 160 - ...-sure-fsi_stream_push-pop-access-by-.patch | 62 - ...C-sh-fsi-remove-fsi_module_init-kill.patch | 106 - ...7-ASoC-sh-fsi-cleanup-suspend-resume.patch | 202 - ...C-sh-fsi-add-fsi_hw_startup-shutdown.patch | 116 - .../0089-sound-irq-Remove-IRQF_DISABLED.patch | 43 - ...C-sh-use-correct-__iomem-annotations.patch | 66 - ....h-to-the-previously-silent-sound-us.patch | 63 - .../0092-ASoC-fsi-fixup-compile-warning.patch | 50 - ...-valid-data-position-control-support.patch | 62 - ...SoC-Constify-snd_soc_dai_ops-structs.patch | 169 - ...modify-specification-method-of-FSI-a.patch | 272 - ...-directory-to-module_platform_driver.patch | 100 - ...se-core-pm_runtime-callbacks-for-fsi.patch | 41 - ...sh-Add-.owner-to-struct-snd_soc_card.patch | 67 - ...-unneeded-empty-runtime-PM-callbacks.patch | 47 - ...runtime-calculation-by-using-pre-set.patch | 81 - ...fsi_stream_xx-functions-were-gathere.patch | 204 - ...ush-pop-calculation-part-was-divided.patch | 159 - ...name-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch | 114 - ...move-fsi_fifo_init-onto-fsi_hw_start.patch | 146 - ...unnecessary-parameter-from-fsi_hw_sh.patch | 51 - ...fsi_stream_push-pop-to-fsi_stream_in.patch | 57 - ...fsi_pio_get_area-parameter-and-using.patch | 127 - ...ne-fsi_is_play-and-fsi_stream_is_pla.patch | 70 - ..._stream-in-fsi_get_current_fifo_samp.patch | 64 - ...d-fsi_stream_handler-and-PIO-handler.patch | 286 - ...-fsi-tidyup-fsi_pio_xxx-are-gathered.patch | 152 - ...se-is_play-as-a-parameter-of-fsi-fun.patch | 291 - ...art_stop-handler-to-fsi_stream_handl.patch | 129 - ...eam_is_working-care-substream-runtim.patch | 41 - ...-information-was-controlled-by-sh_fs.patch | 285 - ...-fsi-add-.init-.quit-handler-support.patch | 48 - ...fixup-fsi_pointer-calculation-method.patch | 42 - .../0118-ASoC-fsi-Add-DMAEngine-support.patch | 316 - ...-for-dmaengine-prep_slave_sg-fallout.patch | 47 - ...ASoC-add-generic-simple-card-support.patch | 241 - ...sh-fsi-select-simple-card-on-Kconfig.patch | 34 - ...122-ASoC-ak4642-convert-to-soc-cache.patch | 162 - .../0123-ASoC-ak4642-ak4642-was-tested.patch | 32 - ...SoC-ak4642-add-ak4642_set_bias_level.patch | 88 - ...dd-DAPM-support-for-HeadPhone-Output.patch | 95 - ...42-add-headphone-mute-switch-control.patch | 47 - ...127-ASoC-ak4642-add-Line-out-support.patch | 61 - .../0128-ASoC-ak4642-add-ak4648-support.patch | 115 - ...Remove-driver-versioning-from-ak4642.patch | 41 - ...-ASoC-Convert-ak4642-to-devm_kzalloc.patch | 47 - ...42-fixup-HeadPhone-L-R-dapm-settings.patch | 85 - ...hmobile-clock-r8a7740-add-SDHI-clock.patch | 54 - ...mobile-clock-r8a7740-add-MMCIF-clock.patch | 45 - ...e-r8a7740-reserve-DMA-memory-for-the.patch | 44 - ...shmobile-clock-r8a7740-add-FSI-clock.patch | 45 - ...le-armadillo800eva-add-SDHI0-support.patch | 131 - ...le-armadillo800eva-add-SDHI1-support.patch | 110 - ...le-armadillo800eva-add-MMCIF-support.patch | 105 - ...e-armadillo800eva-Add-FSI-WM8978-sup.patch | 181 - ...e-Add-support-for-PINT-though-INTC-m.patch | 80 - ...rq-Track-the-owner-of-irq-descriptor.patch | 260 - ...rq_domain-translation-infrastructure.patch | 400 -- ...dd-irq_domain_generate_simple-helper.patch | 122 - ...ion-of-irq_domain_simple_ops-to-irqd.patch | 41 - ...r-already-initialized-irq_domain-in-.patch | 56 - ...ort-domains-with-non-zero-hwirq-base.patch | 113 - ...upport-for-per-cpu-dev_id-interrupts.patch | 769 --- ...ndle_IRQ-not-to-dump-exception-stack.patch | 123 - ..._chip_data-structure-declaration-to-.patch | 59 - ...PU-hotplug-fix-abuse-of-irqdesc-node.patch | 55 - ...d-routing-interrupts-to-offline-CPUs.patch | 52 - ...e-cpu-pm-notifiers-to-save-gic-state.patch | 268 - ...11-1-Add-ARM-cpu-topology-definition.patch | 351 - ...opulate-logical-CPU-mapping-during-b.patch | 74 - ...c-arch-extensions-to-provide-irqchip.patch | 35 - ...onvert-logical-CPU-numbers-into-phys.patch | 67 - ...dd-an-IPI-handler-callable-from-C-co.patch | 46 - ...dd-a-localtimer-handler-callable-fro.patch | 46 - ...159-ARM-gic-consolidate-PPI-handling.patch | 532 -- ...C-Add-global-gic_handle_irq-function.patch | 81 - ...-clockevents-device-before-enabling-.patch | 41 - ...the-affinity-of-mct1-interrupt-using.patch | 36 - ...low-interrupt-type-to-be-set-at-enab.patch | 75 - ...mers-use-the-request_percpu_irq-inte.patch | 489 -- .../0165-ARM-gic-add-irq_domain-support.patch | 288 - ...-ARM-gic-add-OF-based-initialization.patch | 195 - ..._alloc_descs-handling-for-sparse-irq.patch | 99 - ...gic-use-module.h-instead-of-export.h.patch | 32 - ...m-register-GIC-PM-notifier-only-once.patch | 44 - ...void-skipping-non-existent-PPIs-in-i.patch | 52 - ...e-clock-sh73a0-tidyup-CKSCR-main-clo.patch | 32 - ...e-sh73a0-PFC-pull-up-support-for-SDH.patch | 189 - ...vert-logical-CPU-numbers-to-physical.patch | 51 - ...ach-shmobile-sh73a0-GPIO-IRQ-support.patch | 91 - ...e-Use-common-INTC-IRQ-code-on-sh73a0.patch | 259 - ...obile-sh73a0-and-AG5EVM-PINT-support.patch | 174 - ...shmobile-Kota2-TPU-LED-platform-data.patch | 88 - ...hmobile-SH73A0-external-Ethernet-fix.patch | 38 - ...sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch | 233 - ...mobile-add-a-resource-name-for-shdma.patch | 55 - ...ch-shmobile-sh73a0-PINT-IRQ-base-fix.patch | 39 - ...shmobile-sh73a0-IRQ-sparse-alloc-fix.patch | 44 - ...e-clock-sh73a0-add-DSIxPHY-clock-sup.patch | 159 - .../0184-ARM-shmobile-remove-NR_IRQS.patch | 54 - ...mobile-sh73a0-PSTR-32-bit-access-fix.patch | 34 - ...ch-shmobile-sh73a0-sh_clk_ops-rename.patch | 77 - ...e-sh73a0-map_io-and-init_early-updat.patch | 129 - ...e-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch | 95 - ...bile-sh73a0-add-MMC-data-pin-pull-up.patch | 130 - .../0190-ARM-Update-mach-types.patch | 640 -- ...shmobile-add-KZM-A9-GT-board-support.patch | 126 - ...RM-mach-shmobile-kzm9g-add-defconfig.patch | 155 - ...e-Invalidate-caches-when-booting-sec.patch | 97 - ...-mach-shmobile-kzm9g-enable-SMP-boot.patch | 92 - ...mach-shmobile-kzm9g-add-LCDC-support.patch | 204 - ...e-kzm9g-add-ST1232-Touchscreen-suppo.patch | 65 - ...e-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch | 44 - ...M-mach-shmobile-sh73a0.h-add-GPIO_NR.patch | 38 - ...obile-kzm9g-correct-screen-direction.patch | 40 - ...ach-shmobile-kzm9g-add-MMCIF-support.patch | 106 - ...mach-shmobile-kzm9g-add-SDHI-support.patch | 110 - ...-shmobile-kzm9g-add-PCF8757-gpio-key.patch | 140 - ...mach-shmobile-kzm9g-defconfig-update.patch | 88 - ...-shmobile-clock-sh73a0-add-FSI-clock.patch | 46 - ...hmobile-kzm9g-add-FSI-AK4648-support.patch | 162 - ...rm-mach-shmobile-kzm9d-add-defconfig.patch | 114 - ...-kzm9d-defconfig-enable-net_ethernet.patch | 30 - ...hmobile-sh73a0-bugfix-sy-dmac-number.patch | 86 - ...mobile-kzm9g-support-real-time-clock.patch | 53 - ...ix-add-config_i2c-to-kzm9g_defconfig.patch | 51 - ...find_matching_node_by_address-helper.patch | 66 - patches.ltsi/ltsi-makefile-addition.patch | 6 +- .../0018-staging-add-LTTng-to-build.patch | 12 +- ...-Add-LTTng-entry-to-MAINTAINERS-file.patch | 4 +- patches.pramfs/08-pramfs-headers.patch | 15 +- .../17-pramfs-makefile-and-kconfig.patch | 20 +- ...orm-module-alias-where-it-is-missing.patch | 43 - ...dress-in-r8a66597-udc-and-m66592-udc.patch | 50 - ...t-configurable-through-platform-data.patch | 63 - ...a66597-udc-add-support-for-test_mode.patch | 76 - ...gadget-clean-up-fsf-boilerplate-text.patch | 134 - .../006-usb-irq-remove-irqf_disabled.patch | 92 - ...nge-prototype-of-r8a66597_write_fifo.patch | 59 - ...add-function-for-external-controller.patch | 44 - ...add-function-for-external-controller.patch | 86 - ...66597-udc-use-dev_-instead-of-printk.patch | 311 - ...-r8a66597-udc-add-support-for-sudmac.patch | 664 -- ...r8a66597-udc-fix-flush-fifo-handling.patch | 37 - ...e-Automatically-retry-failed-autosus.patch | 78 - ...e-struct-dev_power_domain-to-struct-.patch | 397 -- ...n-struct-dev_pm_info-need-not-depend.patch | 35 - ...upport-for-generic-I-O-PM-domains-v8.patch | 656 -- ...eric-noirq-callback-routines-for-sub.patch | 340 - ...code-from-under-ifdef-CONFIG_PM_RUNT.patch | 184 - ...m-wide-transitions-support-for-gener.patch | 735 -- ...p-devices-support-for-system-sleep-t.patch | 75 - ...cks-management-code-to-be-used-durin.patch | 147 - ...PM-Rename-clock-management-functions.patch | 588 -- ...e-documentation-of-interactions-with.patch | 90 - ...n-special-error-code-if-runtime-PM-i.patch | 115 - ...nditions-between-runtime-PM-and-syst.patch | 224 - ...ve-documentation-of-enable-disable-a.patch | 60 - ...ce-run-time-with-runtime-in-document.patch | 685 -- ...nt-runtime_resume-from-racing-with-p.patch | 53 - ...stent-utilization-of-deferred_resume.patch | 32 - ...ns-Export-pm_genpd_poweron-in-header.patch | 56 - ...Documentation-power-pm-apm-acpi-.txt.patch | 48 - ...evice-state-to-active-during-system-.patch | 36 - ...failing-pm_genpd_prepare-clean-up-pr.patch | 53 - ...t-execute-device-callbacks-under-loc.patch | 604 -- ...-callbacks-to-execute-all-runtime-PM.patch | 383 -- ...t-restore-all-devices-on-power-off-e.patch | 52 - ...ve-handling-of-wakeup-devices-during.patch | 88 - ...-up-power-off-work-only-if-it-is-not.patch | 56 - ...ew-helper-function-pm_runtime_status.patch | 63 - ...duce-function-to-power-off-all-unuse.patch | 88 - ...obile-Use-genpd_queue_power_off_work.patch | 59 - ...e-.power_off-error-code-into-account.patch | 47 - ...oduce-function-to-free-cpufreq-table.patch | 88 - ...suspend_again-callback-to-suspend_op.patch | 151 - ...t-suspend_set_ops-suspend_valid_only.patch | 43 - ...-trace-time-stamps-to-avoid-confusio.patch | 35 - ...error-code-of-pm_notifier_call_chain.patch | 100 - ...ower-opp.c-fix-dev_opp-initial-value.patch | 36 - ...0037-PM-Domains-Fix-pm_genpd_poweron.patch | 45 - ...-_put_sync-from-interrupts-disabled-.patch | 90 - ...ix-build-for-CONFIG_PM_RUNTIME-unset.patch | 109 - ...-might_sleep-to-runtime-PM-functions.patch | 106 - ...-macro-to-test-for-runtime-PM-events.patch | 323 - ...instead-of-mutex-in-clock-management.patch | 197 - ...ct-documentation-of-pm_runtime_irq_s.patch | 35 - ...ment-subdomain-counters-as-atomic-fi.patch | 128 - ...t-take-parent-locks-to-modify-subdom.patch | 150 - ...pm_genpd_poweron-always-survive-pare.patch | 93 - ...ait-for-parent-status-for-generic-PM.patch | 219 - ...-generic-PM-domains-to-have-multiple.patch | 329 - ...e-GPD_STATE_WAIT_PARENT-to-GPD_STATE.patch | 74 - ...e-argument-of-pm_genpd_add_subdomain.patch | 88 - ...1-PM-Introduce-struct-pm_subsys_data.patch | 391 -- ...erence-counting-of-power.subsys_data.patch | 207 - ...power.sybsys_data-to-reduce-overhead.patch | 519 -- ...-and-rename-the-implementation-files.patch | 326 - ...-need-to-supply-locks-to-plist-heads.patch | 246 - .../0056-PM-QoS-Minor-clean-ups.patch | 409 -- .../0057-PM-QoS-Code-reorganization.patch | 85 - .../0058-PM-QoS-Reorganize-data-structs.patch | 243 - ...e-and-export-constraints-management-.patch | 292 - ...lement-per-device-PM-QoS-constraints.patch | 535 -- ...l-notification-mechanism-for-device-.patch | 230 - ...minary-support-for-devices-with-powe.patch | 110 - ...ntime_idle-can-be-called-in-atomic-c.patch | 33 - ...m-Add-cpu-power-management-notifiers.patch | 382 -- ...not-acquire-a-mutex-under-a-spinlock.patch | 194 - ...-device-PM-domain-data-into-base-and.patch | 173 - .../0067-doc-fix-broken-references.patch | 136 - ...-run-callbacks-under-lock-for-power..patch | 146 - ...duce-trace-points-for-tracing-rpm_-f.patch | 169 - ...-rpm-traces.c-only-if-CONFIG_PM_RUNT.patch | 36 - ...time-Replace-dev_dbg-with-trace_rpm_.patch | 105 - ...Add-OPP-availability-change-notifier.patch | 143 - ...-build-when-CONFIG_PM_OPP-is-not-set.patch | 45 - ...dd-function-dev_pm_qos_read_value-v3.patch | 463 -- ...cumentation-for-the-pm_qos-and-dev_p.patch | 155 - ...me-bitrot-in-the-machine-driver-docu.patch | 51 - ...y-documentation-for-regulator-regula.patch | 55 - ...time-Update-document-about-callbacks.patch | 57 - ...ix-kerneldoc-comment-for-rpm_suspend.patch | 57 - ...e-.runtime_suspend-failure-correctly.patch | 74 - ...tatistics-debugfs-file-for-suspend-t.patch | 409 -- ...ue-in-main.c-for-CONFIG_PM_SLEEP-uns.patch | 41 - ...lude-storage-keys-in-hibernation-ima.patch | 302 - ...-defined-uglyness-and-fix-compile-er.patch | 114 - ...he-policy-on-default-wakeup-settings.patch | 52 - ...eze-kernel-threads-after-preallocati.patch | 171 - ...nate-Fix-typo-in-a-kerneldoc-comment.patch | 35 - ...-resumewait-param-to-support-MMC-lik.patch | 101 - ...-resumedelay-kernel-param-in-additio.patch | 82 - ...not-initialize-static-and-extern-var.patch | 46 - ...rove-performance-of-LZO-plain-hibern.patch | 1160 ---- ...vices-involved-in-wakeup-signaling-d.patch | 95 - ...-Update-docs-about-suspend-and-CPU-h.patch | 321 - ...e-redundant-NULL-checks-before-kfree.patch | 37 - ...x-several-implicit-usasges-of-kmod.h.patch | 70 - ...-explicitly-needing-EXPORT_SYMBOL-in.patch | 151 - ...-export.h-for-EXPORT_SYMBOL-THIS_MOD.patch | 143 - ...nge-module.h-export.h-in-power-commo.patch | 33 - ...ime.h-explicitly-requires-notifier.h.patch | 31 - ...M-Sleep-Update-freezer-documentation.patch | 53 - ...runtime-accounting-calculation-error.patch | 40 - .../0102-PM-QoS-Remove-redundant-check.patch | 33 - ...omatically-retry-failed-autosuspends.patch | 95 - .../0104-PM-QoS-Set-cpu_dma_pm_qos-name.patch | 35 - ...-ERR_CAST-instead-of-ERR_PTR-PTR_ERR.patch | 38 - ...isable-enabled-clocks-in-pm_clk_susp.patch | 44 - ...use-the-WARN-macro-in-dev_pm_qos_add.patch | 66 - ...extend-wakeup-paths-to-devices-with-.patch | 115 - ...-the-early-termination-of-test-modes.patch | 81 - ...Fix-bug-in-suspend-statistics-update.patch | 45 - ...necessarily-set-PF_NOFREEZE-explicit.patch | 86 - ...ent-state-restoration-race-in-refrig.patch | 57 - ...-refrigerator-and-update-try_to_free.patch | 336 - ...-if-oom-killed-thread-is-frozen-befo.patch | 53 - ...t-and-use-kthread_freezable_should_s.patch | 239 - ...haw_process-to-__thaw_task-and-simpl.patch | 158 - ...acy-clear_freeze_flag-and-set-PF_NOF.patch | 66 - ...on-t-distinguish-nosig-tasks-on-thaw.patch | 68 - ...cated-lock-instead-of-task_lock-memo.patch | 187 - ...ezing-indicate-freeze-condition-in-e.patch | 162 - ...ezable-conditions-while-holding-free.patch | 87 - ...ean-up-freeze_processes-failure-path.patch | 239 - ...er-prepare-for-removal-of-TIF_FREEZE.patch | 178 - ...ezing-test-freeze-conditions-in-effe.patch | 316 - ...-fallout-from-the-thaw_process-renam.patch | 30 - ...ove-unused-sig_only-from-freeze_task.patch | 142 - ...not-leak-memory-in-error-test-code-p.patch | 75 - ...on-and-remove-extraneous-whitespaces.patch | 55 - ...unnecessary-label-and-jumps-to-it-fo.patch | 57 - ...-Sleep-Simplify-device_suspend_noirq.patch | 58 - ...actor-and-simplify-hibernation_snaps.patch | 80 - ...ent-how-PM-domains-are-used-by-the-P.patch | 122 - ...-inaccurate-information-in-devices.t.patch | 46 - ...documentation-follow-the-new-behavio.patch | 42 - ...documentation-related-to-system-wake.patch | 103 - ...ts-describing-device-power-managemen.patch | 309 - ...ime-Use-device-PM-QoS-constraints-v2.patch | 353 - ...it-possible-to-use-per-device-domain.patch | 390 -- ...duce-save-restore-state-device-callb.patch | 173 - ...k-system-suspend-callback-routines-v.patch | 420 -- ...Add-device-stop-governor-function-v4.patch | 319 - ...efault-power-off-governor-function-v.patch | 207 - ...atically-update-overoptimistic-laten.patch | 128 - ...ompilation-failure-for-CONFIG_PM_GEN.patch | 44 - ...gulator_register-API-signature-in-Do.patch | 37 - ...ble-usermodehelpers-in-software_resu.patch | 38 - ...w-processes-in-SNAPSHOT_CREATE_IMAGE.patch | 83 - ...ove-deprecated-hibernation-test-mode.patch | 138 - ...iagnostic-messages-from-device-suspe.patch | 251 - ...lace-unintuitive-if-condition-in-ker.patch | 35 - ...it-possible-to-assign-names-to-gener.patch | 73 - ...efault-system-suspend-resume-operati.patch | 78 - ...-mutex_-un-lock-pm_mutex-with-un-loc.patch | 234 - ...nd-un-lock_system_sleep-over-using-p.patch | 55 - ...de-an-always-on-power-domain-governo.patch | 66 - ...ove-deprecated-hibernation-snapshot-.patch | 190 - ...ify-generic-system-suspend-callbacks.patch | 97 - ...-internal-functions-in-generic_ops.c.patch | 122 - ..._op-and-pm_noirq_op-return-callback-.patch | 394 -- ...r-callback-directly-if-the-subsystem.patch | 512 -- .../0161-PM-Drop-generic_subsys_pm_ops.patch | 100 - ...duce-dev_pm_qos_add_ancestor_request.patch | 111 - ...y-Add-initial-Charger-Manager-driver.patch | 1143 ---- ...lement-compat_ioctl-for-dev-snapshot.patch | 110 - ...ntensive-memory-corruption-debugging.patch | 266 - ...-do-not-count-debug-pages-as-savable.patch | 56 - ...rger-Manager-Add-properties-for-powe.patch | 475 -- ...-Fix-build-for-CONFIG_PM_SLEEP-unset.patch | 55 - ...governor-functions-for-CONFIG_PM_RUN.patch | 69 - ...-Fix-spelling-mistake-in-basic-pm-de.patch | 30 - ...-Fix-minor-issue-in-freezing_of_task.patch | 42 - ...rect-additional-pages-number-calcula.patch | 34 - .../0173-PM-Domains-Add-OF-support.patch | 124 - ...-s2disk-regression-related-to-freezi.patch | 110 - ...ce-late-suspend-and-early-resume-of-.patch | 979 --- ...ce-generic-callbacks-for-new-device-.patch | 316 - ...ate-early-device-suspend-callbacks-a.patch | 352 - ...-QoS-Simplify-PM-QoS-expansion-merge.patch | 89 - ...w-kernel-threads-in-SNAPSHOT_CREATE_.patch | 49 - ...only-kernel-threads-if-freezing-of-k.patch | 110 - ...-C-state-breakage-with-PM-Qos-change.patch | 58 - ...-code-duplication-in-suspend-statist.patch | 93 - ...Document-the-beauty-of-freeze-thaw-s.patch | 60 - ...w-kernel-threads-in-hibernation_snap.patch | 77 - ...actor-and-simplify-freezer_test_done.patch | 71 - ...de-a-dummy-dev_gpd_data-when-generic.patch | 52 - ...q-o-be-available-for-CONFIG_PM-unset.patch | 53 - ...oS-unconditionally-build-the-feature.patch | 116 - ...ize-wakeup-source-locks-in-wakeup_so.patch | 41 - ...check-wakeup-too-often-in-try_to_fre.patch | 48 - ...unnecessary-label-from-suspend_freez.patch | 51 - ...erneldoc-comments-in-kernel-power-su.patch | 142 - ...ter_state-in-kernel-power-suspend.c-.patch | 75 - ...4-PM-Sleep-Drop-suspend_stats_update.patch | 79 - ...escribing-relationships-between-PM-c.patch | 45 - ...nt-physical-addresses-consistently-w.patch | 39 - ...sible-infinite-loop-during-wakeup-so.patch | 66 - ...e-conditions-related-to-wakeup-sourc.patch | 75 - ...e-wakeup-source-initialization-routi.patch | 179 - ...e-references-to-TIF_FREEZE-in-commen.patch | 80 - ...nclude-for-PM_GENERIC_DOMAINS-n-case.patch | 59 - ...ossible-to-expose-PM-QoS-latency-con.patch | 282 - ...andling-of-wakeup-devices-during-sys.patch | 51 - ...ix-hibernation-restore-of-devices-v2.patch | 97 - ...ains-Introduce-always-on-device-flag.patch | 155 - ...-domain-status-during-hibernation-re.patch | 40 - ...-forget-to-wake-up-waitqueue-on-fail.patch | 49 - ...able-usermode-helpers-right-before-f.patch | 94 - ...sabling-of-usermode-helpers-to-the-f.patch | 188 - ...dd-pm_qos_update_request_timeout-API.patch | 150 - ...001-spi-add-support-for-renesas-rspi.patch | 595 -- .../002-spi-irq-remove-irqf_disabled.patch | 57 - ...acro-for-platform_driver-boilerplate.patch | 92 - ...m_type_mask-decoding-for-access-size.patch | 85 - ...sh7757-add-clkdev_ick_id-for-cleanup.patch | 82 - ...move-clkdev_xxx_id-macro-to-sh_clk.h.patch | 54 - ...-the-compile-error-in-setup-sh7757.c.patch | 51 - ...-for-ehci-and-riic-in-clock-sh7757.c.patch | 57 - ...009-sh-add-a-resource-name-for-shdma.patch | 75 - ...fy-resource-for-spi0-in-setup-sh7757.patch | 46 - ...form_device-for-spi1-in-setup-sh7757.patch | 68 - ...odify-clock-sh7757-for-renesas_usbhs.patch | 48 - ...d-parameter-for-rspi-in-clock-sh7757.patch | 58 - ...eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch | 44 - ...form_device-for-rspi-in-setup-sh7757.patch | 67 - ...fix-build-warning-in-board-sh7757lcr.patch | 82 - ...for-renesas_usbhs-in-board-sh7757lcr.patch | 93 - ...h_mmcif_plat_data-in-board-sh7757lcr.patch | 48 - ...h_giga1_resources-in-board-sh7757lcr.patch | 48 - .../020-sh-kexec-register-crashk_res.patch | 63 - .../021-sh-kexec-add-physical_start.patch | 165 - ...-generalize-runtime-pm-platform-stub.patch | 198 - ...m_runtime-pm_runtime.o-must-be-built.patch | 41 - ...for-the-latest-sh_mobile_sdhi-driver.patch | 41 - series | 836 --- 830 files changed, 29 insertions(+), 129725 deletions(-) delete mode 100644 patches.android/android-0001-Revert-Staging-android-delete-android-drivers.patch delete mode 100644 patches.android/android-0002-staging-android-fix-build-issues.patch delete mode 100644 patches.android/android-0003-android-common-include-linux-slab.h.patch delete mode 100644 patches.android/android-0004-android-common-Fix-slab.h-includes-for-2.6.34-rc4.patch delete mode 100644 patches.android/android-0005-Revert-Staging-android-mark-subsystem-as-broken.patch delete mode 100644 patches.android/android-0006-staging-android-ramconsole-Ensure-ramconsole-does-not-get-cl.patch delete mode 100644 patches.android/android-0007-Staging-android-ram_console-Start-ram-console-earlier.patch delete mode 100644 patches.android/android-0008-Staging-android-timed_gpio-Request-gpios.patch delete mode 100644 patches.android/android-0009-android-logger-Add-new-system-log-for-framework-system-log-m.patch delete mode 100644 patches.android/android-0010-binder-Use-seq_file-for-debug-interface.patch delete mode 100644 patches.android/android-0011-staging-android-binder-Move-debugging-information-from-procf.patch delete mode 100644 patches.android/android-0012-Staging-android-timed_gpio-Properly-discard-invalid-timeout-.patch delete mode 100644 patches.android/android-0013-Staging-android-binder-Create-dedicated-workqueue-for-binder.patch delete mode 100644 patches.android/android-0014-staging-android-lowmemorykiller-Don-t-try-to-kill-the-same-p.patch delete mode 100644 patches.android/android-0015-staging-android-lowmemkiller-Substantially-reduce-overhead-d.patch delete mode 100644 patches.android/android-0016-staging-binder-Fix-memory-corruption-via-page-aliasing.patch delete mode 100644 patches.android/android-0017-staging-android-lowmemorykiller-Remove-bitrotted-codepath.patch delete mode 100644 patches.android/android-0018-staging-android-lowmemorykiller-Update-arguments-of-shrinker.patch delete mode 100644 patches.android/android-0019-staging-android-lowmemorykiller-Ignore-shmem-pages-in-page-c.patch delete mode 100644 patches.android/android-0020-android-lowmemorykiller-Fix-arguments-to-lowmem_shrink.patch delete mode 100644 patches.android/android-0021-android-logger-bump-up-the-logger-buffer-sizes.patch delete mode 100644 patches.android/android-0022-staging-android-ram_console-pass-in-a-boot-info-string.patch delete mode 100644 patches.android/android-0023-Staging-android-fixed-white-spaces-coding-style-issue-in-log.patch delete mode 100644 patches.android/android-0024-staging-android-switch-switch-class-and-GPIO-drivers.patch delete mode 100644 patches.android/android-0025-staging-android-switch-minor-code-formatting-cleanups.patch delete mode 100644 patches.android/android-0026-staging-android-add-pmem-driver.patch delete mode 100644 patches.android/android-0027-ashmem-Anonymous-shared-memory-subsystem.patch delete mode 100644 patches.android/android-0028-ashmem-Implement-read-2-in-ashmem-driver.patch delete mode 100644 patches.android/android-0029-ashmem-Fix-ASHMEM_SET_PROT_MASK.patch delete mode 100644 patches.android/android-0030-ashmem-Update-arguments-of-shrinker-for-2.6.35.patch delete mode 100644 patches.android/android-0031-ashmem-Support-lseek-2-in-ashmem-driver.patch delete mode 100644 patches.android/android-0032-ashmem-Fix-arguments-to-ashmem_shrink.patch delete mode 100644 patches.android/android-0033-ashmem-Whitespace-cleanups.patch delete mode 100644 patches.android/android-0034-Staging-android-fixed-a-space-warning-in-binder.h.patch delete mode 100644 patches.android/android-0035-Staging-android-fixed-80-characters-warnings-in-lowmemorykil.patch delete mode 100644 patches.android/android-0036-Staging-android-binder-Don-t-call-dump_stack-in-binder_vma_o.patch delete mode 100644 patches.android/android-0037-Staging-android-Remove-pmem-driver.patch delete mode 100644 patches.android/android-0038-Staging-android-binder-Fix-crashes-when-sharing-a-binder-fil.patch delete mode 100644 patches.android/android-0039-staging-android-lowmemorykiller-Don-t-wait-more-than-one-sec.patch delete mode 100644 patches.android/android-0040-staging-android-ram_console-Don-t-build-on-arches-w-o-iorema.patch delete mode 100644 patches.android/staging-android-add-the-code-back-to-the-build.patch delete mode 100644 patches.armadillo800eva/0001-module.h-split-out-the-EXPORT_SYMBOL-into-export.h.patch delete mode 100644 patches.armadillo800eva/0002-arm-Add-export.h-to-ARM-specific-files-as-required.patch delete mode 100644 patches.armadillo800eva/0003-ARM-mach-shmobile-cpuidle-single-global-and-last_sta.patch delete mode 100644 patches.armadillo800eva/0004-ARM-entry-re-allocate-registers-in-irq-entry-assembl.patch delete mode 100644 patches.armadillo800eva/0005-ARM-mach-shmobile-rename-clk_init-to-shmobile_clk_in.patch delete mode 100644 patches.armadillo800eva/0006-ARM-mach-shmobile-add-shmobile_earlytimer_init.patch delete mode 100644 patches.armadillo800eva/0007-ARM-mach-shmobile-default-to-no-earlytimer.patch delete mode 100644 patches.armadillo800eva/0008-ARM-shmobile-Consolidate-time-keeping-and-irq-enable.patch delete mode 100644 patches.armadillo800eva/0009-sh-pfc-get_config_reg-shift-clean-up.patch delete mode 100644 patches.armadillo800eva/0010-sh-pfc-Remove-unused-gpio_in_use-member.patch delete mode 100644 patches.armadillo800eva/0011-sh-pfc-Add-GPIO-IRQ-support.patch delete mode 100644 patches.armadillo800eva/0012-ARM-mach-shmobile-move-helper-macro-PORT_DATA_xx-to-.patch delete mode 100644 patches.armadillo800eva/0013-ARM-mach-shmobile-move-helper-macro-PORT_xx-to-sh_pf.patch delete mode 100644 patches.armadillo800eva/0014-ARM-mach-shmobile-move-helper-macro-PORTCR-to-sh_pfc.patch delete mode 100644 patches.armadillo800eva/0015-sh-pfc-ioremap-support.patch delete mode 100644 patches.armadillo800eva/0016-sh-pfc-Add-gpio_read_bit-for-data-register-access.patch delete mode 100644 patches.armadillo800eva/0017-sh-pfc-Convert-index-to-field-and-value-pair.patch delete mode 100644 patches.armadillo800eva/0018-sh-pfc-Add-config_reg_helper-function.patch delete mode 100644 patches.armadillo800eva/0019-sh-pfc-Variable-bitfield-width-config-register-suppo.patch delete mode 100644 patches.armadillo800eva/0020-sh-pfc-Unlock-register-support.patch delete mode 100644 patches.armadillo800eva/0021-ARM-mach-shmobile-Break-out-INTC-IRQ-code.patch delete mode 100644 patches.armadillo800eva/0022-sh-intc-enable-both-edges-GPIO-interrupts-on-sh7372.patch delete mode 100644 patches.armadillo800eva/0023-sh-intc-Add-IRQ-trigger-bit-field-check.patch delete mode 100644 patches.armadillo800eva/0024-sh-userimask.c-needs-linux-stat.h.patch delete mode 100644 patches.armadillo800eva/0025-sh-fix-implicit-use-of-stat.h-in-arch-sh-specific-fi.patch delete mode 100644 patches.armadillo800eva/0026-sh-Add-module.h-to-arch-sh-specific-files-as-require.patch delete mode 100644 patches.armadillo800eva/0027-sh-Add-export.h-to-arch-sh-specific-files-as-require.patch delete mode 100644 patches.armadillo800eva/0028-drivers-sh-Add-export.h-for-EXPORT_SYMBOL-to-intc-vi.patch delete mode 100644 patches.armadillo800eva/0029-driver-core-implement-sysdev-functionality-for-regul.patch delete mode 100644 patches.armadillo800eva/0030-sh-intc-Allow-triggering-on-both-edges-for-ARM-SoCs.patch delete mode 100644 patches.armadillo800eva/0031-sh-intc-convert-sysdev_class-to-a-regular-subsystem.patch delete mode 100644 patches.armadillo800eva/0032-PM-shmobile-Don-t-include-SH7372-s-INTCS-in-syscore-.patch delete mode 100644 patches.armadillo800eva/0033-sh-intc-unify-evt2irq-irq2evt-macros-for-sh-and-arm.patch delete mode 100644 patches.armadillo800eva/0034-sh-intc-Make-global-intc-controller-counter-static.patch delete mode 100644 patches.armadillo800eva/0035-genirq-Add-IRQCHIP_SKIP_SET_WAKE-flag.patch delete mode 100644 patches.armadillo800eva/0036-sh-intc-Prefer-IRQCHIP_SKIP_SET_WAKE-over-a-dummy-se.patch delete mode 100644 patches.armadillo800eva/0037-sh-intc-Kill-off-superfluous-irq_shutdown-hooking.patch delete mode 100644 patches.armadillo800eva/0038-sh-intc-Use-IRQ_SET_MASK_OK_NOCOPY-for-intc_set_affi.patch delete mode 100644 patches.armadillo800eva/0039-sh-intc-optimize-intc-IRQ-lookup.patch delete mode 100644 patches.armadillo800eva/0040-sh-intc-remove-dependency-on-NR_IRQS.patch delete mode 100644 patches.armadillo800eva/0041-sh-intc-Fix-up-section-mismatch-for-intc_ack_data.patch delete mode 100644 patches.armadillo800eva/0042-drivers-sh-late-disabling-of-clocks-V2.patch delete mode 100644 patches.armadillo800eva/0043-sh-clkfwk-Convert-to-IS_ERR_OR_NULL.patch delete mode 100644 patches.armadillo800eva/0044-sh-move-CLKDEV_xxx_ID-macro-to-sh_clk.h.patch delete mode 100644 patches.armadillo800eva/0045-switch-assorted-clock-drivers-to-debugfs_remove_recu.patch delete mode 100644 patches.armadillo800eva/0046-sh-clkfwk-add-clk_rate_mult_range_round.patch delete mode 100644 patches.armadillo800eva/0047-sh-clkfwk-Kill-off-remaining-debugfs-cruft.patch delete mode 100644 patches.armadillo800eva/0048-sh-clkfwk-setup-clock-parent-from-current-register-v.patch delete mode 100644 patches.armadillo800eva/0049-sh-extend-clock-struct-with-mapped_reg-member.patch delete mode 100644 patches.armadillo800eva/0050-sh-use-ioread32-iowrite32-and-mapped_reg-for-mstp32.patch delete mode 100644 patches.armadillo800eva/0051-sh-use-ioread32-iowrite32-and-mapped_reg-for-div4.patch delete mode 100644 patches.armadillo800eva/0052-sh-use-ioread32-iowrite32-and-mapped_reg-for-div6.patch delete mode 100644 patches.armadillo800eva/0053-sh-clkfwk-sh_clk_init_parent-should-be-called-after-.patch delete mode 100644 patches.armadillo800eva/0054-sh-clkfwk-bugfix-use-clk_reparent-for-div6-clocks.patch delete mode 100644 patches.armadillo800eva/0055-sh-introduce-sh_clk_ops-in-parallel-with-clk_ops.patch delete mode 100644 patches.armadillo800eva/0056-sh-convert-cpg-code-to-sh_clk_ops.patch delete mode 100644 patches.armadillo800eva/0057-ARM-mach-shmobile-R-Mobile-A1-support.patch delete mode 100644 patches.armadillo800eva/0058-ARM-mach-shmobile-r8a7740-add-PFC-support.patch delete mode 100644 patches.armadillo800eva/0059-ARM-mach-shmobile-r8a7740-add-i2c-support.patch delete mode 100644 patches.armadillo800eva/0060-ARM-mach-shmobile-r8a7740-add-INTC-support.patch delete mode 100644 patches.armadillo800eva/0061-ARM-mach-shmobile-bonito-Add-LCDC0-support.patch delete mode 100644 patches.armadillo800eva/0062-ARM-mach-shmobile-r8a7740-sh_clk_ops-rename.patch delete mode 100644 patches.armadillo800eva/0063-ARM-mach-shmobile-r8a7740-map_io-and-init_early-upda.patch delete mode 100644 patches.armadillo800eva/0064-ARM-mach-shmobile-rename-clk_init-to-shmobile_clk_in.patch delete mode 100644 patches.armadillo800eva/0065-ARM-mach-shmobile-r8a7740-and-Bonito-timer-rework.patch delete mode 100644 patches.armadillo800eva/0066-ARM-mach-shmobile-pfc-r8a7740-add-gpio_irq-support.patch delete mode 100644 patches.armadillo800eva/0067-net-sh_eth-tidyup-compile-warning.patch delete mode 100644 patches.armadillo800eva/0068-net-sh_eth-remove-__flush_purge_region.patch delete mode 100644 patches.armadillo800eva/0069-sh_eth-Move-the-Renesas-SuperH-driver.patch delete mode 100644 patches.armadillo800eva/0070-net-sh_eth-Fix-build-by-forgot-including-linux-inter.patch delete mode 100644 patches.armadillo800eva/0071-net-remove-use-of-ndo_set_multicast_list-in-drivers.patch delete mode 100644 patches.armadillo800eva/0072-net-sh_eth-fix-the-compile-error.patch delete mode 100644 patches.armadillo800eva/0073-net-sh_eth-use-ioremap.patch delete mode 100644 patches.armadillo800eva/0074-sh-modify-prototype-in-sh_eth.h.patch delete mode 100644 patches.armadillo800eva/0075-net-sh_eth-move-the-asm-sh_eth.h-to-include-linux.patch delete mode 100644 patches.armadillo800eva/0076-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-some.patch delete mode 100644 patches.armadillo800eva/0077-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh77.patch delete mode 100644 patches.armadillo800eva/0078-net-sh_eth-fix-build-failure.patch delete mode 100644 patches.armadillo800eva/0079-net-ethernet-convert-drivers-net-ethernet-to-use-mod.patch delete mode 100644 patches.armadillo800eva/0080-net-make-ethtool_ops-const.patch delete mode 100644 patches.armadillo800eva/0081-sh-eth-use-an-unique-MDIO-bus-name.patch delete mode 100644 patches.armadillo800eva/0082-net-sh-eth-Fix-build-error-by-the-value-which-is-not.patch delete mode 100644 patches.armadillo800eva/0083-drivers-net-Remove-alloc_etherdev-error-messages.patch delete mode 100644 patches.armadillo800eva/0084-net-sh_eth-fix-skb_over_panic-happen.patch delete mode 100644 patches.armadillo800eva/0085-sh-eth-use-netdev-stats-structure-and-fix-dma_map_si.patch delete mode 100644 patches.armadillo800eva/0086-netdev-ethernet-dev_alloc_skb-to-netdev_alloc_skb.patch delete mode 100644 patches.armadillo800eva/0087-renesas-sh_eth.c-fix-linux-interrupt.h-included-twic.patch delete mode 100644 patches.armadillo800eva/0088-net-sh_eth-add-the-value-of-tsu-to-the-SH7757-s-GETH.patch delete mode 100644 patches.armadillo800eva/0089-net-sh_eth-change-the-condition-of-initialization.patch delete mode 100644 patches.armadillo800eva/0090-net-sh_eth-modify-a-condition-of-ioremap-for-TSU.patch delete mode 100644 patches.armadillo800eva/0091-net-sh_eth-add-support-for-multicast-filtering.patch delete mode 100644 patches.armadillo800eva/0092-net-sh_eth-add-support-for-VLAN-tag-filtering.patch delete mode 100644 patches.armadillo800eva/0093-net-sh_eth-Add-support-SH7734.patch delete mode 100644 patches.armadillo800eva/0094-net-sh_eth-fix-endian-check-for-architecture-indepen.patch delete mode 100644 patches.armadillo800eva/0095-net-sh_eth-add-support-R8A7740.patch delete mode 100644 patches.armadillo800eva/0096-atomic-use-linux-atomic.h.patch delete mode 100644 patches.armadillo800eva/0097-fbdev-sh_mobile_meram-Enable-runtime-PM.patch delete mode 100644 patches.armadillo800eva/0098-fbdev-sh_mobile_meram-Enable-disable-MERAM-along-wit.patch delete mode 100644 patches.armadillo800eva/0099-fbdev-sh_mobile_meram-Move-private-data-from-.h-to-..patch delete mode 100644 patches.armadillo800eva/0100-fbdev-sh_mobile_meram-Backup-restore-device-register.patch delete mode 100644 patches.armadillo800eva/0101-drivercore-Add-helper-macro-for-platform_driver-boil.patch delete mode 100644 patches.armadillo800eva/0102-drivercore-Generalize-module_platform_driver.patch delete mode 100644 patches.armadillo800eva/0103-fbdev-sh_mobile_lcdc-Turn-dot-clock-on-before-resumi.patch delete mode 100644 patches.armadillo800eva/0104-fbdev-sh_mobile_lcdc-Replace-hardcoded-register-valu.patch delete mode 100644 patches.armadillo800eva/0105-fbdev-sh_mobile_lcdc-Don-t-acknowlege-interrupts-uni.patch delete mode 100644 patches.armadillo800eva/0106-fbdev-sh_mobile_lcdc-Compute-clock-pattern-using-div.patch delete mode 100644 patches.armadillo800eva/0107-fbdev-sh_mobile_lcdc-Split-LCDC-start-code-from-sh_m.patch delete mode 100644 patches.armadillo800eva/0108-fbdev-sh_mobile_lcdc-Store-the-frame-buffer-base-add.patch delete mode 100644 patches.armadillo800eva/0109-fbdev-sh_mobile_lcdc-Restart-LCDC-in-runtime-PM-resu.patch delete mode 100644 patches.armadillo800eva/0110-fbdev-sh_mobile_meram-Replace-hardcoded-register-val.patch delete mode 100644 patches.armadillo800eva/0111-fbdev-sh_mobile_meram-Validate-ICB-configuration-out.patch delete mode 100644 patches.armadillo800eva/0112-fbdev-sh_mobile_meram-Fix-MExxCTL-register-save-on-r.patch delete mode 100644 patches.armadillo800eva/0113-fbdev-sh_mobile_meram-Remove-unneeded-sh_mobile_mera.patch delete mode 100644 patches.armadillo800eva/0114-sh_mobile_meram-Reset-ICBs-at-unregistration-time.patch delete mode 100644 patches.armadillo800eva/0115-fbdev-sh_mobile_lcdc-Adjust-requested-parameters-in-.patch delete mode 100644 patches.armadillo800eva/0116-fbdev-sh_mobile_lcdc-Add-support-for-format-changes-.patch delete mode 100644 patches.armadillo800eva/0117-fbdev-sh_mobile_lcdc-use-display-information-in-info.patch delete mode 100644 patches.armadillo800eva/0118-fbdev-sh_mobile_lcdc-Update-fix.line_length-in-.fb_s.patch delete mode 100644 patches.armadillo800eva/0119-fbdev-sh_mobile_lcdc-Avoid-forward-declarations.patch delete mode 100644 patches.armadillo800eva/0120-fbdev-sh_mobile_lcdc-Split-channel-initialization-fr.patch delete mode 100644 patches.armadillo800eva/0121-fbdev-sh_mobile_lcdc-Remove-sh_mobile_lcdc_set_bpp.patch delete mode 100644 patches.armadillo800eva/0122-video-irq-Remove-IRQF_DISABLED.patch delete mode 100644 patches.armadillo800eva/0123-video-Add-module.h-to-drivers-video-files-who-really.patch delete mode 100644 patches.armadillo800eva/0124-fbdev-sh_mobile_lcdcfb-fixup-LDHAJR-HSYNPAJ-needs-ma.patch delete mode 100644 patches.armadillo800eva/0125-fbdev-sh_mipi_dsi-tidyup-dsip_clk.patch delete mode 100644 patches.armadillo800eva/0126-fbdev-sh_mipi_dsi-typo-fix-of-SH_MIPI_DSI_HBPBM.patch delete mode 100644 patches.armadillo800eva/0127-fbdev-sh_mipi_dsi-tidyup-VMCTR2-parameter-expression.patch delete mode 100644 patches.armadillo800eva/0128-fbdev-sh_mipi_dsi-add-SH_MIPI_DSI_HFPBM-flag.patch delete mode 100644 patches.armadillo800eva/0129-fbdev-sh_mipi_dsi-add-SH_MIPI_DSI_BL2E-flag.patch delete mode 100644 patches.armadillo800eva/0130-fbdev-sh_mipi_dsi-add-lane-control-support.patch delete mode 100644 patches.armadillo800eva/0131-fbdev-sh_mipi_dsi-add-sync_pulses-sync_events-burst-.patch delete mode 100644 patches.armadillo800eva/0132-fbdev-sh_mipi_dsi-add-VMLEN1-VMLEN2-calculation.patch delete mode 100644 patches.armadillo800eva/0133-fbdev-sh_mipi_dsi-add-set_dot_clock-for-each-platfor.patch delete mode 100644 patches.armadillo800eva/0134-fbdev-sh_mipi_dsi-add-HSxxCLK-support.patch delete mode 100644 patches.armadillo800eva/0135-fbdev-sh_mipi_dsi-sh_mipi-has-pdata-instead-of-dev.patch delete mode 100644 patches.armadillo800eva/0136-fbdev-sh_mipi_dsi-fixup-setup-timing-of-sh_mipi_setu.patch delete mode 100644 patches.armadillo800eva/0137-fbdev-sh_mipi_dsi-fixup-setup-timing-of-SYSCONF.patch delete mode 100644 patches.armadillo800eva/0138-fbdev-sh_mipi_dsi-fixup-setup-timing-DSICTRL.patch delete mode 100644 patches.armadillo800eva/0139-video-convert-drivers-video-to-use-module_platform_d.patch delete mode 100644 patches.armadillo800eva/0140-fbdev-Add-FOURCC-based-format-configuration-API.patch delete mode 100644 patches.armadillo800eva/0141-v4l-Add-V4L2_PIX_FMT_NV24-and-V4L2_PIX_FMT_NV42-form.patch delete mode 100644 patches.armadillo800eva/0142-arm-fix-compile-failure-in-mach-shmobile-board-ag5ev.patch delete mode 100644 patches.armadillo800eva/0143-sh-se7724-fix-compile-breakage.patch delete mode 100644 patches.armadillo800eva/0144-fbdev-sh_mobile_lcdc-Support-FOURCC-based-format-API.patch delete mode 100644 patches.armadillo800eva/0145-fbdev-sh_mobile_lcdc-Reorder-code-into-sections.patch delete mode 100644 patches.armadillo800eva/0146-fbdev-sh_mobile_lcdc-Mark-init-only-symbols-with-__d.patch delete mode 100644 patches.armadillo800eva/0147-fbdev-sh_mobile_lcdc-Move-pm-runtime-enable-to-probe.patch delete mode 100644 patches.armadillo800eva/0148-fbdev-sh_mobile_lcdc-Don-t-pass-struct-device-around.patch delete mode 100644 patches.armadillo800eva/0149-fbdev-sh_mobile_lcdc-Create-functions-to-turn-the-di.patch delete mode 100644 patches.armadillo800eva/0150-fbdev-sh_mobile_hdmi-Don-t-access-LCDC-channel-in-no.patch delete mode 100644 patches.armadillo800eva/0151-sh_mobile_hdmi-Remove-platform-data-lcd_dev-field.patch delete mode 100644 patches.armadillo800eva/0152-fbdev-sh_mobile_lcdc-Add-sh_mobile_lcdc_entity-defin.patch delete mode 100644 patches.armadillo800eva/0153-fbdev-sh_mobile_hdmi-Implement-sh_mobile_lcdc_entity.patch delete mode 100644 patches.armadillo800eva/0154-fbdev-sh_mipi_dsi-Implement-sh_mobile_lcdc_entity-in.patch delete mode 100644 patches.armadillo800eva/0155-fbdev-sh_mobile_lcdc-Handle-HDMI-MIPI-transmitter-de.patch delete mode 100644 patches.armadillo800eva/0156-fbdev-sh_mipi_dsi-Don-t-hook-up-into-board_cfg-displ.patch delete mode 100644 patches.armadillo800eva/0157-fbdev-sh_mobile_hdmi-Don-t-hook-up-into-board_cfg-di.patch delete mode 100644 patches.armadillo800eva/0158-arm-mach-shmobile-Don-t-initialize-the-hdmi_info-lcd.patch delete mode 100644 patches.armadillo800eva/0159-fbdev-sh_mobile_hdmi-Remove-sh_mobile_hdmi_info-lcd_.patch delete mode 100644 patches.armadillo800eva/0160-fbdev-sh_mobile_lcdc-Remove-board-configuration-owne.patch delete mode 100644 patches.armadillo800eva/0161-fbdev-sh_mobile_lcdc-Remove-board-configuration-boar.patch delete mode 100644 patches.armadillo800eva/0162-fbdev-sh_mobile_lcdc-Move-brightness-ops-to-sh_mobil.patch delete mode 100644 patches.armadillo800eva/0163-fbdev-sh_mobile_lcdc-Merge-board_cfg-and-lcd_size_cf.patch delete mode 100644 patches.armadillo800eva/0164-sh_mobile_lcdc-Add-an-lcdc-channel-pointer-to-sh_mob.patch delete mode 100644 patches.armadillo800eva/0165-sh_mobile_hdmi-Use-sh_mobile_lcdc_entity-channel-to-.patch delete mode 100644 patches.armadillo800eva/0166-fbdev-sh_mobile_lcdc-Remove-fb_info-parameter-to-dis.patch delete mode 100644 patches.armadillo800eva/0167-fbdev-sh_mobile_lcdc-Return-display-connection-state.patch delete mode 100644 patches.armadillo800eva/0168-sh_mobile_lcdc-Add-display-notify-callback-to-sh_mob.patch delete mode 100644 patches.armadillo800eva/0169-sh_mobile_hdmi-Use-LCDC-notification-callback.patch delete mode 100644 patches.armadillo800eva/0170-fbdev-sh_mobile_lcdc-Pass-a-video-mode-to-the-notify.patch delete mode 100644 patches.armadillo800eva/0171-fbdev-sh_mobile_hdmi-Don-t-set-sh_hdmi-mode-in-the-d.patch delete mode 100644 patches.armadillo800eva/0172-fbdev-sh_mobile_hdmi-Don-t-access-LCDC-fb_info.patch delete mode 100644 patches.armadillo800eva/0173-fbdev-sh_mobile_lcdc-Store-display-mode-in-a-struct-.patch delete mode 100644 patches.armadillo800eva/0174-fbdev-sh_mobile_lcdc-Rename-lcd-num-_cfg-lcd-num-_mo.patch delete mode 100644 patches.armadillo800eva/0175-fbdev-sh_mobile_lcdc-Reorganize-the-sh_mobile_lcdc_c.patch delete mode 100644 patches.armadillo800eva/0176-fbdev-sh_mobile_lcdc-Add-sh_mobile_format_info-funct.patch delete mode 100644 patches.armadillo800eva/0177-fbdev-sh_mobile_lcdc-Store-the-format-in-struct-sh_m.patch delete mode 100644 patches.armadillo800eva/0178-fbdev-sh_mobile_lcdc-Split-fb-init-cleanup-from-chan.patch delete mode 100644 patches.armadillo800eva/0179-fbdev-sh_mobile_lcdc-Pass-physical-device-pointer-to.patch delete mode 100644 patches.armadillo800eva/0180-fbdev-sh_mobile_lcdc-Store-configuration-in-channel-.patch delete mode 100644 patches.armadillo800eva/0181-fbdev-sh_mobile_lcdc-Pass-channel-pointer-to-sh_mobi.patch delete mode 100644 patches.armadillo800eva/0182-fbdev-sh_mobile_meram-Request-memory-regions-for-mem.patch delete mode 100644 patches.armadillo800eva/0183-fbdev-sh_mobile_meram-Add-_cfg-suffix-to-struct-sh_m.patch delete mode 100644 patches.armadillo800eva/0184-fbdev-sh_mobile_meram-Make-variables-unsigned-where-.patch delete mode 100644 patches.armadillo800eva/0185-fbdev-sh_mobile_meram-Make-current_reg-field-store-t.patch delete mode 100644 patches.armadillo800eva/0186-fbdev-sh_mobile_meram-Add-struct-sh_mobile_meram_icb.patch delete mode 100644 patches.armadillo800eva/0187-fbdev-sh_mobile_meram-Don-t-inline-everything.patch delete mode 100644 patches.armadillo800eva/0188-fbdev-sh_mobile_meram-Divide-the-code-into-sections.patch delete mode 100644 patches.armadillo800eva/0189-fbdev-sh_mobile_meram-Use-genalloc-to-manage-MERAM-a.patch delete mode 100644 patches.armadillo800eva/0190-fbdev-sh_mobile_meram-Allocate-ICBs-automatically.patch delete mode 100644 patches.armadillo800eva/0191-arm-mach-shmobile-Don-t-set-MERAM-ICB-numbers-in-pla.patch delete mode 100644 patches.armadillo800eva/0192-fbdev-sh_mobile_meram-Remove-unused-sh_mobile_meram_.patch delete mode 100644 patches.armadillo800eva/0193-fbdev-sh_mobile_lcdc-Don-t-store-copy-of-platform-da.patch delete mode 100644 patches.armadillo800eva/0194-fbdev-sh_mobile_meram-Don-t-perform-update-in-regist.patch delete mode 100644 patches.armadillo800eva/0195-fbdev-sh_mobile_meram-Remove-unneeded-sanity-checks.patch delete mode 100644 patches.armadillo800eva/0196-fbdev-sh_mobile_meram-Implement-system-suspend-resum.patch delete mode 100644 patches.armadillo800eva/0197-fbdev-sh_mipi_dsi-add-extra-phyctrl-for-sh_mipi_dsi_.patch delete mode 100644 patches.armadillo800eva/0198-serial-sh-sci-Kill-off-bitrotted-H8-300-support.patch delete mode 100644 patches.armadillo800eva/0199-serial-sh-sci-Tidy-up-ioread-write-wrappers-kill-off.patch delete mode 100644 patches.armadillo800eva/0200-serial-sh-sci-Kill-off-some-more-unused-definitions.patch delete mode 100644 patches.armadillo800eva/0201-serial-sh-sci-Generalize-overrun-handling.patch delete mode 100644 patches.armadillo800eva/0202-serial-sh-sci-Consolidate-RXD-pin-handling.patch delete mode 100644 patches.armadillo800eva/0203-serial-sh-sci-More-unused-define-purging.patch delete mode 100644 patches.armadillo800eva/0204-serial-sh-sci-Abstract-register-maps.patch delete mode 100644 patches.armadillo800eva/0205-serial-sh-sci-FIFO-sizing-helper-consolidation.patch delete mode 100644 patches.armadillo800eva/0206-serial-sh-sci-Support-generic-SCLSR-overrun-detectio.patch delete mode 100644 patches.armadillo800eva/0207-serial-sh-sci-Regtype-probing-doesn-t-need-to-be-fat.patch delete mode 100644 patches.armadillo800eva/0208-serial-sh-sci-Add-missing-module-description-author-.patch delete mode 100644 patches.armadillo800eva/0209-serial-sh-sci-Kill-off-per-port-enable-disable-callb.patch delete mode 100644 patches.armadillo800eva/0210-serial-sh-sci-Fix-up-pretty-name-printing-for-port-I.patch delete mode 100644 patches.armadillo800eva/0211-serial-sh-sci-Fix-up-default-regtype-probing.patch delete mode 100644 patches.armadillo800eva/0212-serial-sh-sci-fix-DMA-build-by-including-dma-mapping.patch delete mode 100644 patches.armadillo800eva/0213-serial-sh-sci-console-Runtime-PM-support.patch delete mode 100644 patches.armadillo800eva/0214-sh-sci-PM-Use-power.irq_safe.patch delete mode 100644 patches.armadillo800eva/0215-serial-sh-sci-report-CTS-as-active-for-get_mctrl.patch delete mode 100644 patches.armadillo800eva/0216-serial-sh-sci-don-t-filter-on-DMA-device-use-only-ch.patch delete mode 100644 patches.armadillo800eva/0217-TTY-irq-Remove-IRQF_DISABLED.patch delete mode 100644 patches.armadillo800eva/0218-serial-sh-sci-Fix-up-SH-2A-SCIF-support.patch delete mode 100644 patches.armadillo800eva/0219-serial-sh-sci-Fix-up-SCFCR-handling.patch delete mode 100644 patches.armadillo800eva/0220-serial-sh-sci-Support-icount-statistics-for-error-ca.patch delete mode 100644 patches.armadillo800eva/0221-serial-sh-sci-Clarify-enable_ms-break_ctl-comments.patch delete mode 100644 patches.armadillo800eva/0222-serial-sh-sci-Fix-up-modem-control-handling.patch delete mode 100644 patches.armadillo800eva/0223-serial-sh-sci-Add-support-for-loopback-mode.patch delete mode 100644 patches.armadillo800eva/0224-serial-sh-sci-per-port-modem-control.patch delete mode 100644 patches.armadillo800eva/0225-serial-sh-sci-Avoid-FIFO-clear-for-MCE-toggle.patch delete mode 100644 patches.armadillo800eva/0226-serial-sh-sci-Handle-GPIO-function-requests.patch delete mode 100644 patches.armadillo800eva/0227-Input-gpio_keys-switch-to-using-threaded-IRQs.patch delete mode 100644 patches.armadillo800eva/0228-Input-gpio_keys-move-to-late_initcall.patch delete mode 100644 patches.armadillo800eva/0229-Input-gpio_keys-fix-a-memory-leak.patch delete mode 100644 patches.armadillo800eva/0230-Input-gpio_keys-add-support-for-device-tree-platform.patch delete mode 100644 patches.armadillo800eva/0231-Input-gpio_keys-switch-to-using-SIMPLE_DEV_PM_OPS.patch delete mode 100644 patches.armadillo800eva/0232-Input-gpio_keys-return-proper-error-code-if-memory-a.patch delete mode 100644 patches.armadillo800eva/0233-Input-gpio_keys-fix-two-typos-in-devicetree-document.patch delete mode 100644 patches.armadillo800eva/0234-Input-gpio_keys-use-of_property_read_u32.patch delete mode 100644 patches.armadillo800eva/0235-Input-gpio_keys-fix-struct-device-declared-inside-pa.patch delete mode 100644 patches.armadillo800eva/0236-Input-gpio_keys-constify-platform-data.patch delete mode 100644 patches.armadillo800eva/0237-Input-revert-gpio_keys-switch-to-using-threaded-IRQs.patch delete mode 100644 patches.armadillo800eva/0238-Input-gpio_keys-consolidate-key-destructor-code.patch delete mode 100644 patches.armadillo800eva/0239-Input-gpio_keys-add-support-for-interrupt-only-keys.patch delete mode 100644 patches.armadillo800eva/0240-Input-sh_keysc-fix-compile-warning.patch delete mode 100644 patches.armadillo800eva/0241-Input-keyboard-use-macro-module_platform_driver.patch delete mode 100644 patches.armadillo800eva/0242-Update-Nook-Color-machine-3284-to-common-Encore-name.patch delete mode 100644 patches.armadillo800eva/0243-ARM-7051-1-cpuimx-boards-fix-mach-types-errors.patch delete mode 100644 patches.armadillo800eva/0244-ARM-Add-a-few-machine-types-to-mach-types.patch delete mode 100644 patches.armadillo800eva/0245-ARM-Update-mach-types-to-fix-mxs-build-breakage.patch delete mode 100644 patches.armadillo800eva/0246-ARM-7193-1-Fix-machine_is_xxx-naming-for-eSata-Sheev.patch delete mode 100644 patches.armadillo800eva/0247-ARM-Update-mach-types.patch delete mode 100644 patches.armadillo800eva/0248-ARM-mach-shmobile-add-armadillo800eva-board-support.patch delete mode 100644 patches.armadillo800eva/0249-ARM-mach-shmobile-armadillo800eva-add-defconfig.patch delete mode 100644 patches.armadillo800eva/0250-ARM-mach-shmobile-armadillo800eva-add-support-LCDC0.patch delete mode 100644 patches.armadillo800eva/0251-ARM-mach-shmobile-armadillo800eva-add-support-ST1232.patch delete mode 100644 patches.armadillo800eva/0252-ARM-mach-shmobile-armadillo800eva-add-support-gpio_k.patch delete mode 100644 patches.armadillo800eva/0253-ARM-mach-shmobile-armadillo800eva-add-support-sh_eth.patch delete mode 100644 patches.armadillo800eva/arm-mach-shmobile-armadillo800eva-defconfig-allow-use-of-armhf-userspace.patch delete mode 100644 patches.armadillo800eva/arm-mach-shmobile-armadillo800eva-defconfig-disable-config_sysfs_deprecated.patch delete mode 100644 patches.armadillo800eva/arm-mach-shmobile-armadillo800eva-defconfig-update.patch delete mode 100644 patches.armadillo800eva/arm-mach-shmobile-sh7372-ap4evb-and-mackerel-timer-rework.patch delete mode 100644 patches.armadillo800eva/ltsi-bugfix-armadillo800eva-sh_eth-needs-net_ethernet-on-defconfig.patch delete mode 100644 patches.kzm9g/0001-net-remove-mm.h-inclusion-from-netdevice.h.patch delete mode 100644 patches.kzm9g/0001-tty-serial-allow-ports-to-override-the-irq-handler.patch delete mode 100644 patches.kzm9g/0002-Include-linux-dma-mapping.h-in-linux-dmaengine.h.patch delete mode 100644 patches.kzm9g/0002-serial-introduce-generic-port-in-out-helpers.patch delete mode 100644 patches.kzm9g/0003-dmaengine-failure-to-get-a-specific-DMA-channel-is-n.patch delete mode 100644 patches.kzm9g/0003-serial-8250-increase-PASS_LIMIT.patch delete mode 100644 patches.kzm9g/0004-Improve-slave-cyclic-DMA-engine-documentation.patch delete mode 100644 patches.kzm9g/0004-serial-Fix-wakeup-init-logic-to-speed-up-startup.patch delete mode 100644 patches.kzm9g/0005-dmaengine-use-DEFINE_IDR-for-static-initialization.patch delete mode 100644 patches.kzm9g/0005-tty-serial8250-allow-platforms-to-override-irq-handl.patch delete mode 100644 patches.kzm9g/0006-dmaengine-add-helper-function-for-slave_single.patch delete mode 100644 patches.kzm9g/0006-tty-serial8250-remove-UPIO_DWAPB-32.patch delete mode 100644 patches.kzm9g/0007-dmaengine-remove-struct-scatterlist-for-header.patch delete mode 100644 patches.kzm9g/0007-tty-8250-export-serial8250_handle_irq.patch delete mode 100644 patches.kzm9g/0008-dmaengine-add-new-enum-dma_transfer_direction.patch delete mode 100644 patches.kzm9g/0008-serial-8250-Move-UPIO_TSI-to-powerpc.patch delete mode 100644 patches.kzm9g/0009-linux-dmaengine.h-fix-implicit-use-of-bitmap.h-and-a.patch delete mode 100644 patches.kzm9g/0009-serial-Support-the-EFR-register-of-XR1715x-uarts.patch delete mode 100644 patches.kzm9g/001-ltsi-backport-arm-mach-shmobile-kzm9g-add-smsc-9221-support.patch delete mode 100644 patches.kzm9g/0010-8250-ratelimit-LSR-safety-check-engaged-warning.patch delete mode 100644 patches.kzm9g/0010-DMAEngine-Define-interleaved-transfer-request-api.patch delete mode 100644 patches.kzm9g/0011-dmaengine-add-DMA_TRANS_NONE-to-dma_transfer_directi.patch delete mode 100644 patches.kzm9g/0011-serial-8250-replace-hardcoded-0xbf-with-define.patch delete mode 100644 patches.kzm9g/0012-dmaengine-Add-flow-controller-information-to-dma_sla.patch delete mode 100644 patches.kzm9g/0012-serial-move-struct-uart_8250_port-from-8250.c-to-825.patch delete mode 100644 patches.kzm9g/0013-dma-dmaengine-Distinguish-between-dmaengine-failed-t.patch delete mode 100644 patches.kzm9g/0013-serial-clean-up-parameter-passing-for-8250-Rx-IRQ-ha.patch delete mode 100644 patches.kzm9g/0014-dmaengine-add-private-header-file.patch delete mode 100644 patches.kzm9g/0014-serial-export-the-key-functions-for-an-8250-IRQ-hand.patch delete mode 100644 patches.kzm9g/0015-dmaengine-dma_slave-introduce-inline-wrappers.patch delete mode 100644 patches.kzm9g/0015-serial-make-8250-timeout-use-the-specified-IRQ-handl.patch delete mode 100644 patches.kzm9g/0016-ARM-Add-init_consistent_dma_size.patch delete mode 100644 patches.kzm9g/0016-serial-manually-inline-serial8250_handle_port.patch delete mode 100644 patches.kzm9g/0017-mmc-add-a-card-hotplug-handler-context.patch delete mode 100644 patches.kzm9g/0017-serial-group-all-the-8250-related-code-together.patch delete mode 100644 patches.kzm9g/0018-mmc-add-a-generic-GPIO-card-detect-helper.patch delete mode 100644 patches.kzm9g/0018-serial-Kill-off-NO_IRQ.patch delete mode 100644 patches.kzm9g/0019-mmc-simplify-mmc_cd_gpio_request-by-removing-two-par.patch delete mode 100644 patches.kzm9g/0019-tty-fix-a-build-failure-on-sparc.patch delete mode 100644 patches.kzm9g/002-lsti-backport-arm-mach-shmobile-kzm9g-add-external-usb-host-support.patch delete mode 100644 patches.kzm9g/0020-mmc-Standardize-header-file-inclusion-checks.patch delete mode 100644 patches.kzm9g/0020-tty-sparc-rename-drivers-tty-serial-suncore.h-includ.patch delete mode 100644 patches.kzm9g/0021-mmc-tmio-name-0xd8-as-CTL_DMA_ENABLE.patch delete mode 100644 patches.kzm9g/0021-serial-delete-last-unused-traces-of-pausing-I-O-in-8.patch delete mode 100644 patches.kzm9g/0022-mmc-tmio-Share-register-access-functions.patch delete mode 100644 patches.kzm9g/0022-serial-make-8250-s-serial_in-shareable-to-other-driv.patch delete mode 100644 patches.kzm9g/0023-mmc-sdhi-Add-write16_hook.patch delete mode 100644 patches.kzm9g/0023-serial-delete-useless-void-casts-in-8250.c.patch delete mode 100644 patches.kzm9g/0024-mmc-tmio-Fix-race-condition-resulting-in-spurious-in.patch delete mode 100644 patches.kzm9g/0024-serial-reduce-number-of-indirections-in-8250-code.patch delete mode 100644 patches.kzm9g/0025-mmc-tmio-fix-recursive-spinlock-don-t-schedule-with-.patch delete mode 100644 patches.kzm9g/0025-serial-use-serial_port_in-out-vs-serial_in-out-in-82.patch delete mode 100644 patches.kzm9g/0026-mmc-tmio-maximize-power-saving.patch delete mode 100644 patches.kzm9g/0026-serial-remove-back-and-forth-conversions-in-serial_o.patch delete mode 100644 patches.kzm9g/0027-mmc-tmio-fix-a-recently-introduced-bug-in-DMA-code.patch delete mode 100644 patches.kzm9g/0027-serial-8250_pci-add-a-force-background-timer-flag-an.patch delete mode 100644 patches.kzm9g/0028-8250.c-less-than-2400-baud-fix.patch delete mode 100644 patches.kzm9g/0028-mmc-tmio-fix-a-deadlock.patch delete mode 100644 patches.kzm9g/0029-net-remove-mm.h-inclusion-from-netdevice.h.patch delete mode 100644 patches.kzm9g/0029-serial8250-Add-dl_read-dl_write-callbacks.patch delete mode 100644 patches.kzm9g/003-ltsi-bugfix-sh73a0-add-lost-clk_enable_on_init-for-div6_zb1.patch delete mode 100644 patches.kzm9g/0030-MMC-TMIO-Fix-build-issue-related-to-struct-scatterli.patch delete mode 100644 patches.kzm9g/0030-serial8250-Use-dl_read-dl_write-on-Alchemy.patch delete mode 100644 patches.kzm9g/0031-mmc-tmio-eliminate-unused-variable-mmc-warning.patch delete mode 100644 patches.kzm9g/0031-serial8250-Use-dl_read-dl_write-on-RM9K.patch delete mode 100644 patches.kzm9g/0032-mmc-sdhi-initialise-mmc_data-flags-before-use.patch delete mode 100644 patches.kzm9g/0032-serial8250-Clean-up-default-map-and-dl-code.patch delete mode 100644 patches.kzm9g/0033-mmc-tmio-Cache-interrupt-masks.patch delete mode 100644 patches.kzm9g/0033-serial8250-Introduce-serial8250_register_8250_port.patch delete mode 100644 patches.kzm9g/0034-mmc-tmio-Provide-separate-interrupt-handlers.patch delete mode 100644 patches.kzm9g/0034-serial8250-em-Emma-Mobile-UART-driver-V2.patch delete mode 100644 patches.kzm9g/0035-mmc-sdhi-Allow-named-IRQs-to-use-specific-handlers.patch delete mode 100644 patches.kzm9g/0035-serial8250-em-clk_get-IS_ERR-error-handling-fix.patch delete mode 100644 patches.kzm9g/0036-cpuidle-create-bootparam-cpuidle.off-1.patch delete mode 100644 patches.kzm9g/0036-mmc-irq-Remove-IRQF_DISABLED.patch delete mode 100644 patches.kzm9g/0037-cpuidle-replace-xen-access-to-x86-pm_idle-and-defaul.patch delete mode 100644 patches.kzm9g/0037-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch delete mode 100644 patches.kzm9g/0038-cpuidle-stop-depending-on-pm_idle.patch delete mode 100644 patches.kzm9g/0038-mmc-replace-printk-with-appropriate-display-macro.patch delete mode 100644 patches.kzm9g/0039-cpuidle-Consistent-spelling-of-cpuidle_idle_call.patch delete mode 100644 patches.kzm9g/0039-mmc-tmio-fix-clock-gating-on-platforms-with-a-.set_p.patch delete mode 100644 patches.kzm9g/004-ltsi-arm-mach_shmobile-kzm9g-update-defconfig.patch delete mode 100644 patches.kzm9g/0040-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch delete mode 100644 patches.kzm9g/0040-sh-Fix-up-fallout-from-cpuidle-changes.patch delete mode 100644 patches.kzm9g/0041-cpuidle-Add-module.h-to-drivers-cpuidle-files-as-req.patch delete mode 100644 patches.kzm9g/0041-mmc-remove-the-second-argument-of-k-un-map_atomic.patch delete mode 100644 patches.kzm9g/0042-cpuidle-Move-dev-last_residency-update-to-driver-ent.patch delete mode 100644 patches.kzm9g/0042-mmc-tmio_mmc-Hotplug-code-regrouping.patch delete mode 100644 patches.kzm9g/0043-cpuidle-Remove-CPUIDLE_FLAG_IGNORE-and-dev-prepare.patch delete mode 100644 patches.kzm9g/0043-mmc-host-move-to-dma_transfer_direction.patch delete mode 100644 patches.kzm9g/0044-cpuidle-Split-cpuidle_state-structure-and-move-per-c.patch delete mode 100644 patches.kzm9g/0044-mmc-tmio_mmc-fix-card-eject-during-IO-with-DMA.patch delete mode 100644 patches.kzm9g/0045-cpuidle-Single-Global-registration-of-idle-states.patch delete mode 100644 patches.kzm9g/0045-mmc-tmio_mmc-do-not-enable-card-hotplug-interrupts-i.patch delete mode 100644 patches.kzm9g/0046-cpuidle-Add-common-time-keeping-and-irq-enabling.patch delete mode 100644 patches.kzm9g/0046-mmc-tmio-calculate-the-native-hotplug-condition-only.patch delete mode 100644 patches.kzm9g/0047-mm-add-vm_area_add_early.patch delete mode 100644 patches.kzm9g/0047-mmc-tmio_mmc-support-the-generic-MMC-GPIO-card-hotpl.patch delete mode 100644 patches.kzm9g/0048-clockevents-Make-clockevents_config-a-global-symbol.patch delete mode 100644 patches.kzm9g/0048-mmc-sh_mobile_sdhi-pass-card-hotplug-GPIO-number-to-.patch delete mode 100644 patches.kzm9g/0049-clocksource-em_sti-Emma-Mobile-STI-driver-V2.patch delete mode 100644 patches.kzm9g/0049-mmc-tmio_mmc-power-status-flag-doesn-t-have-to-be-ex.patch delete mode 100644 patches.kzm9g/0050-ARM-move-initialization-of-the-high_memory-variable-.patch delete mode 100644 patches.kzm9g/0050-mmc-tmio_mmc-remove-unused-sdio_irq_enabled-flag.patch delete mode 100644 patches.kzm9g/0051-ARM-move-iotable-mappings-within-the-vmalloc-region.patch delete mode 100644 patches.kzm9g/0051-mmc-sh_mobile_sdhi-do-not-manage-PM-clocks-manually.patch delete mode 100644 patches.kzm9g/0052-ARM-simplify-__iounmap-when-dealing-with-section-bas.patch delete mode 100644 patches.kzm9g/0052-mmc-tmio-cosmetic-prettify-the-tmio_mmc_set_ios-func.patch delete mode 100644 patches.kzm9g/0053-ARM-add-generic-ioremap-optimization-by-reusing-stat.patch delete mode 100644 patches.kzm9g/0053-mmc-sh_mobile_sdhi-add-a-callback-for-board-specific.patch delete mode 100644 patches.kzm9g/0054-ARM-mach-shmobile-Introduce-shmobile_setup_delay.patch delete mode 100644 patches.kzm9g/0054-mmc-sh_mobile_sdhi-support-modular-mmc-core-with-non.patch delete mode 100644 patches.kzm9g/0055-ARM-mach-shmobile-Allow-SoC-specific-CPU-kill-code.patch delete mode 100644 patches.kzm9g/0055-mmc-Standardize-header-file-inclusion-checks.patch delete mode 100644 patches.kzm9g/0056-ARM-mach-shmobile-Use-preset_lpj-with-calibrate_dela.patch delete mode 100644 patches.kzm9g/0056-mmc-sh_mmcif-maximize-power-saving.patch delete mode 100644 patches.kzm9g/0057-ARM-Undelete-KZM9D-mach-type.patch delete mode 100644 patches.kzm9g/0057-mmc-sh_mmcif-simplify-platform-data.patch delete mode 100644 patches.kzm9g/0058-gpio-Emma-Mobile-GPIO-driver.patch delete mode 100644 patches.kzm9g/0058-mmc-Add-module.h-to-drivers-mmc-users-assuming-impli.patch delete mode 100644 patches.kzm9g/0059-mach-shmobile-Emma-Mobile-EV2-SoC-base-support-V3.patch delete mode 100644 patches.kzm9g/0059-mmc-host-move-to-dma_transfer_direction.patch delete mode 100644 patches.kzm9g/0060-mach-shmobile-KZM9D-board-support-V3.patch delete mode 100644 patches.kzm9g/0060-mmc-sh_mmcif-fix-clock-gating-on-platforms-with-a-.d.patch delete mode 100644 patches.kzm9g/0061-mach-shmobile-Emma-Mobile-EV2-SMP-support-V3.patch delete mode 100644 patches.kzm9g/0061-mmc-sh_mmcif-simplify-clock-divisor-calculation.patch delete mode 100644 patches.kzm9g/0062-mach-shmobile-Emma-Mobile-EV2-GPIO-support-V3.patch delete mode 100644 patches.kzm9g/0062-mmc-convert-drivers-mmc-host-to-use-module_platform_.patch delete mode 100644 patches.kzm9g/0063-mach-shmobile-KZM9D-board-Ethernet-support-V3.patch delete mode 100644 patches.kzm9g/0063-mmc-sh_mmcif-process-error-interrupts-first.patch delete mode 100644 patches.kzm9g/0064-mmc-sh_mmcif-cosmetic-clean-up.patch delete mode 100644 patches.kzm9g/0065-mmc-sh_mmcif-process-requests-asynchronously.patch delete mode 100644 patches.kzm9g/0066-mmc-sh_mmcif-remove-now-superfluous-sh_mmcif_host-da.patch delete mode 100644 patches.kzm9g/0067-mmc-sh_mmcif-fix-MMC_GEN_CMD-setting.patch delete mode 100644 patches.kzm9g/0068-mmc-sh_mmcif-simplify-bitmask-macros.patch delete mode 100644 patches.kzm9g/0069-mmc-sh_mmcif-double-clock-speed.patch delete mode 100644 patches.kzm9g/0070-mmc-sh_mmcif-mmc-f_max-should-be-half-of-the-bus-clo.patch delete mode 100644 patches.kzm9g/0071-mmc-sh_mmcif-Simplify-calculation-of-mmc-f_min.patch delete mode 100644 patches.kzm9g/0072-ARM-mach-shmobile-clock-r8a7740-add-USB-clock.patch delete mode 100644 patches.kzm9g/0073-ALSA-workaround-change-the-timing-of-alsa_sound_last.patch delete mode 100644 patches.kzm9g/0074-ASoC-core-Optimise-and-refactor-pcm_new-to-pass-only.patch delete mode 100644 patches.kzm9g/0075-ASoC-core-Allow-components-to-probe-remove-in-sequen.patch delete mode 100644 patches.kzm9g/0076-ASoC-core-Separate-out-PCM-operations-into-new-file.patch delete mode 100644 patches.kzm9g/0077-ASoC-core-PCM-mutex-per-rtd.patch delete mode 100644 patches.kzm9g/0078-ASoC-Allow-DAI-formats-to-be-specified-in-the-dai_li.patch delete mode 100644 patches.kzm9g/0079-ASoC-Hold-runtime-PM-references-to-components-of-act.patch delete mode 100644 patches.kzm9g/0080-ASoC-sh-fsi-tidyup-parameter-of-fsi_stream_push.patch delete mode 100644 patches.kzm9g/0081-ASoC-sh-fsi-add-fsi_set_master_clk.patch delete mode 100644 patches.kzm9g/0082-ASoC-sh-fsi-irq-control-moves-to-fsi_port_start-stop.patch delete mode 100644 patches.kzm9g/0083-ASoC-sh-fsi-tidyup-unclear-variable-naming.patch delete mode 100644 patches.kzm9g/0084-ASoC-sh-fsi-remove-pm_runtime-from-fsi_dai_set_fmt.patch delete mode 100644 patches.kzm9g/0085-ASoC-sh-fsi-make-sure-fsi_stream_push-pop-access-by-.patch delete mode 100644 patches.kzm9g/0086-ASoC-sh-fsi-remove-fsi_module_init-kill.patch delete mode 100644 patches.kzm9g/0087-ASoC-sh-fsi-cleanup-suspend-resume.patch delete mode 100644 patches.kzm9g/0088-ASoC-sh-fsi-add-fsi_hw_startup-shutdown.patch delete mode 100644 patches.kzm9g/0089-sound-irq-Remove-IRQF_DISABLED.patch delete mode 100644 patches.kzm9g/0090-ASoC-sh-use-correct-__iomem-annotations.patch delete mode 100644 patches.kzm9g/0091-sound-Add-module.h-to-the-previously-silent-sound-us.patch delete mode 100644 patches.kzm9g/0092-ASoC-fsi-fixup-compile-warning.patch delete mode 100644 patches.kzm9g/0093-ASoC-fsi-add-valid-data-position-control-support.patch delete mode 100644 patches.kzm9g/0094-ASoC-Constify-snd_soc_dai_ops-structs.patch delete mode 100644 patches.kzm9g/0095-ASoC-fsi-ak4642-modify-specification-method-of-FSI-a.patch delete mode 100644 patches.kzm9g/0096-ASoC-Convert-sh-directory-to-module_platform_driver.patch delete mode 100644 patches.kzm9g/0097-ASoC-Use-core-pm_runtime-callbacks-for-fsi.patch delete mode 100644 patches.kzm9g/0098-ASoC-sh-Add-.owner-to-struct-snd_soc_card.patch delete mode 100644 patches.kzm9g/0099-ASoC-fsi-Remove-unneeded-empty-runtime-PM-callbacks.patch delete mode 100644 patches.kzm9g/0100-ASoC-fsi-reduce-runtime-calculation-by-using-pre-set.patch delete mode 100644 patches.kzm9g/0101-ASoC-fsi-tidyup-fsi_stream_xx-functions-were-gathere.patch delete mode 100644 patches.kzm9g/0102-ASoC-fsi-data-push-pop-calculation-part-was-divided.patch delete mode 100644 patches.kzm9g/0103-ASoC-fsi-rename-fsi_dma_soft_xxx-to-fsi_pio_xxx.patch delete mode 100644 patches.kzm9g/0104-ASoC-fsi-tidyup-move-fsi_fifo_init-onto-fsi_hw_start.patch delete mode 100644 patches.kzm9g/0105-ASoC-fsi-remove-unnecessary-parameter-from-fsi_hw_sh.patch delete mode 100644 patches.kzm9g/0106-ASoC-fsi-rename-fsi_stream_push-pop-to-fsi_stream_in.patch delete mode 100644 patches.kzm9g/0107-ASoC-fsi-modify-fsi_pio_get_area-parameter-and-using.patch delete mode 100644 patches.kzm9g/0108-ASoC-fsi-re-define-fsi_is_play-and-fsi_stream_is_pla.patch delete mode 100644 patches.kzm9g/0109-ASoC-fsi-use-fsi_stream-in-fsi_get_current_fifo_samp.patch delete mode 100644 patches.kzm9g/0110-ASoC-fsi-add-fsi_stream_handler-and-PIO-handler.patch delete mode 100644 patches.kzm9g/0111-ASoC-fsi-tidyup-fsi_pio_xxx-are-gathered.patch delete mode 100644 patches.kzm9g/0112-ASoC-fsi-don-t-use-is_play-as-a-parameter-of-fsi-fun.patch delete mode 100644 patches.kzm9g/0113-ASoC-fsi-add-.start_stop-handler-to-fsi_stream_handl.patch delete mode 100644 patches.kzm9g/0114-ASoC-fsi-fsi_stream_is_working-care-substream-runtim.patch delete mode 100644 patches.kzm9g/0115-ASoC-fsi-PortA-B-information-was-controlled-by-sh_fs.patch delete mode 100644 patches.kzm9g/0116-ASoC-fsi-add-.init-.quit-handler-support.patch delete mode 100644 patches.kzm9g/0117-ASoC-fsi-fixup-fsi_pointer-calculation-method.patch delete mode 100644 patches.kzm9g/0118-ASoC-fsi-Add-DMAEngine-support.patch delete mode 100644 patches.kzm9g/0119-ASoC-fsi-update-for-dmaengine-prep_slave_sg-fallout.patch delete mode 100644 patches.kzm9g/0120-ASoC-add-generic-simple-card-support.patch delete mode 100644 patches.kzm9g/0121-ASoC-sh-fsi-select-simple-card-on-Kconfig.patch delete mode 100644 patches.kzm9g/0122-ASoC-ak4642-convert-to-soc-cache.patch delete mode 100644 patches.kzm9g/0123-ASoC-ak4642-ak4642-was-tested.patch delete mode 100644 patches.kzm9g/0124-ASoC-ak4642-add-ak4642_set_bias_level.patch delete mode 100644 patches.kzm9g/0125-ASoC-ak4642-add-DAPM-support-for-HeadPhone-Output.patch delete mode 100644 patches.kzm9g/0126-ASoC-ak4642-add-headphone-mute-switch-control.patch delete mode 100644 patches.kzm9g/0127-ASoC-ak4642-add-Line-out-support.patch delete mode 100644 patches.kzm9g/0128-ASoC-ak4642-add-ak4648-support.patch delete mode 100644 patches.kzm9g/0129-ASoC-Remove-driver-versioning-from-ak4642.patch delete mode 100644 patches.kzm9g/0130-ASoC-Convert-ak4642-to-devm_kzalloc.patch delete mode 100644 patches.kzm9g/0131-ASoC-ak4642-fixup-HeadPhone-L-R-dapm-settings.patch delete mode 100644 patches.kzm9g/0132-ARM-mach-shmobile-clock-r8a7740-add-SDHI-clock.patch delete mode 100644 patches.kzm9g/0133-ARM-mach-shmobile-clock-r8a7740-add-MMCIF-clock.patch delete mode 100644 patches.kzm9g/0134-ARM-mach-shmobile-r8a7740-reserve-DMA-memory-for-the.patch delete mode 100644 patches.kzm9g/0135-ARM-mach-shmobile-clock-r8a7740-add-FSI-clock.patch delete mode 100644 patches.kzm9g/0136-ARM-mach-shmobile-armadillo800eva-add-SDHI0-support.patch delete mode 100644 patches.kzm9g/0137-ARM-mach-shmobile-armadillo800eva-add-SDHI1-support.patch delete mode 100644 patches.kzm9g/0138-ARM-mach-shmobile-armadillo800eva-add-MMCIF-support.patch delete mode 100644 patches.kzm9g/0139-ARM-mach-shmobile-armadillo800eva-Add-FSI-WM8978-sup.patch delete mode 100644 patches.kzm9g/0140-ARM-mach-shmobile-Add-support-for-PINT-though-INTC-m.patch delete mode 100644 patches.kzm9g/0141-irq-Track-the-owner-of-irq-descriptor.patch delete mode 100644 patches.kzm9g/0142-irq-add-irq_domain-translation-infrastructure.patch delete mode 100644 patches.kzm9g/0143-dt-irq-add-irq_domain_generate_simple-helper.patch delete mode 100644 patches.kzm9g/0144-irq-Add-declaration-of-irq_domain_simple_ops-to-irqd.patch delete mode 100644 patches.kzm9g/0145-irq-Fix-check-for-already-initialized-irq_domain-in-.patch delete mode 100644 patches.kzm9g/0146-irq-support-domains-with-non-zero-hwirq-base.patch delete mode 100644 patches.kzm9g/0147-genirq-Add-support-for-per-cpu-dev_id-interrupts.patch delete mode 100644 patches.kzm9g/0148-ARM-introduce-handle_IRQ-not-to-dump-exception-stack.patch delete mode 100644 patches.kzm9g/0149-ARM-GIC-move-gic_chip_data-structure-declaration-to-.patch delete mode 100644 patches.kzm9g/0150-ARM-CPU-hotplug-fix-abuse-of-irqdesc-node.patch delete mode 100644 patches.kzm9g/0151-ARM-GIC-avoid-routing-interrupts-to-offline-CPUs.patch delete mode 100644 patches.kzm9g/0152-ARM-gic-Use-cpu-pm-notifiers-to-save-gic-state.patch delete mode 100644 patches.kzm9g/0153-ARM-7011-1-Add-ARM-cpu-topology-definition.patch delete mode 100644 patches.kzm9g/0154-ARM-7060-1-smp-populate-logical-CPU-mapping-during-b.patch delete mode 100644 patches.kzm9g/0155-ARM-gic-Allow-gic-arch-extensions-to-provide-irqchip.patch delete mode 100644 patches.kzm9g/0156-ARM-7061-1-gic-convert-logical-CPU-numbers-into-phys.patch delete mode 100644 patches.kzm9g/0157-ARM-7123-1-smp-Add-an-IPI-handler-callable-from-C-co.patch delete mode 100644 patches.kzm9g/0158-ARM-7124-1-smp-Add-a-localtimer-handler-callable-fro.patch delete mode 100644 patches.kzm9g/0159-ARM-gic-consolidate-PPI-handling.patch delete mode 100644 patches.kzm9g/0160-ARM-GIC-Add-global-gic_handle_irq-function.patch delete mode 100644 patches.kzm9g/0161-ARM-twd-register-clockevents-device-before-enabling-.patch delete mode 100644 patches.kzm9g/0162-ARM-EXYNOS4-set-the-affinity-of-mct1-interrupt-using.patch delete mode 100644 patches.kzm9g/0163-genirq-percpu-allow-interrupt-type-to-be-set-at-enab.patch delete mode 100644 patches.kzm9g/0164-ARM-gic-local-timers-use-the-request_percpu_irq-inte.patch delete mode 100644 patches.kzm9g/0165-ARM-gic-add-irq_domain-support.patch delete mode 100644 patches.kzm9g/0166-ARM-gic-add-OF-based-initialization.patch delete mode 100644 patches.kzm9g/0167-ARM-gic-fix-irq_alloc_descs-handling-for-sparse-irq.patch delete mode 100644 patches.kzm9g/0168-ARM-gic-use-module.h-instead-of-export.h.patch delete mode 100644 patches.kzm9g/0169-ARM-7176-1-cpu_pm-register-GIC-PM-notifier-only-once.patch delete mode 100644 patches.kzm9g/0170-ARM-7177-1-GIC-avoid-skipping-non-existent-PPIs-in-i.patch delete mode 100644 patches.kzm9g/0171-ARM-mach-shmobile-clock-sh73a0-tidyup-CKSCR-main-clo.patch delete mode 100644 patches.kzm9g/0172-ARM-mach-shmobile-sh73a0-PFC-pull-up-support-for-SDH.patch delete mode 100644 patches.kzm9g/0173-ARM-shmobile-convert-logical-CPU-numbers-to-physical.patch delete mode 100644 patches.kzm9g/0174-ARM-mach-shmobile-sh73a0-GPIO-IRQ-support.patch delete mode 100644 patches.kzm9g/0175-ARM-mach-shmobile-Use-common-INTC-IRQ-code-on-sh73a0.patch delete mode 100644 patches.kzm9g/0176-ARM-mach-shmobile-sh73a0-and-AG5EVM-PINT-support.patch delete mode 100644 patches.kzm9g/0177-ARM-mach-shmobile-Kota2-TPU-LED-platform-data.patch delete mode 100644 patches.kzm9g/0178-ARM-mach-shmobile-SH73A0-external-Ethernet-fix.patch delete mode 100644 patches.kzm9g/0179-sh-clkfwk-clock-sh73a0-all-div6_clks-use-SH_CLK_DIV6.patch delete mode 100644 patches.kzm9g/0180-arm-mach-shmobile-add-a-resource-name-for-shdma.patch delete mode 100644 patches.kzm9g/0181-ARM-mach-shmobile-sh73a0-PINT-IRQ-base-fix.patch delete mode 100644 patches.kzm9g/0182-ARM-mach-shmobile-sh73a0-IRQ-sparse-alloc-fix.patch delete mode 100644 patches.kzm9g/0183-ARM-mach-shmobile-clock-sh73a0-add-DSIxPHY-clock-sup.patch delete mode 100644 patches.kzm9g/0184-ARM-shmobile-remove-NR_IRQS.patch delete mode 100644 patches.kzm9g/0185-ARM-mach-shmobile-sh73a0-PSTR-32-bit-access-fix.patch delete mode 100644 patches.kzm9g/0186-ARM-mach-shmobile-sh73a0-sh_clk_ops-rename.patch delete mode 100644 patches.kzm9g/0187-ARM-mach-shmobile-sh73a0-map_io-and-init_early-updat.patch delete mode 100644 patches.kzm9g/0188-ARM-mach-shmobile-sh73a0-AG5EVM-and-Kota2-timer-rewo.patch delete mode 100644 patches.kzm9g/0189-ARM-mach-shmobile-sh73a0-add-MMC-data-pin-pull-up.patch delete mode 100644 patches.kzm9g/0190-ARM-Update-mach-types.patch delete mode 100644 patches.kzm9g/0191-ARM-mach-shmobile-add-KZM-A9-GT-board-support.patch delete mode 100644 patches.kzm9g/0192-ARM-mach-shmobile-kzm9g-add-defconfig.patch delete mode 100644 patches.kzm9g/0193-ARM-mach-shmobile-Invalidate-caches-when-booting-sec.patch delete mode 100644 patches.kzm9g/0194-ARM-mach-shmobile-kzm9g-enable-SMP-boot.patch delete mode 100644 patches.kzm9g/0195-ARM-mach-shmobile-kzm9g-add-LCDC-support.patch delete mode 100644 patches.kzm9g/0196-ARM-mach-shmobile-kzm9g-add-ST1232-Touchscreen-suppo.patch delete mode 100644 patches.kzm9g/0197-ARM-mach-shmobile-pfc-sh73a0-fixup-MSEL2CR-MSEL18-fo.patch delete mode 100644 patches.kzm9g/0198-ARM-mach-shmobile-sh73a0.h-add-GPIO_NR.patch delete mode 100644 patches.kzm9g/0199-ARM-mach-shmobile-kzm9g-correct-screen-direction.patch delete mode 100644 patches.kzm9g/0200-ARM-mach-shmobile-kzm9g-add-MMCIF-support.patch delete mode 100644 patches.kzm9g/0201-ARM-mach-shmobile-kzm9g-add-SDHI-support.patch delete mode 100644 patches.kzm9g/0202-ARM-mach-shmobile-kzm9g-add-PCF8757-gpio-key.patch delete mode 100644 patches.kzm9g/0203-ARM-mach-shmobile-kzm9g-defconfig-update.patch delete mode 100644 patches.kzm9g/0204-ARM-mach-shmobile-clock-sh73a0-add-FSI-clock.patch delete mode 100644 patches.kzm9g/0205-ARM-mach-shmobile-kzm9g-add-FSI-AK4648-support.patch delete mode 100644 patches.kzm9g/arm-mach-shmobile-kzm9d-add-defconfig.patch delete mode 100644 patches.kzm9g/arm-mach-shmobile-kzm9d-defconfig-enable-net_ethernet.patch delete mode 100644 patches.kzm9g/arm-shmobile-sh73a0-bugfix-sy-dmac-number.patch delete mode 100644 patches.kzm9g/ltsi-arm-shmobile-kzm9g-support-real-time-clock.patch delete mode 100644 patches.kzm9g/ltsi-bugfix-add-config_i2c-to-kzm9g_defconfig.patch delete mode 100644 patches.kzm9g/of-address-add-of_find_matching_node_by_address-helper.patch delete mode 100644 patches.r8a66597-udc/001-usb-gadget-add-platform-module-alias-where-it-is-missing.patch delete mode 100644 patches.r8a66597-udc/002-usb-update-email-address-in-r8a66597-udc-and-m66592-udc.patch delete mode 100644 patches.r8a66597-udc/003-usb-gadget-r8a66597-udc-make-buswait-configurable-through-platform-data.patch delete mode 100644 patches.r8a66597-udc/004-usb-gadget-r8a66597-udc-add-support-for-test_mode.patch delete mode 100644 patches.r8a66597-udc/005-usb-gadget-clean-up-fsf-boilerplate-text.patch delete mode 100644 patches.r8a66597-udc/006-usb-irq-remove-irqf_disabled.patch delete mode 100644 patches.r8a66597-udc/007-usb-gadget-r8a66597-udc-change-prototype-of-r8a66597_write_fifo.patch delete mode 100644 patches.r8a66597-udc/008-usb-r8a66597-hcd-add-function-for-external-controller.patch delete mode 100644 patches.r8a66597-udc/009-usb-gadget-r8a66597-udc-add-function-for-external-controller.patch delete mode 100644 patches.r8a66597-udc/010-usb-gadget-r8a66597-udc-use-dev_-instead-of-printk.patch delete mode 100644 patches.r8a66597-udc/011-usb-gadget-r8a66597-udc-add-support-for-sudmac.patch delete mode 100644 patches.r8a66597-udc/012-usb-gadget-r8a66597-udc-fix-flush-fifo-handling.patch delete mode 100644 patches.runtime_pm/0001-Revert-PM-Runtime-Automatically-retry-failed-autosus.patch delete mode 100644 patches.runtime_pm/0002-PM-Domains-Rename-struct-dev_power_domain-to-struct-.patch delete mode 100644 patches.runtime_pm/0003-PM-subsys_data-in-struct-dev_pm_info-need-not-depend.patch delete mode 100644 patches.runtime_pm/0004-PM-Domains-Support-for-generic-I-O-PM-domains-v8.patch delete mode 100644 patches.runtime_pm/0005-PM-Introduce-generic-noirq-callback-routines-for-sub.patch delete mode 100644 patches.runtime_pm/0006-PM-Domains-Move-code-from-under-ifdef-CONFIG_PM_RUNT.patch delete mode 100644 patches.runtime_pm/0007-PM-Domains-System-wide-transitions-support-for-gener.patch delete mode 100644 patches.runtime_pm/0008-PM-Domains-Wakeup-devices-support-for-system-sleep-t.patch delete mode 100644 patches.runtime_pm/0009-PM-Allow-the-clocks-management-code-to-be-used-durin.patch delete mode 100644 patches.runtime_pm/0010-PM-Rename-clock-management-functions.patch delete mode 100644 patches.runtime_pm/0011-PM-Runtime-Update-documentation-of-interactions-with.patch delete mode 100644 patches.runtime_pm/0012-PM-Runtime-Return-special-error-code-if-runtime-PM-i.patch delete mode 100644 patches.runtime_pm/0013-PM-Limit-race-conditions-between-runtime-PM-and-syst.patch delete mode 100644 patches.runtime_pm/0014-PM-Runtime-Improve-documentation-of-enable-disable-a.patch delete mode 100644 patches.runtime_pm/0015-PM-Runtime-Replace-run-time-with-runtime-in-document.patch delete mode 100644 patches.runtime_pm/0016-PM-Runtime-Prevent-runtime_resume-from-racing-with-p.patch delete mode 100644 patches.runtime_pm/0017-PM-Runtime-Consistent-utilization-of-deferred_resume.patch delete mode 100644 patches.runtime_pm/0018-PM-Domains-Export-pm_genpd_poweron-in-header.patch delete mode 100644 patches.runtime_pm/0019-doc-Konfig-Documentation-power-pm-apm-acpi-.txt.patch delete mode 100644 patches.runtime_pm/0020-PM-Domains-Set-device-state-to-active-during-system-.patch delete mode 100644 patches.runtime_pm/0021-PM-Domains-Make-failing-pm_genpd_prepare-clean-up-pr.patch delete mode 100644 patches.runtime_pm/0022-PM-Domains-Do-not-execute-device-callbacks-under-loc.patch delete mode 100644 patches.runtime_pm/0023-PM-Domains-Allow-callbacks-to-execute-all-runtime-PM.patch delete mode 100644 patches.runtime_pm/0024-PM-Domains-Do-not-restore-all-devices-on-power-off-e.patch delete mode 100644 patches.runtime_pm/0025-PM-Domains-Improve-handling-of-wakeup-devices-during.patch delete mode 100644 patches.runtime_pm/0026-PM-Domains-Queue-up-power-off-work-only-if-it-is-not.patch delete mode 100644 patches.runtime_pm/0027-PM-Runtime-Add-new-helper-function-pm_runtime_status.patch delete mode 100644 patches.runtime_pm/0028-PM-Domains-Introduce-function-to-power-off-all-unuse.patch delete mode 100644 patches.runtime_pm/0029-ARM-shmobile-Use-genpd_queue_power_off_work.patch delete mode 100644 patches.runtime_pm/0030-PM-Domains-Take-.power_off-error-code-into-account.patch delete mode 100644 patches.runtime_pm/0031-PM-OPP-Introduce-function-to-free-cpufreq-table.patch delete mode 100644 patches.runtime_pm/0032-PM-Suspend-Add-.suspend_again-callback-to-suspend_op.patch delete mode 100644 patches.runtime_pm/0033-PM-Suspend-Export-suspend_set_ops-suspend_valid_only.patch delete mode 100644 patches.runtime_pm/0034-PM-Add-RTC-to-PM-trace-time-stamps-to-avoid-confusio.patch delete mode 100644 patches.runtime_pm/0035-PM-Improve-error-code-of-pm_notifier_call_chain.patch delete mode 100644 patches.runtime_pm/0036-drivers-base-power-opp.c-fix-dev_opp-initial-value.patch delete mode 100644 patches.runtime_pm/0037-PM-Domains-Fix-pm_genpd_poweron.patch delete mode 100644 patches.runtime_pm/0038-PM-Runtime-Allow-_put_sync-from-interrupts-disabled-.patch delete mode 100644 patches.runtime_pm/0039-PM-Domains-Fix-build-for-CONFIG_PM_RUNTIME-unset.patch delete mode 100644 patches.runtime_pm/0040-PM-Runtime-Add-might_sleep-to-runtime-PM-functions.patch delete mode 100644 patches.runtime_pm/0041-PM-Runtime-Add-macro-to-test-for-runtime-PM-events.patch delete mode 100644 patches.runtime_pm/0042-PM-Use-spinlock-instead-of-mutex-in-clock-management.patch delete mode 100644 patches.runtime_pm/0043-PM-Runtime-Correct-documentation-of-pm_runtime_irq_s.patch delete mode 100644 patches.runtime_pm/0044-PM-Domains-Implement-subdomain-counters-as-atomic-fi.patch delete mode 100644 patches.runtime_pm/0045-PM-Domains-Do-not-take-parent-locks-to-modify-subdom.patch delete mode 100644 patches.runtime_pm/0046-PM-Domains-Make-pm_genpd_poweron-always-survive-pare.patch delete mode 100644 patches.runtime_pm/0047-PM-Domains-Add-wait-for-parent-status-for-generic-PM.patch delete mode 100644 patches.runtime_pm/0048-PM-Domains-Allow-generic-PM-domains-to-have-multiple.patch delete mode 100644 patches.runtime_pm/0049-PM-Domains-Rename-GPD_STATE_WAIT_PARENT-to-GPD_STATE.patch delete mode 100644 patches.runtime_pm/0050-PM-Domains-Rename-argument-of-pm_genpd_add_subdomain.patch delete mode 100644 patches.runtime_pm/0051-PM-Introduce-struct-pm_subsys_data.patch delete mode 100644 patches.runtime_pm/0052-PM-Reference-counting-of-power.subsys_data.patch delete mode 100644 patches.runtime_pm/0053-PM-Domains-Use-power.sybsys_data-to-reduce-overhead.patch delete mode 100644 patches.runtime_pm/0054-PM-QoS-Move-and-rename-the-implementation-files.patch delete mode 100644 patches.runtime_pm/0055-plist-Remove-the-need-to-supply-locks-to-plist-heads.patch delete mode 100644 patches.runtime_pm/0056-PM-QoS-Minor-clean-ups.patch delete mode 100644 patches.runtime_pm/0057-PM-QoS-Code-reorganization.patch delete mode 100644 patches.runtime_pm/0058-PM-QoS-Reorganize-data-structs.patch delete mode 100644 patches.runtime_pm/0059-PM-QoS-Generalize-and-export-constraints-management-.patch delete mode 100644 patches.runtime_pm/0060-PM-QoS-Implement-per-device-PM-QoS-constraints.patch delete mode 100644 patches.runtime_pm/0061-PM-QoS-Add-global-notification-mechanism-for-device-.patch delete mode 100644 patches.runtime_pm/0062-PM-Domains-Preliminary-support-for-devices-with-powe.patch delete mode 100644 patches.runtime_pm/0063-PM-Runtime-pm_runtime_idle-can-be-called-in-atomic-c.patch delete mode 100644 patches.runtime_pm/0064-cpu_pm-Add-cpu-power-management-notifiers.patch delete mode 100644 patches.runtime_pm/0065-PM-Clocks-Do-not-acquire-a-mutex-under-a-spinlock.patch delete mode 100644 patches.runtime_pm/0066-PM-Domains-Split-device-PM-domain-data-into-base-and.patch delete mode 100644 patches.runtime_pm/0067-doc-fix-broken-references.patch delete mode 100644 patches.runtime_pm/0068-PM-Runtime-Don-t-run-callbacks-under-lock-for-power..patch delete mode 100644 patches.runtime_pm/0069-PM-Runtime-Introduce-trace-points-for-tracing-rpm_-f.patch delete mode 100644 patches.runtime_pm/0070-PM-Tracing-build-rpm-traces.c-only-if-CONFIG_PM_RUNT.patch delete mode 100644 patches.runtime_pm/0071-PM-Runtime-Replace-dev_dbg-with-trace_rpm_.patch delete mode 100644 patches.runtime_pm/0072-PM-OPP-Add-OPP-availability-change-notifier.patch delete mode 100644 patches.runtime_pm/0073-PM-OPP-Fix-build-when-CONFIG_PM_OPP-is-not-set.patch delete mode 100644 patches.runtime_pm/0074-PM-QoS-Add-function-dev_pm_qos_read_value-v3.patch delete mode 100644 patches.runtime_pm/0075-PM-QoS-Update-Documentation-for-the-pm_qos-and-dev_p.patch delete mode 100644 patches.runtime_pm/0076-regulator-Fix-some-bitrot-in-the-machine-driver-docu.patch delete mode 100644 patches.runtime_pm/0077-regulator-Clarify-documentation-for-regulator-regula.patch delete mode 100644 patches.runtime_pm/0078-PM-Runtime-Update-document-about-callbacks.patch delete mode 100644 patches.runtime_pm/0079-PM-Runtime-Fix-kerneldoc-comment-for-rpm_suspend.patch delete mode 100644 patches.runtime_pm/0080-PM-Runtime-Handle-.runtime_suspend-failure-correctly.patch delete mode 100644 patches.runtime_pm/0081-PM-Suspend-Add-statistics-debugfs-file-for-suspend-t.patch delete mode 100644 patches.runtime_pm/0082-PM-Fix-build-issue-in-main.c-for-CONFIG_PM_SLEEP-uns.patch delete mode 100644 patches.runtime_pm/0083-PM-Hibernate-Include-storage-keys-in-hibernation-ima.patch delete mode 100644 patches.runtime_pm/0084-PM-VT-Cleanup-if-defined-uglyness-and-fix-compile-er.patch delete mode 100644 patches.runtime_pm/0085-PM-Update-the-policy-on-default-wakeup-settings.patch delete mode 100644 patches.runtime_pm/0086-PM-Hibernate-Freeze-kernel-threads-after-preallocati.patch delete mode 100644 patches.runtime_pm/0087-PM-Hibernate-Fix-typo-in-a-kerneldoc-comment.patch delete mode 100644 patches.runtime_pm/0088-PM-Hibernate-Add-resumewait-param-to-support-MMC-lik.patch delete mode 100644 patches.runtime_pm/0089-PM-Hibernate-Add-resumedelay-kernel-param-in-additio.patch delete mode 100644 patches.runtime_pm/0090-PM-Hibernate-Do-not-initialize-static-and-extern-var.patch delete mode 100644 patches.runtime_pm/0091-PM-Hibernate-Improve-performance-of-LZO-plain-hibern.patch delete mode 100644 patches.runtime_pm/0092-PM-Sleep-Mark-devices-involved-in-wakeup-signaling-d.patch delete mode 100644 patches.runtime_pm/0093-PM-Documentation-Update-docs-about-suspend-and-CPU-h.patch delete mode 100644 patches.runtime_pm/0094-PM-Clocks-Remove-redundant-NULL-checks-before-kfree.patch delete mode 100644 patches.runtime_pm/0095-kernel-fix-several-implicit-usasges-of-kmod.h.patch delete mode 100644 patches.runtime_pm/0096-kernel-Fix-files-explicitly-needing-EXPORT_SYMBOL-in.patch delete mode 100644 patches.runtime_pm/0097-drivers-base-Add-export.h-for-EXPORT_SYMBOL-THIS_MOD.patch delete mode 100644 patches.runtime_pm/0098-drivers-base-change-module.h-export.h-in-power-commo.patch delete mode 100644 patches.runtime_pm/0099-pm_runtime.h-explicitly-requires-notifier.h.patch delete mode 100644 patches.runtime_pm/0100-PM-Sleep-Update-freezer-documentation.patch delete mode 100644 patches.runtime_pm/0101-PM-Runtime-Fix-runtime-accounting-calculation-error.patch delete mode 100644 patches.runtime_pm/0102-PM-QoS-Remove-redundant-check.patch delete mode 100644 patches.runtime_pm/0103-PM-Runtime-Automatically-retry-failed-autosuspends.patch delete mode 100644 patches.runtime_pm/0104-PM-QoS-Set-cpu_dma_pm_qos-name.patch delete mode 100644 patches.runtime_pm/0105-PM-OPP-Use-ERR_CAST-instead-of-ERR_PTR-PTR_ERR.patch delete mode 100644 patches.runtime_pm/0106-PM-Clocks-Only-disable-enabled-clocks-in-pm_clk_susp.patch delete mode 100644 patches.runtime_pm/0107-PM-QoS-Properly-use-the-WARN-macro-in-dev_pm_qos_add.patch delete mode 100644 patches.runtime_pm/0108-PM-Sleep-Do-not-extend-wakeup-paths-to-devices-with-.patch delete mode 100644 patches.runtime_pm/0109-PM-Hibernate-Fix-the-early-termination-of-test-modes.patch delete mode 100644 patches.runtime_pm/0110-PM-Suspend-Fix-bug-in-suspend-statistics-update.patch delete mode 100644 patches.runtime_pm/0111-freezer-don-t-unnecessarily-set-PF_NOFREEZE-explicit.patch delete mode 100644 patches.runtime_pm/0112-freezer-fix-current-state-restoration-race-in-refrig.patch delete mode 100644 patches.runtime_pm/0113-freezer-unexport-refrigerator-and-update-try_to_free.patch delete mode 100644 patches.runtime_pm/0114-oom-thaw-threads-if-oom-killed-thread-is-frozen-befo.patch delete mode 100644 patches.runtime_pm/0115-freezer-implement-and-use-kthread_freezable_should_s.patch delete mode 100644 patches.runtime_pm/0116-freezer-rename-thaw_process-to-__thaw_task-and-simpl.patch delete mode 100644 patches.runtime_pm/0117-freezer-remove-racy-clear_freeze_flag-and-set-PF_NOF.patch delete mode 100644 patches.runtime_pm/0118-freezer-don-t-distinguish-nosig-tasks-on-thaw.patch delete mode 100644 patches.runtime_pm/0119-freezer-use-dedicated-lock-instead-of-task_lock-memo.patch delete mode 100644 patches.runtime_pm/0120-freezer-make-freezing-indicate-freeze-condition-in-e.patch delete mode 100644 patches.runtime_pm/0121-freezer-test-freezable-conditions-while-holding-free.patch delete mode 100644 patches.runtime_pm/0122-freezer-clean-up-freeze_processes-failure-path.patch delete mode 100644 patches.runtime_pm/0123-cgroup_freezer-prepare-for-removal-of-TIF_FREEZE.patch delete mode 100644 patches.runtime_pm/0124-freezer-make-freezing-test-freeze-conditions-in-effe.patch delete mode 100644 patches.runtime_pm/0125-Freezer-fix-more-fallout-from-the-thaw_process-renam.patch delete mode 100644 patches.runtime_pm/0126-freezer-remove-unused-sig_only-from-freeze_task.patch delete mode 100644 patches.runtime_pm/0127-PM-Hibernate-Do-not-leak-memory-in-error-test-code-p.patch delete mode 100644 patches.runtime_pm/0128-PM-Fix-indentation-and-remove-extraneous-whitespaces.patch delete mode 100644 patches.runtime_pm/0129-PM-Sleep-Remove-unnecessary-label-and-jumps-to-it-fo.patch delete mode 100644 patches.runtime_pm/0130-PM-Sleep-Simplify-device_suspend_noirq.patch delete mode 100644 patches.runtime_pm/0131-PM-Hibernate-Refactor-and-simplify-hibernation_snaps.patch delete mode 100644 patches.runtime_pm/0132-PM-Domains-Document-how-PM-domains-are-used-by-the-P.patch delete mode 100644 patches.runtime_pm/0133-PM-Sleep-Correct-inaccurate-information-in-devices.t.patch delete mode 100644 patches.runtime_pm/0134-PM-Runtime-Make-documentation-follow-the-new-behavio.patch delete mode 100644 patches.runtime_pm/0135-PM-Sleep-Update-documentation-related-to-system-wake.patch delete mode 100644 patches.runtime_pm/0136-PM-Update-comments-describing-device-power-managemen.patch delete mode 100644 patches.runtime_pm/0137-PM-Runtime-Use-device-PM-QoS-constraints-v2.patch delete mode 100644 patches.runtime_pm/0138-PM-Domains-Make-it-possible-to-use-per-device-domain.patch delete mode 100644 patches.runtime_pm/0139-PM-Domains-Introduce-save-restore-state-device-callb.patch delete mode 100644 patches.runtime_pm/0140-PM-Domains-Rework-system-suspend-callback-routines-v.patch delete mode 100644 patches.runtime_pm/0141-PM-Domains-Add-device-stop-governor-function-v4.patch delete mode 100644 patches.runtime_pm/0142-PM-Domains-Add-default-power-off-governor-function-v.patch delete mode 100644 patches.runtime_pm/0143-PM-Domains-Automatically-update-overoptimistic-laten.patch delete mode 100644 patches.runtime_pm/0144-PM-Domains-fix-compilation-failure-for-CONFIG_PM_GEN.patch delete mode 100644 patches.runtime_pm/0145-regulator-Fix-regulator_register-API-signature-in-Do.patch delete mode 100644 patches.runtime_pm/0146-PM-Hibernate-Enable-usermodehelpers-in-software_resu.patch delete mode 100644 patches.runtime_pm/0147-PM-Hibernate-Thaw-processes-in-SNAPSHOT_CREATE_IMAGE.patch delete mode 100644 patches.runtime_pm/0148-PM-Hibernate-Remove-deprecated-hibernation-test-mode.patch delete mode 100644 patches.runtime_pm/0149-PM-Sleep-Unify-diagnostic-messages-from-device-suspe.patch delete mode 100644 patches.runtime_pm/0150-PM-Hibernate-Replace-unintuitive-if-condition-in-ker.patch delete mode 100644 patches.runtime_pm/0151-PM-Domains-Make-it-possible-to-assign-names-to-gener.patch delete mode 100644 patches.runtime_pm/0152-PM-Domains-Fix-default-system-suspend-resume-operati.patch delete mode 100644 patches.runtime_pm/0153-PM-Sleep-Replace-mutex_-un-lock-pm_mutex-with-un-loc.patch delete mode 100644 patches.runtime_pm/0154-PM-Sleep-Recommend-un-lock_system_sleep-over-using-p.patch delete mode 100644 patches.runtime_pm/0155-PM-Domains-Provide-an-always-on-power-domain-governo.patch delete mode 100644 patches.runtime_pm/0156-PM-Hibernate-Remove-deprecated-hibernation-snapshot-.patch delete mode 100644 patches.runtime_pm/0157-PM-Sleep-Simplify-generic-system-suspend-callbacks.patch delete mode 100644 patches.runtime_pm/0158-PM-Sleep-Merge-internal-functions-in-generic_ops.c.patch delete mode 100644 patches.runtime_pm/0159-PM-Sleep-Make-pm_op-and-pm_noirq_op-return-callback-.patch delete mode 100644 patches.runtime_pm/0160-PM-Run-the-driver-callback-directly-if-the-subsystem.patch delete mode 100644 patches.runtime_pm/0161-PM-Drop-generic_subsys_pm_ops.patch delete mode 100644 patches.runtime_pm/0162-PM-QoS-Introduce-dev_pm_qos_add_ancestor_request.patch delete mode 100644 patches.runtime_pm/0163-power_supply-Add-initial-Charger-Manager-driver.patch delete mode 100644 patches.runtime_pm/0164-PM-Hibernate-Implement-compat_ioctl-for-dev-snapshot.patch delete mode 100644 patches.runtime_pm/0165-mm-more-intensive-memory-corruption-debugging.patch delete mode 100644 patches.runtime_pm/0166-PM-Hibernate-do-not-count-debug-pages-as-savable.patch delete mode 100644 patches.runtime_pm/0167-power_supply-Charger-Manager-Add-properties-for-powe.patch delete mode 100644 patches.runtime_pm/0168-PM-Domains-Fix-build-for-CONFIG_PM_SLEEP-unset.patch delete mode 100644 patches.runtime_pm/0169-PM-Domains-Skip-governor-functions-for-CONFIG_PM_RUN.patch delete mode 100644 patches.runtime_pm/0170-PM-Documentation-Fix-spelling-mistake-in-basic-pm-de.patch delete mode 100644 patches.runtime_pm/0171-PM-Documentation-Fix-minor-issue-in-freezing_of_task.patch delete mode 100644 patches.runtime_pm/0172-PM-Hibernate-Correct-additional-pages-number-calcula.patch delete mode 100644 patches.runtime_pm/0173-PM-Domains-Add-OF-support.patch delete mode 100644 patches.runtime_pm/0174-PM-Hibernate-Fix-s2disk-regression-related-to-freezi.patch delete mode 100644 patches.runtime_pm/0175-PM-Sleep-Introduce-late-suspend-and-early-resume-of-.patch delete mode 100644 patches.runtime_pm/0176-PM-Sleep-Introduce-generic-callbacks-for-new-device-.patch delete mode 100644 patches.runtime_pm/0177-PM-Domains-Run-late-early-device-suspend-callbacks-a.patch delete mode 100644 patches.runtime_pm/0178-PM-QoS-Simplify-PM-QoS-expansion-merge.patch delete mode 100644 patches.runtime_pm/0179-PM-Hibernate-Thaw-kernel-threads-in-SNAPSHOT_CREATE_.patch delete mode 100644 patches.runtime_pm/0180-PM-Freezer-Thaw-only-kernel-threads-if-freezing-of-k.patch delete mode 100644 patches.runtime_pm/0181-PM-QoS-CPU-C-state-breakage-with-PM-Qos-change.patch delete mode 100644 patches.runtime_pm/0182-PM-Suspend-Avoid-code-duplication-in-suspend-statist.patch delete mode 100644 patches.runtime_pm/0183-PM-Freezer-Docs-Document-the-beauty-of-freeze-thaw-s.patch delete mode 100644 patches.runtime_pm/0184-PM-Hibernate-Thaw-kernel-threads-in-hibernation_snap.patch delete mode 100644 patches.runtime_pm/0185-PM-Hibernate-Refactor-and-simplify-freezer_test_done.patch delete mode 100644 patches.runtime_pm/0186-PM-Domains-Provide-a-dummy-dev_gpd_data-when-generic.patch delete mode 100644 patches.runtime_pm/0187-PM-Make-sysrq-o-be-available-for-CONFIG_PM-unset.patch delete mode 100644 patches.runtime_pm/0188-PM-QoS-unconditionally-build-the-feature.patch delete mode 100644 patches.runtime_pm/0189-PM-Sleep-Initialize-wakeup-source-locks-in-wakeup_so.patch delete mode 100644 patches.runtime_pm/0190-PM-Sleep-Do-not-check-wakeup-too-often-in-try_to_fre.patch delete mode 100644 patches.runtime_pm/0191-PM-Sleep-Remove-unnecessary-label-from-suspend_freez.patch delete mode 100644 patches.runtime_pm/0192-PM-Sleep-Unify-kerneldoc-comments-in-kernel-power-su.patch delete mode 100644 patches.runtime_pm/0193-PM-Sleep-Make-enter_state-in-kernel-power-suspend.c-.patch delete mode 100644 patches.runtime_pm/0194-PM-Sleep-Drop-suspend_stats_update.patch delete mode 100644 patches.runtime_pm/0195-PM-Add-comment-describing-relationships-between-PM-c.patch delete mode 100644 patches.runtime_pm/0196-PM-Hibernate-print-physical-addresses-consistently-w.patch delete mode 100644 patches.runtime_pm/0197-PM-Sleep-Fix-possible-infinite-loop-during-wakeup-so.patch delete mode 100644 patches.runtime_pm/0198-PM-Sleep-Fix-race-conditions-related-to-wakeup-sourc.patch delete mode 100644 patches.runtime_pm/0199-PM-Sleep-Add-more-wakeup-source-initialization-routi.patch delete mode 100644 patches.runtime_pm/0200-PM-Freezer-Remove-references-to-TIF_FREEZE-in-commen.patch delete mode 100644 patches.runtime_pm/0201-PM-Domains-Fix-include-for-PM_GENERIC_DOMAINS-n-case.patch delete mode 100644 patches.runtime_pm/0202-PM-QoS-Make-it-possible-to-expose-PM-QoS-latency-con.patch delete mode 100644 patches.runtime_pm/0203-PM-Domains-Fix-handling-of-wakeup-devices-during-sys.patch delete mode 100644 patches.runtime_pm/0204-PM-Domains-Fix-hibernation-restore-of-devices-v2.patch delete mode 100644 patches.runtime_pm/0205-PM-Domains-Introduce-always-on-device-flag.patch delete mode 100644 patches.runtime_pm/0206-PM-Domains-Check-domain-status-during-hibernation-re.patch delete mode 100644 patches.runtime_pm/0207-PM-Runtime-don-t-forget-to-wake-up-waitqueue-on-fail.patch delete mode 100644 patches.runtime_pm/0208-PM-Hibernate-Disable-usermode-helpers-right-before-f.patch delete mode 100644 patches.runtime_pm/0209-PM-Sleep-Move-disabling-of-usermode-helpers-to-the-f.patch delete mode 100644 patches.runtime_pm/0210-PM-QoS-add-pm_qos_update_request_timeout-API.patch delete mode 100644 patches.sh7757lcr/001-spi-add-support-for-renesas-rspi.patch delete mode 100644 patches.sh7757lcr/002-spi-irq-remove-irqf_disabled.patch delete mode 100644 patches.sh7757lcr/003-drivercore-add-helper-macro-for-platform_driver-boilerplate.patch delete mode 100644 patches.sh7757lcr/004-spi-spi-sh-add-ioresource_mem_type_mask-decoding-for-access-size.patch delete mode 100644 patches.sh7757lcr/005-sh-clock-sh7757-add-clkdev_ick_id-for-cleanup.patch delete mode 100644 patches.sh7757lcr/006-sh-move-clkdev_xxx_id-macro-to-sh_clk.h.patch delete mode 100644 patches.sh7757lcr/007-sh-fix-the-compile-error-in-setup-sh7757.c.patch delete mode 100644 patches.sh7757lcr/008-sh-add-parameters-for-ehci-and-riic-in-clock-sh7757.c.patch delete mode 100644 patches.sh7757lcr/009-sh-add-a-resource-name-for-shdma.patch delete mode 100644 patches.sh7757lcr/010-sh-modify-resource-for-spi0-in-setup-sh7757.patch delete mode 100644 patches.sh7757lcr/011-sh-add-platform_device-for-spi1-in-setup-sh7757.patch delete mode 100644 patches.sh7757lcr/012-sh-modify-clock-sh7757-for-renesas_usbhs.patch delete mode 100644 patches.sh7757lcr/013-sh-add-parameter-for-rspi-in-clock-sh7757.patch delete mode 100644 patches.sh7757lcr/014-sh-modify-the-asm-sh_eth.h-to-linux-sh_eth.h-in-sh7757lcr.patch delete mode 100644 patches.sh7757lcr/015-sh-add-platform_device-for-rspi-in-setup-sh7757.patch delete mode 100644 patches.sh7757lcr/016-sh-fix-build-warning-in-board-sh7757lcr.patch delete mode 100644 patches.sh7757lcr/017-sh-add-platform_device-for-renesas_usbhs-in-board-sh7757lcr.patch delete mode 100644 patches.sh7757lcr/018-sh-fix-the-sh_mmcif_plat_data-in-board-sh7757lcr.patch delete mode 100644 patches.sh7757lcr/019-sh-modify-a-resource-of-sh_eth_giga1_resources-in-board-sh7757lcr.patch delete mode 100644 patches.sh7757lcr/020-sh-kexec-register-crashk_res.patch delete mode 100644 patches.sh7757lcr/021-sh-kexec-add-physical_start.patch delete mode 100644 patches.sh7757lcr/drivers-sh-generalize-runtime-pm-platform-stub.patch delete mode 100644 patches.sh7757lcr/sh-also-without-pm_runtime-pm_runtime.o-must-be-built.patch delete mode 100644 patches.sh7757lcr/sh-fix-clock-sh7757-for-the-latest-sh_mobile_sdhi-driver.patch diff --git a/KERNEL_VERSION b/KERNEL_VERSION index f4605dc50cbe..0ce07b72f809 100644 --- a/KERNEL_VERSION +++ b/KERNEL_VERSION @@ -1 +1 @@ -3.0.36 +3.4.11 diff --git a/patches.android/android-0001-Revert-Staging-android-delete-android-drivers.patch b/patches.android/android-0001-Revert-Staging-android-delete-android-drivers.patch deleted file mode 100644 index e278f5d6b3c0..000000000000 --- a/patches.android/android-0001-Revert-Staging-android-delete-android-drivers.patch +++ /dev/null @@ -1,5904 +0,0 @@ -From 355b0502f6efea0ff9492753888772c96972d2a3 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 30 Nov 2011 20:18:14 +0900 -Subject: Revert "Staging: android: delete android drivers" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 355b0502f6efea0ff9492753888772c96972d2a3 - -This reverts commit b0a0ccfad85b3657fe999805df65f5cfe634ab8a. - -Turns out I was wrong, we want these in the tree. - -Note, I've disabled the drivers from the build at the moment, so other -patches can be applied to fix some build issues due to internal api -changes since the code was removed from the tree. - -Cc: Arve HjønnevÃ¥g -Cc: Brian Swetland -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -new file mode 100644 -index 0000000..eb67563 ---- /dev/null -+++ b/drivers/staging/android/Kconfig -@@ -0,0 +1,96 @@ -+menu "Android" -+ -+config ANDROID -+ bool "Android Drivers" -+ depends on BROKEN -+ default N -+ ---help--- -+ Enable support for various drivers needed on the Android platform -+ -+if ANDROID -+ -+config ANDROID_BINDER_IPC -+ bool "Android Binder IPC Driver" -+ default n -+ -+config ANDROID_LOGGER -+ tristate "Android log driver" -+ default n -+ -+config ANDROID_RAM_CONSOLE -+ bool "Android RAM buffer console" -+ default n -+ -+config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE -+ bool "Enable verbose console messages on Android RAM console" -+ default y -+ depends on ANDROID_RAM_CONSOLE -+ -+menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ bool "Android RAM Console Enable error correction" -+ default n -+ depends on ANDROID_RAM_CONSOLE -+ depends on !ANDROID_RAM_CONSOLE_EARLY_INIT -+ select REED_SOLOMON -+ select REED_SOLOMON_ENC8 -+ select REED_SOLOMON_DEC8 -+ -+if ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ -+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE -+ int "Android RAM Console Data data size" -+ default 128 -+ help -+ Must be a power of 2. -+ -+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE -+ int "Android RAM Console ECC size" -+ default 16 -+ -+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE -+ int "Android RAM Console Symbol size" -+ default 8 -+ -+config ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL -+ hex "Android RAM Console Polynomial" -+ default 0x19 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 4) -+ default 0x29 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 5) -+ default 0x61 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 6) -+ default 0x89 if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 7) -+ default 0x11d if (ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE = 8) -+ -+endif # ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ -+config ANDROID_RAM_CONSOLE_EARLY_INIT -+ bool "Start Android RAM console early" -+ default n -+ depends on ANDROID_RAM_CONSOLE -+ -+config ANDROID_RAM_CONSOLE_EARLY_ADDR -+ hex "Android RAM console virtual address" -+ default 0 -+ depends on ANDROID_RAM_CONSOLE_EARLY_INIT -+ -+config ANDROID_RAM_CONSOLE_EARLY_SIZE -+ hex "Android RAM console buffer size" -+ default 0 -+ depends on ANDROID_RAM_CONSOLE_EARLY_INIT -+ -+config ANDROID_TIMED_OUTPUT -+ bool "Timed output class driver" -+ default y -+ -+config ANDROID_TIMED_GPIO -+ tristate "Android timed gpio driver" -+ depends on GENERIC_GPIO && ANDROID_TIMED_OUTPUT -+ default n -+ -+config ANDROID_LOW_MEMORY_KILLER -+ bool "Android Low Memory Killer" -+ default N -+ ---help--- -+ Register processes to be killed when memory is low -+ -+endif # if ANDROID -+ -+endmenu -diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile -new file mode 100644 -index 0000000..8e057e6 ---- /dev/null -+++ b/drivers/staging/android/Makefile -@@ -0,0 +1,6 @@ -+obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o -+obj-$(CONFIG_ANDROID_LOGGER) += logger.o -+obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o -+obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -+obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o -+obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o -diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO -new file mode 100644 -index 0000000..e59c5be ---- /dev/null -+++ b/drivers/staging/android/TODO -@@ -0,0 +1,10 @@ -+TODO: -+ - checkpatch.pl cleanups -+ - sparse fixes -+ - rename files to be not so "generic" -+ - make sure things build as modules properly -+ - add proper arch dependancies as needed -+ - audit userspace interfaces to make sure they are sane -+ -+Please send patches to Greg Kroah-Hartman and Cc: -+Brian Swetland -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -new file mode 100644 -index 0000000..99010d4 ---- /dev/null -+++ b/drivers/staging/android/binder.c -@@ -0,0 +1,3767 @@ -+/* binder.c -+ * -+ * Android IPC Subsystem -+ * -+ * Copyright (C) 2007-2008 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "binder.h" -+ -+static DEFINE_MUTEX(binder_lock); -+static DEFINE_MUTEX(binder_deferred_lock); -+ -+static HLIST_HEAD(binder_procs); -+static HLIST_HEAD(binder_deferred_list); -+static HLIST_HEAD(binder_dead_nodes); -+ -+static struct proc_dir_entry *binder_proc_dir_entry_root; -+static struct proc_dir_entry *binder_proc_dir_entry_proc; -+static struct binder_node *binder_context_mgr_node; -+static uid_t binder_context_mgr_uid = -1; -+static int binder_last_id; -+ -+static int binder_read_proc_proc(char *page, char **start, off_t off, -+ int count, int *eof, void *data); -+ -+/* This is only defined in include/asm-arm/sizes.h */ -+#ifndef SZ_1K -+#define SZ_1K 0x400 -+#endif -+ -+#ifndef SZ_4M -+#define SZ_4M 0x400000 -+#endif -+ -+#define FORBIDDEN_MMAP_FLAGS (VM_WRITE) -+ -+#define BINDER_SMALL_BUF_SIZE (PAGE_SIZE * 64) -+ -+enum { -+ BINDER_DEBUG_USER_ERROR = 1U << 0, -+ BINDER_DEBUG_FAILED_TRANSACTION = 1U << 1, -+ BINDER_DEBUG_DEAD_TRANSACTION = 1U << 2, -+ BINDER_DEBUG_OPEN_CLOSE = 1U << 3, -+ BINDER_DEBUG_DEAD_BINDER = 1U << 4, -+ BINDER_DEBUG_DEATH_NOTIFICATION = 1U << 5, -+ BINDER_DEBUG_READ_WRITE = 1U << 6, -+ BINDER_DEBUG_USER_REFS = 1U << 7, -+ BINDER_DEBUG_THREADS = 1U << 8, -+ BINDER_DEBUG_TRANSACTION = 1U << 9, -+ BINDER_DEBUG_TRANSACTION_COMPLETE = 1U << 10, -+ BINDER_DEBUG_FREE_BUFFER = 1U << 11, -+ BINDER_DEBUG_INTERNAL_REFS = 1U << 12, -+ BINDER_DEBUG_BUFFER_ALLOC = 1U << 13, -+ BINDER_DEBUG_PRIORITY_CAP = 1U << 14, -+ BINDER_DEBUG_BUFFER_ALLOC_ASYNC = 1U << 15, -+}; -+static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | -+ BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; -+module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); -+ -+static int binder_debug_no_lock; -+module_param_named(proc_no_lock, binder_debug_no_lock, bool, S_IWUSR | S_IRUGO); -+ -+static DECLARE_WAIT_QUEUE_HEAD(binder_user_error_wait); -+static int binder_stop_on_user_error; -+ -+static int binder_set_stop_on_user_error(const char *val, -+ struct kernel_param *kp) -+{ -+ int ret; -+ ret = param_set_int(val, kp); -+ if (binder_stop_on_user_error < 2) -+ wake_up(&binder_user_error_wait); -+ return ret; -+} -+module_param_call(stop_on_user_error, binder_set_stop_on_user_error, -+ param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); -+ -+#define binder_debug(mask, x...) \ -+ do { \ -+ if (binder_debug_mask & mask) \ -+ printk(KERN_INFO x); \ -+ } while (0) -+ -+#define binder_user_error(x...) \ -+ do { \ -+ if (binder_debug_mask & BINDER_DEBUG_USER_ERROR) \ -+ printk(KERN_INFO x); \ -+ if (binder_stop_on_user_error) \ -+ binder_stop_on_user_error = 2; \ -+ } while (0) -+ -+enum binder_stat_types { -+ BINDER_STAT_PROC, -+ BINDER_STAT_THREAD, -+ BINDER_STAT_NODE, -+ BINDER_STAT_REF, -+ BINDER_STAT_DEATH, -+ BINDER_STAT_TRANSACTION, -+ BINDER_STAT_TRANSACTION_COMPLETE, -+ BINDER_STAT_COUNT -+}; -+ -+struct binder_stats { -+ int br[_IOC_NR(BR_FAILED_REPLY) + 1]; -+ int bc[_IOC_NR(BC_DEAD_BINDER_DONE) + 1]; -+ int obj_created[BINDER_STAT_COUNT]; -+ int obj_deleted[BINDER_STAT_COUNT]; -+}; -+ -+static struct binder_stats binder_stats; -+ -+static inline void binder_stats_deleted(enum binder_stat_types type) -+{ -+ binder_stats.obj_deleted[type]++; -+} -+ -+static inline void binder_stats_created(enum binder_stat_types type) -+{ -+ binder_stats.obj_created[type]++; -+} -+ -+struct binder_transaction_log_entry { -+ int debug_id; -+ int call_type; -+ int from_proc; -+ int from_thread; -+ int target_handle; -+ int to_proc; -+ int to_thread; -+ int to_node; -+ int data_size; -+ int offsets_size; -+}; -+struct binder_transaction_log { -+ int next; -+ int full; -+ struct binder_transaction_log_entry entry[32]; -+}; -+static struct binder_transaction_log binder_transaction_log; -+static struct binder_transaction_log binder_transaction_log_failed; -+ -+static struct binder_transaction_log_entry *binder_transaction_log_add( -+ struct binder_transaction_log *log) -+{ -+ struct binder_transaction_log_entry *e; -+ e = &log->entry[log->next]; -+ memset(e, 0, sizeof(*e)); -+ log->next++; -+ if (log->next == ARRAY_SIZE(log->entry)) { -+ log->next = 0; -+ log->full = 1; -+ } -+ return e; -+} -+ -+struct binder_work { -+ struct list_head entry; -+ enum { -+ BINDER_WORK_TRANSACTION = 1, -+ BINDER_WORK_TRANSACTION_COMPLETE, -+ BINDER_WORK_NODE, -+ BINDER_WORK_DEAD_BINDER, -+ BINDER_WORK_DEAD_BINDER_AND_CLEAR, -+ BINDER_WORK_CLEAR_DEATH_NOTIFICATION, -+ } type; -+}; -+ -+struct binder_node { -+ int debug_id; -+ struct binder_work work; -+ union { -+ struct rb_node rb_node; -+ struct hlist_node dead_node; -+ }; -+ struct binder_proc *proc; -+ struct hlist_head refs; -+ int internal_strong_refs; -+ int local_weak_refs; -+ int local_strong_refs; -+ void __user *ptr; -+ void __user *cookie; -+ unsigned has_strong_ref:1; -+ unsigned pending_strong_ref:1; -+ unsigned has_weak_ref:1; -+ unsigned pending_weak_ref:1; -+ unsigned has_async_transaction:1; -+ unsigned accept_fds:1; -+ unsigned min_priority:8; -+ struct list_head async_todo; -+}; -+ -+struct binder_ref_death { -+ struct binder_work work; -+ void __user *cookie; -+}; -+ -+struct binder_ref { -+ /* Lookups needed: */ -+ /* node + proc => ref (transaction) */ -+ /* desc + proc => ref (transaction, inc/dec ref) */ -+ /* node => refs + procs (proc exit) */ -+ int debug_id; -+ struct rb_node rb_node_desc; -+ struct rb_node rb_node_node; -+ struct hlist_node node_entry; -+ struct binder_proc *proc; -+ struct binder_node *node; -+ uint32_t desc; -+ int strong; -+ int weak; -+ struct binder_ref_death *death; -+}; -+ -+struct binder_buffer { -+ struct list_head entry; /* free and allocated entries by addesss */ -+ struct rb_node rb_node; /* free entry by size or allocated entry */ -+ /* by address */ -+ unsigned free:1; -+ unsigned allow_user_free:1; -+ unsigned async_transaction:1; -+ unsigned debug_id:29; -+ -+ struct binder_transaction *transaction; -+ -+ struct binder_node *target_node; -+ size_t data_size; -+ size_t offsets_size; -+ uint8_t data[0]; -+}; -+ -+enum binder_deferred_state { -+ BINDER_DEFERRED_PUT_FILES = 0x01, -+ BINDER_DEFERRED_FLUSH = 0x02, -+ BINDER_DEFERRED_RELEASE = 0x04, -+}; -+ -+struct binder_proc { -+ struct hlist_node proc_node; -+ struct rb_root threads; -+ struct rb_root nodes; -+ struct rb_root refs_by_desc; -+ struct rb_root refs_by_node; -+ int pid; -+ struct vm_area_struct *vma; -+ struct task_struct *tsk; -+ struct files_struct *files; -+ struct hlist_node deferred_work_node; -+ int deferred_work; -+ void *buffer; -+ ptrdiff_t user_buffer_offset; -+ -+ struct list_head buffers; -+ struct rb_root free_buffers; -+ struct rb_root allocated_buffers; -+ size_t free_async_space; -+ -+ struct page **pages; -+ size_t buffer_size; -+ uint32_t buffer_free; -+ struct list_head todo; -+ wait_queue_head_t wait; -+ struct binder_stats stats; -+ struct list_head delivered_death; -+ int max_threads; -+ int requested_threads; -+ int requested_threads_started; -+ int ready_threads; -+ long default_priority; -+}; -+ -+enum { -+ BINDER_LOOPER_STATE_REGISTERED = 0x01, -+ BINDER_LOOPER_STATE_ENTERED = 0x02, -+ BINDER_LOOPER_STATE_EXITED = 0x04, -+ BINDER_LOOPER_STATE_INVALID = 0x08, -+ BINDER_LOOPER_STATE_WAITING = 0x10, -+ BINDER_LOOPER_STATE_NEED_RETURN = 0x20 -+}; -+ -+struct binder_thread { -+ struct binder_proc *proc; -+ struct rb_node rb_node; -+ int pid; -+ int looper; -+ struct binder_transaction *transaction_stack; -+ struct list_head todo; -+ uint32_t return_error; /* Write failed, return error code in read buf */ -+ uint32_t return_error2; /* Write failed, return error code in read */ -+ /* buffer. Used when sending a reply to a dead process that */ -+ /* we are also waiting on */ -+ wait_queue_head_t wait; -+ struct binder_stats stats; -+}; -+ -+struct binder_transaction { -+ int debug_id; -+ struct binder_work work; -+ struct binder_thread *from; -+ struct binder_transaction *from_parent; -+ struct binder_proc *to_proc; -+ struct binder_thread *to_thread; -+ struct binder_transaction *to_parent; -+ unsigned need_reply:1; -+ /* unsigned is_dead:1; */ /* not used at the moment */ -+ -+ struct binder_buffer *buffer; -+ unsigned int code; -+ unsigned int flags; -+ long priority; -+ long saved_priority; -+ uid_t sender_euid; -+}; -+ -+static void -+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); -+ -+/* -+ * copied from get_unused_fd_flags -+ */ -+int task_get_unused_fd_flags(struct binder_proc *proc, int flags) -+{ -+ struct files_struct *files = proc->files; -+ int fd, error; -+ struct fdtable *fdt; -+ unsigned long rlim_cur; -+ unsigned long irqs; -+ -+ if (files == NULL) -+ return -ESRCH; -+ -+ error = -EMFILE; -+ spin_lock(&files->file_lock); -+ -+repeat: -+ fdt = files_fdtable(files); -+ fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, -+ files->next_fd); -+ -+ /* -+ * N.B. For clone tasks sharing a files structure, this test -+ * will limit the total number of files that can be opened. -+ */ -+ rlim_cur = 0; -+ if (lock_task_sighand(proc->tsk, &irqs)) { -+ rlim_cur = proc->tsk->signal->rlim[RLIMIT_NOFILE].rlim_cur; -+ unlock_task_sighand(proc->tsk, &irqs); -+ } -+ if (fd >= rlim_cur) -+ goto out; -+ -+ /* Do we need to expand the fd array or fd set? */ -+ error = expand_files(files, fd); -+ if (error < 0) -+ goto out; -+ -+ if (error) { -+ /* -+ * If we needed to expand the fs array we -+ * might have blocked - try again. -+ */ -+ error = -EMFILE; -+ goto repeat; -+ } -+ -+ FD_SET(fd, fdt->open_fds); -+ if (flags & O_CLOEXEC) -+ FD_SET(fd, fdt->close_on_exec); -+ else -+ FD_CLR(fd, fdt->close_on_exec); -+ files->next_fd = fd + 1; -+#if 1 -+ /* Sanity check */ -+ if (fdt->fd[fd] != NULL) { -+ printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd); -+ fdt->fd[fd] = NULL; -+ } -+#endif -+ error = fd; -+ -+out: -+ spin_unlock(&files->file_lock); -+ return error; -+} -+ -+/* -+ * copied from fd_install -+ */ -+static void task_fd_install( -+ struct binder_proc *proc, unsigned int fd, struct file *file) -+{ -+ struct files_struct *files = proc->files; -+ struct fdtable *fdt; -+ -+ if (files == NULL) -+ return; -+ -+ spin_lock(&files->file_lock); -+ fdt = files_fdtable(files); -+ BUG_ON(fdt->fd[fd] != NULL); -+ rcu_assign_pointer(fdt->fd[fd], file); -+ spin_unlock(&files->file_lock); -+} -+ -+/* -+ * copied from __put_unused_fd in open.c -+ */ -+static void __put_unused_fd(struct files_struct *files, unsigned int fd) -+{ -+ struct fdtable *fdt = files_fdtable(files); -+ __FD_CLR(fd, fdt->open_fds); -+ if (fd < files->next_fd) -+ files->next_fd = fd; -+} -+ -+/* -+ * copied from sys_close -+ */ -+static long task_close_fd(struct binder_proc *proc, unsigned int fd) -+{ -+ struct file *filp; -+ struct files_struct *files = proc->files; -+ struct fdtable *fdt; -+ int retval; -+ -+ if (files == NULL) -+ return -ESRCH; -+ -+ spin_lock(&files->file_lock); -+ fdt = files_fdtable(files); -+ if (fd >= fdt->max_fds) -+ goto out_unlock; -+ filp = fdt->fd[fd]; -+ if (!filp) -+ goto out_unlock; -+ rcu_assign_pointer(fdt->fd[fd], NULL); -+ FD_CLR(fd, fdt->close_on_exec); -+ __put_unused_fd(files, fd); -+ spin_unlock(&files->file_lock); -+ retval = filp_close(filp, files); -+ -+ /* can't restart close syscall because file table entry was cleared */ -+ if (unlikely(retval == -ERESTARTSYS || -+ retval == -ERESTARTNOINTR || -+ retval == -ERESTARTNOHAND || -+ retval == -ERESTART_RESTARTBLOCK)) -+ retval = -EINTR; -+ -+ return retval; -+ -+out_unlock: -+ spin_unlock(&files->file_lock); -+ return -EBADF; -+} -+ -+static void binder_set_nice(long nice) -+{ -+ long min_nice; -+ if (can_nice(current, nice)) { -+ set_user_nice(current, nice); -+ return; -+ } -+ min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; -+ binder_debug(BINDER_DEBUG_PRIORITY_CAP, -+ "binder: %d: nice value %ld not allowed use " -+ "%ld instead\n", current->pid, nice, min_nice); -+ set_user_nice(current, min_nice); -+ if (min_nice < 20) -+ return; -+ binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid); -+} -+ -+static size_t binder_buffer_size(struct binder_proc *proc, -+ struct binder_buffer *buffer) -+{ -+ if (list_is_last(&buffer->entry, &proc->buffers)) -+ return proc->buffer + proc->buffer_size - (void *)buffer->data; -+ else -+ return (size_t)list_entry(buffer->entry.next, -+ struct binder_buffer, entry) - (size_t)buffer->data; -+} -+ -+static void binder_insert_free_buffer(struct binder_proc *proc, -+ struct binder_buffer *new_buffer) -+{ -+ struct rb_node **p = &proc->free_buffers.rb_node; -+ struct rb_node *parent = NULL; -+ struct binder_buffer *buffer; -+ size_t buffer_size; -+ size_t new_buffer_size; -+ -+ BUG_ON(!new_buffer->free); -+ -+ new_buffer_size = binder_buffer_size(proc, new_buffer); -+ -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: add free buffer, size %zd, " -+ "at %p\n", proc->pid, new_buffer_size, new_buffer); -+ -+ while (*p) { -+ parent = *p; -+ buffer = rb_entry(parent, struct binder_buffer, rb_node); -+ BUG_ON(!buffer->free); -+ -+ buffer_size = binder_buffer_size(proc, buffer); -+ -+ if (new_buffer_size < buffer_size) -+ p = &parent->rb_left; -+ else -+ p = &parent->rb_right; -+ } -+ rb_link_node(&new_buffer->rb_node, parent, p); -+ rb_insert_color(&new_buffer->rb_node, &proc->free_buffers); -+} -+ -+static void binder_insert_allocated_buffer(struct binder_proc *proc, -+ struct binder_buffer *new_buffer) -+{ -+ struct rb_node **p = &proc->allocated_buffers.rb_node; -+ struct rb_node *parent = NULL; -+ struct binder_buffer *buffer; -+ -+ BUG_ON(new_buffer->free); -+ -+ while (*p) { -+ parent = *p; -+ buffer = rb_entry(parent, struct binder_buffer, rb_node); -+ BUG_ON(buffer->free); -+ -+ if (new_buffer < buffer) -+ p = &parent->rb_left; -+ else if (new_buffer > buffer) -+ p = &parent->rb_right; -+ else -+ BUG(); -+ } -+ rb_link_node(&new_buffer->rb_node, parent, p); -+ rb_insert_color(&new_buffer->rb_node, &proc->allocated_buffers); -+} -+ -+static struct binder_buffer *binder_buffer_lookup(struct binder_proc *proc, -+ void __user *user_ptr) -+{ -+ struct rb_node *n = proc->allocated_buffers.rb_node; -+ struct binder_buffer *buffer; -+ struct binder_buffer *kern_ptr; -+ -+ kern_ptr = user_ptr - proc->user_buffer_offset -+ - offsetof(struct binder_buffer, data); -+ -+ while (n) { -+ buffer = rb_entry(n, struct binder_buffer, rb_node); -+ BUG_ON(buffer->free); -+ -+ if (kern_ptr < buffer) -+ n = n->rb_left; -+ else if (kern_ptr > buffer) -+ n = n->rb_right; -+ else -+ return buffer; -+ } -+ return NULL; -+} -+ -+static int binder_update_page_range(struct binder_proc *proc, int allocate, -+ void *start, void *end, -+ struct vm_area_struct *vma) -+{ -+ void *page_addr; -+ unsigned long user_page_addr; -+ struct vm_struct tmp_area; -+ struct page **page; -+ struct mm_struct *mm; -+ -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: %s pages %p-%p\n", proc->pid, -+ allocate ? "allocate" : "free", start, end); -+ -+ if (end <= start) -+ return 0; -+ -+ if (vma) -+ mm = NULL; -+ else -+ mm = get_task_mm(proc->tsk); -+ -+ if (mm) { -+ down_write(&mm->mmap_sem); -+ vma = proc->vma; -+ } -+ -+ if (allocate == 0) -+ goto free_range; -+ -+ if (vma == NULL) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf failed to " -+ "map pages in userspace, no vma\n", proc->pid); -+ goto err_no_vma; -+ } -+ -+ for (page_addr = start; page_addr < end; page_addr += PAGE_SIZE) { -+ int ret; -+ struct page **page_array_ptr; -+ page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; -+ -+ BUG_ON(*page); -+ *page = alloc_page(GFP_KERNEL | __GFP_ZERO); -+ if (*page == NULL) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf failed " -+ "for page at %p\n", proc->pid, page_addr); -+ goto err_alloc_page_failed; -+ } -+ tmp_area.addr = page_addr; -+ tmp_area.size = PAGE_SIZE + PAGE_SIZE /* guard page? */; -+ page_array_ptr = page; -+ ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); -+ if (ret) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf failed " -+ "to map page at %p in kernel\n", -+ proc->pid, page_addr); -+ goto err_map_kernel_failed; -+ } -+ user_page_addr = -+ (uintptr_t)page_addr + proc->user_buffer_offset; -+ ret = vm_insert_page(vma, user_page_addr, page[0]); -+ if (ret) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf failed " -+ "to map page at %lx in userspace\n", -+ proc->pid, user_page_addr); -+ goto err_vm_insert_page_failed; -+ } -+ /* vm_insert_page does not seem to increment the refcount */ -+ } -+ if (mm) { -+ up_write(&mm->mmap_sem); -+ mmput(mm); -+ } -+ return 0; -+ -+free_range: -+ for (page_addr = end - PAGE_SIZE; page_addr >= start; -+ page_addr -= PAGE_SIZE) { -+ page = &proc->pages[(page_addr - proc->buffer) / PAGE_SIZE]; -+ if (vma) -+ zap_page_range(vma, (uintptr_t)page_addr + -+ proc->user_buffer_offset, PAGE_SIZE, NULL); -+err_vm_insert_page_failed: -+ unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE); -+err_map_kernel_failed: -+ __free_page(*page); -+ *page = NULL; -+err_alloc_page_failed: -+ ; -+ } -+err_no_vma: -+ if (mm) { -+ up_write(&mm->mmap_sem); -+ mmput(mm); -+ } -+ return -ENOMEM; -+} -+ -+static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, -+ size_t data_size, -+ size_t offsets_size, int is_async) -+{ -+ struct rb_node *n = proc->free_buffers.rb_node; -+ struct binder_buffer *buffer; -+ size_t buffer_size; -+ struct rb_node *best_fit = NULL; -+ void *has_page_addr; -+ void *end_page_addr; -+ size_t size; -+ -+ if (proc->vma == NULL) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n", -+ proc->pid); -+ return NULL; -+ } -+ -+ size = ALIGN(data_size, sizeof(void *)) + -+ ALIGN(offsets_size, sizeof(void *)); -+ -+ if (size < data_size || size < offsets_size) { -+ binder_user_error("binder: %d: got transaction with invalid " -+ "size %zd-%zd\n", proc->pid, data_size, offsets_size); -+ return NULL; -+ } -+ -+ if (is_async && -+ proc->free_async_space < size + sizeof(struct binder_buffer)) { -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: binder_alloc_buf size %zd" -+ "failed, no async space left\n", proc->pid, size); -+ return NULL; -+ } -+ -+ while (n) { -+ buffer = rb_entry(n, struct binder_buffer, rb_node); -+ BUG_ON(!buffer->free); -+ buffer_size = binder_buffer_size(proc, buffer); -+ -+ if (size < buffer_size) { -+ best_fit = n; -+ n = n->rb_left; -+ } else if (size > buffer_size) -+ n = n->rb_right; -+ else { -+ best_fit = n; -+ break; -+ } -+ } -+ if (best_fit == NULL) { -+ printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, " -+ "no address space\n", proc->pid, size); -+ return NULL; -+ } -+ if (n == NULL) { -+ buffer = rb_entry(best_fit, struct binder_buffer, rb_node); -+ buffer_size = binder_buffer_size(proc, buffer); -+ } -+ -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: binder_alloc_buf size %zd got buff" -+ "er %p size %zd\n", proc->pid, size, buffer, buffer_size); -+ -+ has_page_addr = -+ (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); -+ if (n == NULL) { -+ if (size + sizeof(struct binder_buffer) + 4 >= buffer_size) -+ buffer_size = size; /* no room for other buffers */ -+ else -+ buffer_size = size + sizeof(struct binder_buffer); -+ } -+ end_page_addr = -+ (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size); -+ if (end_page_addr > has_page_addr) -+ end_page_addr = has_page_addr; -+ if (binder_update_page_range(proc, 1, -+ (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL)) -+ return NULL; -+ -+ rb_erase(best_fit, &proc->free_buffers); -+ buffer->free = 0; -+ binder_insert_allocated_buffer(proc, buffer); -+ if (buffer_size != size) { -+ struct binder_buffer *new_buffer = (void *)buffer->data + size; -+ list_add(&new_buffer->entry, &buffer->entry); -+ new_buffer->free = 1; -+ binder_insert_free_buffer(proc, new_buffer); -+ } -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: binder_alloc_buf size %zd got " -+ "%p\n", proc->pid, size, buffer); -+ buffer->data_size = data_size; -+ buffer->offsets_size = offsets_size; -+ buffer->async_transaction = is_async; -+ if (is_async) { -+ proc->free_async_space -= size + sizeof(struct binder_buffer); -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, -+ "binder: %d: binder_alloc_buf size %zd " -+ "async free %zd\n", proc->pid, size, -+ proc->free_async_space); -+ } -+ -+ return buffer; -+} -+ -+static void *buffer_start_page(struct binder_buffer *buffer) -+{ -+ return (void *)((uintptr_t)buffer & PAGE_MASK); -+} -+ -+static void *buffer_end_page(struct binder_buffer *buffer) -+{ -+ return (void *)(((uintptr_t)(buffer + 1) - 1) & PAGE_MASK); -+} -+ -+static void binder_delete_free_buffer(struct binder_proc *proc, -+ struct binder_buffer *buffer) -+{ -+ struct binder_buffer *prev, *next = NULL; -+ int free_page_end = 1; -+ int free_page_start = 1; -+ -+ BUG_ON(proc->buffers.next == &buffer->entry); -+ prev = list_entry(buffer->entry.prev, struct binder_buffer, entry); -+ BUG_ON(!prev->free); -+ if (buffer_end_page(prev) == buffer_start_page(buffer)) { -+ free_page_start = 0; -+ if (buffer_end_page(prev) == buffer_end_page(buffer)) -+ free_page_end = 0; -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: merge free, buffer %p " -+ "share page with %p\n", proc->pid, buffer, prev); -+ } -+ -+ if (!list_is_last(&buffer->entry, &proc->buffers)) { -+ next = list_entry(buffer->entry.next, -+ struct binder_buffer, entry); -+ if (buffer_start_page(next) == buffer_end_page(buffer)) { -+ free_page_end = 0; -+ if (buffer_start_page(next) == -+ buffer_start_page(buffer)) -+ free_page_start = 0; -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: merge free, buffer" -+ " %p share page with %p\n", proc->pid, -+ buffer, prev); -+ } -+ } -+ list_del(&buffer->entry); -+ if (free_page_start || free_page_end) { -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: merge free, buffer %p do " -+ "not share page%s%s with with %p or %p\n", -+ proc->pid, buffer, free_page_start ? "" : " end", -+ free_page_end ? "" : " start", prev, next); -+ binder_update_page_range(proc, 0, free_page_start ? -+ buffer_start_page(buffer) : buffer_end_page(buffer), -+ (free_page_end ? buffer_end_page(buffer) : -+ buffer_start_page(buffer)) + PAGE_SIZE, NULL); -+ } -+} -+ -+static void binder_free_buf(struct binder_proc *proc, -+ struct binder_buffer *buffer) -+{ -+ size_t size, buffer_size; -+ -+ buffer_size = binder_buffer_size(proc, buffer); -+ -+ size = ALIGN(buffer->data_size, sizeof(void *)) + -+ ALIGN(buffer->offsets_size, sizeof(void *)); -+ -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder: %d: binder_free_buf %p size %zd buffer" -+ "_size %zd\n", proc->pid, buffer, size, buffer_size); -+ -+ BUG_ON(buffer->free); -+ BUG_ON(size > buffer_size); -+ BUG_ON(buffer->transaction != NULL); -+ BUG_ON((void *)buffer < proc->buffer); -+ BUG_ON((void *)buffer > proc->buffer + proc->buffer_size); -+ -+ if (buffer->async_transaction) { -+ proc->free_async_space += size + sizeof(struct binder_buffer); -+ -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, -+ "binder: %d: binder_free_buf size %zd " -+ "async free %zd\n", proc->pid, size, -+ proc->free_async_space); -+ } -+ -+ binder_update_page_range(proc, 0, -+ (void *)PAGE_ALIGN((uintptr_t)buffer->data), -+ (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK), -+ NULL); -+ rb_erase(&buffer->rb_node, &proc->allocated_buffers); -+ buffer->free = 1; -+ if (!list_is_last(&buffer->entry, &proc->buffers)) { -+ struct binder_buffer *next = list_entry(buffer->entry.next, -+ struct binder_buffer, entry); -+ if (next->free) { -+ rb_erase(&next->rb_node, &proc->free_buffers); -+ binder_delete_free_buffer(proc, next); -+ } -+ } -+ if (proc->buffers.next != &buffer->entry) { -+ struct binder_buffer *prev = list_entry(buffer->entry.prev, -+ struct binder_buffer, entry); -+ if (prev->free) { -+ binder_delete_free_buffer(proc, buffer); -+ rb_erase(&prev->rb_node, &proc->free_buffers); -+ buffer = prev; -+ } -+ } -+ binder_insert_free_buffer(proc, buffer); -+} -+ -+static struct binder_node *binder_get_node(struct binder_proc *proc, -+ void __user *ptr) -+{ -+ struct rb_node *n = proc->nodes.rb_node; -+ struct binder_node *node; -+ -+ while (n) { -+ node = rb_entry(n, struct binder_node, rb_node); -+ -+ if (ptr < node->ptr) -+ n = n->rb_left; -+ else if (ptr > node->ptr) -+ n = n->rb_right; -+ else -+ return node; -+ } -+ return NULL; -+} -+ -+static struct binder_node *binder_new_node(struct binder_proc *proc, -+ void __user *ptr, -+ void __user *cookie) -+{ -+ struct rb_node **p = &proc->nodes.rb_node; -+ struct rb_node *parent = NULL; -+ struct binder_node *node; -+ -+ while (*p) { -+ parent = *p; -+ node = rb_entry(parent, struct binder_node, rb_node); -+ -+ if (ptr < node->ptr) -+ p = &(*p)->rb_left; -+ else if (ptr > node->ptr) -+ p = &(*p)->rb_right; -+ else -+ return NULL; -+ } -+ -+ node = kzalloc(sizeof(*node), GFP_KERNEL); -+ if (node == NULL) -+ return NULL; -+ binder_stats_created(BINDER_STAT_NODE); -+ rb_link_node(&node->rb_node, parent, p); -+ rb_insert_color(&node->rb_node, &proc->nodes); -+ node->debug_id = ++binder_last_id; -+ node->proc = proc; -+ node->ptr = ptr; -+ node->cookie = cookie; -+ node->work.type = BINDER_WORK_NODE; -+ INIT_LIST_HEAD(&node->work.entry); -+ INIT_LIST_HEAD(&node->async_todo); -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d:%d node %d u%p c%p created\n", -+ proc->pid, current->pid, node->debug_id, -+ node->ptr, node->cookie); -+ return node; -+} -+ -+static int binder_inc_node(struct binder_node *node, int strong, int internal, -+ struct list_head *target_list) -+{ -+ if (strong) { -+ if (internal) { -+ if (target_list == NULL && -+ node->internal_strong_refs == 0 && -+ !(node == binder_context_mgr_node && -+ node->has_strong_ref)) { -+ printk(KERN_ERR "binder: invalid inc strong " -+ "node for %d\n", node->debug_id); -+ return -EINVAL; -+ } -+ node->internal_strong_refs++; -+ } else -+ node->local_strong_refs++; -+ if (!node->has_strong_ref && target_list) { -+ list_del_init(&node->work.entry); -+ list_add_tail(&node->work.entry, target_list); -+ } -+ } else { -+ if (!internal) -+ node->local_weak_refs++; -+ if (!node->has_weak_ref && list_empty(&node->work.entry)) { -+ if (target_list == NULL) { -+ printk(KERN_ERR "binder: invalid inc weak node " -+ "for %d\n", node->debug_id); -+ return -EINVAL; -+ } -+ list_add_tail(&node->work.entry, target_list); -+ } -+ } -+ return 0; -+} -+ -+static int binder_dec_node(struct binder_node *node, int strong, int internal) -+{ -+ if (strong) { -+ if (internal) -+ node->internal_strong_refs--; -+ else -+ node->local_strong_refs--; -+ if (node->local_strong_refs || node->internal_strong_refs) -+ return 0; -+ } else { -+ if (!internal) -+ node->local_weak_refs--; -+ if (node->local_weak_refs || !hlist_empty(&node->refs)) -+ return 0; -+ } -+ if (node->proc && (node->has_strong_ref || node->has_weak_ref)) { -+ if (list_empty(&node->work.entry)) { -+ list_add_tail(&node->work.entry, &node->proc->todo); -+ wake_up_interruptible(&node->proc->wait); -+ } -+ } else { -+ if (hlist_empty(&node->refs) && !node->local_strong_refs && -+ !node->local_weak_refs) { -+ list_del_init(&node->work.entry); -+ if (node->proc) { -+ rb_erase(&node->rb_node, &node->proc->nodes); -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: refless node %d deleted\n", -+ node->debug_id); -+ } else { -+ hlist_del(&node->dead_node); -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: dead node %d deleted\n", -+ node->debug_id); -+ } -+ kfree(node); -+ binder_stats_deleted(BINDER_STAT_NODE); -+ } -+ } -+ -+ return 0; -+} -+ -+ -+static struct binder_ref *binder_get_ref(struct binder_proc *proc, -+ uint32_t desc) -+{ -+ struct rb_node *n = proc->refs_by_desc.rb_node; -+ struct binder_ref *ref; -+ -+ while (n) { -+ ref = rb_entry(n, struct binder_ref, rb_node_desc); -+ -+ if (desc < ref->desc) -+ n = n->rb_left; -+ else if (desc > ref->desc) -+ n = n->rb_right; -+ else -+ return ref; -+ } -+ return NULL; -+} -+ -+static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, -+ struct binder_node *node) -+{ -+ struct rb_node *n; -+ struct rb_node **p = &proc->refs_by_node.rb_node; -+ struct rb_node *parent = NULL; -+ struct binder_ref *ref, *new_ref; -+ -+ while (*p) { -+ parent = *p; -+ ref = rb_entry(parent, struct binder_ref, rb_node_node); -+ -+ if (node < ref->node) -+ p = &(*p)->rb_left; -+ else if (node > ref->node) -+ p = &(*p)->rb_right; -+ else -+ return ref; -+ } -+ new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); -+ if (new_ref == NULL) -+ return NULL; -+ binder_stats_created(BINDER_STAT_REF); -+ new_ref->debug_id = ++binder_last_id; -+ new_ref->proc = proc; -+ new_ref->node = node; -+ rb_link_node(&new_ref->rb_node_node, parent, p); -+ rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); -+ -+ new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; -+ for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { -+ ref = rb_entry(n, struct binder_ref, rb_node_desc); -+ if (ref->desc > new_ref->desc) -+ break; -+ new_ref->desc = ref->desc + 1; -+ } -+ -+ p = &proc->refs_by_desc.rb_node; -+ while (*p) { -+ parent = *p; -+ ref = rb_entry(parent, struct binder_ref, rb_node_desc); -+ -+ if (new_ref->desc < ref->desc) -+ p = &(*p)->rb_left; -+ else if (new_ref->desc > ref->desc) -+ p = &(*p)->rb_right; -+ else -+ BUG(); -+ } -+ rb_link_node(&new_ref->rb_node_desc, parent, p); -+ rb_insert_color(&new_ref->rb_node_desc, &proc->refs_by_desc); -+ if (node) { -+ hlist_add_head(&new_ref->node_entry, &node->refs); -+ -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d new ref %d desc %d for " -+ "node %d\n", proc->pid, new_ref->debug_id, -+ new_ref->desc, node->debug_id); -+ } else { -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d new ref %d desc %d for " -+ "dead node\n", proc->pid, new_ref->debug_id, -+ new_ref->desc); -+ } -+ return new_ref; -+} -+ -+static void binder_delete_ref(struct binder_ref *ref) -+{ -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d delete ref %d desc %d for " -+ "node %d\n", ref->proc->pid, ref->debug_id, -+ ref->desc, ref->node->debug_id); -+ -+ rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); -+ rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); -+ if (ref->strong) -+ binder_dec_node(ref->node, 1, 1); -+ hlist_del(&ref->node_entry); -+ binder_dec_node(ref->node, 0, 1); -+ if (ref->death) { -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder: %d delete ref %d desc %d " -+ "has death notification\n", ref->proc->pid, -+ ref->debug_id, ref->desc); -+ list_del(&ref->death->work.entry); -+ kfree(ref->death); -+ binder_stats_deleted(BINDER_STAT_DEATH); -+ } -+ kfree(ref); -+ binder_stats_deleted(BINDER_STAT_REF); -+} -+ -+static int binder_inc_ref(struct binder_ref *ref, int strong, -+ struct list_head *target_list) -+{ -+ int ret; -+ if (strong) { -+ if (ref->strong == 0) { -+ ret = binder_inc_node(ref->node, 1, 1, target_list); -+ if (ret) -+ return ret; -+ } -+ ref->strong++; -+ } else { -+ if (ref->weak == 0) { -+ ret = binder_inc_node(ref->node, 0, 1, target_list); -+ if (ret) -+ return ret; -+ } -+ ref->weak++; -+ } -+ return 0; -+} -+ -+ -+static int binder_dec_ref(struct binder_ref *ref, int strong) -+{ -+ if (strong) { -+ if (ref->strong == 0) { -+ binder_user_error("binder: %d invalid dec strong, " -+ "ref %d desc %d s %d w %d\n", -+ ref->proc->pid, ref->debug_id, -+ ref->desc, ref->strong, ref->weak); -+ return -EINVAL; -+ } -+ ref->strong--; -+ if (ref->strong == 0) { -+ int ret; -+ ret = binder_dec_node(ref->node, strong, 1); -+ if (ret) -+ return ret; -+ } -+ } else { -+ if (ref->weak == 0) { -+ binder_user_error("binder: %d invalid dec weak, " -+ "ref %d desc %d s %d w %d\n", -+ ref->proc->pid, ref->debug_id, -+ ref->desc, ref->strong, ref->weak); -+ return -EINVAL; -+ } -+ ref->weak--; -+ } -+ if (ref->strong == 0 && ref->weak == 0) -+ binder_delete_ref(ref); -+ return 0; -+} -+ -+static void binder_pop_transaction(struct binder_thread *target_thread, -+ struct binder_transaction *t) -+{ -+ if (target_thread) { -+ BUG_ON(target_thread->transaction_stack != t); -+ BUG_ON(target_thread->transaction_stack->from != target_thread); -+ target_thread->transaction_stack = -+ target_thread->transaction_stack->from_parent; -+ t->from = NULL; -+ } -+ t->need_reply = 0; -+ if (t->buffer) -+ t->buffer->transaction = NULL; -+ kfree(t); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION); -+} -+ -+static void binder_send_failed_reply(struct binder_transaction *t, -+ uint32_t error_code) -+{ -+ struct binder_thread *target_thread; -+ BUG_ON(t->flags & TF_ONE_WAY); -+ while (1) { -+ target_thread = t->from; -+ if (target_thread) { -+ if (target_thread->return_error != BR_OK && -+ target_thread->return_error2 == BR_OK) { -+ target_thread->return_error2 = -+ target_thread->return_error; -+ target_thread->return_error = BR_OK; -+ } -+ if (target_thread->return_error == BR_OK) { -+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, -+ "binder: send failed reply for " -+ "transaction %d to %d:%d\n", -+ t->debug_id, target_thread->proc->pid, -+ target_thread->pid); -+ -+ binder_pop_transaction(target_thread, t); -+ target_thread->return_error = error_code; -+ wake_up_interruptible(&target_thread->wait); -+ } else { -+ printk(KERN_ERR "binder: reply failed, target " -+ "thread, %d:%d, has error code %d " -+ "already\n", target_thread->proc->pid, -+ target_thread->pid, -+ target_thread->return_error); -+ } -+ return; -+ } else { -+ struct binder_transaction *next = t->from_parent; -+ -+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, -+ "binder: send failed reply " -+ "for transaction %d, target dead\n", -+ t->debug_id); -+ -+ binder_pop_transaction(target_thread, t); -+ if (next == NULL) { -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder: reply failed," -+ " no target thread at root\n"); -+ return; -+ } -+ t = next; -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder: reply failed, no target " -+ "thread -- retry %d\n", t->debug_id); -+ } -+ } -+} -+ -+static void binder_transaction_buffer_release(struct binder_proc *proc, -+ struct binder_buffer *buffer, -+ size_t *failed_at) -+{ -+ size_t *offp, *off_end; -+ int debug_id = buffer->debug_id; -+ -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", -+ proc->pid, buffer->debug_id, -+ buffer->data_size, buffer->offsets_size, failed_at); -+ -+ if (buffer->target_node) -+ binder_dec_node(buffer->target_node, 1, 0); -+ -+ offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *))); -+ if (failed_at) -+ off_end = failed_at; -+ else -+ off_end = (void *)offp + buffer->offsets_size; -+ for (; offp < off_end; offp++) { -+ struct flat_binder_object *fp; -+ if (*offp > buffer->data_size - sizeof(*fp) || -+ buffer->data_size < sizeof(*fp) || -+ !IS_ALIGNED(*offp, sizeof(void *))) { -+ printk(KERN_ERR "binder: transaction release %d bad" -+ "offset %zd, size %zd\n", debug_id, -+ *offp, buffer->data_size); -+ continue; -+ } -+ fp = (struct flat_binder_object *)(buffer->data + *offp); -+ switch (fp->type) { -+ case BINDER_TYPE_BINDER: -+ case BINDER_TYPE_WEAK_BINDER: { -+ struct binder_node *node = binder_get_node(proc, fp->binder); -+ if (node == NULL) { -+ printk(KERN_ERR "binder: transaction release %d" -+ " bad node %p\n", debug_id, fp->binder); -+ break; -+ } -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " node %d u%p\n", -+ node->debug_id, node->ptr); -+ binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0); -+ } break; -+ case BINDER_TYPE_HANDLE: -+ case BINDER_TYPE_WEAK_HANDLE: { -+ struct binder_ref *ref = binder_get_ref(proc, fp->handle); -+ if (ref == NULL) { -+ printk(KERN_ERR "binder: transaction release %d" -+ " bad handle %ld\n", debug_id, -+ fp->handle); -+ break; -+ } -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " ref %d desc %d (node %d)\n", -+ ref->debug_id, ref->desc, ref->node->debug_id); -+ binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE); -+ } break; -+ -+ case BINDER_TYPE_FD: -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " fd %ld\n", fp->handle); -+ if (failed_at) -+ task_close_fd(proc, fp->handle); -+ break; -+ -+ default: -+ printk(KERN_ERR "binder: transaction release %d bad " -+ "object type %lx\n", debug_id, fp->type); -+ break; -+ } -+ } -+} -+ -+static void binder_transaction(struct binder_proc *proc, -+ struct binder_thread *thread, -+ struct binder_transaction_data *tr, int reply) -+{ -+ struct binder_transaction *t; -+ struct binder_work *tcomplete; -+ size_t *offp, *off_end; -+ struct binder_proc *target_proc; -+ struct binder_thread *target_thread = NULL; -+ struct binder_node *target_node = NULL; -+ struct list_head *target_list; -+ wait_queue_head_t *target_wait; -+ struct binder_transaction *in_reply_to = NULL; -+ struct binder_transaction_log_entry *e; -+ uint32_t return_error; -+ -+ e = binder_transaction_log_add(&binder_transaction_log); -+ e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY); -+ e->from_proc = proc->pid; -+ e->from_thread = thread->pid; -+ e->target_handle = tr->target.handle; -+ e->data_size = tr->data_size; -+ e->offsets_size = tr->offsets_size; -+ -+ if (reply) { -+ in_reply_to = thread->transaction_stack; -+ if (in_reply_to == NULL) { -+ binder_user_error("binder: %d:%d got reply transaction " -+ "with no transaction stack\n", -+ proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ goto err_empty_call_stack; -+ } -+ binder_set_nice(in_reply_to->saved_priority); -+ if (in_reply_to->to_thread != thread) { -+ binder_user_error("binder: %d:%d got reply transaction " -+ "with bad transaction stack," -+ " transaction %d has target %d:%d\n", -+ proc->pid, thread->pid, in_reply_to->debug_id, -+ in_reply_to->to_proc ? -+ in_reply_to->to_proc->pid : 0, -+ in_reply_to->to_thread ? -+ in_reply_to->to_thread->pid : 0); -+ return_error = BR_FAILED_REPLY; -+ in_reply_to = NULL; -+ goto err_bad_call_stack; -+ } -+ thread->transaction_stack = in_reply_to->to_parent; -+ target_thread = in_reply_to->from; -+ if (target_thread == NULL) { -+ return_error = BR_DEAD_REPLY; -+ goto err_dead_binder; -+ } -+ if (target_thread->transaction_stack != in_reply_to) { -+ binder_user_error("binder: %d:%d got reply transaction " -+ "with bad target transaction stack %d, " -+ "expected %d\n", -+ proc->pid, thread->pid, -+ target_thread->transaction_stack ? -+ target_thread->transaction_stack->debug_id : 0, -+ in_reply_to->debug_id); -+ return_error = BR_FAILED_REPLY; -+ in_reply_to = NULL; -+ target_thread = NULL; -+ goto err_dead_binder; -+ } -+ target_proc = target_thread->proc; -+ } else { -+ if (tr->target.handle) { -+ struct binder_ref *ref; -+ ref = binder_get_ref(proc, tr->target.handle); -+ if (ref == NULL) { -+ binder_user_error("binder: %d:%d got " -+ "transaction to invalid handle\n", -+ proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ goto err_invalid_target_handle; -+ } -+ target_node = ref->node; -+ } else { -+ target_node = binder_context_mgr_node; -+ if (target_node == NULL) { -+ return_error = BR_DEAD_REPLY; -+ goto err_no_context_mgr_node; -+ } -+ } -+ e->to_node = target_node->debug_id; -+ target_proc = target_node->proc; -+ if (target_proc == NULL) { -+ return_error = BR_DEAD_REPLY; -+ goto err_dead_binder; -+ } -+ if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) { -+ struct binder_transaction *tmp; -+ tmp = thread->transaction_stack; -+ if (tmp->to_thread != thread) { -+ binder_user_error("binder: %d:%d got new " -+ "transaction with bad transaction stack" -+ ", transaction %d has target %d:%d\n", -+ proc->pid, thread->pid, tmp->debug_id, -+ tmp->to_proc ? tmp->to_proc->pid : 0, -+ tmp->to_thread ? -+ tmp->to_thread->pid : 0); -+ return_error = BR_FAILED_REPLY; -+ goto err_bad_call_stack; -+ } -+ while (tmp) { -+ if (tmp->from && tmp->from->proc == target_proc) -+ target_thread = tmp->from; -+ tmp = tmp->from_parent; -+ } -+ } -+ } -+ if (target_thread) { -+ e->to_thread = target_thread->pid; -+ target_list = &target_thread->todo; -+ target_wait = &target_thread->wait; -+ } else { -+ target_list = &target_proc->todo; -+ target_wait = &target_proc->wait; -+ } -+ e->to_proc = target_proc->pid; -+ -+ /* TODO: reuse incoming transaction for reply */ -+ t = kzalloc(sizeof(*t), GFP_KERNEL); -+ if (t == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_alloc_t_failed; -+ } -+ binder_stats_created(BINDER_STAT_TRANSACTION); -+ -+ tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); -+ if (tcomplete == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_alloc_tcomplete_failed; -+ } -+ binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); -+ -+ t->debug_id = ++binder_last_id; -+ e->debug_id = t->debug_id; -+ -+ if (reply) -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ "binder: %d:%d BC_REPLY %d -> %d:%d, " -+ "data %p-%p size %zd-%zd\n", -+ proc->pid, thread->pid, t->debug_id, -+ target_proc->pid, target_thread->pid, -+ tr->data.ptr.buffer, tr->data.ptr.offsets, -+ tr->data_size, tr->offsets_size); -+ else -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ "binder: %d:%d BC_TRANSACTION %d -> " -+ "%d - node %d, data %p-%p size %zd-%zd\n", -+ proc->pid, thread->pid, t->debug_id, -+ target_proc->pid, target_node->debug_id, -+ tr->data.ptr.buffer, tr->data.ptr.offsets, -+ tr->data_size, tr->offsets_size); -+ -+ if (!reply && !(tr->flags & TF_ONE_WAY)) -+ t->from = thread; -+ else -+ t->from = NULL; -+ t->sender_euid = proc->tsk->cred->euid; -+ t->to_proc = target_proc; -+ t->to_thread = target_thread; -+ t->code = tr->code; -+ t->flags = tr->flags; -+ t->priority = task_nice(current); -+ t->buffer = binder_alloc_buf(target_proc, tr->data_size, -+ tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); -+ if (t->buffer == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_binder_alloc_buf_failed; -+ } -+ t->buffer->allow_user_free = 0; -+ t->buffer->debug_id = t->debug_id; -+ t->buffer->transaction = t; -+ t->buffer->target_node = target_node; -+ if (target_node) -+ binder_inc_node(target_node, 1, 0, NULL); -+ -+ offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); -+ -+ if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) { -+ binder_user_error("binder: %d:%d got transaction with invalid " -+ "data ptr\n", proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ goto err_copy_data_failed; -+ } -+ if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) { -+ binder_user_error("binder: %d:%d got transaction with invalid " -+ "offsets ptr\n", proc->pid, thread->pid); -+ return_error = BR_FAILED_REPLY; -+ goto err_copy_data_failed; -+ } -+ if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { -+ binder_user_error("binder: %d:%d got transaction with " -+ "invalid offsets size, %zd\n", -+ proc->pid, thread->pid, tr->offsets_size); -+ return_error = BR_FAILED_REPLY; -+ goto err_bad_offset; -+ } -+ off_end = (void *)offp + tr->offsets_size; -+ for (; offp < off_end; offp++) { -+ struct flat_binder_object *fp; -+ if (*offp > t->buffer->data_size - sizeof(*fp) || -+ t->buffer->data_size < sizeof(*fp) || -+ !IS_ALIGNED(*offp, sizeof(void *))) { -+ binder_user_error("binder: %d:%d got transaction with " -+ "invalid offset, %zd\n", -+ proc->pid, thread->pid, *offp); -+ return_error = BR_FAILED_REPLY; -+ goto err_bad_offset; -+ } -+ fp = (struct flat_binder_object *)(t->buffer->data + *offp); -+ switch (fp->type) { -+ case BINDER_TYPE_BINDER: -+ case BINDER_TYPE_WEAK_BINDER: { -+ struct binder_ref *ref; -+ struct binder_node *node = binder_get_node(proc, fp->binder); -+ if (node == NULL) { -+ node = binder_new_node(proc, fp->binder, fp->cookie); -+ if (node == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_binder_new_node_failed; -+ } -+ node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK; -+ node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); -+ } -+ if (fp->cookie != node->cookie) { -+ binder_user_error("binder: %d:%d sending u%p " -+ "node %d, cookie mismatch %p != %p\n", -+ proc->pid, thread->pid, -+ fp->binder, node->debug_id, -+ fp->cookie, node->cookie); -+ goto err_binder_get_ref_for_node_failed; -+ } -+ ref = binder_get_ref_for_node(target_proc, node); -+ if (ref == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_binder_get_ref_for_node_failed; -+ } -+ if (fp->type == BINDER_TYPE_BINDER) -+ fp->type = BINDER_TYPE_HANDLE; -+ else -+ fp->type = BINDER_TYPE_WEAK_HANDLE; -+ fp->handle = ref->desc; -+ binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, -+ &thread->todo); -+ -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " node %d u%p -> ref %d desc %d\n", -+ node->debug_id, node->ptr, ref->debug_id, -+ ref->desc); -+ } break; -+ case BINDER_TYPE_HANDLE: -+ case BINDER_TYPE_WEAK_HANDLE: { -+ struct binder_ref *ref = binder_get_ref(proc, fp->handle); -+ if (ref == NULL) { -+ binder_user_error("binder: %d:%d got " -+ "transaction with invalid " -+ "handle, %ld\n", proc->pid, -+ thread->pid, fp->handle); -+ return_error = BR_FAILED_REPLY; -+ goto err_binder_get_ref_failed; -+ } -+ if (ref->node->proc == target_proc) { -+ if (fp->type == BINDER_TYPE_HANDLE) -+ fp->type = BINDER_TYPE_BINDER; -+ else -+ fp->type = BINDER_TYPE_WEAK_BINDER; -+ fp->binder = ref->node->ptr; -+ fp->cookie = ref->node->cookie; -+ binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " ref %d desc %d -> node %d u%p\n", -+ ref->debug_id, ref->desc, ref->node->debug_id, -+ ref->node->ptr); -+ } else { -+ struct binder_ref *new_ref; -+ new_ref = binder_get_ref_for_node(target_proc, ref->node); -+ if (new_ref == NULL) { -+ return_error = BR_FAILED_REPLY; -+ goto err_binder_get_ref_for_node_failed; -+ } -+ fp->handle = new_ref->desc; -+ binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " ref %d desc %d -> ref %d desc %d (node %d)\n", -+ ref->debug_id, ref->desc, new_ref->debug_id, -+ new_ref->desc, ref->node->debug_id); -+ } -+ } break; -+ -+ case BINDER_TYPE_FD: { -+ int target_fd; -+ struct file *file; -+ -+ if (reply) { -+ if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { -+ binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", -+ proc->pid, thread->pid, fp->handle); -+ return_error = BR_FAILED_REPLY; -+ goto err_fd_not_allowed; -+ } -+ } else if (!target_node->accept_fds) { -+ binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", -+ proc->pid, thread->pid, fp->handle); -+ return_error = BR_FAILED_REPLY; -+ goto err_fd_not_allowed; -+ } -+ -+ file = fget(fp->handle); -+ if (file == NULL) { -+ binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", -+ proc->pid, thread->pid, fp->handle); -+ return_error = BR_FAILED_REPLY; -+ goto err_fget_failed; -+ } -+ target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC); -+ if (target_fd < 0) { -+ fput(file); -+ return_error = BR_FAILED_REPLY; -+ goto err_get_unused_fd_failed; -+ } -+ task_fd_install(target_proc, target_fd, file); -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ " fd %ld -> %d\n", fp->handle, target_fd); -+ /* TODO: fput? */ -+ fp->handle = target_fd; -+ } break; -+ -+ default: -+ binder_user_error("binder: %d:%d got transactio" -+ "n with invalid object type, %lx\n", -+ proc->pid, thread->pid, fp->type); -+ return_error = BR_FAILED_REPLY; -+ goto err_bad_object_type; -+ } -+ } -+ if (reply) { -+ BUG_ON(t->buffer->async_transaction != 0); -+ binder_pop_transaction(target_thread, in_reply_to); -+ } else if (!(t->flags & TF_ONE_WAY)) { -+ BUG_ON(t->buffer->async_transaction != 0); -+ t->need_reply = 1; -+ t->from_parent = thread->transaction_stack; -+ thread->transaction_stack = t; -+ } else { -+ BUG_ON(target_node == NULL); -+ BUG_ON(t->buffer->async_transaction != 1); -+ if (target_node->has_async_transaction) { -+ target_list = &target_node->async_todo; -+ target_wait = NULL; -+ } else -+ target_node->has_async_transaction = 1; -+ } -+ t->work.type = BINDER_WORK_TRANSACTION; -+ list_add_tail(&t->work.entry, target_list); -+ tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; -+ list_add_tail(&tcomplete->entry, &thread->todo); -+ if (target_wait) -+ wake_up_interruptible(target_wait); -+ return; -+ -+err_get_unused_fd_failed: -+err_fget_failed: -+err_fd_not_allowed: -+err_binder_get_ref_for_node_failed: -+err_binder_get_ref_failed: -+err_binder_new_node_failed: -+err_bad_object_type: -+err_bad_offset: -+err_copy_data_failed: -+ binder_transaction_buffer_release(target_proc, t->buffer, offp); -+ t->buffer->transaction = NULL; -+ binder_free_buf(target_proc, t->buffer); -+err_binder_alloc_buf_failed: -+ kfree(tcomplete); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -+err_alloc_tcomplete_failed: -+ kfree(t); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION); -+err_alloc_t_failed: -+err_bad_call_stack: -+err_empty_call_stack: -+err_dead_binder: -+err_invalid_target_handle: -+err_no_context_mgr_node: -+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, -+ "binder: %d:%d transaction failed %d, size %zd-%zd\n", -+ proc->pid, thread->pid, return_error, -+ tr->data_size, tr->offsets_size); -+ -+ { -+ struct binder_transaction_log_entry *fe; -+ fe = binder_transaction_log_add(&binder_transaction_log_failed); -+ *fe = *e; -+ } -+ -+ BUG_ON(thread->return_error != BR_OK); -+ if (in_reply_to) { -+ thread->return_error = BR_TRANSACTION_COMPLETE; -+ binder_send_failed_reply(in_reply_to, return_error); -+ } else -+ thread->return_error = return_error; -+} -+ -+int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, -+ void __user *buffer, int size, signed long *consumed) -+{ -+ uint32_t cmd; -+ void __user *ptr = buffer + *consumed; -+ void __user *end = buffer + size; -+ -+ while (ptr < end && thread->return_error == BR_OK) { -+ if (get_user(cmd, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { -+ binder_stats.bc[_IOC_NR(cmd)]++; -+ proc->stats.bc[_IOC_NR(cmd)]++; -+ thread->stats.bc[_IOC_NR(cmd)]++; -+ } -+ switch (cmd) { -+ case BC_INCREFS: -+ case BC_ACQUIRE: -+ case BC_RELEASE: -+ case BC_DECREFS: { -+ uint32_t target; -+ struct binder_ref *ref; -+ const char *debug_string; -+ -+ if (get_user(target, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (target == 0 && binder_context_mgr_node && -+ (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { -+ ref = binder_get_ref_for_node(proc, -+ binder_context_mgr_node); -+ if (ref->desc != target) { -+ binder_user_error("binder: %d:" -+ "%d tried to acquire " -+ "reference to desc 0, " -+ "got %d instead\n", -+ proc->pid, thread->pid, -+ ref->desc); -+ } -+ } else -+ ref = binder_get_ref(proc, target); -+ if (ref == NULL) { -+ binder_user_error("binder: %d:%d refcou" -+ "nt change on invalid ref %d\n", -+ proc->pid, thread->pid, target); -+ break; -+ } -+ switch (cmd) { -+ case BC_INCREFS: -+ debug_string = "IncRefs"; -+ binder_inc_ref(ref, 0, NULL); -+ break; -+ case BC_ACQUIRE: -+ debug_string = "Acquire"; -+ binder_inc_ref(ref, 1, NULL); -+ break; -+ case BC_RELEASE: -+ debug_string = "Release"; -+ binder_dec_ref(ref, 1); -+ break; -+ case BC_DECREFS: -+ default: -+ debug_string = "DecRefs"; -+ binder_dec_ref(ref, 0); -+ break; -+ } -+ binder_debug(BINDER_DEBUG_USER_REFS, -+ "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", -+ proc->pid, thread->pid, debug_string, ref->debug_id, -+ ref->desc, ref->strong, ref->weak, ref->node->debug_id); -+ break; -+ } -+ case BC_INCREFS_DONE: -+ case BC_ACQUIRE_DONE: { -+ void __user *node_ptr; -+ void *cookie; -+ struct binder_node *node; -+ -+ if (get_user(node_ptr, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ if (get_user(cookie, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ node = binder_get_node(proc, node_ptr); -+ if (node == NULL) { -+ binder_user_error("binder: %d:%d " -+ "%s u%p no match\n", -+ proc->pid, thread->pid, -+ cmd == BC_INCREFS_DONE ? -+ "BC_INCREFS_DONE" : -+ "BC_ACQUIRE_DONE", -+ node_ptr); -+ break; -+ } -+ if (cookie != node->cookie) { -+ binder_user_error("binder: %d:%d %s u%p node %d" -+ " cookie mismatch %p != %p\n", -+ proc->pid, thread->pid, -+ cmd == BC_INCREFS_DONE ? -+ "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", -+ node_ptr, node->debug_id, -+ cookie, node->cookie); -+ break; -+ } -+ if (cmd == BC_ACQUIRE_DONE) { -+ if (node->pending_strong_ref == 0) { -+ binder_user_error("binder: %d:%d " -+ "BC_ACQUIRE_DONE node %d has " -+ "no pending acquire request\n", -+ proc->pid, thread->pid, -+ node->debug_id); -+ break; -+ } -+ node->pending_strong_ref = 0; -+ } else { -+ if (node->pending_weak_ref == 0) { -+ binder_user_error("binder: %d:%d " -+ "BC_INCREFS_DONE node %d has " -+ "no pending increfs request\n", -+ proc->pid, thread->pid, -+ node->debug_id); -+ break; -+ } -+ node->pending_weak_ref = 0; -+ } -+ binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); -+ binder_debug(BINDER_DEBUG_USER_REFS, -+ "binder: %d:%d %s node %d ls %d lw %d\n", -+ proc->pid, thread->pid, -+ cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", -+ node->debug_id, node->local_strong_refs, node->local_weak_refs); -+ break; -+ } -+ case BC_ATTEMPT_ACQUIRE: -+ printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n"); -+ return -EINVAL; -+ case BC_ACQUIRE_RESULT: -+ printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n"); -+ return -EINVAL; -+ -+ case BC_FREE_BUFFER: { -+ void __user *data_ptr; -+ struct binder_buffer *buffer; -+ -+ if (get_user(data_ptr, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ -+ buffer = binder_buffer_lookup(proc, data_ptr); -+ if (buffer == NULL) { -+ binder_user_error("binder: %d:%d " -+ "BC_FREE_BUFFER u%p no match\n", -+ proc->pid, thread->pid, data_ptr); -+ break; -+ } -+ if (!buffer->allow_user_free) { -+ binder_user_error("binder: %d:%d " -+ "BC_FREE_BUFFER u%p matched " -+ "unreturned buffer\n", -+ proc->pid, thread->pid, data_ptr); -+ break; -+ } -+ binder_debug(BINDER_DEBUG_FREE_BUFFER, -+ "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", -+ proc->pid, thread->pid, data_ptr, buffer->debug_id, -+ buffer->transaction ? "active" : "finished"); -+ -+ if (buffer->transaction) { -+ buffer->transaction->buffer = NULL; -+ buffer->transaction = NULL; -+ } -+ if (buffer->async_transaction && buffer->target_node) { -+ BUG_ON(!buffer->target_node->has_async_transaction); -+ if (list_empty(&buffer->target_node->async_todo)) -+ buffer->target_node->has_async_transaction = 0; -+ else -+ list_move_tail(buffer->target_node->async_todo.next, &thread->todo); -+ } -+ binder_transaction_buffer_release(proc, buffer, NULL); -+ binder_free_buf(proc, buffer); -+ break; -+ } -+ -+ case BC_TRANSACTION: -+ case BC_REPLY: { -+ struct binder_transaction_data tr; -+ -+ if (copy_from_user(&tr, ptr, sizeof(tr))) -+ return -EFAULT; -+ ptr += sizeof(tr); -+ binder_transaction(proc, thread, &tr, cmd == BC_REPLY); -+ break; -+ } -+ -+ case BC_REGISTER_LOOPER: -+ binder_debug(BINDER_DEBUG_THREADS, -+ "binder: %d:%d BC_REGISTER_LOOPER\n", -+ proc->pid, thread->pid); -+ if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { -+ thread->looper |= BINDER_LOOPER_STATE_INVALID; -+ binder_user_error("binder: %d:%d ERROR:" -+ " BC_REGISTER_LOOPER called " -+ "after BC_ENTER_LOOPER\n", -+ proc->pid, thread->pid); -+ } else if (proc->requested_threads == 0) { -+ thread->looper |= BINDER_LOOPER_STATE_INVALID; -+ binder_user_error("binder: %d:%d ERROR:" -+ " BC_REGISTER_LOOPER called " -+ "without request\n", -+ proc->pid, thread->pid); -+ } else { -+ proc->requested_threads--; -+ proc->requested_threads_started++; -+ } -+ thread->looper |= BINDER_LOOPER_STATE_REGISTERED; -+ break; -+ case BC_ENTER_LOOPER: -+ binder_debug(BINDER_DEBUG_THREADS, -+ "binder: %d:%d BC_ENTER_LOOPER\n", -+ proc->pid, thread->pid); -+ if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { -+ thread->looper |= BINDER_LOOPER_STATE_INVALID; -+ binder_user_error("binder: %d:%d ERROR:" -+ " BC_ENTER_LOOPER called after " -+ "BC_REGISTER_LOOPER\n", -+ proc->pid, thread->pid); -+ } -+ thread->looper |= BINDER_LOOPER_STATE_ENTERED; -+ break; -+ case BC_EXIT_LOOPER: -+ binder_debug(BINDER_DEBUG_THREADS, -+ "binder: %d:%d BC_EXIT_LOOPER\n", -+ proc->pid, thread->pid); -+ thread->looper |= BINDER_LOOPER_STATE_EXITED; -+ break; -+ -+ case BC_REQUEST_DEATH_NOTIFICATION: -+ case BC_CLEAR_DEATH_NOTIFICATION: { -+ uint32_t target; -+ void __user *cookie; -+ struct binder_ref *ref; -+ struct binder_ref_death *death; -+ -+ if (get_user(target, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (get_user(cookie, (void __user * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ ref = binder_get_ref(proc, target); -+ if (ref == NULL) { -+ binder_user_error("binder: %d:%d %s " -+ "invalid ref %d\n", -+ proc->pid, thread->pid, -+ cmd == BC_REQUEST_DEATH_NOTIFICATION ? -+ "BC_REQUEST_DEATH_NOTIFICATION" : -+ "BC_CLEAR_DEATH_NOTIFICATION", -+ target); -+ break; -+ } -+ -+ binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, -+ "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", -+ proc->pid, thread->pid, -+ cmd == BC_REQUEST_DEATH_NOTIFICATION ? -+ "BC_REQUEST_DEATH_NOTIFICATION" : -+ "BC_CLEAR_DEATH_NOTIFICATION", -+ cookie, ref->debug_id, ref->desc, -+ ref->strong, ref->weak, ref->node->debug_id); -+ -+ if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { -+ if (ref->death) { -+ binder_user_error("binder: %d:%" -+ "d BC_REQUEST_DEATH_NOTI" -+ "FICATION death notific" -+ "ation already set\n", -+ proc->pid, thread->pid); -+ break; -+ } -+ death = kzalloc(sizeof(*death), GFP_KERNEL); -+ if (death == NULL) { -+ thread->return_error = BR_ERROR; -+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, -+ "binder: %d:%d " -+ "BC_REQUEST_DEATH_NOTIFICATION failed\n", -+ proc->pid, thread->pid); -+ break; -+ } -+ binder_stats_created(BINDER_STAT_DEATH); -+ INIT_LIST_HEAD(&death->work.entry); -+ death->cookie = cookie; -+ ref->death = death; -+ if (ref->node->proc == NULL) { -+ ref->death->work.type = BINDER_WORK_DEAD_BINDER; -+ if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { -+ list_add_tail(&ref->death->work.entry, &thread->todo); -+ } else { -+ list_add_tail(&ref->death->work.entry, &proc->todo); -+ wake_up_interruptible(&proc->wait); -+ } -+ } -+ } else { -+ if (ref->death == NULL) { -+ binder_user_error("binder: %d:%" -+ "d BC_CLEAR_DEATH_NOTIFI" -+ "CATION death notificat" -+ "ion not active\n", -+ proc->pid, thread->pid); -+ break; -+ } -+ death = ref->death; -+ if (death->cookie != cookie) { -+ binder_user_error("binder: %d:%" -+ "d BC_CLEAR_DEATH_NOTIFI" -+ "CATION death notificat" -+ "ion cookie mismatch " -+ "%p != %p\n", -+ proc->pid, thread->pid, -+ death->cookie, cookie); -+ break; -+ } -+ ref->death = NULL; -+ if (list_empty(&death->work.entry)) { -+ death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; -+ if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { -+ list_add_tail(&death->work.entry, &thread->todo); -+ } else { -+ list_add_tail(&death->work.entry, &proc->todo); -+ wake_up_interruptible(&proc->wait); -+ } -+ } else { -+ BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER); -+ death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR; -+ } -+ } -+ } break; -+ case BC_DEAD_BINDER_DONE: { -+ struct binder_work *w; -+ void __user *cookie; -+ struct binder_ref_death *death = NULL; -+ if (get_user(cookie, (void __user * __user *)ptr)) -+ return -EFAULT; -+ -+ ptr += sizeof(void *); -+ list_for_each_entry(w, &proc->delivered_death, entry) { -+ struct binder_ref_death *tmp_death = container_of(w, struct binder_ref_death, work); -+ if (tmp_death->cookie == cookie) { -+ death = tmp_death; -+ break; -+ } -+ } -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", -+ proc->pid, thread->pid, cookie, death); -+ if (death == NULL) { -+ binder_user_error("binder: %d:%d BC_DEAD" -+ "_BINDER_DONE %p not found\n", -+ proc->pid, thread->pid, cookie); -+ break; -+ } -+ -+ list_del_init(&death->work.entry); -+ if (death->work.type == BINDER_WORK_DEAD_BINDER_AND_CLEAR) { -+ death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION; -+ if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) { -+ list_add_tail(&death->work.entry, &thread->todo); -+ } else { -+ list_add_tail(&death->work.entry, &proc->todo); -+ wake_up_interruptible(&proc->wait); -+ } -+ } -+ } break; -+ -+ default: -+ printk(KERN_ERR "binder: %d:%d unknown command %d\n", -+ proc->pid, thread->pid, cmd); -+ return -EINVAL; -+ } -+ *consumed = ptr - buffer; -+ } -+ return 0; -+} -+ -+void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, -+ uint32_t cmd) -+{ -+ if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { -+ binder_stats.br[_IOC_NR(cmd)]++; -+ proc->stats.br[_IOC_NR(cmd)]++; -+ thread->stats.br[_IOC_NR(cmd)]++; -+ } -+} -+ -+static int binder_has_proc_work(struct binder_proc *proc, -+ struct binder_thread *thread) -+{ -+ return !list_empty(&proc->todo) || -+ (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -+} -+ -+static int binder_has_thread_work(struct binder_thread *thread) -+{ -+ return !list_empty(&thread->todo) || thread->return_error != BR_OK || -+ (thread->looper & BINDER_LOOPER_STATE_NEED_RETURN); -+} -+ -+static int binder_thread_read(struct binder_proc *proc, -+ struct binder_thread *thread, -+ void __user *buffer, int size, -+ signed long *consumed, int non_block) -+{ -+ void __user *ptr = buffer + *consumed; -+ void __user *end = buffer + size; -+ -+ int ret = 0; -+ int wait_for_proc_work; -+ -+ if (*consumed == 0) { -+ if (put_user(BR_NOOP, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ } -+ -+retry: -+ wait_for_proc_work = thread->transaction_stack == NULL && -+ list_empty(&thread->todo); -+ -+ if (thread->return_error != BR_OK && ptr < end) { -+ if (thread->return_error2 != BR_OK) { -+ if (put_user(thread->return_error2, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (ptr == end) -+ goto done; -+ thread->return_error2 = BR_OK; -+ } -+ if (put_user(thread->return_error, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ thread->return_error = BR_OK; -+ goto done; -+ } -+ -+ -+ thread->looper |= BINDER_LOOPER_STATE_WAITING; -+ if (wait_for_proc_work) -+ proc->ready_threads++; -+ mutex_unlock(&binder_lock); -+ if (wait_for_proc_work) { -+ if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | -+ BINDER_LOOPER_STATE_ENTERED))) { -+ binder_user_error("binder: %d:%d ERROR: Thread waiting " -+ "for process work before calling BC_REGISTER_" -+ "LOOPER or BC_ENTER_LOOPER (state %x)\n", -+ proc->pid, thread->pid, thread->looper); -+ wait_event_interruptible(binder_user_error_wait, -+ binder_stop_on_user_error < 2); -+ } -+ binder_set_nice(proc->default_priority); -+ if (non_block) { -+ if (!binder_has_proc_work(proc, thread)) -+ ret = -EAGAIN; -+ } else -+ ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread)); -+ } else { -+ if (non_block) { -+ if (!binder_has_thread_work(thread)) -+ ret = -EAGAIN; -+ } else -+ ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); -+ } -+ mutex_lock(&binder_lock); -+ if (wait_for_proc_work) -+ proc->ready_threads--; -+ thread->looper &= ~BINDER_LOOPER_STATE_WAITING; -+ -+ if (ret) -+ return ret; -+ -+ while (1) { -+ uint32_t cmd; -+ struct binder_transaction_data tr; -+ struct binder_work *w; -+ struct binder_transaction *t = NULL; -+ -+ if (!list_empty(&thread->todo)) -+ w = list_first_entry(&thread->todo, struct binder_work, entry); -+ else if (!list_empty(&proc->todo) && wait_for_proc_work) -+ w = list_first_entry(&proc->todo, struct binder_work, entry); -+ else { -+ if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN)) /* no data added */ -+ goto retry; -+ break; -+ } -+ -+ if (end - ptr < sizeof(tr) + 4) -+ break; -+ -+ switch (w->type) { -+ case BINDER_WORK_TRANSACTION: { -+ t = container_of(w, struct binder_transaction, work); -+ } break; -+ case BINDER_WORK_TRANSACTION_COMPLETE: { -+ cmd = BR_TRANSACTION_COMPLETE; -+ if (put_user(cmd, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ -+ binder_stat_br(proc, thread, cmd); -+ binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, -+ "binder: %d:%d BR_TRANSACTION_COMPLETE\n", -+ proc->pid, thread->pid); -+ -+ list_del(&w->entry); -+ kfree(w); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -+ } break; -+ case BINDER_WORK_NODE: { -+ struct binder_node *node = container_of(w, struct binder_node, work); -+ uint32_t cmd = BR_NOOP; -+ const char *cmd_name; -+ int strong = node->internal_strong_refs || node->local_strong_refs; -+ int weak = !hlist_empty(&node->refs) || node->local_weak_refs || strong; -+ if (weak && !node->has_weak_ref) { -+ cmd = BR_INCREFS; -+ cmd_name = "BR_INCREFS"; -+ node->has_weak_ref = 1; -+ node->pending_weak_ref = 1; -+ node->local_weak_refs++; -+ } else if (strong && !node->has_strong_ref) { -+ cmd = BR_ACQUIRE; -+ cmd_name = "BR_ACQUIRE"; -+ node->has_strong_ref = 1; -+ node->pending_strong_ref = 1; -+ node->local_strong_refs++; -+ } else if (!strong && node->has_strong_ref) { -+ cmd = BR_RELEASE; -+ cmd_name = "BR_RELEASE"; -+ node->has_strong_ref = 0; -+ } else if (!weak && node->has_weak_ref) { -+ cmd = BR_DECREFS; -+ cmd_name = "BR_DECREFS"; -+ node->has_weak_ref = 0; -+ } -+ if (cmd != BR_NOOP) { -+ if (put_user(cmd, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (put_user(node->ptr, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ if (put_user(node->cookie, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ -+ binder_stat_br(proc, thread, cmd); -+ binder_debug(BINDER_DEBUG_USER_REFS, -+ "binder: %d:%d %s %d u%p c%p\n", -+ proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); -+ } else { -+ list_del_init(&w->entry); -+ if (!weak && !strong) { -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d:%d node %d u%p c%p deleted\n", -+ proc->pid, thread->pid, node->debug_id, -+ node->ptr, node->cookie); -+ rb_erase(&node->rb_node, &proc->nodes); -+ kfree(node); -+ binder_stats_deleted(BINDER_STAT_NODE); -+ } else { -+ binder_debug(BINDER_DEBUG_INTERNAL_REFS, -+ "binder: %d:%d node %d u%p c%p state unchanged\n", -+ proc->pid, thread->pid, node->debug_id, node->ptr, -+ node->cookie); -+ } -+ } -+ } break; -+ case BINDER_WORK_DEAD_BINDER: -+ case BINDER_WORK_DEAD_BINDER_AND_CLEAR: -+ case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: { -+ struct binder_ref_death *death; -+ uint32_t cmd; -+ -+ death = container_of(w, struct binder_ref_death, work); -+ if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) -+ cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE; -+ else -+ cmd = BR_DEAD_BINDER; -+ if (put_user(cmd, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (put_user(death->cookie, (void * __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(void *); -+ binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, -+ "binder: %d:%d %s %p\n", -+ proc->pid, thread->pid, -+ cmd == BR_DEAD_BINDER ? -+ "BR_DEAD_BINDER" : -+ "BR_CLEAR_DEATH_NOTIFICATION_DONE", -+ death->cookie); -+ -+ if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) { -+ list_del(&w->entry); -+ kfree(death); -+ binder_stats_deleted(BINDER_STAT_DEATH); -+ } else -+ list_move(&w->entry, &proc->delivered_death); -+ if (cmd == BR_DEAD_BINDER) -+ goto done; /* DEAD_BINDER notifications can cause transactions */ -+ } break; -+ } -+ -+ if (!t) -+ continue; -+ -+ BUG_ON(t->buffer == NULL); -+ if (t->buffer->target_node) { -+ struct binder_node *target_node = t->buffer->target_node; -+ tr.target.ptr = target_node->ptr; -+ tr.cookie = target_node->cookie; -+ t->saved_priority = task_nice(current); -+ if (t->priority < target_node->min_priority && -+ !(t->flags & TF_ONE_WAY)) -+ binder_set_nice(t->priority); -+ else if (!(t->flags & TF_ONE_WAY) || -+ t->saved_priority > target_node->min_priority) -+ binder_set_nice(target_node->min_priority); -+ cmd = BR_TRANSACTION; -+ } else { -+ tr.target.ptr = NULL; -+ tr.cookie = NULL; -+ cmd = BR_REPLY; -+ } -+ tr.code = t->code; -+ tr.flags = t->flags; -+ tr.sender_euid = t->sender_euid; -+ -+ if (t->from) { -+ struct task_struct *sender = t->from->proc->tsk; -+ tr.sender_pid = task_tgid_nr_ns(sender, -+ current->nsproxy->pid_ns); -+ } else { -+ tr.sender_pid = 0; -+ } -+ -+ tr.data_size = t->buffer->data_size; -+ tr.offsets_size = t->buffer->offsets_size; -+ tr.data.ptr.buffer = (void *)t->buffer->data + -+ proc->user_buffer_offset; -+ tr.data.ptr.offsets = tr.data.ptr.buffer + -+ ALIGN(t->buffer->data_size, -+ sizeof(void *)); -+ -+ if (put_user(cmd, (uint32_t __user *)ptr)) -+ return -EFAULT; -+ ptr += sizeof(uint32_t); -+ if (copy_to_user(ptr, &tr, sizeof(tr))) -+ return -EFAULT; -+ ptr += sizeof(tr); -+ -+ binder_stat_br(proc, thread, cmd); -+ binder_debug(BINDER_DEBUG_TRANSACTION, -+ "binder: %d:%d %s %d %d:%d, cmd %d" -+ "size %zd-%zd ptr %p-%p\n", -+ proc->pid, thread->pid, -+ (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : -+ "BR_REPLY", -+ t->debug_id, t->from ? t->from->proc->pid : 0, -+ t->from ? t->from->pid : 0, cmd, -+ t->buffer->data_size, t->buffer->offsets_size, -+ tr.data.ptr.buffer, tr.data.ptr.offsets); -+ -+ list_del(&t->work.entry); -+ t->buffer->allow_user_free = 1; -+ if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY)) { -+ t->to_parent = thread->transaction_stack; -+ t->to_thread = thread; -+ thread->transaction_stack = t; -+ } else { -+ t->buffer->transaction = NULL; -+ kfree(t); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION); -+ } -+ break; -+ } -+ -+done: -+ -+ *consumed = ptr - buffer; -+ if (proc->requested_threads + proc->ready_threads == 0 && -+ proc->requested_threads_started < proc->max_threads && -+ (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | -+ BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */ -+ /*spawn a new thread if we leave this out */) { -+ proc->requested_threads++; -+ binder_debug(BINDER_DEBUG_THREADS, -+ "binder: %d:%d BR_SPAWN_LOOPER\n", -+ proc->pid, thread->pid); -+ if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) -+ return -EFAULT; -+ } -+ return 0; -+} -+ -+static void binder_release_work(struct list_head *list) -+{ -+ struct binder_work *w; -+ while (!list_empty(list)) { -+ w = list_first_entry(list, struct binder_work, entry); -+ list_del_init(&w->entry); -+ switch (w->type) { -+ case BINDER_WORK_TRANSACTION: { -+ struct binder_transaction *t; -+ -+ t = container_of(w, struct binder_transaction, work); -+ if (t->buffer->target_node && !(t->flags & TF_ONE_WAY)) -+ binder_send_failed_reply(t, BR_DEAD_REPLY); -+ } break; -+ case BINDER_WORK_TRANSACTION_COMPLETE: { -+ kfree(w); -+ binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); -+ } break; -+ default: -+ break; -+ } -+ } -+ -+} -+ -+static struct binder_thread *binder_get_thread(struct binder_proc *proc) -+{ -+ struct binder_thread *thread = NULL; -+ struct rb_node *parent = NULL; -+ struct rb_node **p = &proc->threads.rb_node; -+ -+ while (*p) { -+ parent = *p; -+ thread = rb_entry(parent, struct binder_thread, rb_node); -+ -+ if (current->pid < thread->pid) -+ p = &(*p)->rb_left; -+ else if (current->pid > thread->pid) -+ p = &(*p)->rb_right; -+ else -+ break; -+ } -+ if (*p == NULL) { -+ thread = kzalloc(sizeof(*thread), GFP_KERNEL); -+ if (thread == NULL) -+ return NULL; -+ binder_stats_created(BINDER_STAT_THREAD); -+ thread->proc = proc; -+ thread->pid = current->pid; -+ init_waitqueue_head(&thread->wait); -+ INIT_LIST_HEAD(&thread->todo); -+ rb_link_node(&thread->rb_node, parent, p); -+ rb_insert_color(&thread->rb_node, &proc->threads); -+ thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; -+ thread->return_error = BR_OK; -+ thread->return_error2 = BR_OK; -+ } -+ return thread; -+} -+ -+static int binder_free_thread(struct binder_proc *proc, -+ struct binder_thread *thread) -+{ -+ struct binder_transaction *t; -+ struct binder_transaction *send_reply = NULL; -+ int active_transactions = 0; -+ -+ rb_erase(&thread->rb_node, &proc->threads); -+ t = thread->transaction_stack; -+ if (t && t->to_thread == thread) -+ send_reply = t; -+ while (t) { -+ active_transactions++; -+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, -+ "binder: release %d:%d transaction %d " -+ "%s, still active\n", proc->pid, thread->pid, -+ t->debug_id, -+ (t->to_thread == thread) ? "in" : "out"); -+ -+ if (t->to_thread == thread) { -+ t->to_proc = NULL; -+ t->to_thread = NULL; -+ if (t->buffer) { -+ t->buffer->transaction = NULL; -+ t->buffer = NULL; -+ } -+ t = t->to_parent; -+ } else if (t->from == thread) { -+ t->from = NULL; -+ t = t->from_parent; -+ } else -+ BUG(); -+ } -+ if (send_reply) -+ binder_send_failed_reply(send_reply, BR_DEAD_REPLY); -+ binder_release_work(&thread->todo); -+ kfree(thread); -+ binder_stats_deleted(BINDER_STAT_THREAD); -+ return active_transactions; -+} -+ -+static unsigned int binder_poll(struct file *filp, -+ struct poll_table_struct *wait) -+{ -+ struct binder_proc *proc = filp->private_data; -+ struct binder_thread *thread = NULL; -+ int wait_for_proc_work; -+ -+ mutex_lock(&binder_lock); -+ thread = binder_get_thread(proc); -+ -+ wait_for_proc_work = thread->transaction_stack == NULL && -+ list_empty(&thread->todo) && thread->return_error == BR_OK; -+ mutex_unlock(&binder_lock); -+ -+ if (wait_for_proc_work) { -+ if (binder_has_proc_work(proc, thread)) -+ return POLLIN; -+ poll_wait(filp, &proc->wait, wait); -+ if (binder_has_proc_work(proc, thread)) -+ return POLLIN; -+ } else { -+ if (binder_has_thread_work(thread)) -+ return POLLIN; -+ poll_wait(filp, &thread->wait, wait); -+ if (binder_has_thread_work(thread)) -+ return POLLIN; -+ } -+ return 0; -+} -+ -+static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -+{ -+ int ret; -+ struct binder_proc *proc = filp->private_data; -+ struct binder_thread *thread; -+ unsigned int size = _IOC_SIZE(cmd); -+ void __user *ubuf = (void __user *)arg; -+ -+ /*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ -+ -+ ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); -+ if (ret) -+ return ret; -+ -+ mutex_lock(&binder_lock); -+ thread = binder_get_thread(proc); -+ if (thread == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ -+ switch (cmd) { -+ case BINDER_WRITE_READ: { -+ struct binder_write_read bwr; -+ if (size != sizeof(struct binder_write_read)) { -+ ret = -EINVAL; -+ goto err; -+ } -+ if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { -+ ret = -EFAULT; -+ goto err; -+ } -+ binder_debug(BINDER_DEBUG_READ_WRITE, -+ "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", -+ proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, -+ bwr.read_size, bwr.read_buffer); -+ -+ if (bwr.write_size > 0) { -+ ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); -+ if (ret < 0) { -+ bwr.read_consumed = 0; -+ if (copy_to_user(ubuf, &bwr, sizeof(bwr))) -+ ret = -EFAULT; -+ goto err; -+ } -+ } -+ if (bwr.read_size > 0) { -+ ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); -+ if (!list_empty(&proc->todo)) -+ wake_up_interruptible(&proc->wait); -+ if (ret < 0) { -+ if (copy_to_user(ubuf, &bwr, sizeof(bwr))) -+ ret = -EFAULT; -+ goto err; -+ } -+ } -+ binder_debug(BINDER_DEBUG_READ_WRITE, -+ "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", -+ proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, -+ bwr.read_consumed, bwr.read_size); -+ if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { -+ ret = -EFAULT; -+ goto err; -+ } -+ break; -+ } -+ case BINDER_SET_MAX_THREADS: -+ if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) { -+ ret = -EINVAL; -+ goto err; -+ } -+ break; -+ case BINDER_SET_CONTEXT_MGR: -+ if (binder_context_mgr_node != NULL) { -+ printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n"); -+ ret = -EBUSY; -+ goto err; -+ } -+ if (binder_context_mgr_uid != -1) { -+ if (binder_context_mgr_uid != current->cred->euid) { -+ printk(KERN_ERR "binder: BINDER_SET_" -+ "CONTEXT_MGR bad uid %d != %d\n", -+ current->cred->euid, -+ binder_context_mgr_uid); -+ ret = -EPERM; -+ goto err; -+ } -+ } else -+ binder_context_mgr_uid = current->cred->euid; -+ binder_context_mgr_node = binder_new_node(proc, NULL, NULL); -+ if (binder_context_mgr_node == NULL) { -+ ret = -ENOMEM; -+ goto err; -+ } -+ binder_context_mgr_node->local_weak_refs++; -+ binder_context_mgr_node->local_strong_refs++; -+ binder_context_mgr_node->has_strong_ref = 1; -+ binder_context_mgr_node->has_weak_ref = 1; -+ break; -+ case BINDER_THREAD_EXIT: -+ binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", -+ proc->pid, thread->pid); -+ binder_free_thread(proc, thread); -+ thread = NULL; -+ break; -+ case BINDER_VERSION: -+ if (size != sizeof(struct binder_version)) { -+ ret = -EINVAL; -+ goto err; -+ } -+ if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) { -+ ret = -EINVAL; -+ goto err; -+ } -+ break; -+ default: -+ ret = -EINVAL; -+ goto err; -+ } -+ ret = 0; -+err: -+ if (thread) -+ thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; -+ mutex_unlock(&binder_lock); -+ wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); -+ if (ret && ret != -ERESTARTSYS) -+ printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); -+ return ret; -+} -+ -+static void binder_vma_open(struct vm_area_struct *vma) -+{ -+ struct binder_proc *proc = vma->vm_private_data; -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, -+ "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", -+ proc->pid, vma->vm_start, vma->vm_end, -+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, -+ (unsigned long)pgprot_val(vma->vm_page_prot)); -+ dump_stack(); -+} -+ -+static void binder_vma_close(struct vm_area_struct *vma) -+{ -+ struct binder_proc *proc = vma->vm_private_data; -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, -+ "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", -+ proc->pid, vma->vm_start, vma->vm_end, -+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, -+ (unsigned long)pgprot_val(vma->vm_page_prot)); -+ proc->vma = NULL; -+ binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); -+} -+ -+static struct vm_operations_struct binder_vm_ops = { -+ .open = binder_vma_open, -+ .close = binder_vma_close, -+}; -+ -+static int binder_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ int ret; -+ struct vm_struct *area; -+ struct binder_proc *proc = filp->private_data; -+ const char *failure_string; -+ struct binder_buffer *buffer; -+ -+ if ((vma->vm_end - vma->vm_start) > SZ_4M) -+ vma->vm_end = vma->vm_start + SZ_4M; -+ -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, -+ "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", -+ proc->pid, vma->vm_start, vma->vm_end, -+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, -+ (unsigned long)pgprot_val(vma->vm_page_prot)); -+ -+ if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) { -+ ret = -EPERM; -+ failure_string = "bad vm_flags"; -+ goto err_bad_arg; -+ } -+ vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; -+ -+ if (proc->buffer) { -+ ret = -EBUSY; -+ failure_string = "already mapped"; -+ goto err_already_mapped; -+ } -+ -+ area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); -+ if (area == NULL) { -+ ret = -ENOMEM; -+ failure_string = "get_vm_area"; -+ goto err_get_vm_area_failed; -+ } -+ proc->buffer = area->addr; -+ proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; -+ -+#ifdef CONFIG_CPU_CACHE_VIPT -+ if (cache_is_vipt_aliasing()) { -+ while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) { -+ printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer); -+ vma->vm_start += PAGE_SIZE; -+ } -+ } -+#endif -+ proc->pages = kzalloc(sizeof(proc->pages[0]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL); -+ if (proc->pages == NULL) { -+ ret = -ENOMEM; -+ failure_string = "alloc page array"; -+ goto err_alloc_pages_failed; -+ } -+ proc->buffer_size = vma->vm_end - vma->vm_start; -+ -+ vma->vm_ops = &binder_vm_ops; -+ vma->vm_private_data = proc; -+ -+ if (binder_update_page_range(proc, 1, proc->buffer, proc->buffer + PAGE_SIZE, vma)) { -+ ret = -ENOMEM; -+ failure_string = "alloc small buf"; -+ goto err_alloc_small_buf_failed; -+ } -+ buffer = proc->buffer; -+ INIT_LIST_HEAD(&proc->buffers); -+ list_add(&buffer->entry, &proc->buffers); -+ buffer->free = 1; -+ binder_insert_free_buffer(proc, buffer); -+ proc->free_async_space = proc->buffer_size / 2; -+ barrier(); -+ proc->files = get_files_struct(current); -+ proc->vma = vma; -+ -+ /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", -+ proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/ -+ return 0; -+ -+err_alloc_small_buf_failed: -+ kfree(proc->pages); -+ proc->pages = NULL; -+err_alloc_pages_failed: -+ vfree(proc->buffer); -+ proc->buffer = NULL; -+err_get_vm_area_failed: -+err_already_mapped: -+err_bad_arg: -+ printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", -+ proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); -+ return ret; -+} -+ -+static int binder_open(struct inode *nodp, struct file *filp) -+{ -+ struct binder_proc *proc; -+ -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", -+ current->group_leader->pid, current->pid); -+ -+ proc = kzalloc(sizeof(*proc), GFP_KERNEL); -+ if (proc == NULL) -+ return -ENOMEM; -+ get_task_struct(current); -+ proc->tsk = current; -+ INIT_LIST_HEAD(&proc->todo); -+ init_waitqueue_head(&proc->wait); -+ proc->default_priority = task_nice(current); -+ mutex_lock(&binder_lock); -+ binder_stats_created(BINDER_STAT_PROC); -+ hlist_add_head(&proc->proc_node, &binder_procs); -+ proc->pid = current->group_leader->pid; -+ INIT_LIST_HEAD(&proc->delivered_death); -+ filp->private_data = proc; -+ mutex_unlock(&binder_lock); -+ -+ if (binder_proc_dir_entry_proc) { -+ char strbuf[11]; -+ snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); -+ remove_proc_entry(strbuf, binder_proc_dir_entry_proc); -+ create_proc_read_entry(strbuf, S_IRUGO, -+ binder_proc_dir_entry_proc, -+ binder_read_proc_proc, proc); -+ } -+ -+ return 0; -+} -+ -+static int binder_flush(struct file *filp, fl_owner_t id) -+{ -+ struct binder_proc *proc = filp->private_data; -+ -+ binder_defer_work(proc, BINDER_DEFERRED_FLUSH); -+ -+ return 0; -+} -+ -+static void binder_deferred_flush(struct binder_proc *proc) -+{ -+ struct rb_node *n; -+ int wake_count = 0; -+ for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) { -+ struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); -+ thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN; -+ if (thread->looper & BINDER_LOOPER_STATE_WAITING) { -+ wake_up_interruptible(&thread->wait); -+ wake_count++; -+ } -+ } -+ wake_up_interruptible_all(&proc->wait); -+ -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, -+ "binder_flush: %d woke %d threads\n", proc->pid, -+ wake_count); -+} -+ -+static int binder_release(struct inode *nodp, struct file *filp) -+{ -+ struct binder_proc *proc = filp->private_data; -+ if (binder_proc_dir_entry_proc) { -+ char strbuf[11]; -+ snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); -+ remove_proc_entry(strbuf, binder_proc_dir_entry_proc); -+ } -+ -+ binder_defer_work(proc, BINDER_DEFERRED_RELEASE); -+ -+ return 0; -+} -+ -+static void binder_deferred_release(struct binder_proc *proc) -+{ -+ struct hlist_node *pos; -+ struct binder_transaction *t; -+ struct rb_node *n; -+ int threads, nodes, incoming_refs, outgoing_refs, buffers, active_transactions, page_count; -+ -+ BUG_ON(proc->vma); -+ BUG_ON(proc->files); -+ -+ hlist_del(&proc->proc_node); -+ if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder_release: %d context_mgr_node gone\n", -+ proc->pid); -+ binder_context_mgr_node = NULL; -+ } -+ -+ threads = 0; -+ active_transactions = 0; -+ while ((n = rb_first(&proc->threads))) { -+ struct binder_thread *thread = rb_entry(n, struct binder_thread, rb_node); -+ threads++; -+ active_transactions += binder_free_thread(proc, thread); -+ } -+ nodes = 0; -+ incoming_refs = 0; -+ while ((n = rb_first(&proc->nodes))) { -+ struct binder_node *node = rb_entry(n, struct binder_node, rb_node); -+ -+ nodes++; -+ rb_erase(&node->rb_node, &proc->nodes); -+ list_del_init(&node->work.entry); -+ if (hlist_empty(&node->refs)) { -+ kfree(node); -+ binder_stats_deleted(BINDER_STAT_NODE); -+ } else { -+ struct binder_ref *ref; -+ int death = 0; -+ -+ node->proc = NULL; -+ node->local_strong_refs = 0; -+ node->local_weak_refs = 0; -+ hlist_add_head(&node->dead_node, &binder_dead_nodes); -+ -+ hlist_for_each_entry(ref, pos, &node->refs, node_entry) { -+ incoming_refs++; -+ if (ref->death) { -+ death++; -+ if (list_empty(&ref->death->work.entry)) { -+ ref->death->work.type = BINDER_WORK_DEAD_BINDER; -+ list_add_tail(&ref->death->work.entry, &ref->proc->todo); -+ wake_up_interruptible(&ref->proc->wait); -+ } else -+ BUG(); -+ } -+ } -+ binder_debug(BINDER_DEBUG_DEAD_BINDER, -+ "binder: node %d now dead, " -+ "refs %d, death %d\n", node->debug_id, -+ incoming_refs, death); -+ } -+ } -+ outgoing_refs = 0; -+ while ((n = rb_first(&proc->refs_by_desc))) { -+ struct binder_ref *ref = rb_entry(n, struct binder_ref, -+ rb_node_desc); -+ outgoing_refs++; -+ binder_delete_ref(ref); -+ } -+ binder_release_work(&proc->todo); -+ buffers = 0; -+ -+ while ((n = rb_first(&proc->allocated_buffers))) { -+ struct binder_buffer *buffer = rb_entry(n, struct binder_buffer, -+ rb_node); -+ t = buffer->transaction; -+ if (t) { -+ t->buffer = NULL; -+ buffer->transaction = NULL; -+ printk(KERN_ERR "binder: release proc %d, " -+ "transaction %d, not freed\n", -+ proc->pid, t->debug_id); -+ /*BUG();*/ -+ } -+ binder_free_buf(proc, buffer); -+ buffers++; -+ } -+ -+ binder_stats_deleted(BINDER_STAT_PROC); -+ -+ page_count = 0; -+ if (proc->pages) { -+ int i; -+ for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { -+ if (proc->pages[i]) { -+ binder_debug(BINDER_DEBUG_BUFFER_ALLOC, -+ "binder_release: %d: " -+ "page %d at %p not freed\n", -+ proc->pid, i, -+ proc->buffer + i * PAGE_SIZE); -+ __free_page(proc->pages[i]); -+ page_count++; -+ } -+ } -+ kfree(proc->pages); -+ vfree(proc->buffer); -+ } -+ -+ put_task_struct(proc->tsk); -+ -+ binder_debug(BINDER_DEBUG_OPEN_CLOSE, -+ "binder_release: %d threads %d, nodes %d (ref %d), " -+ "refs %d, active transactions %d, buffers %d, " -+ "pages %d\n", -+ proc->pid, threads, nodes, incoming_refs, outgoing_refs, -+ active_transactions, buffers, page_count); -+ -+ kfree(proc); -+} -+ -+static void binder_deferred_func(struct work_struct *work) -+{ -+ struct binder_proc *proc; -+ struct files_struct *files; -+ -+ int defer; -+ do { -+ mutex_lock(&binder_lock); -+ mutex_lock(&binder_deferred_lock); -+ if (!hlist_empty(&binder_deferred_list)) { -+ proc = hlist_entry(binder_deferred_list.first, -+ struct binder_proc, deferred_work_node); -+ hlist_del_init(&proc->deferred_work_node); -+ defer = proc->deferred_work; -+ proc->deferred_work = 0; -+ } else { -+ proc = NULL; -+ defer = 0; -+ } -+ mutex_unlock(&binder_deferred_lock); -+ -+ files = NULL; -+ if (defer & BINDER_DEFERRED_PUT_FILES) { -+ files = proc->files; -+ if (files) -+ proc->files = NULL; -+ } -+ -+ if (defer & BINDER_DEFERRED_FLUSH) -+ binder_deferred_flush(proc); -+ -+ if (defer & BINDER_DEFERRED_RELEASE) -+ binder_deferred_release(proc); /* frees proc */ -+ -+ mutex_unlock(&binder_lock); -+ if (files) -+ put_files_struct(files); -+ } while (proc); -+} -+static DECLARE_WORK(binder_deferred_work, binder_deferred_func); -+ -+static void -+binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) -+{ -+ mutex_lock(&binder_deferred_lock); -+ proc->deferred_work |= defer; -+ if (hlist_unhashed(&proc->deferred_work_node)) { -+ hlist_add_head(&proc->deferred_work_node, -+ &binder_deferred_list); -+ schedule_work(&binder_deferred_work); -+ } -+ mutex_unlock(&binder_deferred_lock); -+} -+ -+static char *print_binder_transaction(char *buf, char *end, const char *prefix, -+ struct binder_transaction *t) -+{ -+ buf += snprintf(buf, end - buf, -+ "%s %d: %p from %d:%d to %d:%d code %x " -+ "flags %x pri %ld r%d", -+ prefix, t->debug_id, t, -+ t->from ? t->from->proc->pid : 0, -+ t->from ? t->from->pid : 0, -+ t->to_proc ? t->to_proc->pid : 0, -+ t->to_thread ? t->to_thread->pid : 0, -+ t->code, t->flags, t->priority, t->need_reply); -+ if (buf >= end) -+ return buf; -+ if (t->buffer == NULL) { -+ buf += snprintf(buf, end - buf, " buffer free\n"); -+ return buf; -+ } -+ if (t->buffer->target_node) { -+ buf += snprintf(buf, end - buf, " node %d", -+ t->buffer->target_node->debug_id); -+ if (buf >= end) -+ return buf; -+ } -+ buf += snprintf(buf, end - buf, " size %zd:%zd data %p\n", -+ t->buffer->data_size, t->buffer->offsets_size, -+ t->buffer->data); -+ return buf; -+} -+ -+static char *print_binder_buffer(char *buf, char *end, const char *prefix, -+ struct binder_buffer *buffer) -+{ -+ buf += snprintf(buf, end - buf, "%s %d: %p size %zd:%zd %s\n", -+ prefix, buffer->debug_id, buffer->data, -+ buffer->data_size, buffer->offsets_size, -+ buffer->transaction ? "active" : "delivered"); -+ return buf; -+} -+ -+static char *print_binder_work(char *buf, char *end, const char *prefix, -+ const char *transaction_prefix, -+ struct binder_work *w) -+{ -+ struct binder_node *node; -+ struct binder_transaction *t; -+ -+ switch (w->type) { -+ case BINDER_WORK_TRANSACTION: -+ t = container_of(w, struct binder_transaction, work); -+ buf = print_binder_transaction(buf, end, transaction_prefix, t); -+ break; -+ case BINDER_WORK_TRANSACTION_COMPLETE: -+ buf += snprintf(buf, end - buf, -+ "%stransaction complete\n", prefix); -+ break; -+ case BINDER_WORK_NODE: -+ node = container_of(w, struct binder_node, work); -+ buf += snprintf(buf, end - buf, "%snode work %d: u%p c%p\n", -+ prefix, node->debug_id, node->ptr, -+ node->cookie); -+ break; -+ case BINDER_WORK_DEAD_BINDER: -+ buf += snprintf(buf, end - buf, "%shas dead binder\n", prefix); -+ break; -+ case BINDER_WORK_DEAD_BINDER_AND_CLEAR: -+ buf += snprintf(buf, end - buf, -+ "%shas cleared dead binder\n", prefix); -+ break; -+ case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: -+ buf += snprintf(buf, end - buf, -+ "%shas cleared death notification\n", prefix); -+ break; -+ default: -+ buf += snprintf(buf, end - buf, "%sunknown work: type %d\n", -+ prefix, w->type); -+ break; -+ } -+ return buf; -+} -+ -+static char *print_binder_thread(char *buf, char *end, -+ struct binder_thread *thread, -+ int print_always) -+{ -+ struct binder_transaction *t; -+ struct binder_work *w; -+ char *start_buf = buf; -+ char *header_buf; -+ -+ buf += snprintf(buf, end - buf, " thread %d: l %02x\n", -+ thread->pid, thread->looper); -+ header_buf = buf; -+ t = thread->transaction_stack; -+ while (t) { -+ if (buf >= end) -+ break; -+ if (t->from == thread) { -+ buf = print_binder_transaction(buf, end, -+ " outgoing transaction", t); -+ t = t->from_parent; -+ } else if (t->to_thread == thread) { -+ buf = print_binder_transaction(buf, end, -+ " incoming transaction", t); -+ t = t->to_parent; -+ } else { -+ buf = print_binder_transaction(buf, end, -+ " bad transaction", t); -+ t = NULL; -+ } -+ } -+ list_for_each_entry(w, &thread->todo, entry) { -+ if (buf >= end) -+ break; -+ buf = print_binder_work(buf, end, " ", -+ " pending transaction", w); -+ } -+ if (!print_always && buf == header_buf) -+ buf = start_buf; -+ return buf; -+} -+ -+static char *print_binder_node(char *buf, char *end, struct binder_node *node) -+{ -+ struct binder_ref *ref; -+ struct hlist_node *pos; -+ struct binder_work *w; -+ int count; -+ -+ count = 0; -+ hlist_for_each_entry(ref, pos, &node->refs, node_entry) -+ count++; -+ -+ buf += snprintf(buf, end - buf, -+ " node %d: u%p c%p hs %d hw %d ls %d lw %d " -+ "is %d iw %d", -+ node->debug_id, node->ptr, node->cookie, -+ node->has_strong_ref, node->has_weak_ref, -+ node->local_strong_refs, node->local_weak_refs, -+ node->internal_strong_refs, count); -+ if (buf >= end) -+ return buf; -+ if (count) { -+ buf += snprintf(buf, end - buf, " proc"); -+ if (buf >= end) -+ return buf; -+ hlist_for_each_entry(ref, pos, &node->refs, node_entry) { -+ buf += snprintf(buf, end - buf, " %d", ref->proc->pid); -+ if (buf >= end) -+ return buf; -+ } -+ } -+ buf += snprintf(buf, end - buf, "\n"); -+ list_for_each_entry(w, &node->async_todo, entry) { -+ if (buf >= end) -+ break; -+ buf = print_binder_work(buf, end, " ", -+ " pending async transaction", w); -+ } -+ return buf; -+} -+ -+static char *print_binder_ref(char *buf, char *end, struct binder_ref *ref) -+{ -+ buf += snprintf(buf, end - buf, -+ " ref %d: desc %d %snode %d s %d w %d d %p\n", -+ ref->debug_id, ref->desc, -+ ref->node->proc ? "" : "dead ", ref->node->debug_id, -+ ref->strong, ref->weak, ref->death); -+ return buf; -+} -+ -+static char *print_binder_proc(char *buf, char *end, -+ struct binder_proc *proc, int print_all) -+{ -+ struct binder_work *w; -+ struct rb_node *n; -+ char *start_buf = buf; -+ char *header_buf; -+ -+ buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); -+ header_buf = buf; -+ -+ for (n = rb_first(&proc->threads); -+ n != NULL && buf < end; -+ n = rb_next(n)) -+ buf = print_binder_thread(buf, end, -+ rb_entry(n, struct binder_thread, -+ rb_node), print_all); -+ for (n = rb_first(&proc->nodes); -+ n != NULL && buf < end; -+ n = rb_next(n)) { -+ struct binder_node *node = rb_entry(n, struct binder_node, -+ rb_node); -+ if (print_all || node->has_async_transaction) -+ buf = print_binder_node(buf, end, node); -+ } -+ if (print_all) { -+ for (n = rb_first(&proc->refs_by_desc); -+ n != NULL && buf < end; -+ n = rb_next(n)) -+ buf = print_binder_ref(buf, end, -+ rb_entry(n, struct binder_ref, -+ rb_node_desc)); -+ } -+ for (n = rb_first(&proc->allocated_buffers); -+ n != NULL && buf < end; -+ n = rb_next(n)) -+ buf = print_binder_buffer(buf, end, " buffer", -+ rb_entry(n, struct binder_buffer, -+ rb_node)); -+ list_for_each_entry(w, &proc->todo, entry) { -+ if (buf >= end) -+ break; -+ buf = print_binder_work(buf, end, " ", -+ " pending transaction", w); -+ } -+ list_for_each_entry(w, &proc->delivered_death, entry) { -+ if (buf >= end) -+ break; -+ buf += snprintf(buf, end - buf, -+ " has delivered dead binder\n"); -+ break; -+ } -+ if (!print_all && buf == header_buf) -+ buf = start_buf; -+ return buf; -+} -+ -+static const char *binder_return_strings[] = { -+ "BR_ERROR", -+ "BR_OK", -+ "BR_TRANSACTION", -+ "BR_REPLY", -+ "BR_ACQUIRE_RESULT", -+ "BR_DEAD_REPLY", -+ "BR_TRANSACTION_COMPLETE", -+ "BR_INCREFS", -+ "BR_ACQUIRE", -+ "BR_RELEASE", -+ "BR_DECREFS", -+ "BR_ATTEMPT_ACQUIRE", -+ "BR_NOOP", -+ "BR_SPAWN_LOOPER", -+ "BR_FINISHED", -+ "BR_DEAD_BINDER", -+ "BR_CLEAR_DEATH_NOTIFICATION_DONE", -+ "BR_FAILED_REPLY" -+}; -+ -+static const char *binder_command_strings[] = { -+ "BC_TRANSACTION", -+ "BC_REPLY", -+ "BC_ACQUIRE_RESULT", -+ "BC_FREE_BUFFER", -+ "BC_INCREFS", -+ "BC_ACQUIRE", -+ "BC_RELEASE", -+ "BC_DECREFS", -+ "BC_INCREFS_DONE", -+ "BC_ACQUIRE_DONE", -+ "BC_ATTEMPT_ACQUIRE", -+ "BC_REGISTER_LOOPER", -+ "BC_ENTER_LOOPER", -+ "BC_EXIT_LOOPER", -+ "BC_REQUEST_DEATH_NOTIFICATION", -+ "BC_CLEAR_DEATH_NOTIFICATION", -+ "BC_DEAD_BINDER_DONE" -+}; -+ -+static const char *binder_objstat_strings[] = { -+ "proc", -+ "thread", -+ "node", -+ "ref", -+ "death", -+ "transaction", -+ "transaction_complete" -+}; -+ -+static char *print_binder_stats(char *buf, char *end, const char *prefix, -+ struct binder_stats *stats) -+{ -+ int i; -+ -+ BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != -+ ARRAY_SIZE(binder_command_strings)); -+ for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { -+ if (stats->bc[i]) -+ buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, -+ binder_command_strings[i], -+ stats->bc[i]); -+ if (buf >= end) -+ return buf; -+ } -+ -+ BUILD_BUG_ON(ARRAY_SIZE(stats->br) != -+ ARRAY_SIZE(binder_return_strings)); -+ for (i = 0; i < ARRAY_SIZE(stats->br); i++) { -+ if (stats->br[i]) -+ buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, -+ binder_return_strings[i], stats->br[i]); -+ if (buf >= end) -+ return buf; -+ } -+ -+ BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != -+ ARRAY_SIZE(binder_objstat_strings)); -+ BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != -+ ARRAY_SIZE(stats->obj_deleted)); -+ for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { -+ if (stats->obj_created[i] || stats->obj_deleted[i]) -+ buf += snprintf(buf, end - buf, -+ "%s%s: active %d total %d\n", prefix, -+ binder_objstat_strings[i], -+ stats->obj_created[i] - -+ stats->obj_deleted[i], -+ stats->obj_created[i]); -+ if (buf >= end) -+ return buf; -+ } -+ return buf; -+} -+ -+static char *print_binder_proc_stats(char *buf, char *end, -+ struct binder_proc *proc) -+{ -+ struct binder_work *w; -+ struct rb_node *n; -+ int count, strong, weak; -+ -+ buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); -+ if (buf >= end) -+ return buf; -+ count = 0; -+ for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) -+ count++; -+ buf += snprintf(buf, end - buf, " threads: %d\n", count); -+ if (buf >= end) -+ return buf; -+ buf += snprintf(buf, end - buf, " requested threads: %d+%d/%d\n" -+ " ready threads %d\n" -+ " free async space %zd\n", proc->requested_threads, -+ proc->requested_threads_started, proc->max_threads, -+ proc->ready_threads, proc->free_async_space); -+ if (buf >= end) -+ return buf; -+ count = 0; -+ for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) -+ count++; -+ buf += snprintf(buf, end - buf, " nodes: %d\n", count); -+ if (buf >= end) -+ return buf; -+ count = 0; -+ strong = 0; -+ weak = 0; -+ for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { -+ struct binder_ref *ref = rb_entry(n, struct binder_ref, -+ rb_node_desc); -+ count++; -+ strong += ref->strong; -+ weak += ref->weak; -+ } -+ buf += snprintf(buf, end - buf, " refs: %d s %d w %d\n", -+ count, strong, weak); -+ if (buf >= end) -+ return buf; -+ -+ count = 0; -+ for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) -+ count++; -+ buf += snprintf(buf, end - buf, " buffers: %d\n", count); -+ if (buf >= end) -+ return buf; -+ -+ count = 0; -+ list_for_each_entry(w, &proc->todo, entry) { -+ switch (w->type) { -+ case BINDER_WORK_TRANSACTION: -+ count++; -+ break; -+ default: -+ break; -+ } -+ } -+ buf += snprintf(buf, end - buf, " pending transactions: %d\n", count); -+ if (buf >= end) -+ return buf; -+ -+ buf = print_binder_stats(buf, end, " ", &proc->stats); -+ -+ return buf; -+} -+ -+ -+static int binder_read_proc_state(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ struct binder_proc *proc; -+ struct hlist_node *pos; -+ struct binder_node *node; -+ int len = 0; -+ char *buf = page; -+ char *end = page + PAGE_SIZE; -+ int do_lock = !binder_debug_no_lock; -+ -+ if (off) -+ return 0; -+ -+ if (do_lock) -+ mutex_lock(&binder_lock); -+ -+ buf += snprintf(buf, end - buf, "binder state:\n"); -+ -+ if (!hlist_empty(&binder_dead_nodes)) -+ buf += snprintf(buf, end - buf, "dead nodes:\n"); -+ hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) { -+ if (buf >= end) -+ break; -+ buf = print_binder_node(buf, end, node); -+ } -+ -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -+ if (buf >= end) -+ break; -+ buf = print_binder_proc(buf, end, proc, 1); -+ } -+ if (do_lock) -+ mutex_unlock(&binder_lock); -+ if (buf > page + PAGE_SIZE) -+ buf = page + PAGE_SIZE; -+ -+ *start = page + off; -+ -+ len = buf - page; -+ if (len > off) -+ len -= off; -+ else -+ len = 0; -+ -+ return len < count ? len : count; -+} -+ -+static int binder_read_proc_stats(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ struct binder_proc *proc; -+ struct hlist_node *pos; -+ int len = 0; -+ char *p = page; -+ int do_lock = !binder_debug_no_lock; -+ -+ if (off) -+ return 0; -+ -+ if (do_lock) -+ mutex_lock(&binder_lock); -+ -+ p += snprintf(p, PAGE_SIZE, "binder stats:\n"); -+ -+ p = print_binder_stats(p, page + PAGE_SIZE, "", &binder_stats); -+ -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -+ if (p >= page + PAGE_SIZE) -+ break; -+ p = print_binder_proc_stats(p, page + PAGE_SIZE, proc); -+ } -+ if (do_lock) -+ mutex_unlock(&binder_lock); -+ if (p > page + PAGE_SIZE) -+ p = page + PAGE_SIZE; -+ -+ *start = page + off; -+ -+ len = p - page; -+ if (len > off) -+ len -= off; -+ else -+ len = 0; -+ -+ return len < count ? len : count; -+} -+ -+static int binder_read_proc_transactions(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ struct binder_proc *proc; -+ struct hlist_node *pos; -+ int len = 0; -+ char *buf = page; -+ char *end = page + PAGE_SIZE; -+ int do_lock = !binder_debug_no_lock; -+ -+ if (off) -+ return 0; -+ -+ if (do_lock) -+ mutex_lock(&binder_lock); -+ -+ buf += snprintf(buf, end - buf, "binder transactions:\n"); -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -+ if (buf >= end) -+ break; -+ buf = print_binder_proc(buf, end, proc, 0); -+ } -+ if (do_lock) -+ mutex_unlock(&binder_lock); -+ if (buf > page + PAGE_SIZE) -+ buf = page + PAGE_SIZE; -+ -+ *start = page + off; -+ -+ len = buf - page; -+ if (len > off) -+ len -= off; -+ else -+ len = 0; -+ -+ return len < count ? len : count; -+} -+ -+static int binder_read_proc_proc(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ struct binder_proc *proc = data; -+ int len = 0; -+ char *p = page; -+ int do_lock = !binder_debug_no_lock; -+ -+ if (off) -+ return 0; -+ -+ if (do_lock) -+ mutex_lock(&binder_lock); -+ p += snprintf(p, PAGE_SIZE, "binder proc state:\n"); -+ p = print_binder_proc(p, page + PAGE_SIZE, proc, 1); -+ if (do_lock) -+ mutex_unlock(&binder_lock); -+ -+ if (p > page + PAGE_SIZE) -+ p = page + PAGE_SIZE; -+ *start = page + off; -+ -+ len = p - page; -+ if (len > off) -+ len -= off; -+ else -+ len = 0; -+ -+ return len < count ? len : count; -+} -+ -+static char *print_binder_transaction_log_entry(char *buf, char *end, -+ struct binder_transaction_log_entry *e) -+{ -+ buf += snprintf(buf, end - buf, -+ "%d: %s from %d:%d to %d:%d node %d handle %d " -+ "size %d:%d\n", -+ e->debug_id, (e->call_type == 2) ? "reply" : -+ ((e->call_type == 1) ? "async" : "call "), e->from_proc, -+ e->from_thread, e->to_proc, e->to_thread, e->to_node, -+ e->target_handle, e->data_size, e->offsets_size); -+ return buf; -+} -+ -+static int binder_read_proc_transaction_log( -+ char *page, char **start, off_t off, int count, int *eof, void *data) -+{ -+ struct binder_transaction_log *log = data; -+ int len = 0; -+ int i; -+ char *buf = page; -+ char *end = page + PAGE_SIZE; -+ -+ if (off) -+ return 0; -+ -+ if (log->full) { -+ for (i = log->next; i < ARRAY_SIZE(log->entry); i++) { -+ if (buf >= end) -+ break; -+ buf = print_binder_transaction_log_entry(buf, end, -+ &log->entry[i]); -+ } -+ } -+ for (i = 0; i < log->next; i++) { -+ if (buf >= end) -+ break; -+ buf = print_binder_transaction_log_entry(buf, end, -+ &log->entry[i]); -+ } -+ -+ *start = page + off; -+ -+ len = buf - page; -+ if (len > off) -+ len -= off; -+ else -+ len = 0; -+ -+ return len < count ? len : count; -+} -+ -+static const struct file_operations binder_fops = { -+ .owner = THIS_MODULE, -+ .poll = binder_poll, -+ .unlocked_ioctl = binder_ioctl, -+ .mmap = binder_mmap, -+ .open = binder_open, -+ .flush = binder_flush, -+ .release = binder_release, -+}; -+ -+static struct miscdevice binder_miscdev = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "binder", -+ .fops = &binder_fops -+}; -+ -+static int __init binder_init(void) -+{ -+ int ret; -+ -+ binder_proc_dir_entry_root = proc_mkdir("binder", NULL); -+ if (binder_proc_dir_entry_root) -+ binder_proc_dir_entry_proc = proc_mkdir("proc", -+ binder_proc_dir_entry_root); -+ ret = misc_register(&binder_miscdev); -+ if (binder_proc_dir_entry_root) { -+ create_proc_read_entry("state", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ binder_read_proc_state, -+ NULL); -+ create_proc_read_entry("stats", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ binder_read_proc_stats, -+ NULL); -+ create_proc_read_entry("transactions", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ binder_read_proc_transactions, -+ NULL); -+ create_proc_read_entry("transaction_log", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ binder_read_proc_transaction_log, -+ &binder_transaction_log); -+ create_proc_read_entry("failed_transaction_log", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ binder_read_proc_transaction_log, -+ &binder_transaction_log_failed); -+ } -+ return ret; -+} -+ -+device_initcall(binder_init); -+ -+MODULE_LICENSE("GPL v2"); -diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h -new file mode 100644 -index 0000000..863ae1a ---- /dev/null -+++ b/drivers/staging/android/binder.h -@@ -0,0 +1,330 @@ -+/* -+ * Copyright (C) 2008 Google, Inc. -+ * -+ * Based on, but no longer compatible with, the original -+ * OpenBinder.org binder driver interface, which is: -+ * -+ * Copyright (c) 2005 Palmsource, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _LINUX_BINDER_H -+#define _LINUX_BINDER_H -+ -+#include -+ -+#define B_PACK_CHARS(c1, c2, c3, c4) \ -+ ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4)) -+#define B_TYPE_LARGE 0x85 -+ -+enum { -+ BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE), -+ BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE), -+ BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE), -+ BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE), -+ BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE), -+}; -+ -+enum { -+ FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff, -+ FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100, -+}; -+ -+/* -+ * This is the flattened representation of a Binder object for transfer -+ * between processes. The 'offsets' supplied as part of a binder transaction -+ * contains offsets into the data where these structures occur. The Binder -+ * driver takes care of re-writing the structure type and data as it moves -+ * between processes. -+ */ -+struct flat_binder_object { -+ /* 8 bytes for large_flat_header. */ -+ unsigned long type; -+ unsigned long flags; -+ -+ /* 8 bytes of data. */ -+ union { -+ void *binder; /* local object */ -+ signed long handle; /* remote object */ -+ }; -+ -+ /* extra data associated with local object */ -+ void *cookie; -+}; -+ -+/* -+ * On 64-bit platforms where user code may run in 32-bits the driver must -+ * translate the buffer (and local binder) addresses apropriately. -+ */ -+ -+struct binder_write_read { -+ signed long write_size; /* bytes to write */ -+ signed long write_consumed; /* bytes consumed by driver */ -+ unsigned long write_buffer; -+ signed long read_size; /* bytes to read */ -+ signed long read_consumed; /* bytes consumed by driver */ -+ unsigned long read_buffer; -+}; -+ -+/* Use with BINDER_VERSION, driver fills in fields. */ -+struct binder_version { -+ /* driver protocol version -- increment with incompatible change */ -+ signed long protocol_version; -+}; -+ -+/* This is the current protocol version. */ -+#define BINDER_CURRENT_PROTOCOL_VERSION 7 -+ -+#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -+#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t) -+#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) -+#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int) -+#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int) -+#define BINDER_THREAD_EXIT _IOW('b', 8, int) -+#define BINDER_VERSION _IOWR('b', 9, struct binder_version) -+ -+/* -+ * NOTE: Two special error codes you should check for when calling -+ * in to the driver are: -+ * -+ * EINTR -- The operation has been interupted. This should be -+ * handled by retrying the ioctl() until a different error code -+ * is returned. -+ * -+ * ECONNREFUSED -- The driver is no longer accepting operations -+ * from your process. That is, the process is being destroyed. -+ * You should handle this by exiting from your process. Note -+ * that once this error code is returned, all further calls to -+ * the driver from any thread will return this same code. -+ */ -+ -+enum transaction_flags { -+ TF_ONE_WAY = 0x01, /* this is a one-way call: async, no return */ -+ TF_ROOT_OBJECT = 0x04, /* contents are the component's root object */ -+ TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ -+ TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ -+}; -+ -+struct binder_transaction_data { -+ /* The first two are only used for bcTRANSACTION and brTRANSACTION, -+ * identifying the target and contents of the transaction. -+ */ -+ union { -+ size_t handle; /* target descriptor of command transaction */ -+ void *ptr; /* target descriptor of return transaction */ -+ } target; -+ void *cookie; /* target object cookie */ -+ unsigned int code; /* transaction command */ -+ -+ /* General information about the transaction. */ -+ unsigned int flags; -+ pid_t sender_pid; -+ uid_t sender_euid; -+ size_t data_size; /* number of bytes of data */ -+ size_t offsets_size; /* number of bytes of offsets */ -+ -+ /* If this transaction is inline, the data immediately -+ * follows here; otherwise, it ends with a pointer to -+ * the data buffer. -+ */ -+ union { -+ struct { -+ /* transaction data */ -+ const void *buffer; -+ /* offsets from buffer to flat_binder_object structs */ -+ const void *offsets; -+ } ptr; -+ uint8_t buf[8]; -+ } data; -+}; -+ -+struct binder_ptr_cookie { -+ void *ptr; -+ void *cookie; -+}; -+ -+struct binder_pri_desc { -+ int priority; -+ int desc; -+}; -+ -+struct binder_pri_ptr_cookie { -+ int priority; -+ void *ptr; -+ void *cookie; -+}; -+ -+enum BinderDriverReturnProtocol { -+ BR_ERROR = _IOR('r', 0, int), -+ /* -+ * int: error code -+ */ -+ -+ BR_OK = _IO('r', 1), -+ /* No parameters! */ -+ -+ BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data), -+ BR_REPLY = _IOR('r', 3, struct binder_transaction_data), -+ /* -+ * binder_transaction_data: the received command. -+ */ -+ -+ BR_ACQUIRE_RESULT = _IOR('r', 4, int), -+ /* -+ * not currently supported -+ * int: 0 if the last bcATTEMPT_ACQUIRE was not successful. -+ * Else the remote object has acquired a primary reference. -+ */ -+ -+ BR_DEAD_REPLY = _IO('r', 5), -+ /* -+ * The target of the last transaction (either a bcTRANSACTION or -+ * a bcATTEMPT_ACQUIRE) is no longer with us. No parameters. -+ */ -+ -+ BR_TRANSACTION_COMPLETE = _IO('r', 6), -+ /* -+ * No parameters... always refers to the last transaction requested -+ * (including replies). Note that this will be sent even for -+ * asynchronous transactions. -+ */ -+ -+ BR_INCREFS = _IOR('r', 7, struct binder_ptr_cookie), -+ BR_ACQUIRE = _IOR('r', 8, struct binder_ptr_cookie), -+ BR_RELEASE = _IOR('r', 9, struct binder_ptr_cookie), -+ BR_DECREFS = _IOR('r', 10, struct binder_ptr_cookie), -+ /* -+ * void *: ptr to binder -+ * void *: cookie for binder -+ */ -+ -+ BR_ATTEMPT_ACQUIRE = _IOR('r', 11, struct binder_pri_ptr_cookie), -+ /* -+ * not currently supported -+ * int: priority -+ * void *: ptr to binder -+ * void *: cookie for binder -+ */ -+ -+ BR_NOOP = _IO('r', 12), -+ /* -+ * No parameters. Do nothing and examine the next command. It exists -+ * primarily so that we can replace it with a BR_SPAWN_LOOPER command. -+ */ -+ -+ BR_SPAWN_LOOPER = _IO('r', 13), -+ /* -+ * No parameters. The driver has determined that a process has no -+ * threads waiting to service incomming transactions. When a process -+ * receives this command, it must spawn a new service thread and -+ * register it via bcENTER_LOOPER. -+ */ -+ -+ BR_FINISHED = _IO('r', 14), -+ /* -+ * not currently supported -+ * stop threadpool thread -+ */ -+ -+ BR_DEAD_BINDER = _IOR('r', 15, void *), -+ /* -+ * void *: cookie -+ */ -+ BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r', 16, void *), -+ /* -+ * void *: cookie -+ */ -+ -+ BR_FAILED_REPLY = _IO('r', 17), -+ /* -+ * The the last transaction (either a bcTRANSACTION or -+ * a bcATTEMPT_ACQUIRE) failed (e.g. out of memory). No parameters. -+ */ -+}; -+ -+enum BinderDriverCommandProtocol { -+ BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data), -+ BC_REPLY = _IOW('c', 1, struct binder_transaction_data), -+ /* -+ * binder_transaction_data: the sent command. -+ */ -+ -+ BC_ACQUIRE_RESULT = _IOW('c', 2, int), -+ /* -+ * not currently supported -+ * int: 0 if the last BR_ATTEMPT_ACQUIRE was not successful. -+ * Else you have acquired a primary reference on the object. -+ */ -+ -+ BC_FREE_BUFFER = _IOW('c', 3, int), -+ /* -+ * void *: ptr to transaction data received on a read -+ */ -+ -+ BC_INCREFS = _IOW('c', 4, int), -+ BC_ACQUIRE = _IOW('c', 5, int), -+ BC_RELEASE = _IOW('c', 6, int), -+ BC_DECREFS = _IOW('c', 7, int), -+ /* -+ * int: descriptor -+ */ -+ -+ BC_INCREFS_DONE = _IOW('c', 8, struct binder_ptr_cookie), -+ BC_ACQUIRE_DONE = _IOW('c', 9, struct binder_ptr_cookie), -+ /* -+ * void *: ptr to binder -+ * void *: cookie for binder -+ */ -+ -+ BC_ATTEMPT_ACQUIRE = _IOW('c', 10, struct binder_pri_desc), -+ /* -+ * not currently supported -+ * int: priority -+ * int: descriptor -+ */ -+ -+ BC_REGISTER_LOOPER = _IO('c', 11), -+ /* -+ * No parameters. -+ * Register a spawned looper thread with the device. -+ */ -+ -+ BC_ENTER_LOOPER = _IO('c', 12), -+ BC_EXIT_LOOPER = _IO('c', 13), -+ /* -+ * No parameters. -+ * These two commands are sent as an application-level thread -+ * enters and exits the binder loop, respectively. They are -+ * used so the binder can have an accurate count of the number -+ * of looping threads it has available. -+ */ -+ -+ BC_REQUEST_DEATH_NOTIFICATION = _IOW('c', 14, struct binder_ptr_cookie), -+ /* -+ * void *: ptr to binder -+ * void *: cookie -+ */ -+ -+ BC_CLEAR_DEATH_NOTIFICATION = _IOW('c', 15, struct binder_ptr_cookie), -+ /* -+ * void *: ptr to binder -+ * void *: cookie -+ */ -+ -+ BC_DEAD_BINDER_DONE = _IOW('c', 16, void *), -+ /* -+ * void *: cookie -+ */ -+}; -+ -+#endif /* _LINUX_BINDER_H */ -+ -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -new file mode 100644 -index 0000000..6c10b45 ---- /dev/null -+++ b/drivers/staging/android/logger.c -@@ -0,0 +1,607 @@ -+/* -+ * drivers/misc/logger.c -+ * -+ * A Logging Subsystem -+ * -+ * Copyright (C) 2007-2008 Google, Inc. -+ * -+ * Robert Love -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "logger.h" -+ -+#include -+ -+/* -+ * struct logger_log - represents a specific log, such as 'main' or 'radio' -+ * -+ * This structure lives from module insertion until module removal, so it does -+ * not need additional reference counting. The structure is protected by the -+ * mutex 'mutex'. -+ */ -+struct logger_log { -+ unsigned char *buffer;/* the ring buffer itself */ -+ struct miscdevice misc; /* misc device representing the log */ -+ wait_queue_head_t wq; /* wait queue for readers */ -+ struct list_head readers; /* this log's readers */ -+ struct mutex mutex; /* mutex protecting buffer */ -+ size_t w_off; /* current write head offset */ -+ size_t head; /* new readers start here */ -+ size_t size; /* size of the log */ -+}; -+ -+/* -+ * struct logger_reader - a logging device open for reading -+ * -+ * This object lives from open to release, so we don't need additional -+ * reference counting. The structure is protected by log->mutex. -+ */ -+struct logger_reader { -+ struct logger_log *log; /* associated log */ -+ struct list_head list; /* entry in logger_log's list */ -+ size_t r_off; /* current read head offset */ -+}; -+ -+/* logger_offset - returns index 'n' into the log via (optimized) modulus */ -+#define logger_offset(n) ((n) & (log->size - 1)) -+ -+/* -+ * file_get_log - Given a file structure, return the associated log -+ * -+ * This isn't aesthetic. We have several goals: -+ * -+ * 1) Need to quickly obtain the associated log during an I/O operation -+ * 2) Readers need to maintain state (logger_reader) -+ * 3) Writers need to be very fast (open() should be a near no-op) -+ * -+ * In the reader case, we can trivially go file->logger_reader->logger_log. -+ * For a writer, we don't want to maintain a logger_reader, so we just go -+ * file->logger_log. Thus what file->private_data points at depends on whether -+ * or not the file was opened for reading. This function hides that dirtiness. -+ */ -+static inline struct logger_log *file_get_log(struct file *file) -+{ -+ if (file->f_mode & FMODE_READ) { -+ struct logger_reader *reader = file->private_data; -+ return reader->log; -+ } else -+ return file->private_data; -+} -+ -+/* -+ * get_entry_len - Grabs the length of the payload of the next entry starting -+ * from 'off'. -+ * -+ * Caller needs to hold log->mutex. -+ */ -+static __u32 get_entry_len(struct logger_log *log, size_t off) -+{ -+ __u16 val; -+ -+ switch (log->size - off) { -+ case 1: -+ memcpy(&val, log->buffer + off, 1); -+ memcpy(((char *) &val) + 1, log->buffer, 1); -+ break; -+ default: -+ memcpy(&val, log->buffer + off, 2); -+ } -+ -+ return sizeof(struct logger_entry) + val; -+} -+ -+/* -+ * do_read_log_to_user - reads exactly 'count' bytes from 'log' into the -+ * user-space buffer 'buf'. Returns 'count' on success. -+ * -+ * Caller must hold log->mutex. -+ */ -+static ssize_t do_read_log_to_user(struct logger_log *log, -+ struct logger_reader *reader, -+ char __user *buf, -+ size_t count) -+{ -+ size_t len; -+ -+ /* -+ * We read from the log in two disjoint operations. First, we read from -+ * the current read head offset up to 'count' bytes or to the end of -+ * the log, whichever comes first. -+ */ -+ len = min(count, log->size - reader->r_off); -+ if (copy_to_user(buf, log->buffer + reader->r_off, len)) -+ return -EFAULT; -+ -+ /* -+ * Second, we read any remaining bytes, starting back at the head of -+ * the log. -+ */ -+ if (count != len) -+ if (copy_to_user(buf + len, log->buffer, count - len)) -+ return -EFAULT; -+ -+ reader->r_off = logger_offset(reader->r_off + count); -+ -+ return count; -+} -+ -+/* -+ * logger_read - our log's read() method -+ * -+ * Behavior: -+ * -+ * - O_NONBLOCK works -+ * - If there are no log entries to read, blocks until log is written to -+ * - Atomically reads exactly one log entry -+ * -+ * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read -+ * buffer is insufficient to hold next entry. -+ */ -+static ssize_t logger_read(struct file *file, char __user *buf, -+ size_t count, loff_t *pos) -+{ -+ struct logger_reader *reader = file->private_data; -+ struct logger_log *log = reader->log; -+ ssize_t ret; -+ DEFINE_WAIT(wait); -+ -+start: -+ while (1) { -+ prepare_to_wait(&log->wq, &wait, TASK_INTERRUPTIBLE); -+ -+ mutex_lock(&log->mutex); -+ ret = (log->w_off == reader->r_off); -+ mutex_unlock(&log->mutex); -+ if (!ret) -+ break; -+ -+ if (file->f_flags & O_NONBLOCK) { -+ ret = -EAGAIN; -+ break; -+ } -+ -+ if (signal_pending(current)) { -+ ret = -EINTR; -+ break; -+ } -+ -+ schedule(); -+ } -+ -+ finish_wait(&log->wq, &wait); -+ if (ret) -+ return ret; -+ -+ mutex_lock(&log->mutex); -+ -+ /* is there still something to read or did we race? */ -+ if (unlikely(log->w_off == reader->r_off)) { -+ mutex_unlock(&log->mutex); -+ goto start; -+ } -+ -+ /* get the size of the next entry */ -+ ret = get_entry_len(log, reader->r_off); -+ if (count < ret) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* get exactly one entry from the log */ -+ ret = do_read_log_to_user(log, reader, buf, ret); -+ -+out: -+ mutex_unlock(&log->mutex); -+ -+ return ret; -+} -+ -+/* -+ * get_next_entry - return the offset of the first valid entry at least 'len' -+ * bytes after 'off'. -+ * -+ * Caller must hold log->mutex. -+ */ -+static size_t get_next_entry(struct logger_log *log, size_t off, size_t len) -+{ -+ size_t count = 0; -+ -+ do { -+ size_t nr = get_entry_len(log, off); -+ off = logger_offset(off + nr); -+ count += nr; -+ } while (count < len); -+ -+ return off; -+} -+ -+/* -+ * clock_interval - is a < c < b in mod-space? Put another way, does the line -+ * from a to b cross c? -+ */ -+static inline int clock_interval(size_t a, size_t b, size_t c) -+{ -+ if (b < a) { -+ if (a < c || b >= c) -+ return 1; -+ } else { -+ if (a < c && b >= c) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* -+ * fix_up_readers - walk the list of all readers and "fix up" any who were -+ * lapped by the writer; also do the same for the default "start head". -+ * We do this by "pulling forward" the readers and start head to the first -+ * entry after the new write head. -+ * -+ * The caller needs to hold log->mutex. -+ */ -+static void fix_up_readers(struct logger_log *log, size_t len) -+{ -+ size_t old = log->w_off; -+ size_t new = logger_offset(old + len); -+ struct logger_reader *reader; -+ -+ if (clock_interval(old, new, log->head)) -+ log->head = get_next_entry(log, log->head, len); -+ -+ list_for_each_entry(reader, &log->readers, list) -+ if (clock_interval(old, new, reader->r_off)) -+ reader->r_off = get_next_entry(log, reader->r_off, len); -+} -+ -+/* -+ * do_write_log - writes 'len' bytes from 'buf' to 'log' -+ * -+ * The caller needs to hold log->mutex. -+ */ -+static void do_write_log(struct logger_log *log, const void *buf, size_t count) -+{ -+ size_t len; -+ -+ len = min(count, log->size - log->w_off); -+ memcpy(log->buffer + log->w_off, buf, len); -+ -+ if (count != len) -+ memcpy(log->buffer, buf + len, count - len); -+ -+ log->w_off = logger_offset(log->w_off + count); -+ -+} -+ -+/* -+ * do_write_log_user - writes 'len' bytes from the user-space buffer 'buf' to -+ * the log 'log' -+ * -+ * The caller needs to hold log->mutex. -+ * -+ * Returns 'count' on success, negative error code on failure. -+ */ -+static ssize_t do_write_log_from_user(struct logger_log *log, -+ const void __user *buf, size_t count) -+{ -+ size_t len; -+ -+ len = min(count, log->size - log->w_off); -+ if (len && copy_from_user(log->buffer + log->w_off, buf, len)) -+ return -EFAULT; -+ -+ if (count != len) -+ if (copy_from_user(log->buffer, buf + len, count - len)) -+ return -EFAULT; -+ -+ log->w_off = logger_offset(log->w_off + count); -+ -+ return count; -+} -+ -+/* -+ * logger_aio_write - our write method, implementing support for write(), -+ * writev(), and aio_write(). Writes are our fast path, and we try to optimize -+ * them above all else. -+ */ -+ssize_t logger_aio_write(struct kiocb *iocb, const struct iovec *iov, -+ unsigned long nr_segs, loff_t ppos) -+{ -+ struct logger_log *log = file_get_log(iocb->ki_filp); -+ size_t orig = log->w_off; -+ struct logger_entry header; -+ struct timespec now; -+ ssize_t ret = 0; -+ -+ now = current_kernel_time(); -+ -+ header.pid = current->tgid; -+ header.tid = current->pid; -+ header.sec = now.tv_sec; -+ header.nsec = now.tv_nsec; -+ header.len = min_t(size_t, iocb->ki_left, LOGGER_ENTRY_MAX_PAYLOAD); -+ -+ /* null writes succeed, return zero */ -+ if (unlikely(!header.len)) -+ return 0; -+ -+ mutex_lock(&log->mutex); -+ -+ /* -+ * Fix up any readers, pulling them forward to the first readable -+ * entry after (what will be) the new write offset. We do this now -+ * because if we partially fail, we can end up with clobbered log -+ * entries that encroach on readable buffer. -+ */ -+ fix_up_readers(log, sizeof(struct logger_entry) + header.len); -+ -+ do_write_log(log, &header, sizeof(struct logger_entry)); -+ -+ while (nr_segs-- > 0) { -+ size_t len; -+ ssize_t nr; -+ -+ /* figure out how much of this vector we can keep */ -+ len = min_t(size_t, iov->iov_len, header.len - ret); -+ -+ /* write out this segment's payload */ -+ nr = do_write_log_from_user(log, iov->iov_base, len); -+ if (unlikely(nr < 0)) { -+ log->w_off = orig; -+ mutex_unlock(&log->mutex); -+ return nr; -+ } -+ -+ iov++; -+ ret += nr; -+ } -+ -+ mutex_unlock(&log->mutex); -+ -+ /* wake up any blocked readers */ -+ wake_up_interruptible(&log->wq); -+ -+ return ret; -+} -+ -+static struct logger_log *get_log_from_minor(int); -+ -+/* -+ * logger_open - the log's open() file operation -+ * -+ * Note how near a no-op this is in the write-only case. Keep it that way! -+ */ -+static int logger_open(struct inode *inode, struct file *file) -+{ -+ struct logger_log *log; -+ int ret; -+ -+ ret = nonseekable_open(inode, file); -+ if (ret) -+ return ret; -+ -+ log = get_log_from_minor(MINOR(inode->i_rdev)); -+ if (!log) -+ return -ENODEV; -+ -+ if (file->f_mode & FMODE_READ) { -+ struct logger_reader *reader; -+ -+ reader = kmalloc(sizeof(struct logger_reader), GFP_KERNEL); -+ if (!reader) -+ return -ENOMEM; -+ -+ reader->log = log; -+ INIT_LIST_HEAD(&reader->list); -+ -+ mutex_lock(&log->mutex); -+ reader->r_off = log->head; -+ list_add_tail(&reader->list, &log->readers); -+ mutex_unlock(&log->mutex); -+ -+ file->private_data = reader; -+ } else -+ file->private_data = log; -+ -+ return 0; -+} -+ -+/* -+ * logger_release - the log's release file operation -+ * -+ * Note this is a total no-op in the write-only case. Keep it that way! -+ */ -+static int logger_release(struct inode *ignored, struct file *file) -+{ -+ if (file->f_mode & FMODE_READ) { -+ struct logger_reader *reader = file->private_data; -+ list_del(&reader->list); -+ kfree(reader); -+ } -+ -+ return 0; -+} -+ -+/* -+ * logger_poll - the log's poll file operation, for poll/select/epoll -+ * -+ * Note we always return POLLOUT, because you can always write() to the log. -+ * Note also that, strictly speaking, a return value of POLLIN does not -+ * guarantee that the log is readable without blocking, as there is a small -+ * chance that the writer can lap the reader in the interim between poll() -+ * returning and the read() request. -+ */ -+static unsigned int logger_poll(struct file *file, poll_table *wait) -+{ -+ struct logger_reader *reader; -+ struct logger_log *log; -+ unsigned int ret = POLLOUT | POLLWRNORM; -+ -+ if (!(file->f_mode & FMODE_READ)) -+ return ret; -+ -+ reader = file->private_data; -+ log = reader->log; -+ -+ poll_wait(file, &log->wq, wait); -+ -+ mutex_lock(&log->mutex); -+ if (log->w_off != reader->r_off) -+ ret |= POLLIN | POLLRDNORM; -+ mutex_unlock(&log->mutex); -+ -+ return ret; -+} -+ -+static long logger_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct logger_log *log = file_get_log(file); -+ struct logger_reader *reader; -+ long ret = -ENOTTY; -+ -+ mutex_lock(&log->mutex); -+ -+ switch (cmd) { -+ case LOGGER_GET_LOG_BUF_SIZE: -+ ret = log->size; -+ break; -+ case LOGGER_GET_LOG_LEN: -+ if (!(file->f_mode & FMODE_READ)) { -+ ret = -EBADF; -+ break; -+ } -+ reader = file->private_data; -+ if (log->w_off >= reader->r_off) -+ ret = log->w_off - reader->r_off; -+ else -+ ret = (log->size - reader->r_off) + log->w_off; -+ break; -+ case LOGGER_GET_NEXT_ENTRY_LEN: -+ if (!(file->f_mode & FMODE_READ)) { -+ ret = -EBADF; -+ break; -+ } -+ reader = file->private_data; -+ if (log->w_off != reader->r_off) -+ ret = get_entry_len(log, reader->r_off); -+ else -+ ret = 0; -+ break; -+ case LOGGER_FLUSH_LOG: -+ if (!(file->f_mode & FMODE_WRITE)) { -+ ret = -EBADF; -+ break; -+ } -+ list_for_each_entry(reader, &log->readers, list) -+ reader->r_off = log->w_off; -+ log->head = log->w_off; -+ ret = 0; -+ break; -+ } -+ -+ mutex_unlock(&log->mutex); -+ -+ return ret; -+} -+ -+static const struct file_operations logger_fops = { -+ .owner = THIS_MODULE, -+ .read = logger_read, -+ .aio_write = logger_aio_write, -+ .poll = logger_poll, -+ .unlocked_ioctl = logger_ioctl, -+ .compat_ioctl = logger_ioctl, -+ .open = logger_open, -+ .release = logger_release, -+}; -+ -+/* -+ * Defines a log structure with name 'NAME' and a size of 'SIZE' bytes, which -+ * must be a power of two, greater than LOGGER_ENTRY_MAX_LEN, and less than -+ * LONG_MAX minus LOGGER_ENTRY_MAX_LEN. -+ */ -+#define DEFINE_LOGGER_DEVICE(VAR, NAME, SIZE) \ -+static unsigned char _buf_ ## VAR[SIZE]; \ -+static struct logger_log VAR = { \ -+ .buffer = _buf_ ## VAR, \ -+ .misc = { \ -+ .minor = MISC_DYNAMIC_MINOR, \ -+ .name = NAME, \ -+ .fops = &logger_fops, \ -+ .parent = NULL, \ -+ }, \ -+ .wq = __WAIT_QUEUE_HEAD_INITIALIZER(VAR .wq), \ -+ .readers = LIST_HEAD_INIT(VAR .readers), \ -+ .mutex = __MUTEX_INITIALIZER(VAR .mutex), \ -+ .w_off = 0, \ -+ .head = 0, \ -+ .size = SIZE, \ -+}; -+ -+DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024) -+DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) -+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024) -+ -+static struct logger_log *get_log_from_minor(int minor) -+{ -+ if (log_main.misc.minor == minor) -+ return &log_main; -+ if (log_events.misc.minor == minor) -+ return &log_events; -+ if (log_radio.misc.minor == minor) -+ return &log_radio; -+ return NULL; -+} -+ -+static int __init init_log(struct logger_log *log) -+{ -+ int ret; -+ -+ ret = misc_register(&log->misc); -+ if (unlikely(ret)) { -+ printk(KERN_ERR "logger: failed to register misc " -+ "device for log '%s'!\n", log->misc.name); -+ return ret; -+ } -+ -+ printk(KERN_INFO "logger: created %luK log '%s'\n", -+ (unsigned long) log->size >> 10, log->misc.name); -+ -+ return 0; -+} -+ -+static int __init logger_init(void) -+{ -+ int ret; -+ -+ ret = init_log(&log_main); -+ if (unlikely(ret)) -+ goto out; -+ -+ ret = init_log(&log_events); -+ if (unlikely(ret)) -+ goto out; -+ -+ ret = init_log(&log_radio); -+ if (unlikely(ret)) -+ goto out; -+ -+out: -+ return ret; -+} -+device_initcall(logger_init); -diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h -new file mode 100644 -index 0000000..a562434 ---- /dev/null -+++ b/drivers/staging/android/logger.h -@@ -0,0 +1,48 @@ -+/* include/linux/logger.h -+ * -+ * Copyright (C) 2007-2008 Google, Inc. -+ * Author: Robert Love -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _LINUX_LOGGER_H -+#define _LINUX_LOGGER_H -+ -+#include -+#include -+ -+struct logger_entry { -+ __u16 len; /* length of the payload */ -+ __u16 __pad; /* no matter what, we get 2 bytes of padding */ -+ __s32 pid; /* generating process's pid */ -+ __s32 tid; /* generating process's tid */ -+ __s32 sec; /* seconds since Epoch */ -+ __s32 nsec; /* nanoseconds */ -+ char msg[0]; /* the entry's payload */ -+}; -+ -+#define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ -+#define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ -+#define LOGGER_LOG_MAIN "log_main" /* everything else */ -+ -+#define LOGGER_ENTRY_MAX_LEN (4*1024) -+#define LOGGER_ENTRY_MAX_PAYLOAD \ -+ (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) -+ -+#define __LOGGERIO 0xAE -+ -+#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ -+#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ -+#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ -+#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ -+ -+#endif /* _LINUX_LOGGER_H */ -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -new file mode 100644 -index 0000000..935d281 ---- /dev/null -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -0,0 +1,173 @@ -+/* drivers/misc/lowmemorykiller.c -+ * -+ * The lowmemorykiller driver lets user-space specify a set of memory thresholds -+ * where processes with a range of oom_adj values will get killed. Specify the -+ * minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the -+ * number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both -+ * files take a comma separated list of numbers in ascending order. -+ * -+ * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and -+ * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes -+ * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages -+ * and kill processes with a oom_adj value of 0 or higher when the free memory -+ * drops below 1024 pages. -+ * -+ * The driver considers memory used for caches to be free, but if a large -+ * percentage of the cached memory is locked this can be very inaccurate -+ * and processes may not get killed until the normal oom killer is triggered. -+ * -+ * Copyright (C) 2007-2008 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static uint32_t lowmem_debug_level = 2; -+static int lowmem_adj[6] = { -+ 0, -+ 1, -+ 6, -+ 12, -+}; -+static int lowmem_adj_size = 4; -+static size_t lowmem_minfree[6] = { -+ 3 * 512, /* 6MB */ -+ 2 * 1024, /* 8MB */ -+ 4 * 1024, /* 16MB */ -+ 16 * 1024, /* 64MB */ -+}; -+static int lowmem_minfree_size = 4; -+ -+#define lowmem_print(level, x...) \ -+ do { \ -+ if (lowmem_debug_level >= (level)) \ -+ printk(x); \ -+ } while (0) -+ -+static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) -+{ -+ struct task_struct *p; -+ struct task_struct *selected = NULL; -+ int rem = 0; -+ int tasksize; -+ int i; -+ int min_adj = OOM_ADJUST_MAX + 1; -+ int selected_tasksize = 0; -+ int selected_oom_adj; -+ int array_size = ARRAY_SIZE(lowmem_adj); -+ int other_free = global_page_state(NR_FREE_PAGES); -+ int other_file = global_page_state(NR_FILE_PAGES); -+ -+ if (lowmem_adj_size < array_size) -+ array_size = lowmem_adj_size; -+ if (lowmem_minfree_size < array_size) -+ array_size = lowmem_minfree_size; -+ for (i = 0; i < array_size; i++) { -+ if (other_free < lowmem_minfree[i] && -+ other_file < lowmem_minfree[i]) { -+ min_adj = lowmem_adj[i]; -+ break; -+ } -+ } -+ if (nr_to_scan > 0) -+ lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n", -+ nr_to_scan, gfp_mask, other_free, other_file, -+ min_adj); -+ rem = global_page_state(NR_ACTIVE_ANON) + -+ global_page_state(NR_ACTIVE_FILE) + -+ global_page_state(NR_INACTIVE_ANON) + -+ global_page_state(NR_INACTIVE_FILE); -+ if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { -+ lowmem_print(5, "lowmem_shrink %d, %x, return %d\n", -+ nr_to_scan, gfp_mask, rem); -+ return rem; -+ } -+ selected_oom_adj = min_adj; -+ -+ read_lock(&tasklist_lock); -+ for_each_process(p) { -+ struct mm_struct *mm; -+ int oom_adj; -+ -+ task_lock(p); -+ mm = p->mm; -+ if (!mm) { -+ task_unlock(p); -+ continue; -+ } -+ oom_adj = mm->oom_adj; -+ if (oom_adj < min_adj) { -+ task_unlock(p); -+ continue; -+ } -+ tasksize = get_mm_rss(mm); -+ task_unlock(p); -+ if (tasksize <= 0) -+ continue; -+ if (selected) { -+ if (oom_adj < selected_oom_adj) -+ continue; -+ if (oom_adj == selected_oom_adj && -+ tasksize <= selected_tasksize) -+ continue; -+ } -+ selected = p; -+ selected_tasksize = tasksize; -+ selected_oom_adj = oom_adj; -+ lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", -+ p->pid, p->comm, oom_adj, tasksize); -+ } -+ if (selected) { -+ lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", -+ selected->pid, selected->comm, -+ selected_oom_adj, selected_tasksize); -+ force_sig(SIGKILL, selected); -+ rem -= selected_tasksize; -+ } -+ lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", -+ nr_to_scan, gfp_mask, rem); -+ read_unlock(&tasklist_lock); -+ return rem; -+} -+ -+static struct shrinker lowmem_shrinker = { -+ .shrink = lowmem_shrink, -+ .seeks = DEFAULT_SEEKS * 16 -+}; -+ -+static int __init lowmem_init(void) -+{ -+ register_shrinker(&lowmem_shrinker); -+ return 0; -+} -+ -+static void __exit lowmem_exit(void) -+{ -+ unregister_shrinker(&lowmem_shrinker); -+} -+ -+module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR); -+module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size, -+ S_IRUGO | S_IWUSR); -+module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size, -+ S_IRUGO | S_IWUSR); -+module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR); -+ -+module_init(lowmem_init); -+module_exit(lowmem_exit); -+ -+MODULE_LICENSE("GPL"); -+ -diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c -new file mode 100644 -index 0000000..8f18a59 ---- /dev/null -+++ b/drivers/staging/android/ram_console.c -@@ -0,0 +1,410 @@ -+/* drivers/android/ram_console.c -+ * -+ * Copyright (C) 2007-2008 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+#include -+#endif -+ -+struct ram_console_buffer { -+ uint32_t sig; -+ uint32_t start; -+ uint32_t size; -+ uint8_t data[0]; -+}; -+ -+#define RAM_CONSOLE_SIG (0x43474244) /* DBGC */ -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -+static char __initdata -+ ram_console_old_log_init_buffer[CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE]; -+#endif -+static char *ram_console_old_log; -+static size_t ram_console_old_log_size; -+ -+static struct ram_console_buffer *ram_console_buffer; -+static size_t ram_console_buffer_size; -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+static char *ram_console_par_buffer; -+static struct rs_control *ram_console_rs_decoder; -+static int ram_console_corrected_bytes; -+static int ram_console_bad_blocks; -+#define ECC_BLOCK_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE -+#define ECC_SIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE -+#define ECC_SYMSIZE CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE -+#define ECC_POLY CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL -+#endif -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+static void ram_console_encode_rs8(uint8_t *data, size_t len, uint8_t *ecc) -+{ -+ int i; -+ uint16_t par[ECC_SIZE]; -+ /* Initialize the parity buffer */ -+ memset(par, 0, sizeof(par)); -+ encode_rs8(ram_console_rs_decoder, data, len, par, 0); -+ for (i = 0; i < ECC_SIZE; i++) -+ ecc[i] = par[i]; -+} -+ -+static int ram_console_decode_rs8(void *data, size_t len, uint8_t *ecc) -+{ -+ int i; -+ uint16_t par[ECC_SIZE]; -+ for (i = 0; i < ECC_SIZE; i++) -+ par[i] = ecc[i]; -+ return decode_rs8(ram_console_rs_decoder, data, par, len, -+ NULL, 0, NULL, 0, NULL); -+} -+#endif -+ -+static void ram_console_update(const char *s, unsigned int count) -+{ -+ struct ram_console_buffer *buffer = ram_console_buffer; -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ uint8_t *buffer_end = buffer->data + ram_console_buffer_size; -+ uint8_t *block; -+ uint8_t *par; -+ int size = ECC_BLOCK_SIZE; -+#endif -+ memcpy(buffer->data + buffer->start, s, count); -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ block = buffer->data + (buffer->start & ~(ECC_BLOCK_SIZE - 1)); -+ par = ram_console_par_buffer + -+ (buffer->start / ECC_BLOCK_SIZE) * ECC_SIZE; -+ do { -+ if (block + ECC_BLOCK_SIZE > buffer_end) -+ size = buffer_end - block; -+ ram_console_encode_rs8(block, size, par); -+ block += ECC_BLOCK_SIZE; -+ par += ECC_SIZE; -+ } while (block < buffer->data + buffer->start + count); -+#endif -+} -+ -+static void ram_console_update_header(void) -+{ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ struct ram_console_buffer *buffer = ram_console_buffer; -+ uint8_t *par; -+ par = ram_console_par_buffer + -+ DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; -+ ram_console_encode_rs8((uint8_t *)buffer, sizeof(*buffer), par); -+#endif -+} -+ -+static void -+ram_console_write(struct console *console, const char *s, unsigned int count) -+{ -+ int rem; -+ struct ram_console_buffer *buffer = ram_console_buffer; -+ -+ if (count > ram_console_buffer_size) { -+ s += count - ram_console_buffer_size; -+ count = ram_console_buffer_size; -+ } -+ rem = ram_console_buffer_size - buffer->start; -+ if (rem < count) { -+ ram_console_update(s, rem); -+ s += rem; -+ count -= rem; -+ buffer->start = 0; -+ buffer->size = ram_console_buffer_size; -+ } -+ ram_console_update(s, count); -+ -+ buffer->start += count; -+ if (buffer->size < ram_console_buffer_size) -+ buffer->size += count; -+ ram_console_update_header(); -+} -+ -+static struct console ram_console = { -+ .name = "ram", -+ .write = ram_console_write, -+ .flags = CON_PRINTBUFFER | CON_ENABLED, -+ .index = -1, -+}; -+ -+static void __init -+ram_console_save_old(struct ram_console_buffer *buffer, char *dest) -+{ -+ size_t old_log_size = buffer->size; -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ uint8_t *block; -+ uint8_t *par; -+ char strbuf[80]; -+ int strbuf_len; -+ -+ block = buffer->data; -+ par = ram_console_par_buffer; -+ while (block < buffer->data + buffer->size) { -+ int numerr; -+ int size = ECC_BLOCK_SIZE; -+ if (block + size > buffer->data + ram_console_buffer_size) -+ size = buffer->data + ram_console_buffer_size - block; -+ numerr = ram_console_decode_rs8(block, size, par); -+ if (numerr > 0) { -+#if 0 -+ printk(KERN_INFO "ram_console: error in block %p, %d\n", -+ block, numerr); -+#endif -+ ram_console_corrected_bytes += numerr; -+ } else if (numerr < 0) { -+#if 0 -+ printk(KERN_INFO "ram_console: uncorrectable error in " -+ "block %p\n", block); -+#endif -+ ram_console_bad_blocks++; -+ } -+ block += ECC_BLOCK_SIZE; -+ par += ECC_SIZE; -+ } -+ if (ram_console_corrected_bytes || ram_console_bad_blocks) -+ strbuf_len = snprintf(strbuf, sizeof(strbuf), -+ "\n%d Corrected bytes, %d unrecoverable blocks\n", -+ ram_console_corrected_bytes, ram_console_bad_blocks); -+ else -+ strbuf_len = snprintf(strbuf, sizeof(strbuf), -+ "\nNo errors detected\n"); -+ if (strbuf_len >= sizeof(strbuf)) -+ strbuf_len = sizeof(strbuf) - 1; -+ old_log_size += strbuf_len; -+#endif -+ -+ if (dest == NULL) { -+ dest = kmalloc(old_log_size, GFP_KERNEL); -+ if (dest == NULL) { -+ printk(KERN_ERR -+ "ram_console: failed to allocate buffer\n"); -+ return; -+ } -+ } -+ -+ ram_console_old_log = dest; -+ ram_console_old_log_size = old_log_size; -+ memcpy(ram_console_old_log, -+ &buffer->data[buffer->start], buffer->size - buffer->start); -+ memcpy(ram_console_old_log + buffer->size - buffer->start, -+ &buffer->data[0], buffer->start); -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ memcpy(ram_console_old_log + old_log_size - strbuf_len, -+ strbuf, strbuf_len); -+#endif -+} -+ -+static int __init ram_console_init(struct ram_console_buffer *buffer, -+ size_t buffer_size, char *old_buf) -+{ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ int numerr; -+ uint8_t *par; -+#endif -+ ram_console_buffer = buffer; -+ ram_console_buffer_size = -+ buffer_size - sizeof(struct ram_console_buffer); -+ -+ if (ram_console_buffer_size > buffer_size) { -+ pr_err("ram_console: buffer %p, invalid size %zu, " -+ "datasize %zu\n", buffer, buffer_size, -+ ram_console_buffer_size); -+ return 0; -+ } -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -+ ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size, -+ ECC_BLOCK_SIZE) + 1) * ECC_SIZE; -+ -+ if (ram_console_buffer_size > buffer_size) { -+ pr_err("ram_console: buffer %p, invalid size %zu, " -+ "non-ecc datasize %zu\n", -+ buffer, buffer_size, ram_console_buffer_size); -+ return 0; -+ } -+ -+ ram_console_par_buffer = buffer->data + ram_console_buffer_size; -+ -+ -+ /* first consecutive root is 0 -+ * primitive element to generate roots = 1 -+ */ -+ ram_console_rs_decoder = init_rs(ECC_SYMSIZE, ECC_POLY, 0, 1, ECC_SIZE); -+ if (ram_console_rs_decoder == NULL) { -+ printk(KERN_INFO "ram_console: init_rs failed\n"); -+ return 0; -+ } -+ -+ ram_console_corrected_bytes = 0; -+ ram_console_bad_blocks = 0; -+ -+ par = ram_console_par_buffer + -+ DIV_ROUND_UP(ram_console_buffer_size, ECC_BLOCK_SIZE) * ECC_SIZE; -+ -+ numerr = ram_console_decode_rs8(buffer, sizeof(*buffer), par); -+ if (numerr > 0) { -+ printk(KERN_INFO "ram_console: error in header, %d\n", numerr); -+ ram_console_corrected_bytes += numerr; -+ } else if (numerr < 0) { -+ printk(KERN_INFO -+ "ram_console: uncorrectable error in header\n"); -+ ram_console_bad_blocks++; -+ } -+#endif -+ -+ if (buffer->sig == RAM_CONSOLE_SIG) { -+ if (buffer->size > ram_console_buffer_size -+ || buffer->start > buffer->size) -+ printk(KERN_INFO "ram_console: found existing invalid " -+ "buffer, size %d, start %d\n", -+ buffer->size, buffer->start); -+ else { -+ printk(KERN_INFO "ram_console: found existing buffer, " -+ "size %d, start %d\n", -+ buffer->size, buffer->start); -+ ram_console_save_old(buffer, old_buf); -+ } -+ } else { -+ printk(KERN_INFO "ram_console: no valid data in buffer " -+ "(sig = 0x%08x)\n", buffer->sig); -+ } -+ -+ buffer->sig = RAM_CONSOLE_SIG; -+ buffer->start = 0; -+ buffer->size = 0; -+ -+ register_console(&ram_console); -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE -+ console_verbose(); -+#endif -+ return 0; -+} -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -+static int __init ram_console_early_init(void) -+{ -+ return ram_console_init((struct ram_console_buffer *) -+ CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR, -+ CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE, -+ ram_console_old_log_init_buffer); -+} -+#else -+static int ram_console_driver_probe(struct platform_device *pdev) -+{ -+ struct resource *res = pdev->resource; -+ size_t start; -+ size_t buffer_size; -+ void *buffer; -+ -+ if (res == NULL || pdev->num_resources != 1 || -+ !(res->flags & IORESOURCE_MEM)) { -+ printk(KERN_ERR "ram_console: invalid resource, %p %d flags " -+ "%lx\n", res, pdev->num_resources, res ? res->flags : 0); -+ return -ENXIO; -+ } -+ buffer_size = res->end - res->start + 1; -+ start = res->start; -+ printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n", -+ start, buffer_size); -+ buffer = ioremap(res->start, buffer_size); -+ if (buffer == NULL) { -+ printk(KERN_ERR "ram_console: failed to map memory\n"); -+ return -ENOMEM; -+ } -+ -+ return ram_console_init(buffer, buffer_size, NULL/* allocate */); -+} -+ -+static struct platform_driver ram_console_driver = { -+ .probe = ram_console_driver_probe, -+ .driver = { -+ .name = "ram_console", -+ }, -+}; -+ -+static int __init ram_console_module_init(void) -+{ -+ int err; -+ err = platform_driver_register(&ram_console_driver); -+ return err; -+} -+#endif -+ -+static ssize_t ram_console_read_old(struct file *file, char __user *buf, -+ size_t len, loff_t *offset) -+{ -+ loff_t pos = *offset; -+ ssize_t count; -+ -+ if (pos >= ram_console_old_log_size) -+ return 0; -+ -+ count = min(len, (size_t)(ram_console_old_log_size - pos)); -+ if (copy_to_user(buf, ram_console_old_log + pos, count)) -+ return -EFAULT; -+ -+ *offset += count; -+ return count; -+} -+ -+static const struct file_operations ram_console_file_ops = { -+ .owner = THIS_MODULE, -+ .read = ram_console_read_old, -+}; -+ -+static int __init ram_console_late_init(void) -+{ -+ struct proc_dir_entry *entry; -+ -+ if (ram_console_old_log == NULL) -+ return 0; -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -+ ram_console_old_log = kmalloc(ram_console_old_log_size, GFP_KERNEL); -+ if (ram_console_old_log == NULL) { -+ printk(KERN_ERR -+ "ram_console: failed to allocate buffer for old log\n"); -+ ram_console_old_log_size = 0; -+ return 0; -+ } -+ memcpy(ram_console_old_log, -+ ram_console_old_log_init_buffer, ram_console_old_log_size); -+#endif -+ entry = create_proc_entry("last_kmsg", S_IFREG | S_IRUGO, NULL); -+ if (!entry) { -+ printk(KERN_ERR "ram_console: failed to create proc entry\n"); -+ kfree(ram_console_old_log); -+ ram_console_old_log = NULL; -+ return 0; -+ } -+ -+ entry->proc_fops = &ram_console_file_ops; -+ entry->size = ram_console_old_log_size; -+ return 0; -+} -+ -+#ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT -+console_initcall(ram_console_early_init); -+#else -+module_init(ram_console_module_init); -+#endif -+late_initcall(ram_console_late_init); -+ -diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c -new file mode 100644 -index 0000000..be7cdaa ---- /dev/null -+++ b/drivers/staging/android/timed_gpio.c -@@ -0,0 +1,166 @@ -+/* drivers/misc/timed_gpio.c -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "timed_output.h" -+#include "timed_gpio.h" -+ -+ -+struct timed_gpio_data { -+ struct timed_output_dev dev; -+ struct hrtimer timer; -+ spinlock_t lock; -+ unsigned gpio; -+ int max_timeout; -+ u8 active_low; -+}; -+ -+static enum hrtimer_restart gpio_timer_func(struct hrtimer *timer) -+{ -+ struct timed_gpio_data *data = -+ container_of(timer, struct timed_gpio_data, timer); -+ -+ gpio_direction_output(data->gpio, data->active_low ? 1 : 0); -+ return HRTIMER_NORESTART; -+} -+ -+static int gpio_get_time(struct timed_output_dev *dev) -+{ -+ struct timed_gpio_data *data = -+ container_of(dev, struct timed_gpio_data, dev); -+ -+ if (hrtimer_active(&data->timer)) { -+ ktime_t r = hrtimer_get_remaining(&data->timer); -+ struct timeval t = ktime_to_timeval(r); -+ return t.tv_sec * 1000 + t.tv_usec / 1000; -+ } else -+ return 0; -+} -+ -+static void gpio_enable(struct timed_output_dev *dev, int value) -+{ -+ struct timed_gpio_data *data = -+ container_of(dev, struct timed_gpio_data, dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&data->lock, flags); -+ -+ /* cancel previous timer and set GPIO according to value */ -+ hrtimer_cancel(&data->timer); -+ gpio_direction_output(data->gpio, data->active_low ? !value : !!value); -+ -+ if (value > 0) { -+ if (value > data->max_timeout) -+ value = data->max_timeout; -+ -+ hrtimer_start(&data->timer, -+ ktime_set(value / 1000, (value % 1000) * 1000000), -+ HRTIMER_MODE_REL); -+ } -+ -+ spin_unlock_irqrestore(&data->lock, flags); -+} -+ -+static int timed_gpio_probe(struct platform_device *pdev) -+{ -+ struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; -+ struct timed_gpio *cur_gpio; -+ struct timed_gpio_data *gpio_data, *gpio_dat; -+ int i, j, ret = 0; -+ -+ if (!pdata) -+ return -EBUSY; -+ -+ gpio_data = kzalloc(sizeof(struct timed_gpio_data) * pdata->num_gpios, -+ GFP_KERNEL); -+ if (!gpio_data) -+ return -ENOMEM; -+ -+ for (i = 0; i < pdata->num_gpios; i++) { -+ cur_gpio = &pdata->gpios[i]; -+ gpio_dat = &gpio_data[i]; -+ -+ hrtimer_init(&gpio_dat->timer, CLOCK_MONOTONIC, -+ HRTIMER_MODE_REL); -+ gpio_dat->timer.function = gpio_timer_func; -+ spin_lock_init(&gpio_dat->lock); -+ -+ gpio_dat->dev.name = cur_gpio->name; -+ gpio_dat->dev.get_time = gpio_get_time; -+ gpio_dat->dev.enable = gpio_enable; -+ ret = timed_output_dev_register(&gpio_dat->dev); -+ if (ret < 0) { -+ for (j = 0; j < i; j++) -+ timed_output_dev_unregister(&gpio_data[i].dev); -+ kfree(gpio_data); -+ return ret; -+ } -+ -+ gpio_dat->gpio = cur_gpio->gpio; -+ gpio_dat->max_timeout = cur_gpio->max_timeout; -+ gpio_dat->active_low = cur_gpio->active_low; -+ gpio_direction_output(gpio_dat->gpio, gpio_dat->active_low); -+ } -+ -+ platform_set_drvdata(pdev, gpio_data); -+ -+ return 0; -+} -+ -+static int timed_gpio_remove(struct platform_device *pdev) -+{ -+ struct timed_gpio_platform_data *pdata = pdev->dev.platform_data; -+ struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); -+ int i; -+ -+ for (i = 0; i < pdata->num_gpios; i++) -+ timed_output_dev_unregister(&gpio_data[i].dev); -+ -+ kfree(gpio_data); -+ -+ return 0; -+} -+ -+static struct platform_driver timed_gpio_driver = { -+ .probe = timed_gpio_probe, -+ .remove = timed_gpio_remove, -+ .driver = { -+ .name = TIMED_GPIO_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init timed_gpio_init(void) -+{ -+ return platform_driver_register(&timed_gpio_driver); -+} -+ -+static void __exit timed_gpio_exit(void) -+{ -+ platform_driver_unregister(&timed_gpio_driver); -+} -+ -+module_init(timed_gpio_init); -+module_exit(timed_gpio_exit); -+ -+MODULE_AUTHOR("Mike Lockwood "); -+MODULE_DESCRIPTION("timed gpio driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/staging/android/timed_gpio.h b/drivers/staging/android/timed_gpio.h -new file mode 100644 -index 0000000..a0e15f8 ---- /dev/null -+++ b/drivers/staging/android/timed_gpio.h -@@ -0,0 +1,33 @@ -+/* include/linux/timed_gpio.h -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+*/ -+ -+#ifndef _LINUX_TIMED_GPIO_H -+#define _LINUX_TIMED_GPIO_H -+ -+#define TIMED_GPIO_NAME "timed-gpio" -+ -+struct timed_gpio { -+ const char *name; -+ unsigned gpio; -+ int max_timeout; -+ u8 active_low; -+}; -+ -+struct timed_gpio_platform_data { -+ int num_gpios; -+ struct timed_gpio *gpios; -+}; -+ -+#endif -diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c -new file mode 100644 -index 0000000..62e7918 ---- /dev/null -+++ b/drivers/staging/android/timed_output.c -@@ -0,0 +1,121 @@ -+/* drivers/misc/timed_output.c -+ * -+ * Copyright (C) 2009 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "timed_output.h" -+ -+static struct class *timed_output_class; -+static atomic_t device_count; -+ -+static ssize_t enable_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct timed_output_dev *tdev = dev_get_drvdata(dev); -+ int remaining = tdev->get_time(tdev); -+ -+ return sprintf(buf, "%d\n", remaining); -+} -+ -+static ssize_t enable_store( -+ struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t size) -+{ -+ struct timed_output_dev *tdev = dev_get_drvdata(dev); -+ int value; -+ -+ sscanf(buf, "%d", &value); -+ tdev->enable(tdev, value); -+ -+ return size; -+} -+ -+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, enable_show, enable_store); -+ -+static int create_timed_output_class(void) -+{ -+ if (!timed_output_class) { -+ timed_output_class = class_create(THIS_MODULE, "timed_output"); -+ if (IS_ERR(timed_output_class)) -+ return PTR_ERR(timed_output_class); -+ atomic_set(&device_count, 0); -+ } -+ -+ return 0; -+} -+ -+int timed_output_dev_register(struct timed_output_dev *tdev) -+{ -+ int ret; -+ -+ if (!tdev || !tdev->name || !tdev->enable || !tdev->get_time) -+ return -EINVAL; -+ -+ ret = create_timed_output_class(); -+ if (ret < 0) -+ return ret; -+ -+ tdev->index = atomic_inc_return(&device_count); -+ tdev->dev = device_create(timed_output_class, NULL, -+ MKDEV(0, tdev->index), NULL, tdev->name); -+ if (IS_ERR(tdev->dev)) -+ return PTR_ERR(tdev->dev); -+ -+ ret = device_create_file(tdev->dev, &dev_attr_enable); -+ if (ret < 0) -+ goto err_create_file; -+ -+ dev_set_drvdata(tdev->dev, tdev); -+ tdev->state = 0; -+ return 0; -+ -+err_create_file: -+ device_destroy(timed_output_class, MKDEV(0, tdev->index)); -+ printk(KERN_ERR "timed_output: Failed to register driver %s\n", -+ tdev->name); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(timed_output_dev_register); -+ -+void timed_output_dev_unregister(struct timed_output_dev *tdev) -+{ -+ device_remove_file(tdev->dev, &dev_attr_enable); -+ device_destroy(timed_output_class, MKDEV(0, tdev->index)); -+ dev_set_drvdata(tdev->dev, NULL); -+} -+EXPORT_SYMBOL_GPL(timed_output_dev_unregister); -+ -+static int __init timed_output_init(void) -+{ -+ return create_timed_output_class(); -+} -+ -+static void __exit timed_output_exit(void) -+{ -+ class_destroy(timed_output_class); -+} -+ -+module_init(timed_output_init); -+module_exit(timed_output_exit); -+ -+MODULE_AUTHOR("Mike Lockwood "); -+MODULE_DESCRIPTION("timed output class driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/staging/android/timed_output.h b/drivers/staging/android/timed_output.h -new file mode 100644 -index 0000000..ec907ab ---- /dev/null -+++ b/drivers/staging/android/timed_output.h -@@ -0,0 +1,37 @@ -+/* include/linux/timed_output.h -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+*/ -+ -+#ifndef _LINUX_TIMED_OUTPUT_H -+#define _LINUX_TIMED_OUTPUT_H -+ -+struct timed_output_dev { -+ const char *name; -+ -+ /* enable the output and set the timer */ -+ void (*enable)(struct timed_output_dev *sdev, int timeout); -+ -+ /* returns the current number of milliseconds remaining on the timer */ -+ int (*get_time)(struct timed_output_dev *sdev); -+ -+ /* private data */ -+ struct device *dev; -+ int index; -+ int state; -+}; -+ -+extern int timed_output_dev_register(struct timed_output_dev *dev); -+extern void timed_output_dev_unregister(struct timed_output_dev *dev); -+ -+#endif diff --git a/patches.android/android-0002-staging-android-fix-build-issues.patch b/patches.android/android-0002-staging-android-fix-build-issues.patch deleted file mode 100644 index 7761ae26d5c3..000000000000 --- a/patches.android/android-0002-staging-android-fix-build-issues.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 23687af9317c9c01d4609667d3566af7f5e71e65 Mon Sep 17 00:00:00 2001 -From: Corentin Chary -Date: Sat, 28 Nov 2009 09:45:14 +0100 -Subject: staging/android: fix build issues -Patch-mainline: HEAD -Git-commit: 23687af9317c9c01d4609667d3566af7f5e71e65 - -Signed-off-by: Corentin Chary -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -index 6c10b45..64cc2a1 100644 ---- a/drivers/staging/android/logger.c -+++ b/drivers/staging/android/logger.c -@@ -17,6 +17,7 @@ - * GNU General Public License for more details. - */ - -+#include - #include - #include - #include -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 935d281..32314e8 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -100,15 +100,17 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - read_lock(&tasklist_lock); - for_each_process(p) { - struct mm_struct *mm; -+ struct signal_struct *sig; - int oom_adj; - - task_lock(p); - mm = p->mm; -- if (!mm) { -+ sig = p->signal; -+ if (!mm || !sig) { - task_unlock(p); - continue; - } -- oom_adj = mm->oom_adj; -+ oom_adj = sig->oom_adj; - if (oom_adj < min_adj) { - task_unlock(p); - continue; diff --git a/patches.android/android-0003-android-common-include-linux-slab.h.patch b/patches.android/android-0003-android-common-include-linux-slab.h.patch deleted file mode 100644 index b31913061f90..000000000000 --- a/patches.android/android-0003-android-common-include-linux-slab.h.patch +++ /dev/null @@ -1,21 +0,0 @@ -From c1b197ae67a201e404df9084cfd544eb8cb2e8a6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Tue, 20 Apr 2010 22:33:05 -0700 -Subject: android-common: include linux/slab.h -Patch-mainline: HEAD -Git-commit: c1b197ae67a201e404df9084cfd544eb8cb2e8a6 - -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c -index be7cdaa..3bfe6e0 100644 ---- a/drivers/staging/android/timed_gpio.c -+++ b/drivers/staging/android/timed_gpio.c -@@ -16,6 +16,7 @@ - - #include - #include -+#include - #include - #include - #include diff --git a/patches.android/android-0004-android-common-Fix-slab.h-includes-for-2.6.34-rc4.patch b/patches.android/android-0004-android-common-Fix-slab.h-includes-for-2.6.34-rc4.patch deleted file mode 100644 index bad9b9bb105a..000000000000 --- a/patches.android/android-0004-android-common-Fix-slab.h-includes-for-2.6.34-rc4.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c11a166cd4c19664355e0e3d9c04cfa7ee4aa9f4 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Thu, 15 Apr 2010 15:21:51 -0700 -Subject: android-common: Fix slab.h includes for 2.6.34-rc4 -Patch-mainline: HEAD -Git-commit: c11a166cd4c19664355e0e3d9c04cfa7ee4aa9f4 - -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 99010d4..3aec4530 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #include "binder.h" - -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -index 64cc2a1..dd76564 100644 ---- a/drivers/staging/android/logger.c -+++ b/drivers/staging/android/logger.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include "logger.h" - diff --git a/patches.android/android-0005-Revert-Staging-android-mark-subsystem-as-broken.patch b/patches.android/android-0005-Revert-Staging-android-mark-subsystem-as-broken.patch deleted file mode 100644 index 5fe607e7aee5..000000000000 --- a/patches.android/android-0005-Revert-Staging-android-mark-subsystem-as-broken.patch +++ /dev/null @@ -1,30 +0,0 @@ -From e59bbb8ea3fb5794c09e48490a74b673aee4adc2 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 30 Nov 2011 20:32:24 +0900 -Subject: Revert "Staging: android: mark subsystem as broken" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: e59bbb8ea3fb5794c09e48490a74b673aee4adc2 - -This reverts commit 2cdf99ce2b9418c9d7c5f907195cfac421375520. - -It now builds, so this can be reverted. - -Cc: Arve HjønnevÃ¥g -Cc: Brian Swetland -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index eb67563..2471949 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -2,7 +2,6 @@ menu "Android" - - config ANDROID - bool "Android Drivers" -- depends on BROKEN - default N - ---help--- - Enable support for various drivers needed on the Android platform diff --git a/patches.android/android-0006-staging-android-ramconsole-Ensure-ramconsole-does-not-get-cl.patch b/patches.android/android-0006-staging-android-ramconsole-Ensure-ramconsole-does-not-get-cl.patch deleted file mode 100644 index 5583d85cd999..000000000000 --- a/patches.android/android-0006-staging-android-ramconsole-Ensure-ramconsole-does-not-get-cl.patch +++ /dev/null @@ -1,35 +0,0 @@ -From fdfc8089429b58b4ac901926fe83fa85b0b7bfc1 Mon Sep 17 00:00:00 2001 -From: San Mehat -Date: Thu, 17 Sep 2009 14:27:41 -0700 -Subject: staging: android: ramconsole: Ensure ramconsole does not get - cluttered by apanic threads -Patch-mainline: HEAD -Git-commit: fdfc8089429b58b4ac901926fe83fa85b0b7bfc1 - -[Note, this is part of a patch from Sam, just the drivers/staging/ -portion, that adds a function that the apanic code calls, but the apanic -code isn't here, so just include part of this to make merges and diffs -easier and this keeps things self-contained - gregkh] - -Signed-off-by: San Mehat -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c -index 8f18a59..d735be4 100644 ---- a/drivers/staging/android/ram_console.c -+++ b/drivers/staging/android/ram_console.c -@@ -146,6 +146,14 @@ static struct console ram_console = { - .index = -1, - }; - -+void ram_console_enable_console(int enabled) -+{ -+ if (enabled) -+ ram_console.flags |= CON_ENABLED; -+ else -+ ram_console.flags &= ~CON_ENABLED; -+} -+ - static void __init - ram_console_save_old(struct ram_console_buffer *buffer, char *dest) - { diff --git a/patches.android/android-0007-Staging-android-ram_console-Start-ram-console-earlier.patch b/patches.android/android-0007-Staging-android-ram_console-Start-ram-console-earlier.patch deleted file mode 100644 index 196de3821f3f..000000000000 --- a/patches.android/android-0007-Staging-android-ram_console-Start-ram-console-earlier.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 81057ec1ded5ddf15149c3b266f414c0fbde5530 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Thu, 17 Dec 2009 23:42:08 -0800 -Subject: Staging: android: ram_console: Start ram console earlier -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 81057ec1ded5ddf15149c3b266f414c0fbde5530 - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c -index d735be4..53f736b 100644 ---- a/drivers/staging/android/ram_console.c -+++ b/drivers/staging/android/ram_console.c -@@ -412,7 +412,7 @@ static int __init ram_console_late_init(void) - #ifdef CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT - console_initcall(ram_console_early_init); - #else --module_init(ram_console_module_init); -+postcore_initcall(ram_console_module_init); - #endif - late_initcall(ram_console_late_init); - diff --git a/patches.android/android-0008-Staging-android-timed_gpio-Request-gpios.patch b/patches.android/android-0008-Staging-android-timed_gpio-Request-gpios.patch deleted file mode 100644 index 2ef7c1f6ee10..000000000000 --- a/patches.android/android-0008-Staging-android-timed_gpio-Request-gpios.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0445f1548fc66a72f3b91cdbe8f26b120245efd1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Wed, 6 Jan 2010 17:17:33 -0800 -Subject: Staging: android: timed_gpio: Request gpios. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 0445f1548fc66a72f3b91cdbe8f26b120245efd1 - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c -index 3bfe6e0..a64481c 100644 ---- a/drivers/staging/android/timed_gpio.c -+++ b/drivers/staging/android/timed_gpio.c -@@ -107,10 +107,17 @@ static int timed_gpio_probe(struct platform_device *pdev) - gpio_dat->dev.name = cur_gpio->name; - gpio_dat->dev.get_time = gpio_get_time; - gpio_dat->dev.enable = gpio_enable; -- ret = timed_output_dev_register(&gpio_dat->dev); -+ ret = gpio_request(cur_gpio->gpio, cur_gpio->name); -+ if (ret >= 0) { -+ ret = timed_output_dev_register(&gpio_dat->dev); -+ if (ret < 0) -+ gpio_free(cur_gpio->gpio); -+ } - if (ret < 0) { -- for (j = 0; j < i; j++) -+ for (j = 0; j < i; j++) { - timed_output_dev_unregister(&gpio_data[i].dev); -+ gpio_free(gpio_data[i].gpio); -+ } - kfree(gpio_data); - return ret; - } -@@ -132,8 +139,10 @@ static int timed_gpio_remove(struct platform_device *pdev) - struct timed_gpio_data *gpio_data = platform_get_drvdata(pdev); - int i; - -- for (i = 0; i < pdata->num_gpios; i++) -+ for (i = 0; i < pdata->num_gpios; i++) { - timed_output_dev_unregister(&gpio_data[i].dev); -+ gpio_free(gpio_data[i].gpio); -+ } - - kfree(gpio_data); - diff --git a/patches.android/android-0009-android-logger-Add-new-system-log-for-framework-system-log-m.patch b/patches.android/android-0009-android-logger-Add-new-system-log-for-framework-system-log-m.patch deleted file mode 100644 index c4e4cf3f4c22..000000000000 --- a/patches.android/android-0009-android-logger-Add-new-system-log-for-framework-system-log-m.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 3537cdaa16205d2af7e1195276c786f22bada574 Mon Sep 17 00:00:00 2001 -From: San Mehat -Date: Tue, 23 Feb 2010 16:09:47 -0800 -Subject: android: logger: Add new system log for framework/system log - messages -Patch-mainline: HEAD -Git-commit: 3537cdaa16205d2af7e1195276c786f22bada574 - -Signed-off-by: San Mehat -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -index dd76564..531bdbe 100644 ---- a/drivers/staging/android/logger.c -+++ b/drivers/staging/android/logger.c -@@ -558,6 +558,7 @@ static struct logger_log VAR = { \ - DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024) - DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) - DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024) -+DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024) - - static struct logger_log *get_log_from_minor(int minor) - { -@@ -567,6 +568,8 @@ static struct logger_log *get_log_from_minor(int minor) - return &log_events; - if (log_radio.misc.minor == minor) - return &log_radio; -+ if (log_system.misc.minor == minor) -+ return &log_system; - return NULL; - } - -@@ -603,6 +606,10 @@ static int __init logger_init(void) - if (unlikely(ret)) - goto out; - -+ ret = init_log(&log_system); -+ if (unlikely(ret)) -+ goto out; -+ - out: - return ret; - } -diff --git a/drivers/staging/android/logger.h b/drivers/staging/android/logger.h -index a562434..2cb06e9 100644 ---- a/drivers/staging/android/logger.h -+++ b/drivers/staging/android/logger.h -@@ -32,6 +32,7 @@ struct logger_entry { - - #define LOGGER_LOG_RADIO "log_radio" /* radio-related messages */ - #define LOGGER_LOG_EVENTS "log_events" /* system/hardware events */ -+#define LOGGER_LOG_SYSTEM "log_system" /* system/framework messages */ - #define LOGGER_LOG_MAIN "log_main" /* everything else */ - - #define LOGGER_ENTRY_MAX_LEN (4*1024) diff --git a/patches.android/android-0010-binder-Use-seq_file-for-debug-interface.patch b/patches.android/android-0010-binder-Use-seq_file-for-debug-interface.patch deleted file mode 100644 index a05bb2ceaa54..000000000000 --- a/patches.android/android-0010-binder-Use-seq_file-for-debug-interface.patch +++ /dev/null @@ -1,835 +0,0 @@ -From 5249f4883045de494916db7b1a6d6e1e422e9a0b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Tue, 28 Apr 2009 20:57:50 -0700 -Subject: binder: Use seq_file for debug interface. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 5249f4883045de494916db7b1a6d6e1e422e9a0b - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 3aec4530..371232b 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -48,8 +49,22 @@ static struct binder_node *binder_context_mgr_node; - static uid_t binder_context_mgr_uid = -1; - static int binder_last_id; - --static int binder_read_proc_proc(char *page, char **start, off_t off, -- int count, int *eof, void *data); -+#define BINDER_DEBUG_ENTRY(name) \ -+static int binder_##name##_open(struct inode *inode, struct file *file) \ -+{ \ -+ return single_open(file, binder_##name##_show, PDE(inode)->data); \ -+} \ -+\ -+static const struct file_operations binder_##name##_fops = { \ -+ .owner = THIS_MODULE, \ -+ .open = binder_##name##_open, \ -+ .read = seq_read, \ -+ .llseek = seq_lseek, \ -+ .release = single_release, \ -+} -+ -+static int binder_proc_show(struct seq_file *m, void *unused); -+BINDER_DEBUG_ENTRY(proc); - - /* This is only defined in include/asm-arm/sizes.h */ - #ifndef SZ_1K -@@ -2880,9 +2895,9 @@ static int binder_open(struct inode *nodp, struct file *filp) - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); - remove_proc_entry(strbuf, binder_proc_dir_entry_proc); -- create_proc_read_entry(strbuf, S_IRUGO, -- binder_proc_dir_entry_proc, -- binder_read_proc_proc, proc); -+ proc_create_data(strbuf, S_IRUGO, -+ binder_proc_dir_entry_proc, -+ &binder_proc_fops, proc); - } - - return 0; -@@ -3105,49 +3120,41 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) - mutex_unlock(&binder_deferred_lock); - } - --static char *print_binder_transaction(char *buf, char *end, const char *prefix, -- struct binder_transaction *t) --{ -- buf += snprintf(buf, end - buf, -- "%s %d: %p from %d:%d to %d:%d code %x " -- "flags %x pri %ld r%d", -- prefix, t->debug_id, t, -- t->from ? t->from->proc->pid : 0, -- t->from ? t->from->pid : 0, -- t->to_proc ? t->to_proc->pid : 0, -- t->to_thread ? t->to_thread->pid : 0, -- t->code, t->flags, t->priority, t->need_reply); -- if (buf >= end) -- return buf; -+static void print_binder_transaction(struct seq_file *m, const char *prefix, -+ struct binder_transaction *t) -+{ -+ seq_printf(m, -+ "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d", -+ prefix, t->debug_id, t, -+ t->from ? t->from->proc->pid : 0, -+ t->from ? t->from->pid : 0, -+ t->to_proc ? t->to_proc->pid : 0, -+ t->to_thread ? t->to_thread->pid : 0, -+ t->code, t->flags, t->priority, t->need_reply); - if (t->buffer == NULL) { -- buf += snprintf(buf, end - buf, " buffer free\n"); -- return buf; -- } -- if (t->buffer->target_node) { -- buf += snprintf(buf, end - buf, " node %d", -- t->buffer->target_node->debug_id); -- if (buf >= end) -- return buf; -+ seq_puts(m, " buffer free\n"); -+ return; - } -- buf += snprintf(buf, end - buf, " size %zd:%zd data %p\n", -- t->buffer->data_size, t->buffer->offsets_size, -- t->buffer->data); -- return buf; -+ if (t->buffer->target_node) -+ seq_printf(m, " node %d", -+ t->buffer->target_node->debug_id); -+ seq_printf(m, " size %zd:%zd data %p\n", -+ t->buffer->data_size, t->buffer->offsets_size, -+ t->buffer->data); - } - --static char *print_binder_buffer(char *buf, char *end, const char *prefix, -- struct binder_buffer *buffer) -+static void print_binder_buffer(struct seq_file *m, const char *prefix, -+ struct binder_buffer *buffer) - { -- buf += snprintf(buf, end - buf, "%s %d: %p size %zd:%zd %s\n", -- prefix, buffer->debug_id, buffer->data, -- buffer->data_size, buffer->offsets_size, -- buffer->transaction ? "active" : "delivered"); -- return buf; -+ seq_printf(m, "%s %d: %p size %zd:%zd %s\n", -+ prefix, buffer->debug_id, buffer->data, -+ buffer->data_size, buffer->offsets_size, -+ buffer->transaction ? "active" : "delivered"); - } - --static char *print_binder_work(char *buf, char *end, const char *prefix, -- const char *transaction_prefix, -- struct binder_work *w) -+static void print_binder_work(struct seq_file *m, const char *prefix, -+ const char *transaction_prefix, -+ struct binder_work *w) - { - struct binder_node *node; - struct binder_transaction *t; -@@ -3155,79 +3162,65 @@ static char *print_binder_work(char *buf, char *end, const char *prefix, - switch (w->type) { - case BINDER_WORK_TRANSACTION: - t = container_of(w, struct binder_transaction, work); -- buf = print_binder_transaction(buf, end, transaction_prefix, t); -+ print_binder_transaction(m, transaction_prefix, t); - break; - case BINDER_WORK_TRANSACTION_COMPLETE: -- buf += snprintf(buf, end - buf, -- "%stransaction complete\n", prefix); -+ seq_printf(m, "%stransaction complete\n", prefix); - break; - case BINDER_WORK_NODE: - node = container_of(w, struct binder_node, work); -- buf += snprintf(buf, end - buf, "%snode work %d: u%p c%p\n", -- prefix, node->debug_id, node->ptr, -- node->cookie); -+ seq_printf(m, "%snode work %d: u%p c%p\n", -+ prefix, node->debug_id, node->ptr, node->cookie); - break; - case BINDER_WORK_DEAD_BINDER: -- buf += snprintf(buf, end - buf, "%shas dead binder\n", prefix); -+ seq_printf(m, "%shas dead binder\n", prefix); - break; - case BINDER_WORK_DEAD_BINDER_AND_CLEAR: -- buf += snprintf(buf, end - buf, -- "%shas cleared dead binder\n", prefix); -+ seq_printf(m, "%shas cleared dead binder\n", prefix); - break; - case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: -- buf += snprintf(buf, end - buf, -- "%shas cleared death notification\n", prefix); -+ seq_printf(m, "%shas cleared death notification\n", prefix); - break; - default: -- buf += snprintf(buf, end - buf, "%sunknown work: type %d\n", -- prefix, w->type); -+ seq_printf(m, "%sunknown work: type %d\n", prefix, w->type); - break; - } -- return buf; - } - --static char *print_binder_thread(char *buf, char *end, -- struct binder_thread *thread, -- int print_always) -+static void print_binder_thread(struct seq_file *m, -+ struct binder_thread *thread, -+ int print_always) - { - struct binder_transaction *t; - struct binder_work *w; -- char *start_buf = buf; -- char *header_buf; -+ size_t start_pos = m->count; -+ size_t header_pos; - -- buf += snprintf(buf, end - buf, " thread %d: l %02x\n", -- thread->pid, thread->looper); -- header_buf = buf; -+ seq_printf(m, " thread %d: l %02x\n", thread->pid, thread->looper); -+ header_pos = m->count; - t = thread->transaction_stack; - while (t) { -- if (buf >= end) -- break; - if (t->from == thread) { -- buf = print_binder_transaction(buf, end, -- " outgoing transaction", t); -+ print_binder_transaction(m, -+ " outgoing transaction", t); - t = t->from_parent; - } else if (t->to_thread == thread) { -- buf = print_binder_transaction(buf, end, -- " incoming transaction", t); -+ print_binder_transaction(m, -+ " incoming transaction", t); - t = t->to_parent; - } else { -- buf = print_binder_transaction(buf, end, -- " bad transaction", t); -+ print_binder_transaction(m, " bad transaction", t); - t = NULL; - } - } - list_for_each_entry(w, &thread->todo, entry) { -- if (buf >= end) -- break; -- buf = print_binder_work(buf, end, " ", -- " pending transaction", w); -+ print_binder_work(m, " ", " pending transaction", w); - } -- if (!print_always && buf == header_buf) -- buf = start_buf; -- return buf; -+ if (!print_always && m->count == header_pos) -+ m->count = start_pos; - } - --static char *print_binder_node(char *buf, char *end, struct binder_node *node) -+static void print_binder_node(struct seq_file *m, struct binder_node *node) - { - struct binder_ref *ref; - struct hlist_node *pos; -@@ -3238,100 +3231,67 @@ static char *print_binder_node(char *buf, char *end, struct binder_node *node) - hlist_for_each_entry(ref, pos, &node->refs, node_entry) - count++; - -- buf += snprintf(buf, end - buf, -- " node %d: u%p c%p hs %d hw %d ls %d lw %d " -- "is %d iw %d", -- node->debug_id, node->ptr, node->cookie, -- node->has_strong_ref, node->has_weak_ref, -- node->local_strong_refs, node->local_weak_refs, -- node->internal_strong_refs, count); -- if (buf >= end) -- return buf; -+ seq_printf(m, " node %d: u%p c%p hs %d hw %d ls %d lw %d is %d iw %d", -+ node->debug_id, node->ptr, node->cookie, -+ node->has_strong_ref, node->has_weak_ref, -+ node->local_strong_refs, node->local_weak_refs, -+ node->internal_strong_refs, count); - if (count) { -- buf += snprintf(buf, end - buf, " proc"); -- if (buf >= end) -- return buf; -- hlist_for_each_entry(ref, pos, &node->refs, node_entry) { -- buf += snprintf(buf, end - buf, " %d", ref->proc->pid); -- if (buf >= end) -- return buf; -- } -+ seq_puts(m, " proc"); -+ hlist_for_each_entry(ref, pos, &node->refs, node_entry) -+ seq_printf(m, " %d", ref->proc->pid); - } -- buf += snprintf(buf, end - buf, "\n"); -- list_for_each_entry(w, &node->async_todo, entry) { -- if (buf >= end) -- break; -- buf = print_binder_work(buf, end, " ", -- " pending async transaction", w); -- } -- return buf; -+ seq_puts(m, "\n"); -+ list_for_each_entry(w, &node->async_todo, entry) -+ print_binder_work(m, " ", -+ " pending async transaction", w); - } - --static char *print_binder_ref(char *buf, char *end, struct binder_ref *ref) -+static void print_binder_ref(struct seq_file *m, struct binder_ref *ref) - { -- buf += snprintf(buf, end - buf, -- " ref %d: desc %d %snode %d s %d w %d d %p\n", -- ref->debug_id, ref->desc, -- ref->node->proc ? "" : "dead ", ref->node->debug_id, -- ref->strong, ref->weak, ref->death); -- return buf; -+ seq_printf(m, " ref %d: desc %d %snode %d s %d w %d d %p\n", -+ ref->debug_id, ref->desc, ref->node->proc ? "" : "dead ", -+ ref->node->debug_id, ref->strong, ref->weak, ref->death); - } - --static char *print_binder_proc(char *buf, char *end, -- struct binder_proc *proc, int print_all) -+static void print_binder_proc(struct seq_file *m, -+ struct binder_proc *proc, int print_all) - { - struct binder_work *w; - struct rb_node *n; -- char *start_buf = buf; -- char *header_buf; -- -- buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); -- header_buf = buf; -- -- for (n = rb_first(&proc->threads); -- n != NULL && buf < end; -- n = rb_next(n)) -- buf = print_binder_thread(buf, end, -- rb_entry(n, struct binder_thread, -- rb_node), print_all); -- for (n = rb_first(&proc->nodes); -- n != NULL && buf < end; -- n = rb_next(n)) { -+ size_t start_pos = m->count; -+ size_t header_pos; -+ -+ seq_printf(m, "proc %d\n", proc->pid); -+ header_pos = m->count; -+ -+ for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) -+ print_binder_thread(m, rb_entry(n, struct binder_thread, -+ rb_node), print_all); -+ for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) { - struct binder_node *node = rb_entry(n, struct binder_node, - rb_node); - if (print_all || node->has_async_transaction) -- buf = print_binder_node(buf, end, node); -+ print_binder_node(m, node); - } - if (print_all) { - for (n = rb_first(&proc->refs_by_desc); -- n != NULL && buf < end; -+ n != NULL; - n = rb_next(n)) -- buf = print_binder_ref(buf, end, -- rb_entry(n, struct binder_ref, -- rb_node_desc)); -- } -- for (n = rb_first(&proc->allocated_buffers); -- n != NULL && buf < end; -- n = rb_next(n)) -- buf = print_binder_buffer(buf, end, " buffer", -- rb_entry(n, struct binder_buffer, -- rb_node)); -- list_for_each_entry(w, &proc->todo, entry) { -- if (buf >= end) -- break; -- buf = print_binder_work(buf, end, " ", -- " pending transaction", w); -+ print_binder_ref(m, rb_entry(n, struct binder_ref, -+ rb_node_desc)); - } -+ for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) -+ print_binder_buffer(m, " buffer", -+ rb_entry(n, struct binder_buffer, rb_node)); -+ list_for_each_entry(w, &proc->todo, entry) -+ print_binder_work(m, " ", " pending transaction", w); - list_for_each_entry(w, &proc->delivered_death, entry) { -- if (buf >= end) -- break; -- buf += snprintf(buf, end - buf, -- " has delivered dead binder\n"); -+ seq_puts(m, " has delivered dead binder\n"); - break; - } -- if (!print_all && buf == header_buf) -- buf = start_buf; -- return buf; -+ if (!print_all && m->count == header_pos) -+ m->count = start_pos; - } - - static const char *binder_return_strings[] = { -@@ -3385,79 +3345,61 @@ static const char *binder_objstat_strings[] = { - "transaction_complete" - }; - --static char *print_binder_stats(char *buf, char *end, const char *prefix, -- struct binder_stats *stats) -+static void print_binder_stats(struct seq_file *m, const char *prefix, -+ struct binder_stats *stats) - { - int i; - - BUILD_BUG_ON(ARRAY_SIZE(stats->bc) != -- ARRAY_SIZE(binder_command_strings)); -+ ARRAY_SIZE(binder_command_strings)); - for (i = 0; i < ARRAY_SIZE(stats->bc); i++) { - if (stats->bc[i]) -- buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, -- binder_command_strings[i], -- stats->bc[i]); -- if (buf >= end) -- return buf; -+ seq_printf(m, "%s%s: %d\n", prefix, -+ binder_command_strings[i], stats->bc[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->br) != -- ARRAY_SIZE(binder_return_strings)); -+ ARRAY_SIZE(binder_return_strings)); - for (i = 0; i < ARRAY_SIZE(stats->br); i++) { - if (stats->br[i]) -- buf += snprintf(buf, end - buf, "%s%s: %d\n", prefix, -- binder_return_strings[i], stats->br[i]); -- if (buf >= end) -- return buf; -+ seq_printf(m, "%s%s: %d\n", prefix, -+ binder_return_strings[i], stats->br[i]); - } - - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != -- ARRAY_SIZE(binder_objstat_strings)); -+ ARRAY_SIZE(binder_objstat_strings)); - BUILD_BUG_ON(ARRAY_SIZE(stats->obj_created) != -- ARRAY_SIZE(stats->obj_deleted)); -+ ARRAY_SIZE(stats->obj_deleted)); - for (i = 0; i < ARRAY_SIZE(stats->obj_created); i++) { - if (stats->obj_created[i] || stats->obj_deleted[i]) -- buf += snprintf(buf, end - buf, -- "%s%s: active %d total %d\n", prefix, -- binder_objstat_strings[i], -- stats->obj_created[i] - -- stats->obj_deleted[i], -- stats->obj_created[i]); -- if (buf >= end) -- return buf; -+ seq_printf(m, "%s%s: active %d total %d\n", prefix, -+ binder_objstat_strings[i], -+ stats->obj_created[i] - stats->obj_deleted[i], -+ stats->obj_created[i]); - } -- return buf; - } - --static char *print_binder_proc_stats(char *buf, char *end, -- struct binder_proc *proc) -+static void print_binder_proc_stats(struct seq_file *m, -+ struct binder_proc *proc) - { - struct binder_work *w; - struct rb_node *n; - int count, strong, weak; - -- buf += snprintf(buf, end - buf, "proc %d\n", proc->pid); -- if (buf >= end) -- return buf; -+ seq_printf(m, "proc %d\n", proc->pid); - count = 0; - for (n = rb_first(&proc->threads); n != NULL; n = rb_next(n)) - count++; -- buf += snprintf(buf, end - buf, " threads: %d\n", count); -- if (buf >= end) -- return buf; -- buf += snprintf(buf, end - buf, " requested threads: %d+%d/%d\n" -+ seq_printf(m, " threads: %d\n", count); -+ seq_printf(m, " requested threads: %d+%d/%d\n" - " ready threads %d\n" - " free async space %zd\n", proc->requested_threads, - proc->requested_threads_started, proc->max_threads, - proc->ready_threads, proc->free_async_space); -- if (buf >= end) -- return buf; - count = 0; - for (n = rb_first(&proc->nodes); n != NULL; n = rb_next(n)) - count++; -- buf += snprintf(buf, end - buf, " nodes: %d\n", count); -- if (buf >= end) -- return buf; -+ seq_printf(m, " nodes: %d\n", count); - count = 0; - strong = 0; - weak = 0; -@@ -3468,17 +3410,12 @@ static char *print_binder_proc_stats(char *buf, char *end, - strong += ref->strong; - weak += ref->weak; - } -- buf += snprintf(buf, end - buf, " refs: %d s %d w %d\n", -- count, strong, weak); -- if (buf >= end) -- return buf; -+ seq_printf(m, " refs: %d s %d w %d\n", count, strong, weak); - - count = 0; - for (n = rb_first(&proc->allocated_buffers); n != NULL; n = rb_next(n)) - count++; -- buf += snprintf(buf, end - buf, " buffers: %d\n", count); -- if (buf >= end) -- return buf; -+ seq_printf(m, " buffers: %d\n", count); - - count = 0; - list_for_each_entry(w, &proc->todo, entry) { -@@ -3490,222 +3427,110 @@ static char *print_binder_proc_stats(char *buf, char *end, - break; - } - } -- buf += snprintf(buf, end - buf, " pending transactions: %d\n", count); -- if (buf >= end) -- return buf; -- -- buf = print_binder_stats(buf, end, " ", &proc->stats); -+ seq_printf(m, " pending transactions: %d\n", count); - -- return buf; -+ print_binder_stats(m, " ", &proc->stats); - } - - --static int binder_read_proc_state(char *page, char **start, off_t off, -- int count, int *eof, void *data) -+static int binder_state_show(struct seq_file *m, void *unused) - { - struct binder_proc *proc; - struct hlist_node *pos; - struct binder_node *node; -- int len = 0; -- char *buf = page; -- char *end = page + PAGE_SIZE; - int do_lock = !binder_debug_no_lock; - -- if (off) -- return 0; -- - if (do_lock) - mutex_lock(&binder_lock); - -- buf += snprintf(buf, end - buf, "binder state:\n"); -+ seq_puts(m, "binder state:\n"); - - if (!hlist_empty(&binder_dead_nodes)) -- buf += snprintf(buf, end - buf, "dead nodes:\n"); -- hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) { -- if (buf >= end) -- break; -- buf = print_binder_node(buf, end, node); -- } -+ seq_puts(m, "dead nodes:\n"); -+ hlist_for_each_entry(node, pos, &binder_dead_nodes, dead_node) -+ print_binder_node(m, node); - -- hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -- if (buf >= end) -- break; -- buf = print_binder_proc(buf, end, proc, 1); -- } -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) -+ print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); -- if (buf > page + PAGE_SIZE) -- buf = page + PAGE_SIZE; -- -- *start = page + off; -- -- len = buf - page; -- if (len > off) -- len -= off; -- else -- len = 0; -- -- return len < count ? len : count; -+ return 0; - } - --static int binder_read_proc_stats(char *page, char **start, off_t off, -- int count, int *eof, void *data) -+static int binder_stats_show(struct seq_file *m, void *unused) - { - struct binder_proc *proc; - struct hlist_node *pos; -- int len = 0; -- char *p = page; - int do_lock = !binder_debug_no_lock; - -- if (off) -- return 0; -- - if (do_lock) - mutex_lock(&binder_lock); - -- p += snprintf(p, PAGE_SIZE, "binder stats:\n"); -+ seq_puts(m, "binder stats:\n"); - -- p = print_binder_stats(p, page + PAGE_SIZE, "", &binder_stats); -+ print_binder_stats(m, "", &binder_stats); - -- hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -- if (p >= page + PAGE_SIZE) -- break; -- p = print_binder_proc_stats(p, page + PAGE_SIZE, proc); -- } -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) -+ print_binder_proc_stats(m, proc); - if (do_lock) - mutex_unlock(&binder_lock); -- if (p > page + PAGE_SIZE) -- p = page + PAGE_SIZE; -- -- *start = page + off; -- -- len = p - page; -- if (len > off) -- len -= off; -- else -- len = 0; -- -- return len < count ? len : count; -+ return 0; - } - --static int binder_read_proc_transactions(char *page, char **start, off_t off, -- int count, int *eof, void *data) -+static int binder_transactions_show(struct seq_file *m, void *unused) - { - struct binder_proc *proc; - struct hlist_node *pos; -- int len = 0; -- char *buf = page; -- char *end = page + PAGE_SIZE; - int do_lock = !binder_debug_no_lock; - -- if (off) -- return 0; -- - if (do_lock) - mutex_lock(&binder_lock); - -- buf += snprintf(buf, end - buf, "binder transactions:\n"); -- hlist_for_each_entry(proc, pos, &binder_procs, proc_node) { -- if (buf >= end) -- break; -- buf = print_binder_proc(buf, end, proc, 0); -- } -+ seq_puts(m, "binder transactions:\n"); -+ hlist_for_each_entry(proc, pos, &binder_procs, proc_node) -+ print_binder_proc(m, proc, 0); - if (do_lock) - mutex_unlock(&binder_lock); -- if (buf > page + PAGE_SIZE) -- buf = page + PAGE_SIZE; -- -- *start = page + off; -- -- len = buf - page; -- if (len > off) -- len -= off; -- else -- len = 0; -- -- return len < count ? len : count; -+ return 0; - } - --static int binder_read_proc_proc(char *page, char **start, off_t off, -- int count, int *eof, void *data) -+static int binder_proc_show(struct seq_file *m, void *unused) - { -- struct binder_proc *proc = data; -- int len = 0; -- char *p = page; -+ struct binder_proc *proc = m->private; - int do_lock = !binder_debug_no_lock; - -- if (off) -- return 0; -- - if (do_lock) - mutex_lock(&binder_lock); -- p += snprintf(p, PAGE_SIZE, "binder proc state:\n"); -- p = print_binder_proc(p, page + PAGE_SIZE, proc, 1); -+ seq_puts(m, "binder proc state:\n"); -+ print_binder_proc(m, proc, 1); - if (do_lock) - mutex_unlock(&binder_lock); -- -- if (p > page + PAGE_SIZE) -- p = page + PAGE_SIZE; -- *start = page + off; -- -- len = p - page; -- if (len > off) -- len -= off; -- else -- len = 0; -- -- return len < count ? len : count; -+ return 0; - } - --static char *print_binder_transaction_log_entry(char *buf, char *end, -+static void print_binder_transaction_log_entry(struct seq_file *m, - struct binder_transaction_log_entry *e) - { -- buf += snprintf(buf, end - buf, -- "%d: %s from %d:%d to %d:%d node %d handle %d " -- "size %d:%d\n", -- e->debug_id, (e->call_type == 2) ? "reply" : -- ((e->call_type == 1) ? "async" : "call "), e->from_proc, -- e->from_thread, e->to_proc, e->to_thread, e->to_node, -- e->target_handle, e->data_size, e->offsets_size); -- return buf; -+ seq_printf(m, -+ "%d: %s from %d:%d to %d:%d node %d handle %d size %d:%d\n", -+ e->debug_id, (e->call_type == 2) ? "reply" : -+ ((e->call_type == 1) ? "async" : "call "), e->from_proc, -+ e->from_thread, e->to_proc, e->to_thread, e->to_node, -+ e->target_handle, e->data_size, e->offsets_size); - } - --static int binder_read_proc_transaction_log( -- char *page, char **start, off_t off, int count, int *eof, void *data) -+static int binder_transaction_log_show(struct seq_file *m, void *unused) - { -- struct binder_transaction_log *log = data; -- int len = 0; -+ struct binder_transaction_log *log = m->private; - int i; -- char *buf = page; -- char *end = page + PAGE_SIZE; -- -- if (off) -- return 0; - - if (log->full) { -- for (i = log->next; i < ARRAY_SIZE(log->entry); i++) { -- if (buf >= end) -- break; -- buf = print_binder_transaction_log_entry(buf, end, -- &log->entry[i]); -- } -+ for (i = log->next; i < ARRAY_SIZE(log->entry); i++) -+ print_binder_transaction_log_entry(m, &log->entry[i]); - } -- for (i = 0; i < log->next; i++) { -- if (buf >= end) -- break; -- buf = print_binder_transaction_log_entry(buf, end, -- &log->entry[i]); -- } -- -- *start = page + off; -- -- len = buf - page; -- if (len > off) -- len -= off; -- else -- len = 0; -- -- return len < count ? len : count; -+ for (i = 0; i < log->next; i++) -+ print_binder_transaction_log_entry(m, &log->entry[i]); -+ return 0; - } - - static const struct file_operations binder_fops = { -@@ -3724,6 +3549,11 @@ static struct miscdevice binder_miscdev = { - .fops = &binder_fops - }; - -+BINDER_DEBUG_ENTRY(state); -+BINDER_DEBUG_ENTRY(stats); -+BINDER_DEBUG_ENTRY(transactions); -+BINDER_DEBUG_ENTRY(transaction_log); -+ - static int __init binder_init(void) - { - int ret; -@@ -3734,31 +3564,28 @@ static int __init binder_init(void) - binder_proc_dir_entry_root); - ret = misc_register(&binder_miscdev); - if (binder_proc_dir_entry_root) { -- create_proc_read_entry("state", -- S_IRUGO, -- binder_proc_dir_entry_root, -- binder_read_proc_state, -- NULL); -- create_proc_read_entry("stats", -- S_IRUGO, -- binder_proc_dir_entry_root, -- binder_read_proc_stats, -- NULL); -- create_proc_read_entry("transactions", -- S_IRUGO, -- binder_proc_dir_entry_root, -- binder_read_proc_transactions, -- NULL); -- create_proc_read_entry("transaction_log", -- S_IRUGO, -- binder_proc_dir_entry_root, -- binder_read_proc_transaction_log, -- &binder_transaction_log); -- create_proc_read_entry("failed_transaction_log", -- S_IRUGO, -- binder_proc_dir_entry_root, -- binder_read_proc_transaction_log, -- &binder_transaction_log_failed); -+ proc_create("state", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ &binder_state_fops); -+ proc_create("stats", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ &binder_stats_fops); -+ proc_create("transactions", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ &binder_transactions_fops); -+ proc_create_data("transaction_log", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ &binder_transaction_log_fops, -+ &binder_transaction_log); -+ proc_create_data("failed_transaction_log", -+ S_IRUGO, -+ binder_proc_dir_entry_root, -+ &binder_transaction_log_fops, -+ &binder_transaction_log_failed); - } - return ret; - } diff --git a/patches.android/android-0011-staging-android-binder-Move-debugging-information-from-procf.patch b/patches.android/android-0011-staging-android-binder-Move-debugging-information-from-procf.patch deleted file mode 100644 index 961982ec39ea..000000000000 --- a/patches.android/android-0011-staging-android-binder-Move-debugging-information-from-procf.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 16b665543864904714f028b1d349f5d905f39afb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Tue, 28 Apr 2009 20:57:50 -0700 -Subject: staging: android: binder: Move debugging information from - procfs to debugfs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 16b665543864904714f028b1d349f5d905f39afb - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 371232b..669e2a6 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+#include - #include - #include - #include -@@ -43,8 +43,8 @@ static HLIST_HEAD(binder_procs); - static HLIST_HEAD(binder_deferred_list); - static HLIST_HEAD(binder_dead_nodes); - --static struct proc_dir_entry *binder_proc_dir_entry_root; --static struct proc_dir_entry *binder_proc_dir_entry_proc; -+static struct dentry *binder_debugfs_dir_entry_root; -+static struct dentry *binder_debugfs_dir_entry_proc; - static struct binder_node *binder_context_mgr_node; - static uid_t binder_context_mgr_uid = -1; - static int binder_last_id; -@@ -52,7 +52,7 @@ static int binder_last_id; - #define BINDER_DEBUG_ENTRY(name) \ - static int binder_##name##_open(struct inode *inode, struct file *file) \ - { \ -- return single_open(file, binder_##name##_show, PDE(inode)->data); \ -+ return single_open(file, binder_##name##_show, inode->i_private); \ - } \ - \ - static const struct file_operations binder_##name##_fops = { \ -@@ -310,6 +310,7 @@ struct binder_proc { - int requested_threads_started; - int ready_threads; - long default_priority; -+ struct dentry *debugfs_entry; - }; - - enum { -@@ -2891,13 +2892,11 @@ static int binder_open(struct inode *nodp, struct file *filp) - filp->private_data = proc; - mutex_unlock(&binder_lock); - -- if (binder_proc_dir_entry_proc) { -+ if (binder_debugfs_dir_entry_proc) { - char strbuf[11]; - snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); -- remove_proc_entry(strbuf, binder_proc_dir_entry_proc); -- proc_create_data(strbuf, S_IRUGO, -- binder_proc_dir_entry_proc, -- &binder_proc_fops, proc); -+ proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, -+ binder_debugfs_dir_entry_proc, proc, &binder_proc_fops); - } - - return 0; -@@ -2934,12 +2933,7 @@ static void binder_deferred_flush(struct binder_proc *proc) - static int binder_release(struct inode *nodp, struct file *filp) - { - struct binder_proc *proc = filp->private_data; -- if (binder_proc_dir_entry_proc) { -- char strbuf[11]; -- snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); -- remove_proc_entry(strbuf, binder_proc_dir_entry_proc); -- } -- -+ debugfs_remove(proc->debugfs_entry); - binder_defer_work(proc, BINDER_DEFERRED_RELEASE); - - return 0; -@@ -3558,34 +3552,37 @@ static int __init binder_init(void) - { - int ret; - -- binder_proc_dir_entry_root = proc_mkdir("binder", NULL); -- if (binder_proc_dir_entry_root) -- binder_proc_dir_entry_proc = proc_mkdir("proc", -- binder_proc_dir_entry_root); -+ binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); -+ if (binder_debugfs_dir_entry_root) -+ binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", -+ binder_debugfs_dir_entry_root); - ret = misc_register(&binder_miscdev); -- if (binder_proc_dir_entry_root) { -- proc_create("state", -- S_IRUGO, -- binder_proc_dir_entry_root, -- &binder_state_fops); -- proc_create("stats", -- S_IRUGO, -- binder_proc_dir_entry_root, -- &binder_stats_fops); -- proc_create("transactions", -- S_IRUGO, -- binder_proc_dir_entry_root, -- &binder_transactions_fops); -- proc_create_data("transaction_log", -- S_IRUGO, -- binder_proc_dir_entry_root, -- &binder_transaction_log_fops, -- &binder_transaction_log); -- proc_create_data("failed_transaction_log", -- S_IRUGO, -- binder_proc_dir_entry_root, -- &binder_transaction_log_fops, -- &binder_transaction_log_failed); -+ if (binder_debugfs_dir_entry_root) { -+ debugfs_create_file("state", -+ S_IRUGO, -+ binder_debugfs_dir_entry_root, -+ NULL, -+ &binder_state_fops); -+ debugfs_create_file("stats", -+ S_IRUGO, -+ binder_debugfs_dir_entry_root, -+ NULL, -+ &binder_stats_fops); -+ debugfs_create_file("transactions", -+ S_IRUGO, -+ binder_debugfs_dir_entry_root, -+ NULL, -+ &binder_transactions_fops); -+ debugfs_create_file("transaction_log", -+ S_IRUGO, -+ binder_debugfs_dir_entry_root, -+ &binder_transaction_log, -+ &binder_transaction_log_fops); -+ debugfs_create_file("failed_transaction_log", -+ S_IRUGO, -+ binder_debugfs_dir_entry_root, -+ &binder_transaction_log_failed, -+ &binder_transaction_log_fops); - } - return ret; - } diff --git a/patches.android/android-0012-Staging-android-timed_gpio-Properly-discard-invalid-timeout-.patch b/patches.android/android-0012-Staging-android-timed_gpio-Properly-discard-invalid-timeout-.patch deleted file mode 100644 index 3fa2971af386..000000000000 --- a/patches.android/android-0012-Staging-android-timed_gpio-Properly-discard-invalid-timeout-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8bfe15f3de0af92fd822b7475878bddc93fa490d Mon Sep 17 00:00:00 2001 -From: Mike Lockwood -Date: Sat, 17 Apr 2010 12:01:35 -0400 -Subject: Staging: android: timed_gpio: Properly discard invalid - timeout values. -Patch-mainline: HEAD -Git-commit: 8bfe15f3de0af92fd822b7475878bddc93fa490d - -The timed output device never previously checked the return value of sscanf, -resulting in an uninitialized int being passed to enable() if input value -was invalid. - -Signed-off-by: Mike Lockwood -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/timed_output.c b/drivers/staging/android/timed_output.c -index 62e7918..f373422 100644 ---- a/drivers/staging/android/timed_output.c -+++ b/drivers/staging/android/timed_output.c -@@ -41,7 +41,9 @@ static ssize_t enable_store( - struct timed_output_dev *tdev = dev_get_drvdata(dev); - int value; - -- sscanf(buf, "%d", &value); -+ if (sscanf(buf, "%d", &value) != 1) -+ return -EINVAL; -+ - tdev->enable(tdev, value); - - return size; diff --git a/patches.android/android-0013-Staging-android-binder-Create-dedicated-workqueue-for-binder.patch b/patches.android/android-0013-Staging-android-binder-Create-dedicated-workqueue-for-binder.patch deleted file mode 100644 index 69bb56fbb6c8..000000000000 --- a/patches.android/android-0013-Staging-android-binder-Create-dedicated-workqueue-for-binder.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 3c762a49b12073c96f6a55b4dfc8b6a2a45fedff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Thu, 22 Apr 2010 15:53:23 -0700 -Subject: Staging: android: binder: Create dedicated workqueue for - binder deferred work -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 3c762a49b12073c96f6a55b4dfc8b6a2a45fedff - -Some drivers flush the global workqueue when closed. This would deadlock if -the last reference to the file was released from the binder. - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 669e2a6..6d6fe7b 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -48,6 +48,7 @@ static struct dentry *binder_debugfs_dir_entry_proc; - static struct binder_node *binder_context_mgr_node; - static uid_t binder_context_mgr_uid = -1; - static int binder_last_id; -+static struct workqueue_struct *binder_deferred_workqueue; - - #define BINDER_DEBUG_ENTRY(name) \ - static int binder_##name##_open(struct inode *inode, struct file *file) \ -@@ -3109,7 +3110,7 @@ binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer) - if (hlist_unhashed(&proc->deferred_work_node)) { - hlist_add_head(&proc->deferred_work_node, - &binder_deferred_list); -- schedule_work(&binder_deferred_work); -+ queue_work(binder_deferred_workqueue, &binder_deferred_work); - } - mutex_unlock(&binder_deferred_lock); - } -@@ -3552,6 +3553,10 @@ static int __init binder_init(void) - { - int ret; - -+ binder_deferred_workqueue = create_singlethread_workqueue("binder"); -+ if (!binder_deferred_workqueue) -+ return -ENOMEM; -+ - binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); - if (binder_debugfs_dir_entry_root) - binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", diff --git a/patches.android/android-0014-staging-android-lowmemorykiller-Don-t-try-to-kill-the-same-p.patch b/patches.android/android-0014-staging-android-lowmemorykiller-Don-t-try-to-kill-the-same-p.patch deleted file mode 100644 index 75be85a7c75d..000000000000 --- a/patches.android/android-0014-staging-android-lowmemorykiller-Don-t-try-to-kill-the-same-p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 4964cd41cd966502c1e0c5bc929ed15c175f8218 Mon Sep 17 00:00:00 2001 -From: San Mehat -Date: Mon, 26 Apr 2010 15:11:04 -0700 -Subject: staging: android: lowmemorykiller: Don't try to kill the - same pid over and over -Patch-mainline: HEAD -Git-commit: 4964cd41cd966502c1e0c5bc929ed15c175f8218 - - Under certain circumstances, a process can take awhile to -handle a sig-kill (especially if it's in a scheduler group with -a very low share ratio). When this occurs, lowmemkiller returns -to vmscan indicating the process memory has been freed - even -though the process is still waiting to die. Since the memory -hasn't actually freed, lowmemkiller is called again shortly after, -and picks the same process to die; regardless of the fact that -it has already been 'scheduled' to die and the memory has already -been reported to vmscan as having been freed. - - Solution is to check fatal_signal_pending() on the selected -task, and if it's already pending destruction return; indicating -to vmscan that no resources were freed on this pass. - -Signed-off-by: San Mehat -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 32314e8..8372178 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -133,6 +133,12 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - p->pid, p->comm, oom_adj, tasksize); - } - if (selected) { -+ if (fatal_signal_pending(selected)) { -+ pr_warning("process %d is suffering a slow death\n", -+ selected->pid); -+ read_unlock(&tasklist_lock); -+ return rem; -+ } - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); diff --git a/patches.android/android-0015-staging-android-lowmemkiller-Substantially-reduce-overhead-d.patch b/patches.android/android-0015-staging-android-lowmemkiller-Substantially-reduce-overhead-d.patch deleted file mode 100644 index 5f8061281573..000000000000 --- a/patches.android/android-0015-staging-android-lowmemkiller-Substantially-reduce-overhead-d.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 4755b72e261478b48337e0e54c8448cbea32c5c8 Mon Sep 17 00:00:00 2001 -From: San Mehat -Date: Wed, 5 May 2010 11:38:42 -0700 -Subject: staging: android: lowmemkiller: Substantially reduce - overhead during reclaim -Patch-mainline: HEAD -Git-commit: 4755b72e261478b48337e0e54c8448cbea32c5c8 - -This patch optimizes lowmemkiller to not do any work when it has an outstanding -kill-request. This greatly reduces the pressure on the task_list lock -(improving interactivity), as well as improving the vmscan performance -when under heavy memory pressure (by up to 20x in tests). - -Note: For this enhancement to work, you need CONFIG_PROFILING - -Signed-off-by: San Mehat -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 8372178..4523093 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - - static uint32_t lowmem_debug_level = 2; - static int lowmem_adj[6] = { -@@ -51,12 +53,32 @@ static size_t lowmem_minfree[6] = { - }; - static int lowmem_minfree_size = 4; - -+static struct task_struct *lowmem_deathpending; -+ - #define lowmem_print(level, x...) \ - do { \ - if (lowmem_debug_level >= (level)) \ - printk(x); \ - } while (0) - -+static int -+task_notify_func(struct notifier_block *self, unsigned long val, void *data); -+ -+static struct notifier_block task_nb = { -+ .notifier_call = task_notify_func, -+}; -+ -+static int -+task_notify_func(struct notifier_block *self, unsigned long val, void *data) -+{ -+ struct task_struct *task = data; -+ if (task == lowmem_deathpending) { -+ lowmem_deathpending = NULL; -+ task_handoff_unregister(&task_nb); -+ } -+ return NOTIFY_OK; -+} -+ - static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - { - struct task_struct *p; -@@ -71,6 +93,18 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - int other_free = global_page_state(NR_FREE_PAGES); - int other_file = global_page_state(NR_FILE_PAGES); - -+ /* -+ * If we already have a death outstanding, then -+ * bail out right away; indicating to vmscan -+ * that we have nothing further to offer on -+ * this pass. -+ * -+ * Note: Currently you need CONFIG_PROFILING -+ * for this to work correctly. -+ */ -+ if (lowmem_deathpending) -+ return 0; -+ - if (lowmem_adj_size < array_size) - array_size = lowmem_adj_size; - if (lowmem_minfree_size < array_size) -@@ -142,6 +176,15 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); -+ /* -+ * If CONFIG_PROFILING is off, then task_handoff_register() -+ * is a nop. In that case we don't want to stall the killer -+ * by setting lowmem_deathpending. -+ */ -+#ifdef CONFIG_PROFILING -+ lowmem_deathpending = selected; -+ task_handoff_register(&task_nb); -+#endif - force_sig(SIGKILL, selected); - rem -= selected_tasksize; - } diff --git a/patches.android/android-0016-staging-binder-Fix-memory-corruption-via-page-aliasing.patch b/patches.android/android-0016-staging-binder-Fix-memory-corruption-via-page-aliasing.patch deleted file mode 100644 index dc17772c2bdc..000000000000 --- a/patches.android/android-0016-staging-binder-Fix-memory-corruption-via-page-aliasing.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 58526090ece3582516e62779739a7d665a74708c Mon Sep 17 00:00:00 2001 -From: Christopher Lais -Date: Sat, 1 May 2010 15:51:48 -0500 -Subject: staging: binder: Fix memory corruption via page aliasing -Patch-mainline: HEAD -Git-commit: 58526090ece3582516e62779739a7d665a74708c - -binder_deferred_release was not unmapping the page from the buffer -before freeing it, causing memory corruption. This only happened -when page(s) had not been freed by binder_update_page_range, which -properly unmaps the pages. - -This only happens on architectures with VIPT aliasing. - -To reproduce, create a program which opens, mmaps, munmaps, then closes -the binder very quickly. This should leave a page allocated when the -binder is released. When binder_deferrred_release is called on the -close, the page will remain mapped to the address in the linear -proc->buffer. Later, we may map the same physical page to a different -virtual address that has different coloring, and this may cause -aliasing to occur. - -PAGE_POISONING will greatly increase your chances of noticing any -problems. - -Signed-off-by: Christopher Lais -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 6d6fe7b..7491801 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -3036,11 +3036,14 @@ static void binder_deferred_release(struct binder_proc *proc) - int i; - for (i = 0; i < proc->buffer_size / PAGE_SIZE; i++) { - if (proc->pages[i]) { -+ void *page_addr = proc->buffer + i * PAGE_SIZE; - binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder_release: %d: " - "page %d at %p not freed\n", - proc->pid, i, -- proc->buffer + i * PAGE_SIZE); -+ page_addr); -+ unmap_kernel_range((unsigned long)page_addr, -+ PAGE_SIZE); - __free_page(proc->pages[i]); - page_count++; - } diff --git a/patches.android/android-0017-staging-android-lowmemorykiller-Remove-bitrotted-codepath.patch b/patches.android/android-0017-staging-android-lowmemorykiller-Remove-bitrotted-codepath.patch deleted file mode 100644 index 290c30bf9a87..000000000000 --- a/patches.android/android-0017-staging-android-lowmemorykiller-Remove-bitrotted-codepath.patch +++ /dev/null @@ -1,32 +0,0 @@ -From eb943f6be011b33455b767880e13c34a2bb96a5e Mon Sep 17 00:00:00 2001 -From: San Mehat -Date: Thu, 6 May 2010 15:43:46 -0700 -Subject: staging: android: lowmemorykiller: Remove bitrotted codepath -Patch-mainline: HEAD -Git-commit: eb943f6be011b33455b767880e13c34a2bb96a5e - -Now that we're murder-synchronous, this code path will never be -called (and if it does, it doesn't tell us anything useful other -than we killed a task that was already being killed by somebody -else but hadn't gotten its' signal yet) - -Signed-off-by: San Mehat -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 4523093..cf79eb9 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -167,12 +167,6 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) - p->pid, p->comm, oom_adj, tasksize); - } - if (selected) { -- if (fatal_signal_pending(selected)) { -- pr_warning("process %d is suffering a slow death\n", -- selected->pid); -- read_unlock(&tasklist_lock); -- return rem; -- } - lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", - selected->pid, selected->comm, - selected_oom_adj, selected_tasksize); diff --git a/patches.android/android-0018-staging-android-lowmemorykiller-Update-arguments-of-shrinker.patch b/patches.android/android-0018-staging-android-lowmemorykiller-Update-arguments-of-shrinker.patch deleted file mode 100644 index 71bfef441c30..000000000000 --- a/patches.android/android-0018-staging-android-lowmemorykiller-Update-arguments-of-shrinker.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 06a1074e1c789a777732f8c432d913b0fedb8ff5 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Sat, 21 Aug 2010 17:25:42 -0700 -Subject: staging: android: lowmemorykiller: Update arguments of - shrinker for 2.6.35 -Patch-mainline: HEAD -Git-commit: 06a1074e1c789a777732f8c432d913b0fedb8ff5 - -Signed-off-by: Colin Cross -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index cf79eb9..93a1758 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -79,7 +79,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) - return NOTIFY_OK; - } - --static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask) -+static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - { - struct task_struct *p; - struct task_struct *selected = NULL; diff --git a/patches.android/android-0019-staging-android-lowmemorykiller-Ignore-shmem-pages-in-page-c.patch b/patches.android/android-0019-staging-android-lowmemorykiller-Ignore-shmem-pages-in-page-c.patch deleted file mode 100644 index 3d032787d3ee..000000000000 --- a/patches.android/android-0019-staging-android-lowmemorykiller-Ignore-shmem-pages-in-page-c.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 71b2c82bdf67ab24716c536e10de436169d3574c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Tue, 23 Nov 2010 17:29:04 -0800 -Subject: staging: android: lowmemorykiller: Ignore shmem pages in - page-cache -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 71b2c82bdf67ab24716c536e10de436169d3574c - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 93a1758..0ae08ad 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -91,7 +91,8 @@ static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - int selected_oom_adj; - int array_size = ARRAY_SIZE(lowmem_adj); - int other_free = global_page_state(NR_FREE_PAGES); -- int other_file = global_page_state(NR_FILE_PAGES); -+ int other_file = global_page_state(NR_FILE_PAGES) - -+ global_page_state(NR_SHMEM); - - /* - * If we already have a death outstanding, then diff --git a/patches.android/android-0020-android-lowmemorykiller-Fix-arguments-to-lowmem_shrink.patch b/patches.android/android-0020-android-lowmemorykiller-Fix-arguments-to-lowmem_shrink.patch deleted file mode 100644 index 0a31aeafa768..000000000000 --- a/patches.android/android-0020-android-lowmemorykiller-Fix-arguments-to-lowmem_shrink.patch +++ /dev/null @@ -1,61 +0,0 @@ -From cae9bf11ef0d92875b222f994a2cfd723991435a Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Wed, 22 Jun 2011 16:05:47 -0700 -Subject: android: lowmemorykiller: Fix arguments to lowmem_shrink -Patch-mainline: HEAD -Git-commit: cae9bf11ef0d92875b222f994a2cfd723991435a - -The arguments to shrink functions have changed, update -lowmem_shrink to match. - -Signed-off-by: Colin Cross -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 0ae08ad..4098bbb 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -79,7 +79,7 @@ task_notify_func(struct notifier_block *self, unsigned long val, void *data) - return NOTIFY_OK; - } - --static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) -+static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) - { - struct task_struct *p; - struct task_struct *selected = NULL; -@@ -117,17 +117,17 @@ static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - break; - } - } -- if (nr_to_scan > 0) -- lowmem_print(3, "lowmem_shrink %d, %x, ofree %d %d, ma %d\n", -- nr_to_scan, gfp_mask, other_free, other_file, -+ if (sc->nr_to_scan > 0) -+ lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", -+ sc->nr_to_scan, sc->gfp_mask, other_free, other_file, - min_adj); - rem = global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); -- if (nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { -- lowmem_print(5, "lowmem_shrink %d, %x, return %d\n", -- nr_to_scan, gfp_mask, rem); -+ if (sc->nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { -+ lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", -+ sc->nr_to_scan, sc->gfp_mask, rem); - return rem; - } - selected_oom_adj = min_adj; -@@ -183,8 +183,8 @@ static int lowmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - force_sig(SIGKILL, selected); - rem -= selected_tasksize; - } -- lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", -- nr_to_scan, gfp_mask, rem); -+ lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", -+ sc->nr_to_scan, sc->gfp_mask, rem); - read_unlock(&tasklist_lock); - return rem; - } diff --git a/patches.android/android-0021-android-logger-bump-up-the-logger-buffer-sizes.patch b/patches.android/android-0021-android-logger-bump-up-the-logger-buffer-sizes.patch deleted file mode 100644 index d1442539984b..000000000000 --- a/patches.android/android-0021-android-logger-bump-up-the-logger-buffer-sizes.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 2b374956f3afee5857c85b073d726be11f4d2e9b Mon Sep 17 00:00:00 2001 -From: JP Abgrall -Date: Thu, 11 Aug 2011 21:33:35 -0700 -Subject: android: logger: bump up the logger buffer sizes -Patch-mainline: HEAD -Git-commit: 2b374956f3afee5857c85b073d726be11f4d2e9b - -(port from common android-2.6.39 - commit: 11430f16545205c614dd5bd58e4a7ee630fc0f9f) - -events: (no change, 256) -main: 64 -> 256 -radio: 64 -> 256 -system: 64 -> 256 - -Signed-off-by: JP Abgrall -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -index 531bdbe..fa76ce7 100644 ---- a/drivers/staging/android/logger.c -+++ b/drivers/staging/android/logger.c -@@ -555,10 +555,10 @@ static struct logger_log VAR = { \ - .size = SIZE, \ - }; - --DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 64*1024) -+DEFINE_LOGGER_DEVICE(log_main, LOGGER_LOG_MAIN, 256*1024) - DEFINE_LOGGER_DEVICE(log_events, LOGGER_LOG_EVENTS, 256*1024) --DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 64*1024) --DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 64*1024) -+DEFINE_LOGGER_DEVICE(log_radio, LOGGER_LOG_RADIO, 256*1024) -+DEFINE_LOGGER_DEVICE(log_system, LOGGER_LOG_SYSTEM, 256*1024) - - static struct logger_log *get_log_from_minor(int minor) - { diff --git a/patches.android/android-0022-staging-android-ram_console-pass-in-a-boot-info-string.patch b/patches.android/android-0022-staging-android-ram_console-pass-in-a-boot-info-string.patch deleted file mode 100644 index 8d89238ab5ca..000000000000 --- a/patches.android/android-0022-staging-android-ram_console-pass-in-a-boot-info-string.patch +++ /dev/null @@ -1,166 +0,0 @@ -From a6707f830e39ab5ef285d9155525eac5e500e55d Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Tue, 25 Oct 2011 14:31:58 -0700 -Subject: staging: android: ram_console: pass in a boot info string -Patch-mainline: HEAD -Git-commit: a6707f830e39ab5ef285d9155525eac5e500e55d - -Allow the board file to pass a boot info string through the -platform data that is appended to the /proc/last_kmsg file. - -[moved the .h file to drivers/staging/android/ to be self-contained - gregkh] - -Signed-off-by: Colin Cross -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c -index 53f736b..6d4d679 100644 ---- a/drivers/staging/android/ram_console.c -+++ b/drivers/staging/android/ram_console.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include "ram_console.h" - - #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - #include -@@ -155,14 +156,20 @@ void ram_console_enable_console(int enabled) - } - - static void __init --ram_console_save_old(struct ram_console_buffer *buffer, char *dest) -+ram_console_save_old(struct ram_console_buffer *buffer, const char *bootinfo, -+ char *dest) - { - size_t old_log_size = buffer->size; -+ size_t bootinfo_size = 0; -+ size_t total_size = old_log_size; -+ char *ptr; -+ const char *bootinfo_label = "Boot info:\n"; -+ - #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - uint8_t *block; - uint8_t *par; - char strbuf[80]; -- int strbuf_len; -+ int strbuf_len = 0; - - block = buffer->data; - par = ram_console_par_buffer; -@@ -197,11 +204,15 @@ ram_console_save_old(struct ram_console_buffer *buffer, char *dest) - "\nNo errors detected\n"); - if (strbuf_len >= sizeof(strbuf)) - strbuf_len = sizeof(strbuf) - 1; -- old_log_size += strbuf_len; -+ total_size += strbuf_len; - #endif - -+ if (bootinfo) -+ bootinfo_size = strlen(bootinfo) + strlen(bootinfo_label); -+ total_size += bootinfo_size; -+ - if (dest == NULL) { -- dest = kmalloc(old_log_size, GFP_KERNEL); -+ dest = kmalloc(total_size, GFP_KERNEL); - if (dest == NULL) { - printk(KERN_ERR - "ram_console: failed to allocate buffer\n"); -@@ -210,19 +221,27 @@ ram_console_save_old(struct ram_console_buffer *buffer, char *dest) - } - - ram_console_old_log = dest; -- ram_console_old_log_size = old_log_size; -+ ram_console_old_log_size = total_size; - memcpy(ram_console_old_log, - &buffer->data[buffer->start], buffer->size - buffer->start); - memcpy(ram_console_old_log + buffer->size - buffer->start, - &buffer->data[0], buffer->start); -+ ptr = ram_console_old_log + old_log_size; - #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION -- memcpy(ram_console_old_log + old_log_size - strbuf_len, -- strbuf, strbuf_len); -+ memcpy(ptr, strbuf, strbuf_len); -+ ptr += strbuf_len; - #endif -+ if (bootinfo) { -+ memcpy(ptr, bootinfo_label, strlen(bootinfo_label)); -+ ptr += strlen(bootinfo_label); -+ memcpy(ptr, bootinfo, bootinfo_size); -+ ptr += bootinfo_size; -+ } - } - - static int __init ram_console_init(struct ram_console_buffer *buffer, -- size_t buffer_size, char *old_buf) -+ size_t buffer_size, const char *bootinfo, -+ char *old_buf) - { - #ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION - int numerr; -@@ -289,7 +308,7 @@ static int __init ram_console_init(struct ram_console_buffer *buffer, - printk(KERN_INFO "ram_console: found existing buffer, " - "size %d, start %d\n", - buffer->size, buffer->start); -- ram_console_save_old(buffer, old_buf); -+ ram_console_save_old(buffer, bootinfo, old_buf); - } - } else { - printk(KERN_INFO "ram_console: no valid data in buffer " -@@ -313,6 +332,7 @@ static int __init ram_console_early_init(void) - return ram_console_init((struct ram_console_buffer *) - CONFIG_ANDROID_RAM_CONSOLE_EARLY_ADDR, - CONFIG_ANDROID_RAM_CONSOLE_EARLY_SIZE, -+ NULL, - ram_console_old_log_init_buffer); - } - #else -@@ -322,6 +342,8 @@ static int ram_console_driver_probe(struct platform_device *pdev) - size_t start; - size_t buffer_size; - void *buffer; -+ const char *bootinfo = NULL; -+ struct ram_console_platform_data *pdata = pdev->dev.platform_data; - - if (res == NULL || pdev->num_resources != 1 || - !(res->flags & IORESOURCE_MEM)) { -@@ -339,7 +361,10 @@ static int ram_console_driver_probe(struct platform_device *pdev) - return -ENOMEM; - } - -- return ram_console_init(buffer, buffer_size, NULL/* allocate */); -+ if (pdata) -+ bootinfo = pdata->bootinfo; -+ -+ return ram_console_init(buffer, buffer_size, bootinfo, NULL/* allocate */); - } - - static struct platform_driver ram_console_driver = { -diff --git a/drivers/staging/android/ram_console.h b/drivers/staging/android/ram_console.h -new file mode 100644 -index 0000000..9f1125c ---- /dev/null -+++ b/drivers/staging/android/ram_console.h -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2010 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_ -+#define _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_ -+ -+struct ram_console_platform_data { -+ const char *bootinfo; -+}; -+ -+#endif /* _INCLUDE_LINUX_PLATFORM_DATA_RAM_CONSOLE_H_ */ diff --git a/patches.android/android-0023-Staging-android-fixed-white-spaces-coding-style-issue-in-log.patch b/patches.android/android-0023-Staging-android-fixed-white-spaces-coding-style-issue-in-log.patch deleted file mode 100644 index c0e6e6c61a6a..000000000000 --- a/patches.android/android-0023-Staging-android-fixed-white-spaces-coding-style-issue-in-log.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 277cdd01d6e831e2168cb3f2c082eecd7fcaac06 Mon Sep 17 00:00:00 2001 -From: Marco Navarra -Date: Thu, 15 Dec 2011 17:57:48 +0100 -Subject: Staging: android: fixed white spaces coding style issue in - logger.c -Patch-mainline: HEAD -Git-commit: 277cdd01d6e831e2168cb3f2c082eecd7fcaac06 - -This patch fixes some space-before-tabs warnings found by checkpatch tool on the staging android driver file logger.c - -Signed-off-by: Marco Navarra -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/logger.c b/drivers/staging/android/logger.c -index fa76ce7..ffc2d04 100644 ---- a/drivers/staging/android/logger.c -+++ b/drivers/staging/android/logger.c -@@ -37,7 +37,7 @@ - * mutex 'mutex'. - */ - struct logger_log { -- unsigned char *buffer;/* the ring buffer itself */ -+ unsigned char *buffer;/* the ring buffer itself */ - struct miscdevice misc; /* misc device representing the log */ - wait_queue_head_t wq; /* wait queue for readers */ - struct list_head readers; /* this log's readers */ -@@ -67,9 +67,9 @@ struct logger_reader { - * - * This isn't aesthetic. We have several goals: - * -- * 1) Need to quickly obtain the associated log during an I/O operation -- * 2) Readers need to maintain state (logger_reader) -- * 3) Writers need to be very fast (open() should be a near no-op) -+ * 1) Need to quickly obtain the associated log during an I/O operation -+ * 2) Readers need to maintain state (logger_reader) -+ * 3) Writers need to be very fast (open() should be a near no-op) - * - * In the reader case, we can trivially go file->logger_reader->logger_log. - * For a writer, we don't want to maintain a logger_reader, so we just go -@@ -147,9 +147,9 @@ static ssize_t do_read_log_to_user(struct logger_log *log, - * - * Behavior: - * -- * - O_NONBLOCK works -- * - If there are no log entries to read, blocks until log is written to -- * - Atomically reads exactly one log entry -+ * - O_NONBLOCK works -+ * - If there are no log entries to read, blocks until log is written to -+ * - Atomically reads exactly one log entry - * - * Optimal read size is LOGGER_ENTRY_MAX_LEN. Will set errno to EINVAL if read - * buffer is insufficient to hold next entry. diff --git a/patches.android/android-0024-staging-android-switch-switch-class-and-GPIO-drivers.patch b/patches.android/android-0024-staging-android-switch-switch-class-and-GPIO-drivers.patch deleted file mode 100644 index 3dde18bae7df..000000000000 --- a/patches.android/android-0024-staging-android-switch-switch-class-and-GPIO-drivers.patch +++ /dev/null @@ -1,499 +0,0 @@ -From e0f5bb9b3850bdd7907eda9eb923cd3f9d4358b8 Mon Sep 17 00:00:00 2001 -From: Mike Lockwood -Date: Tue, 14 Oct 2008 12:50:16 -0400 -Subject: staging: android: switch: switch class and GPIO drivers. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: e0f5bb9b3850bdd7907eda9eb923cd3f9d4358b8 - -This adds the Android switch driver code to the staging tree. - -[Note, this code was located in drivers/switch/ in the Android kernel -releases, but as that api wasn't generally accepted, and the interface -is working toward changing to the newly proposed extcon inteface, this -driver was placed here until the extcon code is merged into mainline and -the Android userspace code is converted over to using it. - gregkh] - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Mike Lockwood -Cc: MyungJoo Ham -Cc: Kyungmin Park -Cc: Donggeun Kim -Cc: Arnd Bergmann -Cc: MyungJoo Ham -Cc: Linus Walleij -Cc: Dmitry Torokhov -Cc: NeilBrown -Cc: Morten CHRISTIANSEN -Cc: Mark Brown -Cc: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index 2471949..0712b18 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -90,6 +90,8 @@ config ANDROID_LOW_MEMORY_KILLER - ---help--- - Register processes to be killed when memory is low - -+source "drivers/staging/android/switch/Kconfig" -+ - endif # if ANDROID - - endmenu -diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile -index 8e057e6..36e32bc 100644 ---- a/drivers/staging/android/Makefile -+++ b/drivers/staging/android/Makefile -@@ -4,3 +4,4 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o - obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o - obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o - obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o -+obj-$(CONFIG_ANDROID_SWITCH) += switch/ -diff --git a/drivers/staging/android/switch/Kconfig b/drivers/staging/android/switch/Kconfig -new file mode 100644 -index 0000000..36846f6 ---- /dev/null -+++ b/drivers/staging/android/switch/Kconfig -@@ -0,0 +1,11 @@ -+menuconfig ANDROID_SWITCH -+ tristate "Android Switch class support" -+ help -+ Say Y here to enable Android switch class support. This allows -+ monitoring switches by userspace via sysfs and uevent. -+ -+config ANDROID_SWITCH_GPIO -+ tristate "Android GPIO Switch support" -+ depends on GENERIC_GPIO && ANDROID_SWITCH -+ help -+ Say Y here to enable GPIO based switch support. -diff --git a/drivers/staging/android/switch/Makefile b/drivers/staging/android/switch/Makefile -new file mode 100644 -index 0000000..d76bfdc ---- /dev/null -+++ b/drivers/staging/android/switch/Makefile -@@ -0,0 +1,4 @@ -+# Android Switch Class Driver -+obj-$(CONFIG_ANDROID_SWITCH) += switch_class.o -+obj-$(CONFIG_ANDROID_SWITCH_GPIO) += switch_gpio.o -+ -diff --git a/drivers/staging/android/switch/switch.h b/drivers/staging/android/switch/switch.h -new file mode 100644 -index 0000000..3e4c748 ---- /dev/null -+++ b/drivers/staging/android/switch/switch.h -@@ -0,0 +1,53 @@ -+/* -+ * Switch class driver -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+*/ -+ -+#ifndef __LINUX_SWITCH_H__ -+#define __LINUX_SWITCH_H__ -+ -+struct switch_dev { -+ const char *name; -+ struct device *dev; -+ int index; -+ int state; -+ -+ ssize_t (*print_name)(struct switch_dev *sdev, char *buf); -+ ssize_t (*print_state)(struct switch_dev *sdev, char *buf); -+}; -+ -+struct gpio_switch_platform_data { -+ const char *name; -+ unsigned gpio; -+ -+ /* if NULL, switch_dev.name will be printed */ -+ const char *name_on; -+ const char *name_off; -+ /* if NULL, "0" or "1" will be printed */ -+ const char *state_on; -+ const char *state_off; -+}; -+ -+extern int switch_dev_register(struct switch_dev *sdev); -+extern void switch_dev_unregister(struct switch_dev *sdev); -+ -+static inline int switch_get_state(struct switch_dev *sdev) -+{ -+ return sdev->state; -+} -+ -+extern void switch_set_state(struct switch_dev *sdev, int state); -+ -+#endif /* __LINUX_SWITCH_H__ */ -diff --git a/drivers/staging/android/switch/switch_class.c b/drivers/staging/android/switch/switch_class.c -new file mode 100644 -index 0000000..7468044 ---- /dev/null -+++ b/drivers/staging/android/switch/switch_class.c -@@ -0,0 +1,174 @@ -+/* -+ * switch_class.c -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "switch.h" -+ -+struct class *switch_class; -+static atomic_t device_count; -+ -+static ssize_t state_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct switch_dev *sdev = (struct switch_dev *) -+ dev_get_drvdata(dev); -+ -+ if (sdev->print_state) { -+ int ret = sdev->print_state(sdev, buf); -+ if (ret >= 0) -+ return ret; -+ } -+ return sprintf(buf, "%d\n", sdev->state); -+} -+ -+static ssize_t name_show(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct switch_dev *sdev = (struct switch_dev *) -+ dev_get_drvdata(dev); -+ -+ if (sdev->print_name) { -+ int ret = sdev->print_name(sdev, buf); -+ if (ret >= 0) -+ return ret; -+ } -+ return sprintf(buf, "%s\n", sdev->name); -+} -+ -+static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL); -+static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL); -+ -+void switch_set_state(struct switch_dev *sdev, int state) -+{ -+ char name_buf[120]; -+ char state_buf[120]; -+ char *prop_buf; -+ char *envp[3]; -+ int env_offset = 0; -+ int length; -+ -+ if (sdev->state != state) { -+ sdev->state = state; -+ -+ prop_buf = (char *)get_zeroed_page(GFP_KERNEL); -+ if (prop_buf) { -+ length = name_show(sdev->dev, NULL, prop_buf); -+ if (length > 0) { -+ if (prop_buf[length - 1] == '\n') -+ prop_buf[length - 1] = 0; -+ snprintf(name_buf, sizeof(name_buf), -+ "SWITCH_NAME=%s", prop_buf); -+ envp[env_offset++] = name_buf; -+ } -+ length = state_show(sdev->dev, NULL, prop_buf); -+ if (length > 0) { -+ if (prop_buf[length - 1] == '\n') -+ prop_buf[length - 1] = 0; -+ snprintf(state_buf, sizeof(state_buf), -+ "SWITCH_STATE=%s", prop_buf); -+ envp[env_offset++] = state_buf; -+ } -+ envp[env_offset] = NULL; -+ kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp); -+ free_page((unsigned long)prop_buf); -+ } else { -+ printk(KERN_ERR "out of memory in switch_set_state\n"); -+ kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE); -+ } -+ } -+} -+EXPORT_SYMBOL_GPL(switch_set_state); -+ -+static int create_switch_class(void) -+{ -+ if (!switch_class) { -+ switch_class = class_create(THIS_MODULE, "switch"); -+ if (IS_ERR(switch_class)) -+ return PTR_ERR(switch_class); -+ atomic_set(&device_count, 0); -+ } -+ -+ return 0; -+} -+ -+int switch_dev_register(struct switch_dev *sdev) -+{ -+ int ret; -+ -+ if (!switch_class) { -+ ret = create_switch_class(); -+ if (ret < 0) -+ return ret; -+ } -+ -+ sdev->index = atomic_inc_return(&device_count); -+ sdev->dev = device_create(switch_class, NULL, -+ MKDEV(0, sdev->index), NULL, sdev->name); -+ if (IS_ERR(sdev->dev)) -+ return PTR_ERR(sdev->dev); -+ -+ ret = device_create_file(sdev->dev, &dev_attr_state); -+ if (ret < 0) -+ goto err_create_file_1; -+ ret = device_create_file(sdev->dev, &dev_attr_name); -+ if (ret < 0) -+ goto err_create_file_2; -+ -+ dev_set_drvdata(sdev->dev, sdev); -+ sdev->state = 0; -+ return 0; -+ -+err_create_file_2: -+ device_remove_file(sdev->dev, &dev_attr_state); -+err_create_file_1: -+ device_destroy(switch_class, MKDEV(0, sdev->index)); -+ printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(switch_dev_register); -+ -+void switch_dev_unregister(struct switch_dev *sdev) -+{ -+ device_remove_file(sdev->dev, &dev_attr_name); -+ device_remove_file(sdev->dev, &dev_attr_state); -+ device_destroy(switch_class, MKDEV(0, sdev->index)); -+ dev_set_drvdata(sdev->dev, NULL); -+} -+EXPORT_SYMBOL_GPL(switch_dev_unregister); -+ -+static int __init switch_class_init(void) -+{ -+ return create_switch_class(); -+} -+ -+static void __exit switch_class_exit(void) -+{ -+ class_destroy(switch_class); -+} -+ -+module_init(switch_class_init); -+module_exit(switch_class_exit); -+ -+MODULE_AUTHOR("Mike Lockwood "); -+MODULE_DESCRIPTION("Switch class driver"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/staging/android/switch/switch_gpio.c b/drivers/staging/android/switch/switch_gpio.c -new file mode 100644 -index 0000000..6ba8d97 ---- /dev/null -+++ b/drivers/staging/android/switch/switch_gpio.c -@@ -0,0 +1,172 @@ -+/* -+ * switch_gpio.c -+ * -+ * Copyright (C) 2008 Google, Inc. -+ * Author: Mike Lockwood -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "switch.h" -+ -+struct gpio_switch_data { -+ struct switch_dev sdev; -+ unsigned gpio; -+ const char *name_on; -+ const char *name_off; -+ const char *state_on; -+ const char *state_off; -+ int irq; -+ struct work_struct work; -+}; -+ -+static void gpio_switch_work(struct work_struct *work) -+{ -+ int state; -+ struct gpio_switch_data *data = -+ container_of(work, struct gpio_switch_data, work); -+ -+ state = gpio_get_value(data->gpio); -+ switch_set_state(&data->sdev, state); -+} -+ -+static irqreturn_t gpio_irq_handler(int irq, void *dev_id) -+{ -+ struct gpio_switch_data *switch_data = -+ (struct gpio_switch_data *)dev_id; -+ -+ schedule_work(&switch_data->work); -+ return IRQ_HANDLED; -+} -+ -+static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf) -+{ -+ struct gpio_switch_data *switch_data = -+ container_of(sdev, struct gpio_switch_data, sdev); -+ const char *state; -+ if (switch_get_state(sdev)) -+ state = switch_data->state_on; -+ else -+ state = switch_data->state_off; -+ -+ if (state) -+ return sprintf(buf, "%s\n", state); -+ return -1; -+} -+ -+static int gpio_switch_probe(struct platform_device *pdev) -+{ -+ struct gpio_switch_platform_data *pdata = pdev->dev.platform_data; -+ struct gpio_switch_data *switch_data; -+ int ret = 0; -+ -+ if (!pdata) -+ return -EBUSY; -+ -+ switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL); -+ if (!switch_data) -+ return -ENOMEM; -+ -+ switch_data->sdev.name = pdata->name; -+ switch_data->gpio = pdata->gpio; -+ switch_data->name_on = pdata->name_on; -+ switch_data->name_off = pdata->name_off; -+ switch_data->state_on = pdata->state_on; -+ switch_data->state_off = pdata->state_off; -+ switch_data->sdev.print_state = switch_gpio_print_state; -+ -+ ret = switch_dev_register(&switch_data->sdev); -+ if (ret < 0) -+ goto err_switch_dev_register; -+ -+ ret = gpio_request(switch_data->gpio, pdev->name); -+ if (ret < 0) -+ goto err_request_gpio; -+ -+ ret = gpio_direction_input(switch_data->gpio); -+ if (ret < 0) -+ goto err_set_gpio_input; -+ -+ INIT_WORK(&switch_data->work, gpio_switch_work); -+ -+ switch_data->irq = gpio_to_irq(switch_data->gpio); -+ if (switch_data->irq < 0) { -+ ret = switch_data->irq; -+ goto err_detect_irq_num_failed; -+ } -+ -+ ret = request_irq(switch_data->irq, gpio_irq_handler, -+ IRQF_TRIGGER_LOW, pdev->name, switch_data); -+ if (ret < 0) -+ goto err_request_irq; -+ -+ /* Perform initial detection */ -+ gpio_switch_work(&switch_data->work); -+ -+ return 0; -+ -+err_request_irq: -+err_detect_irq_num_failed: -+err_set_gpio_input: -+ gpio_free(switch_data->gpio); -+err_request_gpio: -+ switch_dev_unregister(&switch_data->sdev); -+err_switch_dev_register: -+ kfree(switch_data); -+ -+ return ret; -+} -+ -+static int __devexit gpio_switch_remove(struct platform_device *pdev) -+{ -+ struct gpio_switch_data *switch_data = platform_get_drvdata(pdev); -+ -+ cancel_work_sync(&switch_data->work); -+ gpio_free(switch_data->gpio); -+ switch_dev_unregister(&switch_data->sdev); -+ kfree(switch_data); -+ -+ return 0; -+} -+ -+static struct platform_driver gpio_switch_driver = { -+ .probe = gpio_switch_probe, -+ .remove = __devexit_p(gpio_switch_remove), -+ .driver = { -+ .name = "switch-gpio", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init gpio_switch_init(void) -+{ -+ return platform_driver_register(&gpio_switch_driver); -+} -+ -+static void __exit gpio_switch_exit(void) -+{ -+ platform_driver_unregister(&gpio_switch_driver); -+} -+ -+module_init(gpio_switch_init); -+module_exit(gpio_switch_exit); -+ -+MODULE_AUTHOR("Mike Lockwood "); -+MODULE_DESCRIPTION("GPIO Switch driver"); -+MODULE_LICENSE("GPL"); diff --git a/patches.android/android-0025-staging-android-switch-minor-code-formatting-cleanups.patch b/patches.android/android-0025-staging-android-switch-minor-code-formatting-cleanups.patch deleted file mode 100644 index 97151bdb699c..000000000000 --- a/patches.android/android-0025-staging-android-switch-minor-code-formatting-cleanups.patch +++ /dev/null @@ -1,55 +0,0 @@ -From c001dff0f6715813bdb8e978dc8c05416c01962b Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Fri, 16 Dec 2011 13:41:37 -0800 -Subject: staging: android: switch: minor code formatting cleanups -Patch-mainline: HEAD -Git-commit: c001dff0f6715813bdb8e978dc8c05416c01962b - -This fixes a number of minor space issues in the Android switch code. - -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/switch/switch.h b/drivers/staging/android/switch/switch.h -index 3e4c748..4fcb310 100644 ---- a/drivers/staging/android/switch/switch.h -+++ b/drivers/staging/android/switch/switch.h -@@ -30,7 +30,7 @@ struct switch_dev { - - struct gpio_switch_platform_data { - const char *name; -- unsigned gpio; -+ unsigned gpio; - - /* if NULL, switch_dev.name will be printed */ - const char *name_on; -diff --git a/drivers/staging/android/switch/switch_gpio.c b/drivers/staging/android/switch/switch_gpio.c -index 6ba8d97..38b2c2f 100644 ---- a/drivers/staging/android/switch/switch_gpio.c -+++ b/drivers/staging/android/switch/switch_gpio.c -@@ -91,7 +91,7 @@ static int gpio_switch_probe(struct platform_device *pdev) - switch_data->state_off = pdata->state_off; - switch_data->sdev.print_state = switch_gpio_print_state; - -- ret = switch_dev_register(&switch_data->sdev); -+ ret = switch_dev_register(&switch_data->sdev); - if (ret < 0) - goto err_switch_dev_register; - -@@ -126,7 +126,7 @@ err_detect_irq_num_failed: - err_set_gpio_input: - gpio_free(switch_data->gpio); - err_request_gpio: -- switch_dev_unregister(&switch_data->sdev); -+ switch_dev_unregister(&switch_data->sdev); - err_switch_dev_register: - kfree(switch_data); - -@@ -139,7 +139,7 @@ static int __devexit gpio_switch_remove(struct platform_device *pdev) - - cancel_work_sync(&switch_data->work); - gpio_free(switch_data->gpio); -- switch_dev_unregister(&switch_data->sdev); -+ switch_dev_unregister(&switch_data->sdev); - kfree(switch_data); - - return 0; diff --git a/patches.android/android-0026-staging-android-add-pmem-driver.patch b/patches.android/android-0026-staging-android-add-pmem-driver.patch deleted file mode 100644 index 756606ca5a16..000000000000 --- a/patches.android/android-0026-staging-android-add-pmem-driver.patch +++ /dev/null @@ -1,1499 +0,0 @@ -From b6aba85c35baa7d08b7a601b30589bcae607d9e0 Mon Sep 17 00:00:00 2001 -From: Rebecca Schultz -Date: Thu, 24 Jul 2008 11:22:53 -0700 -Subject: staging: android: add pmem driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: b6aba85c35baa7d08b7a601b30589bcae607d9e0 - -This adds the Android pmem driver to the staging tree. - -[At this point in time, it is dependent on the ARM platform, due to some -build issues that require it. - gregkh] - -Signed-off-by: Rebecca Schultz -Signed-off-by: Rebecca Schultz Zavin -Signed-off-by: Dima Zavin -Signed-off-by: Jamie Gennis -Cc: Brian Swetland -Cc: Arve HjønnevÃ¥g -Cc: Colin Cross -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index 0712b18..6094fd6 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -90,6 +90,10 @@ config ANDROID_LOW_MEMORY_KILLER - ---help--- - Register processes to be killed when memory is low - -+config ANDROID_PMEM -+ bool "Android pmem allocator" -+ depends on ARM -+ - source "drivers/staging/android/switch/Kconfig" - - endif # if ANDROID -diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile -index 36e32bc..8fd7391 100644 ---- a/drivers/staging/android/Makefile -+++ b/drivers/staging/android/Makefile -@@ -4,4 +4,5 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o - obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o - obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o - obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o -+obj-$(CONFIG_ANDROID_PMEM) += pmem.o - obj-$(CONFIG_ANDROID_SWITCH) += switch/ -diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h -new file mode 100644 -index 0000000..f633621 ---- /dev/null -+++ b/drivers/staging/android/android_pmem.h -@@ -0,0 +1,93 @@ -+/* include/linux/android_pmem.h -+ * -+ * Copyright (C) 2007 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#ifndef _ANDROID_PMEM_H_ -+#define _ANDROID_PMEM_H_ -+ -+#define PMEM_IOCTL_MAGIC 'p' -+#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int) -+#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int) -+#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int) -+#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int) -+/* This ioctl will allocate pmem space, backing the file, it will fail -+ * if the file already has an allocation, pass it the len as the argument -+ * to the ioctl */ -+#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int) -+/* This will connect a one pmem file to another, pass the file that is already -+ * backed in memory as the argument to the ioctl -+ */ -+#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int) -+/* Returns the total size of the pmem region it is sent to as a pmem_region -+ * struct (with offset set to 0). -+ */ -+#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int) -+#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int) -+ -+struct android_pmem_platform_data -+{ -+ const char* name; -+ /* starting physical address of memory region */ -+ unsigned long start; -+ /* size of memory region */ -+ unsigned long size; -+ /* set to indicate the region should not be managed with an allocator */ -+ unsigned no_allocator; -+ /* set to indicate maps of this region should be cached, if a mix of -+ * cached and uncached is desired, set this and open the device with -+ * O_SYNC to get an uncached region */ -+ unsigned cached; -+ /* The MSM7k has bits to enable a write buffer in the bus controller*/ -+ unsigned buffered; -+}; -+ -+struct pmem_region { -+ unsigned long offset; -+ unsigned long len; -+}; -+ -+#ifdef CONFIG_ANDROID_PMEM -+int is_pmem_file(struct file *file); -+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, -+ unsigned long *end, struct file **filp); -+int get_pmem_user_addr(struct file *file, unsigned long *start, -+ unsigned long *end); -+void put_pmem_file(struct file* file); -+void flush_pmem_file(struct file *file, unsigned long start, unsigned long len); -+int pmem_setup(struct android_pmem_platform_data *pdata, -+ long (*ioctl)(struct file *, unsigned int, unsigned long), -+ int (*release)(struct inode *, struct file *)); -+int pmem_remap(struct pmem_region *region, struct file *file, -+ unsigned operation); -+ -+#else -+static inline int is_pmem_file(struct file *file) { return 0; } -+static inline int get_pmem_file(int fd, unsigned long *start, -+ unsigned long *vstart, unsigned long *end, -+ struct file **filp) { return -ENOSYS; } -+static inline int get_pmem_user_addr(struct file *file, unsigned long *start, -+ unsigned long *end) { return -ENOSYS; } -+static inline void put_pmem_file(struct file* file) { return; } -+static inline void flush_pmem_file(struct file *file, unsigned long start, -+ unsigned long len) { return; } -+static inline int pmem_setup(struct android_pmem_platform_data *pdata, -+ long (*ioctl)(struct file *, unsigned int, unsigned long), -+ int (*release)(struct inode *, struct file *)) { return -ENOSYS; } -+ -+static inline int pmem_remap(struct pmem_region *region, struct file *file, -+ unsigned operation) { return -ENOSYS; } -+#endif -+ -+#endif //_ANDROID_PPP_H_ -+ -diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c -new file mode 100644 -index 0000000..7d97032 ---- /dev/null -+++ b/drivers/staging/android/pmem.c -@@ -0,0 +1,1345 @@ -+/* pmem.c -+ * -+ * Copyright (C) 2007 Google, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "android_pmem.h" -+ -+#define PMEM_MAX_DEVICES 10 -+#define PMEM_MAX_ORDER 128 -+#define PMEM_MIN_ALLOC PAGE_SIZE -+ -+#define PMEM_DEBUG 1 -+ -+/* indicates that a refernce to this file has been taken via get_pmem_file, -+ * the file should not be released until put_pmem_file is called */ -+#define PMEM_FLAGS_BUSY 0x1 -+/* indicates that this is a suballocation of a larger master range */ -+#define PMEM_FLAGS_CONNECTED 0x1 << 1 -+/* indicates this is a master and not a sub allocation and that it is mmaped */ -+#define PMEM_FLAGS_MASTERMAP 0x1 << 2 -+/* submap and unsubmap flags indicate: -+ * 00: subregion has never been mmaped -+ * 10: subregion has been mmaped, reference to the mm was taken -+ * 11: subretion has ben released, refernece to the mm still held -+ * 01: subretion has been released, reference to the mm has been released -+ */ -+#define PMEM_FLAGS_SUBMAP 0x1 << 3 -+#define PMEM_FLAGS_UNSUBMAP 0x1 << 4 -+ -+ -+struct pmem_data { -+ /* in alloc mode: an index into the bitmap -+ * in no_alloc mode: the size of the allocation */ -+ int index; -+ /* see flags above for descriptions */ -+ unsigned int flags; -+ /* protects this data field, if the mm_mmap sem will be held at the -+ * same time as this sem, the mm sem must be taken first (as this is -+ * the order for vma_open and vma_close ops */ -+ struct rw_semaphore sem; -+ /* info about the mmaping process */ -+ struct vm_area_struct *vma; -+ /* task struct of the mapping process */ -+ struct task_struct *task; -+ /* process id of teh mapping process */ -+ pid_t pid; -+ /* file descriptor of the master */ -+ int master_fd; -+ /* file struct of the master */ -+ struct file *master_file; -+ /* a list of currently available regions if this is a suballocation */ -+ struct list_head region_list; -+ /* a linked list of data so we can access them for debugging */ -+ struct list_head list; -+#if PMEM_DEBUG -+ int ref; -+#endif -+}; -+ -+struct pmem_bits { -+ unsigned allocated:1; /* 1 if allocated, 0 if free */ -+ unsigned order:7; /* size of the region in pmem space */ -+}; -+ -+struct pmem_region_node { -+ struct pmem_region region; -+ struct list_head list; -+}; -+ -+#define PMEM_DEBUG_MSGS 0 -+#if PMEM_DEBUG_MSGS -+#define DLOG(fmt,args...) \ -+ do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ -+ ##args); } \ -+ while (0) -+#else -+#define DLOG(x...) do {} while (0) -+#endif -+ -+struct pmem_info { -+ struct miscdevice dev; -+ /* physical start address of the remaped pmem space */ -+ unsigned long base; -+ /* vitual start address of the remaped pmem space */ -+ unsigned char __iomem *vbase; -+ /* total size of the pmem space */ -+ unsigned long size; -+ /* number of entries in the pmem space */ -+ unsigned long num_entries; -+ /* pfn of the garbage page in memory */ -+ unsigned long garbage_pfn; -+ /* index of the garbage page in the pmem space */ -+ int garbage_index; -+ /* the bitmap for the region indicating which entries are allocated -+ * and which are free */ -+ struct pmem_bits *bitmap; -+ /* indicates the region should not be managed with an allocator */ -+ unsigned no_allocator; -+ /* indicates maps of this region should be cached, if a mix of -+ * cached and uncached is desired, set this and open the device with -+ * O_SYNC to get an uncached region */ -+ unsigned cached; -+ unsigned buffered; -+ /* in no_allocator mode the first mapper gets the whole space and sets -+ * this flag */ -+ unsigned allocated; -+ /* for debugging, creates a list of pmem file structs, the -+ * data_list_lock should be taken before pmem_data->sem if both are -+ * needed */ -+ struct mutex data_list_lock; -+ struct list_head data_list; -+ /* pmem_sem protects the bitmap array -+ * a write lock should be held when modifying entries in bitmap -+ * a read lock should be held when reading data from bits or -+ * dereferencing a pointer into bitmap -+ * -+ * pmem_data->sem protects the pmem data of a particular file -+ * Many of the function that require the pmem_data->sem have a non- -+ * locking version for when the caller is already holding that sem. -+ * -+ * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER: -+ * down(pmem_data->sem) => down(bitmap_sem) -+ */ -+ struct rw_semaphore bitmap_sem; -+ -+ long (*ioctl)(struct file *, unsigned int, unsigned long); -+ int (*release)(struct inode *, struct file *); -+}; -+ -+static struct pmem_info pmem[PMEM_MAX_DEVICES]; -+static int id_count; -+ -+#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated) -+#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order -+#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) -+#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) -+#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC) -+#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base) -+#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC) -+#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \ -+ PMEM_LEN(id, index)) -+#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase) -+#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \ -+ PMEM_LEN(id, index)) -+#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED) -+#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK))) -+#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \ -+ (!(data->flags & PMEM_FLAGS_UNSUBMAP))) -+ -+static int pmem_release(struct inode *, struct file *); -+static int pmem_mmap(struct file *, struct vm_area_struct *); -+static int pmem_open(struct inode *, struct file *); -+static long pmem_ioctl(struct file *, unsigned int, unsigned long); -+ -+struct file_operations pmem_fops = { -+ .release = pmem_release, -+ .mmap = pmem_mmap, -+ .open = pmem_open, -+ .unlocked_ioctl = pmem_ioctl, -+}; -+ -+static int get_id(struct file *file) -+{ -+ return MINOR(file->f_dentry->d_inode->i_rdev); -+} -+ -+int is_pmem_file(struct file *file) -+{ -+ int id; -+ -+ if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode)) -+ return 0; -+ id = get_id(file); -+ if (unlikely(id >= PMEM_MAX_DEVICES)) -+ return 0; -+ if (unlikely(file->f_dentry->d_inode->i_rdev != -+ MKDEV(MISC_MAJOR, pmem[id].dev.minor))) -+ return 0; -+ return 1; -+} -+ -+static int has_allocation(struct file *file) -+{ -+ struct pmem_data *data; -+ /* check is_pmem_file first if not accessed via pmem_file_ops */ -+ -+ if (unlikely(!file->private_data)) -+ return 0; -+ data = (struct pmem_data *)file->private_data; -+ if (unlikely(data->index < 0)) -+ return 0; -+ return 1; -+} -+ -+static int is_master_owner(struct file *file) -+{ -+ struct file *master_file; -+ struct pmem_data *data; -+ int put_needed, ret = 0; -+ -+ if (!is_pmem_file(file) || !has_allocation(file)) -+ return 0; -+ data = (struct pmem_data *)file->private_data; -+ if (PMEM_FLAGS_MASTERMAP & data->flags) -+ return 1; -+ master_file = fget_light(data->master_fd, &put_needed); -+ if (master_file && data->master_file == master_file) -+ ret = 1; -+ fput_light(master_file, put_needed); -+ return ret; -+} -+ -+static int pmem_free(int id, int index) -+{ -+ /* caller should hold the write lock on pmem_sem! */ -+ int buddy, curr = index; -+ DLOG("index %d\n", index); -+ -+ if (pmem[id].no_allocator) { -+ pmem[id].allocated = 0; -+ return 0; -+ } -+ /* clean up the bitmap, merging any buddies */ -+ pmem[id].bitmap[curr].allocated = 0; -+ /* find a slots buddy Buddy# = Slot# ^ (1 << order) -+ * if the buddy is also free merge them -+ * repeat until the buddy is not free or end of the bitmap is reached -+ */ -+ do { -+ buddy = PMEM_BUDDY_INDEX(id, curr); -+ if (PMEM_IS_FREE(id, buddy) && -+ PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) { -+ PMEM_ORDER(id, buddy)++; -+ PMEM_ORDER(id, curr)++; -+ curr = min(buddy, curr); -+ } else { -+ break; -+ } -+ } while (curr < pmem[id].num_entries); -+ -+ return 0; -+} -+ -+static void pmem_revoke(struct file *file, struct pmem_data *data); -+ -+static int pmem_release(struct inode *inode, struct file *file) -+{ -+ struct pmem_data *data = (struct pmem_data *)file->private_data; -+ struct pmem_region_node *region_node; -+ struct list_head *elt, *elt2; -+ int id = get_id(file), ret = 0; -+ -+ -+ mutex_lock(&pmem[id].data_list_lock); -+ /* if this file is a master, revoke all the memory in the connected -+ * files */ -+ if (PMEM_FLAGS_MASTERMAP & data->flags) { -+ struct pmem_data *sub_data; -+ list_for_each(elt, &pmem[id].data_list) { -+ sub_data = list_entry(elt, struct pmem_data, list); -+ down_read(&sub_data->sem); -+ if (PMEM_IS_SUBMAP(sub_data) && -+ file == sub_data->master_file) { -+ up_read(&sub_data->sem); -+ pmem_revoke(file, sub_data); -+ } else -+ up_read(&sub_data->sem); -+ } -+ } -+ list_del(&data->list); -+ mutex_unlock(&pmem[id].data_list_lock); -+ -+ -+ down_write(&data->sem); -+ -+ /* if its not a conencted file and it has an allocation, free it */ -+ if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) { -+ down_write(&pmem[id].bitmap_sem); -+ ret = pmem_free(id, data->index); -+ up_write(&pmem[id].bitmap_sem); -+ } -+ -+ /* if this file is a submap (mapped, connected file), downref the -+ * task struct */ -+ if (PMEM_FLAGS_SUBMAP & data->flags) -+ if (data->task) { -+ put_task_struct(data->task); -+ data->task = NULL; -+ } -+ -+ file->private_data = NULL; -+ -+ list_for_each_safe(elt, elt2, &data->region_list) { -+ region_node = list_entry(elt, struct pmem_region_node, list); -+ list_del(elt); -+ kfree(region_node); -+ } -+ BUG_ON(!list_empty(&data->region_list)); -+ -+ up_write(&data->sem); -+ kfree(data); -+ if (pmem[id].release) -+ ret = pmem[id].release(inode, file); -+ -+ return ret; -+} -+ -+static int pmem_open(struct inode *inode, struct file *file) -+{ -+ struct pmem_data *data; -+ int id = get_id(file); -+ int ret = 0; -+ -+ DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file)); -+ /* setup file->private_data to indicate its unmapped */ -+ /* you can only open a pmem device one time */ -+ if (file->private_data != NULL) -+ return -1; -+ data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL); -+ if (!data) { -+ printk("pmem: unable to allocate memory for pmem metadata."); -+ return -1; -+ } -+ data->flags = 0; -+ data->index = -1; -+ data->task = NULL; -+ data->vma = NULL; -+ data->pid = 0; -+ data->master_file = NULL; -+#if PMEM_DEBUG -+ data->ref = 0; -+#endif -+ INIT_LIST_HEAD(&data->region_list); -+ init_rwsem(&data->sem); -+ -+ file->private_data = data; -+ INIT_LIST_HEAD(&data->list); -+ -+ mutex_lock(&pmem[id].data_list_lock); -+ list_add(&data->list, &pmem[id].data_list); -+ mutex_unlock(&pmem[id].data_list_lock); -+ return ret; -+} -+ -+static unsigned long pmem_order(unsigned long len) -+{ -+ int i; -+ -+ len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC; -+ len--; -+ for (i = 0; i < sizeof(len)*8; i++) -+ if (len >> i == 0) -+ break; -+ return i; -+} -+ -+static int pmem_allocate(int id, unsigned long len) -+{ -+ /* caller should hold the write lock on pmem_sem! */ -+ /* return the corresponding pdata[] entry */ -+ int curr = 0; -+ int end = pmem[id].num_entries; -+ int best_fit = -1; -+ unsigned long order = pmem_order(len); -+ -+ if (pmem[id].no_allocator) { -+ DLOG("no allocator"); -+ if ((len > pmem[id].size) || pmem[id].allocated) -+ return -1; -+ pmem[id].allocated = 1; -+ return len; -+ } -+ -+ if (order > PMEM_MAX_ORDER) -+ return -1; -+ DLOG("order %lx\n", order); -+ -+ /* look through the bitmap: -+ * if you find a free slot of the correct order use it -+ * otherwise, use the best fit (smallest with size > order) slot -+ */ -+ while (curr < end) { -+ if (PMEM_IS_FREE(id, curr)) { -+ if (PMEM_ORDER(id, curr) == (unsigned char)order) { -+ /* set the not free bit and clear others */ -+ best_fit = curr; -+ break; -+ } -+ if (PMEM_ORDER(id, curr) > (unsigned char)order && -+ (best_fit < 0 || -+ PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit))) -+ best_fit = curr; -+ } -+ curr = PMEM_NEXT_INDEX(id, curr); -+ } -+ -+ /* if best_fit < 0, there are no suitable slots, -+ * return an error -+ */ -+ if (best_fit < 0) { -+ printk("pmem: no space left to allocate!\n"); -+ return -1; -+ } -+ -+ /* now partition the best fit: -+ * split the slot into 2 buddies of order - 1 -+ * repeat until the slot is of the correct order -+ */ -+ while (PMEM_ORDER(id, best_fit) > (unsigned char)order) { -+ int buddy; -+ PMEM_ORDER(id, best_fit) -= 1; -+ buddy = PMEM_BUDDY_INDEX(id, best_fit); -+ PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit); -+ } -+ pmem[id].bitmap[best_fit].allocated = 1; -+ return best_fit; -+} -+ -+static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot) -+{ -+ int id = get_id(file); -+#ifdef pgprot_noncached -+ if (pmem[id].cached == 0 || file->f_flags & O_SYNC) -+ return pgprot_noncached(vma_prot); -+#endif -+#ifdef pgprot_ext_buffered -+ else if (pmem[id].buffered) -+ return pgprot_ext_buffered(vma_prot); -+#endif -+ return vma_prot; -+} -+ -+static unsigned long pmem_start_addr(int id, struct pmem_data *data) -+{ -+ if (pmem[id].no_allocator) -+ return PMEM_START_ADDR(id, 0); -+ else -+ return PMEM_START_ADDR(id, data->index); -+ -+} -+ -+static void *pmem_start_vaddr(int id, struct pmem_data *data) -+{ -+ return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase; -+} -+ -+static unsigned long pmem_len(int id, struct pmem_data *data) -+{ -+ if (pmem[id].no_allocator) -+ return data->index; -+ else -+ return PMEM_LEN(id, data->index); -+} -+ -+static int pmem_map_garbage(int id, struct vm_area_struct *vma, -+ struct pmem_data *data, unsigned long offset, -+ unsigned long len) -+{ -+ int i, garbage_pages = len >> PAGE_SHIFT; -+ -+ vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE; -+ for (i = 0; i < garbage_pages; i++) { -+ if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE), -+ pmem[id].garbage_pfn)) -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma, -+ struct pmem_data *data, unsigned long offset, -+ unsigned long len) -+{ -+ int garbage_pages; -+ DLOG("unmap offset %lx len %lx\n", offset, len); -+ -+ BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); -+ -+ garbage_pages = len >> PAGE_SHIFT; -+ zap_page_range(vma, vma->vm_start + offset, len, NULL); -+ pmem_map_garbage(id, vma, data, offset, len); -+ return 0; -+} -+ -+static int pmem_map_pfn_range(int id, struct vm_area_struct *vma, -+ struct pmem_data *data, unsigned long offset, -+ unsigned long len) -+{ -+ DLOG("map offset %lx len %lx\n", offset, len); -+ BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start)); -+ BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end)); -+ BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); -+ BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset)); -+ -+ if (io_remap_pfn_range(vma, vma->vm_start + offset, -+ (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT, -+ len, vma->vm_page_prot)) { -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma, -+ struct pmem_data *data, unsigned long offset, -+ unsigned long len) -+{ -+ /* hold the mm semp for the vma you are modifying when you call this */ -+ BUG_ON(!vma); -+ zap_page_range(vma, vma->vm_start + offset, len, NULL); -+ return pmem_map_pfn_range(id, vma, data, offset, len); -+} -+ -+static void pmem_vma_open(struct vm_area_struct *vma) -+{ -+ struct file *file = vma->vm_file; -+ struct pmem_data *data = file->private_data; -+ int id = get_id(file); -+ /* this should never be called as we don't support copying pmem -+ * ranges via fork */ -+ BUG_ON(!has_allocation(file)); -+ down_write(&data->sem); -+ /* remap the garbage pages, forkers don't get access to the data */ -+ pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end); -+ up_write(&data->sem); -+} -+ -+static void pmem_vma_close(struct vm_area_struct *vma) -+{ -+ struct file *file = vma->vm_file; -+ struct pmem_data *data = file->private_data; -+ -+ DLOG("current %u ppid %u file %p count %d\n", current->pid, -+ current->parent->pid, file, file_count(file)); -+ if (unlikely(!is_pmem_file(file) || !has_allocation(file))) { -+ printk(KERN_WARNING "pmem: something is very wrong, you are " -+ "closing a vm backing an allocation that doesn't " -+ "exist!\n"); -+ return; -+ } -+ down_write(&data->sem); -+ if (data->vma == vma) { -+ data->vma = NULL; -+ if ((data->flags & PMEM_FLAGS_CONNECTED) && -+ (data->flags & PMEM_FLAGS_SUBMAP)) -+ data->flags |= PMEM_FLAGS_UNSUBMAP; -+ } -+ /* the kernel is going to free this vma now anyway */ -+ up_write(&data->sem); -+} -+ -+static struct vm_operations_struct vm_ops = { -+ .open = pmem_vma_open, -+ .close = pmem_vma_close, -+}; -+ -+static int pmem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ struct pmem_data *data; -+ int index; -+ unsigned long vma_size = vma->vm_end - vma->vm_start; -+ int ret = 0, id = get_id(file); -+ -+ if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) { -+#if PMEM_DEBUG -+ printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned" -+ " and a multiple of pages_size.\n"); -+#endif -+ return -EINVAL; -+ } -+ -+ data = (struct pmem_data *)file->private_data; -+ down_write(&data->sem); -+ /* check this file isn't already mmaped, for submaps check this file -+ * has never been mmaped */ -+ if ((data->flags & PMEM_FLAGS_SUBMAP) || -+ (data->flags & PMEM_FLAGS_UNSUBMAP)) { -+#if PMEM_DEBUG -+ printk(KERN_ERR "pmem: you can only mmap a pmem file once, " -+ "this file is already mmaped. %x\n", data->flags); -+#endif -+ ret = -EINVAL; -+ goto error; -+ } -+ /* if file->private_data == unalloced, alloc*/ -+ if (data && data->index == -1) { -+ down_write(&pmem[id].bitmap_sem); -+ index = pmem_allocate(id, vma->vm_end - vma->vm_start); -+ up_write(&pmem[id].bitmap_sem); -+ data->index = index; -+ } -+ /* either no space was available or an error occured */ -+ if (!has_allocation(file)) { -+ ret = -EINVAL; -+ printk("pmem: could not find allocation for map.\n"); -+ goto error; -+ } -+ -+ if (pmem_len(id, data) < vma_size) { -+#if PMEM_DEBUG -+ printk(KERN_WARNING "pmem: mmap size [%lu] does not match" -+ "size of backing region [%lu].\n", vma_size, -+ pmem_len(id, data)); -+#endif -+ ret = -EINVAL; -+ goto error; -+ } -+ -+ vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT; -+ vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot); -+ -+ if (data->flags & PMEM_FLAGS_CONNECTED) { -+ struct pmem_region_node *region_node; -+ struct list_head *elt; -+ if (pmem_map_garbage(id, vma, data, 0, vma_size)) { -+ printk("pmem: mmap failed in kernel!\n"); -+ ret = -EAGAIN; -+ goto error; -+ } -+ list_for_each(elt, &data->region_list) { -+ region_node = list_entry(elt, struct pmem_region_node, -+ list); -+ DLOG("remapping file: %p %lx %lx\n", file, -+ region_node->region.offset, -+ region_node->region.len); -+ if (pmem_remap_pfn_range(id, vma, data, -+ region_node->region.offset, -+ region_node->region.len)) { -+ ret = -EAGAIN; -+ goto error; -+ } -+ } -+ data->flags |= PMEM_FLAGS_SUBMAP; -+ get_task_struct(current->group_leader); -+ data->task = current->group_leader; -+ data->vma = vma; -+#if PMEM_DEBUG -+ data->pid = current->pid; -+#endif -+ DLOG("submmapped file %p vma %p pid %u\n", file, vma, -+ current->pid); -+ } else { -+ if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) { -+ printk(KERN_INFO "pmem: mmap failed in kernel!\n"); -+ ret = -EAGAIN; -+ goto error; -+ } -+ data->flags |= PMEM_FLAGS_MASTERMAP; -+ data->pid = current->pid; -+ } -+ vma->vm_ops = &vm_ops; -+error: -+ up_write(&data->sem); -+ return ret; -+} -+ -+/* the following are the api for accessing pmem regions by other drivers -+ * from inside the kernel */ -+int get_pmem_user_addr(struct file *file, unsigned long *start, -+ unsigned long *len) -+{ -+ struct pmem_data *data; -+ if (!is_pmem_file(file) || !has_allocation(file)) { -+#if PMEM_DEBUG -+ printk(KERN_INFO "pmem: requested pmem data from invalid" -+ "file.\n"); -+#endif -+ return -1; -+ } -+ data = (struct pmem_data *)file->private_data; -+ down_read(&data->sem); -+ if (data->vma) { -+ *start = data->vma->vm_start; -+ *len = data->vma->vm_end - data->vma->vm_start; -+ } else { -+ *start = 0; -+ *len = 0; -+ } -+ up_read(&data->sem); -+ return 0; -+} -+ -+int get_pmem_addr(struct file *file, unsigned long *start, -+ unsigned long *vstart, unsigned long *len) -+{ -+ struct pmem_data *data; -+ int id; -+ -+ if (!is_pmem_file(file) || !has_allocation(file)) { -+ return -1; -+ } -+ -+ data = (struct pmem_data *)file->private_data; -+ if (data->index == -1) { -+#if PMEM_DEBUG -+ printk(KERN_INFO "pmem: requested pmem data from file with no " -+ "allocation.\n"); -+ return -1; -+#endif -+ } -+ id = get_id(file); -+ -+ down_read(&data->sem); -+ *start = pmem_start_addr(id, data); -+ *len = pmem_len(id, data); -+ *vstart = (unsigned long)pmem_start_vaddr(id, data); -+ up_read(&data->sem); -+#if PMEM_DEBUG -+ down_write(&data->sem); -+ data->ref++; -+ up_write(&data->sem); -+#endif -+ return 0; -+} -+ -+int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, -+ unsigned long *len, struct file **filp) -+{ -+ struct file *file; -+ -+ file = fget(fd); -+ if (unlikely(file == NULL)) { -+ printk(KERN_INFO "pmem: requested data from file descriptor " -+ "that doesn't exist."); -+ return -1; -+ } -+ -+ if (get_pmem_addr(file, start, vstart, len)) -+ goto end; -+ -+ if (filp) -+ *filp = file; -+ return 0; -+end: -+ fput(file); -+ return -1; -+} -+ -+void put_pmem_file(struct file *file) -+{ -+ struct pmem_data *data; -+ int id; -+ -+ if (!is_pmem_file(file)) -+ return; -+ id = get_id(file); -+ data = (struct pmem_data *)file->private_data; -+#if PMEM_DEBUG -+ down_write(&data->sem); -+ if (data->ref == 0) { -+ printk("pmem: pmem_put > pmem_get %s (pid %d)\n", -+ pmem[id].dev.name, data->pid); -+ BUG(); -+ } -+ data->ref--; -+ up_write(&data->sem); -+#endif -+ fput(file); -+} -+ -+void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len) -+{ -+ struct pmem_data *data; -+ int id; -+ void *vaddr; -+ struct pmem_region_node *region_node; -+ struct list_head *elt; -+ void *flush_start, *flush_end; -+ -+ if (!is_pmem_file(file) || !has_allocation(file)) { -+ return; -+ } -+ -+ id = get_id(file); -+ data = (struct pmem_data *)file->private_data; -+ if (!pmem[id].cached || file->f_flags & O_SYNC) -+ return; -+ -+ down_read(&data->sem); -+ vaddr = pmem_start_vaddr(id, data); -+ /* if this isn't a submmapped file, flush the whole thing */ -+ if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) { -+ dmac_flush_range(vaddr, vaddr + pmem_len(id, data)); -+ goto end; -+ } -+ /* otherwise, flush the region of the file we are drawing */ -+ list_for_each(elt, &data->region_list) { -+ region_node = list_entry(elt, struct pmem_region_node, list); -+ if ((offset >= region_node->region.offset) && -+ ((offset + len) <= (region_node->region.offset + -+ region_node->region.len))) { -+ flush_start = vaddr + region_node->region.offset; -+ flush_end = flush_start + region_node->region.len; -+ dmac_flush_range(flush_start, flush_end); -+ break; -+ } -+ } -+end: -+ up_read(&data->sem); -+} -+ -+static int pmem_connect(unsigned long connect, struct file *file) -+{ -+ struct pmem_data *data = (struct pmem_data *)file->private_data; -+ struct pmem_data *src_data; -+ struct file *src_file; -+ int ret = 0, put_needed; -+ -+ down_write(&data->sem); -+ /* retrieve the src file and check it is a pmem file with an alloc */ -+ src_file = fget_light(connect, &put_needed); -+ DLOG("connect %p to %p\n", file, src_file); -+ if (!src_file) { -+ printk("pmem: src file not found!\n"); -+ ret = -EINVAL; -+ goto err_no_file; -+ } -+ if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) { -+ printk(KERN_INFO "pmem: src file is not a pmem file or has no " -+ "alloc!\n"); -+ ret = -EINVAL; -+ goto err_bad_file; -+ } -+ src_data = (struct pmem_data *)src_file->private_data; -+ -+ if (has_allocation(file) && (data->index != src_data->index)) { -+ printk("pmem: file is already mapped but doesn't match this" -+ " src_file!\n"); -+ ret = -EINVAL; -+ goto err_bad_file; -+ } -+ data->index = src_data->index; -+ data->flags |= PMEM_FLAGS_CONNECTED; -+ data->master_fd = connect; -+ data->master_file = src_file; -+ -+err_bad_file: -+ fput_light(src_file, put_needed); -+err_no_file: -+ up_write(&data->sem); -+ return ret; -+} -+ -+static void pmem_unlock_data_and_mm(struct pmem_data *data, -+ struct mm_struct *mm) -+{ -+ up_write(&data->sem); -+ if (mm != NULL) { -+ up_write(&mm->mmap_sem); -+ mmput(mm); -+ } -+} -+ -+static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data, -+ struct mm_struct **locked_mm) -+{ -+ int ret = 0; -+ struct mm_struct *mm = NULL; -+ *locked_mm = NULL; -+lock_mm: -+ down_read(&data->sem); -+ if (PMEM_IS_SUBMAP(data)) { -+ mm = get_task_mm(data->task); -+ if (!mm) { -+#if PMEM_DEBUG -+ printk("pmem: can't remap task is gone!\n"); -+#endif -+ up_read(&data->sem); -+ return -1; -+ } -+ } -+ up_read(&data->sem); -+ -+ if (mm) -+ down_write(&mm->mmap_sem); -+ -+ down_write(&data->sem); -+ /* check that the file didn't get mmaped before we could take the -+ * data sem, this should be safe b/c you can only submap each file -+ * once */ -+ if (PMEM_IS_SUBMAP(data) && !mm) { -+ pmem_unlock_data_and_mm(data, mm); -+ up_write(&data->sem); -+ goto lock_mm; -+ } -+ /* now check that vma.mm is still there, it could have been -+ * deleted by vma_close before we could get the data->sem */ -+ if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) { -+ /* might as well release this */ -+ if (data->flags & PMEM_FLAGS_SUBMAP) { -+ put_task_struct(data->task); -+ data->task = NULL; -+ /* lower the submap flag to show the mm is gone */ -+ data->flags &= ~(PMEM_FLAGS_SUBMAP); -+ } -+ pmem_unlock_data_and_mm(data, mm); -+ return -1; -+ } -+ *locked_mm = mm; -+ return ret; -+} -+ -+int pmem_remap(struct pmem_region *region, struct file *file, -+ unsigned operation) -+{ -+ int ret; -+ struct pmem_region_node *region_node; -+ struct mm_struct *mm = NULL; -+ struct list_head *elt, *elt2; -+ int id = get_id(file); -+ struct pmem_data *data = (struct pmem_data *)file->private_data; -+ -+ /* pmem region must be aligned on a page boundry */ -+ if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || -+ !PMEM_IS_PAGE_ALIGNED(region->len))) { -+#if PMEM_DEBUG -+ printk("pmem: request for unaligned pmem suballocation " -+ "%lx %lx\n", region->offset, region->len); -+#endif -+ return -EINVAL; -+ } -+ -+ /* if userspace requests a region of len 0, there's nothing to do */ -+ if (region->len == 0) -+ return 0; -+ -+ /* lock the mm and data */ -+ ret = pmem_lock_data_and_mm(file, data, &mm); -+ if (ret) -+ return 0; -+ -+ /* only the owner of the master file can remap the client fds -+ * that back in it */ -+ if (!is_master_owner(file)) { -+#if PMEM_DEBUG -+ printk("pmem: remap requested from non-master process\n"); -+#endif -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ /* check that the requested range is within the src allocation */ -+ if (unlikely((region->offset > pmem_len(id, data)) || -+ (region->len > pmem_len(id, data)) || -+ (region->offset + region->len > pmem_len(id, data)))) { -+#if PMEM_DEBUG -+ printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n"); -+#endif -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (operation == PMEM_MAP) { -+ region_node = kmalloc(sizeof(struct pmem_region_node), -+ GFP_KERNEL); -+ if (!region_node) { -+ ret = -ENOMEM; -+#if PMEM_DEBUG -+ printk(KERN_INFO "No space to allocate metadata!"); -+#endif -+ goto err; -+ } -+ region_node->region = *region; -+ list_add(®ion_node->list, &data->region_list); -+ } else if (operation == PMEM_UNMAP) { -+ int found = 0; -+ list_for_each_safe(elt, elt2, &data->region_list) { -+ region_node = list_entry(elt, struct pmem_region_node, -+ list); -+ if (region->len == 0 || -+ (region_node->region.offset == region->offset && -+ region_node->region.len == region->len)) { -+ list_del(elt); -+ kfree(region_node); -+ found = 1; -+ } -+ } -+ if (!found) { -+#if PMEM_DEBUG -+ printk("pmem: Unmap region does not map any mapped " -+ "region!"); -+#endif -+ ret = -EINVAL; -+ goto err; -+ } -+ } -+ -+ if (data->vma && PMEM_IS_SUBMAP(data)) { -+ if (operation == PMEM_MAP) -+ ret = pmem_remap_pfn_range(id, data->vma, data, -+ region->offset, region->len); -+ else if (operation == PMEM_UNMAP) -+ ret = pmem_unmap_pfn_range(id, data->vma, data, -+ region->offset, region->len); -+ } -+ -+err: -+ pmem_unlock_data_and_mm(data, mm); -+ return ret; -+} -+ -+static void pmem_revoke(struct file *file, struct pmem_data *data) -+{ -+ struct pmem_region_node *region_node; -+ struct list_head *elt, *elt2; -+ struct mm_struct *mm = NULL; -+ int id = get_id(file); -+ int ret = 0; -+ -+ data->master_file = NULL; -+ ret = pmem_lock_data_and_mm(file, data, &mm); -+ /* if lock_data_and_mm fails either the task that mapped the fd, or -+ * the vma that mapped it have already gone away, nothing more -+ * needs to be done */ -+ if (ret) -+ return; -+ /* unmap everything */ -+ /* delete the regions and region list nothing is mapped any more */ -+ if (data->vma) -+ list_for_each_safe(elt, elt2, &data->region_list) { -+ region_node = list_entry(elt, struct pmem_region_node, -+ list); -+ pmem_unmap_pfn_range(id, data->vma, data, -+ region_node->region.offset, -+ region_node->region.len); -+ list_del(elt); -+ kfree(region_node); -+ } -+ /* delete the master file */ -+ pmem_unlock_data_and_mm(data, mm); -+} -+ -+static void pmem_get_size(struct pmem_region *region, struct file *file) -+{ -+ struct pmem_data *data = (struct pmem_data *)file->private_data; -+ int id = get_id(file); -+ -+ if (!has_allocation(file)) { -+ region->offset = 0; -+ region->len = 0; -+ return; -+ } else { -+ region->offset = pmem_start_addr(id, data); -+ region->len = pmem_len(id, data); -+ } -+ DLOG("offset %lx len %lx\n", region->offset, region->len); -+} -+ -+ -+static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct pmem_data *data; -+ int id = get_id(file); -+ -+ switch (cmd) { -+ case PMEM_GET_PHYS: -+ { -+ struct pmem_region region; -+ DLOG("get_phys\n"); -+ if (!has_allocation(file)) { -+ region.offset = 0; -+ region.len = 0; -+ } else { -+ data = (struct pmem_data *)file->private_data; -+ region.offset = pmem_start_addr(id, data); -+ region.len = pmem_len(id, data); -+ } -+ printk(KERN_INFO "pmem: request for physical address of pmem region " -+ "from process %d.\n", current->pid); -+ if (copy_to_user((void __user *)arg, ®ion, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ break; -+ } -+ case PMEM_MAP: -+ { -+ struct pmem_region region; -+ if (copy_from_user(®ion, (void __user *)arg, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ data = (struct pmem_data *)file->private_data; -+ return pmem_remap(®ion, file, PMEM_MAP); -+ } -+ break; -+ case PMEM_UNMAP: -+ { -+ struct pmem_region region; -+ if (copy_from_user(®ion, (void __user *)arg, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ data = (struct pmem_data *)file->private_data; -+ return pmem_remap(®ion, file, PMEM_UNMAP); -+ break; -+ } -+ case PMEM_GET_SIZE: -+ { -+ struct pmem_region region; -+ DLOG("get_size\n"); -+ pmem_get_size(®ion, file); -+ if (copy_to_user((void __user *)arg, ®ion, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ break; -+ } -+ case PMEM_GET_TOTAL_SIZE: -+ { -+ struct pmem_region region; -+ DLOG("get total size\n"); -+ region.offset = 0; -+ get_id(file); -+ region.len = pmem[id].size; -+ if (copy_to_user((void __user *)arg, ®ion, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ break; -+ } -+ case PMEM_ALLOCATE: -+ { -+ if (has_allocation(file)) -+ return -EINVAL; -+ data = (struct pmem_data *)file->private_data; -+ data->index = pmem_allocate(id, arg); -+ break; -+ } -+ case PMEM_CONNECT: -+ DLOG("connect\n"); -+ return pmem_connect(arg, file); -+ break; -+ case PMEM_CACHE_FLUSH: -+ { -+ struct pmem_region region; -+ DLOG("flush\n"); -+ if (copy_from_user(®ion, (void __user *)arg, -+ sizeof(struct pmem_region))) -+ return -EFAULT; -+ flush_pmem_file(file, region.offset, region.len); -+ break; -+ } -+ default: -+ if (pmem[id].ioctl) -+ return pmem[id].ioctl(file, cmd, arg); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+#if PMEM_DEBUG -+static ssize_t debug_open(struct inode *inode, struct file *file) -+{ -+ file->private_data = inode->i_private; -+ return 0; -+} -+ -+static ssize_t debug_read(struct file *file, char __user *buf, size_t count, -+ loff_t *ppos) -+{ -+ struct list_head *elt, *elt2; -+ struct pmem_data *data; -+ struct pmem_region_node *region_node; -+ int id = (int)file->private_data; -+ const int debug_bufmax = 4096; -+ static char buffer[4096]; -+ int n = 0; -+ -+ DLOG("debug open\n"); -+ n = scnprintf(buffer, debug_bufmax, -+ "pid #: mapped regions (offset, len) (offset,len)...\n"); -+ -+ mutex_lock(&pmem[id].data_list_lock); -+ list_for_each(elt, &pmem[id].data_list) { -+ data = list_entry(elt, struct pmem_data, list); -+ down_read(&data->sem); -+ n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:", -+ data->pid); -+ list_for_each(elt2, &data->region_list) { -+ region_node = list_entry(elt2, struct pmem_region_node, -+ list); -+ n += scnprintf(buffer + n, debug_bufmax - n, -+ "(%lx,%lx) ", -+ region_node->region.offset, -+ region_node->region.len); -+ } -+ n += scnprintf(buffer + n, debug_bufmax - n, "\n"); -+ up_read(&data->sem); -+ } -+ mutex_unlock(&pmem[id].data_list_lock); -+ -+ n++; -+ buffer[n] = 0; -+ return simple_read_from_buffer(buf, count, ppos, buffer, n); -+} -+ -+static struct file_operations debug_fops = { -+ .read = debug_read, -+ .open = debug_open, -+}; -+#endif -+ -+#if 0 -+static struct miscdevice pmem_dev = { -+ .name = "pmem", -+ .fops = &pmem_fops, -+}; -+#endif -+ -+int pmem_setup(struct android_pmem_platform_data *pdata, -+ long (*ioctl)(struct file *, unsigned int, unsigned long), -+ int (*release)(struct inode *, struct file *)) -+{ -+ int err = 0; -+ int i, index = 0; -+ int id = id_count; -+ id_count++; -+ -+ pmem[id].no_allocator = pdata->no_allocator; -+ pmem[id].cached = pdata->cached; -+ pmem[id].buffered = pdata->buffered; -+ pmem[id].base = pdata->start; -+ pmem[id].size = pdata->size; -+ pmem[id].ioctl = ioctl; -+ pmem[id].release = release; -+ init_rwsem(&pmem[id].bitmap_sem); -+ mutex_init(&pmem[id].data_list_lock); -+ INIT_LIST_HEAD(&pmem[id].data_list); -+ pmem[id].dev.name = pdata->name; -+ pmem[id].dev.minor = id; -+ pmem[id].dev.fops = &pmem_fops; -+ printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached); -+ -+ err = misc_register(&pmem[id].dev); -+ if (err) { -+ printk(KERN_ALERT "Unable to register pmem driver!\n"); -+ goto err_cant_register_device; -+ } -+ pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC; -+ -+ pmem[id].bitmap = kmalloc(pmem[id].num_entries * -+ sizeof(struct pmem_bits), GFP_KERNEL); -+ if (!pmem[id].bitmap) -+ goto err_no_mem_for_metadata; -+ -+ memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) * -+ pmem[id].num_entries); -+ -+ for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) { -+ if ((pmem[id].num_entries) & 1<name, S_IFREG | S_IRUGO, NULL, (void *)id, -+ &debug_fops); -+#endif -+ return 0; -+error_cant_remap: -+ kfree(pmem[id].bitmap); -+err_no_mem_for_metadata: -+ misc_deregister(&pmem[id].dev); -+err_cant_register_device: -+ return -1; -+} -+ -+static int pmem_probe(struct platform_device *pdev) -+{ -+ struct android_pmem_platform_data *pdata; -+ -+ if (!pdev || !pdev->dev.platform_data) { -+ printk(KERN_ALERT "Unable to probe pmem!\n"); -+ return -1; -+ } -+ pdata = pdev->dev.platform_data; -+ return pmem_setup(pdata, NULL, NULL); -+} -+ -+ -+static int pmem_remove(struct platform_device *pdev) -+{ -+ int id = pdev->id; -+ __free_page(pfn_to_page(pmem[id].garbage_pfn)); -+ misc_deregister(&pmem[id].dev); -+ return 0; -+} -+ -+static struct platform_driver pmem_driver = { -+ .probe = pmem_probe, -+ .remove = pmem_remove, -+ .driver = { .name = "android_pmem" } -+}; -+ -+ -+static int __init pmem_init(void) -+{ -+ return platform_driver_register(&pmem_driver); -+} -+ -+static void __exit pmem_exit(void) -+{ -+ platform_driver_unregister(&pmem_driver); -+} -+ -+module_init(pmem_init); -+module_exit(pmem_exit); -+ diff --git a/patches.android/android-0027-ashmem-Anonymous-shared-memory-subsystem.patch b/patches.android/android-0027-ashmem-Anonymous-shared-memory-subsystem.patch deleted file mode 100644 index 1d3f83365c6f..000000000000 --- a/patches.android/android-0027-ashmem-Anonymous-shared-memory-subsystem.patch +++ /dev/null @@ -1,829 +0,0 @@ -From 11980c2ac4ccfad21a5f8ee9e12059f1e687bb40 Mon Sep 17 00:00:00 2001 -From: Robert Love -Date: Tue, 20 Dec 2011 16:49:48 -0800 -Subject: ashmem: Anonymous shared memory subsystem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 11980c2ac4ccfad21a5f8ee9e12059f1e687bb40 - -The anonymous shared memory (ashmem) subsystem provides a -Unix-y,file-based shared memory interface to user-space. It -works like anonymous memory (e.g. mmapping fd=0) except if -you share the file descriptor via the usual means, you will -share the mapping. The shared memory can be accessed via both -mmap or file I/O. The backing store is a simple shmem file. - -Additionally, ashmem introduces the concept of page pinning. -Pinned pages (the default) behave like any anonymous memory. -Unpinned pages are available to the kernel for eviction during -VM pressure. When repinning the pages, the return value -instructs user-space as to any eviction. In this manner, -user-space processes may implement caching and similar -resource management that efficiently integrates with kernel -memory management. - -Signed-off-by: Robert Love - -ashmem: Don't install fault handler for private mmaps. - -Ashmem is used to create named private heaps. If this heap is backed -by a tmpfs file it will allocate two pages for every page touched. -In 2.6.27, the extra page would later be freed, but 2.6.29 does not -scan anonymous pages when running without swap so the memory is not -freed while the file is referenced. This change changes the behavior -of private ashmem mmaps to match /dev/zero instead tmpfs. - -Signed-off-by: Arve HjønnevÃ¥g - -ashmem: Add common prefix to name reported in /proc/pid/maps - -Signed-off-by: Arve HjønnevÃ¥g - -ashmem: don't require a page aligned size - -This makes ashmem more similar to shmem and mmap, by -not requiring the specified size to be page aligned, -instead rounding it internally as needed. - -Signed-off-by: Marco Nelissen -[jstultz: Improved commit subject and included patch description -from rlove. Also moved ashmem files to staging dir, and reworked -code to avoid touching mm/shmem.c while we're in staging.] -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index 6094fd6..becf711 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -12,6 +12,15 @@ config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" - default n - -+config ASHMEM -+ bool "Enable the Anonymous Shared Memory Subsystem" -+ default n -+ depends on SHMEM || TINY_SHMEM -+ help -+ The ashmem subsystem is a new shared memory allocator, similar to -+ POSIX SHM but with different behavior and sporting a simpler -+ file-based API. -+ - config ANDROID_LOGGER - tristate "Android log driver" - default n -diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile -index 8fd7391..eaed1ff 100644 ---- a/drivers/staging/android/Makefile -+++ b/drivers/staging/android/Makefile -@@ -1,4 +1,5 @@ - obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o -+obj-$(CONFIG_ASHMEM) += ashmem.o - obj-$(CONFIG_ANDROID_LOGGER) += logger.o - obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o - obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -new file mode 100644 -index 0000000..5775c6c ---- /dev/null -+++ b/drivers/staging/android/ashmem.c -@@ -0,0 +1,678 @@ -+/* mm/ashmem.c -+** -+** Anonymous Shared Memory Subsystem, ashmem -+** -+** Copyright (C) 2008 Google, Inc. -+** -+** Robert Love -+** -+** This software is licensed under the terms of the GNU General Public -+** License version 2, as published by the Free Software Foundation, and -+** may be copied, distributed, and modified under those terms. -+** -+** 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. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "ashmem.h" -+ -+#define ASHMEM_NAME_PREFIX "dev/ashmem/" -+#define ASHMEM_NAME_PREFIX_LEN (sizeof(ASHMEM_NAME_PREFIX) - 1) -+#define ASHMEM_FULL_NAME_LEN (ASHMEM_NAME_LEN + ASHMEM_NAME_PREFIX_LEN) -+ -+/* -+ * ashmem_area - anonymous shared memory area -+ * Lifecycle: From our parent file's open() until its release() -+ * Locking: Protected by `ashmem_mutex' -+ * Big Note: Mappings do NOT pin this structure; it dies on close() -+ */ -+struct ashmem_area { -+ char name[ASHMEM_FULL_NAME_LEN];/* optional name for /proc/pid/maps */ -+ struct list_head unpinned_list; /* list of all ashmem areas */ -+ struct file *file; /* the shmem-based backing file */ -+ size_t size; /* size of the mapping, in bytes */ -+ unsigned long prot_mask; /* allowed prot bits, as vm_flags */ -+}; -+ -+/* -+ * ashmem_range - represents an interval of unpinned (evictable) pages -+ * Lifecycle: From unpin to pin -+ * Locking: Protected by `ashmem_mutex' -+ */ -+struct ashmem_range { -+ struct list_head lru; /* entry in LRU list */ -+ struct list_head unpinned; /* entry in its area's unpinned list */ -+ struct ashmem_area *asma; /* associated area */ -+ size_t pgstart; /* starting page, inclusive */ -+ size_t pgend; /* ending page, inclusive */ -+ unsigned int purged; /* ASHMEM_NOT or ASHMEM_WAS_PURGED */ -+}; -+ -+/* LRU list of unpinned pages, protected by ashmem_mutex */ -+static LIST_HEAD(ashmem_lru_list); -+ -+/* Count of pages on our LRU list, protected by ashmem_mutex */ -+static unsigned long lru_count; -+ -+/* -+ * ashmem_mutex - protects the list of and each individual ashmem_area -+ * -+ * Lock Ordering: ashmex_mutex -> i_mutex -> i_alloc_sem -+ */ -+static DEFINE_MUTEX(ashmem_mutex); -+ -+static struct kmem_cache *ashmem_area_cachep __read_mostly; -+static struct kmem_cache *ashmem_range_cachep __read_mostly; -+ -+#define range_size(range) \ -+ ((range)->pgend - (range)->pgstart + 1) -+ -+#define range_on_lru(range) \ -+ ((range)->purged == ASHMEM_NOT_PURGED) -+ -+#define page_range_subsumes_range(range, start, end) \ -+ (((range)->pgstart >= (start)) && ((range)->pgend <= (end))) -+ -+#define page_range_subsumed_by_range(range, start, end) \ -+ (((range)->pgstart <= (start)) && ((range)->pgend >= (end))) -+ -+#define page_in_range(range, page) \ -+ (((range)->pgstart <= (page)) && ((range)->pgend >= (page))) -+ -+#define page_range_in_range(range, start, end) \ -+ (page_in_range(range, start) || page_in_range(range, end) || \ -+ page_range_subsumes_range(range, start, end)) -+ -+#define range_before_page(range, page) \ -+ ((range)->pgend < (page)) -+ -+#define PROT_MASK (PROT_EXEC | PROT_READ | PROT_WRITE) -+ -+static inline void lru_add(struct ashmem_range *range) -+{ -+ list_add_tail(&range->lru, &ashmem_lru_list); -+ lru_count += range_size(range); -+} -+ -+static inline void lru_del(struct ashmem_range *range) -+{ -+ list_del(&range->lru); -+ lru_count -= range_size(range); -+} -+ -+/* -+ * range_alloc - allocate and initialize a new ashmem_range structure -+ * -+ * 'asma' - associated ashmem_area -+ * 'prev_range' - the previous ashmem_range in the sorted asma->unpinned list -+ * 'purged' - initial purge value (ASMEM_NOT_PURGED or ASHMEM_WAS_PURGED) -+ * 'start' - starting page, inclusive -+ * 'end' - ending page, inclusive -+ * -+ * Caller must hold ashmem_mutex. -+ */ -+static int range_alloc(struct ashmem_area *asma, -+ struct ashmem_range *prev_range, unsigned int purged, -+ size_t start, size_t end) -+{ -+ struct ashmem_range *range; -+ -+ range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL); -+ if (unlikely(!range)) -+ return -ENOMEM; -+ -+ range->asma = asma; -+ range->pgstart = start; -+ range->pgend = end; -+ range->purged = purged; -+ -+ list_add_tail(&range->unpinned, &prev_range->unpinned); -+ -+ if (range_on_lru(range)) -+ lru_add(range); -+ -+ return 0; -+} -+ -+static void range_del(struct ashmem_range *range) -+{ -+ list_del(&range->unpinned); -+ if (range_on_lru(range)) -+ lru_del(range); -+ kmem_cache_free(ashmem_range_cachep, range); -+} -+ -+/* -+ * range_shrink - shrinks a range -+ * -+ * Caller must hold ashmem_mutex. -+ */ -+static inline void range_shrink(struct ashmem_range *range, -+ size_t start, size_t end) -+{ -+ size_t pre = range_size(range); -+ -+ range->pgstart = start; -+ range->pgend = end; -+ -+ if (range_on_lru(range)) -+ lru_count -= pre - range_size(range); -+} -+ -+static int ashmem_open(struct inode *inode, struct file *file) -+{ -+ struct ashmem_area *asma; -+ int ret; -+ -+ ret = nonseekable_open(inode, file); -+ if (unlikely(ret)) -+ return ret; -+ -+ asma = kmem_cache_zalloc(ashmem_area_cachep, GFP_KERNEL); -+ if (unlikely(!asma)) -+ return -ENOMEM; -+ -+ INIT_LIST_HEAD(&asma->unpinned_list); -+ memcpy(asma->name, ASHMEM_NAME_PREFIX, ASHMEM_NAME_PREFIX_LEN); -+ asma->prot_mask = PROT_MASK; -+ file->private_data = asma; -+ -+ return 0; -+} -+ -+static int ashmem_release(struct inode *ignored, struct file *file) -+{ -+ struct ashmem_area *asma = file->private_data; -+ struct ashmem_range *range, *next; -+ -+ mutex_lock(&ashmem_mutex); -+ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) -+ range_del(range); -+ mutex_unlock(&ashmem_mutex); -+ -+ if (asma->file) -+ fput(asma->file); -+ kmem_cache_free(ashmem_area_cachep, asma); -+ -+ return 0; -+} -+ -+static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ struct ashmem_area *asma = file->private_data; -+ int ret = 0; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ /* user needs to SET_SIZE before mapping */ -+ if (unlikely(!asma->size)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* requested protection bits must match our allowed protection mask */ -+ if (unlikely((vma->vm_flags & ~asma->prot_mask) & PROT_MASK)) { -+ ret = -EPERM; -+ goto out; -+ } -+ -+ if (!asma->file) { -+ char *name = ASHMEM_NAME_DEF; -+ struct file *vmfile; -+ -+ if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') -+ name = asma->name; -+ -+ /* ... and allocate the backing shmem file */ -+ vmfile = shmem_file_setup(name, asma->size, vma->vm_flags); -+ if (unlikely(IS_ERR(vmfile))) { -+ ret = PTR_ERR(vmfile); -+ goto out; -+ } -+ asma->file = vmfile; -+ } -+ get_file(asma->file); -+ -+ /* -+ * XXX - Reworked to use shmem_zero_setup() instead of -+ * shmem_set_file while we're in staging. -jstultz -+ */ -+ if (vma->vm_flags & VM_SHARED) { -+ ret = shmem_zero_setup(vma); -+ if (ret) { -+ fput(asma->file); -+ goto out; -+ } -+ } -+ -+ if (vma->vm_file) -+ fput(vma->vm_file); -+ vma->vm_file = asma->file; -+ vma->vm_flags |= VM_CAN_NONLINEAR; -+ -+out: -+ mutex_unlock(&ashmem_mutex); -+ return ret; -+} -+ -+/* -+ * ashmem_shrink - our cache shrinker, called from mm/vmscan.c :: shrink_slab -+ * -+ * 'nr_to_scan' is the number of objects (pages) to prune, or 0 to query how -+ * many objects (pages) we have in total. -+ * -+ * 'gfp_mask' is the mask of the allocation that got us into this mess. -+ * -+ * Return value is the number of objects (pages) remaining, or -1 if we cannot -+ * proceed without risk of deadlock (due to gfp_mask). -+ * -+ * We approximate LRU via least-recently-unpinned, jettisoning unpinned partial -+ * chunks of ashmem regions LRU-wise one-at-a-time until we hit 'nr_to_scan' -+ * pages freed. -+ */ -+static int ashmem_shrink(int nr_to_scan, gfp_t gfp_mask) -+{ -+ struct ashmem_range *range, *next; -+ -+ /* We might recurse into filesystem code, so bail out if necessary */ -+ if (nr_to_scan && !(gfp_mask & __GFP_FS)) -+ return -1; -+ if (!nr_to_scan) -+ return lru_count; -+ -+ mutex_lock(&ashmem_mutex); -+ list_for_each_entry_safe(range, next, &ashmem_lru_list, lru) { -+ struct inode *inode = range->asma->file->f_dentry->d_inode; -+ loff_t start = range->pgstart * PAGE_SIZE; -+ loff_t end = (range->pgend + 1) * PAGE_SIZE - 1; -+ -+ vmtruncate_range(inode, start, end); -+ range->purged = ASHMEM_WAS_PURGED; -+ lru_del(range); -+ -+ nr_to_scan -= range_size(range); -+ if (nr_to_scan <= 0) -+ break; -+ } -+ mutex_unlock(&ashmem_mutex); -+ -+ return lru_count; -+} -+ -+static struct shrinker ashmem_shrinker = { -+ .shrink = ashmem_shrink, -+ .seeks = DEFAULT_SEEKS * 4, -+}; -+ -+static int set_prot_mask(struct ashmem_area *asma, unsigned long prot) -+{ -+ int ret = 0; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ /* the user can only remove, not add, protection bits */ -+ if (unlikely((asma->prot_mask & prot) != prot)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* does the application expect PROT_READ to imply PROT_EXEC? */ -+ if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) -+ prot |= PROT_EXEC; -+ -+ asma->prot_mask = prot; -+ -+out: -+ mutex_unlock(&ashmem_mutex); -+ return ret; -+} -+ -+static int set_name(struct ashmem_area *asma, void __user *name) -+{ -+ int ret = 0; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ /* cannot change an existing mapping's name */ -+ if (unlikely(asma->file)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (unlikely(copy_from_user(asma->name + ASHMEM_NAME_PREFIX_LEN, -+ name, ASHMEM_NAME_LEN))) -+ ret = -EFAULT; -+ asma->name[ASHMEM_FULL_NAME_LEN-1] = '\0'; -+ -+out: -+ mutex_unlock(&ashmem_mutex); -+ -+ return ret; -+} -+ -+static int get_name(struct ashmem_area *asma, void __user *name) -+{ -+ int ret = 0; -+ -+ mutex_lock(&ashmem_mutex); -+ if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') { -+ size_t len; -+ -+ /* -+ * Copying only `len', instead of ASHMEM_NAME_LEN, bytes -+ * prevents us from revealing one user's stack to another. -+ */ -+ len = strlen(asma->name + ASHMEM_NAME_PREFIX_LEN) + 1; -+ if (unlikely(copy_to_user(name, -+ asma->name + ASHMEM_NAME_PREFIX_LEN, len))) -+ ret = -EFAULT; -+ } else { -+ if (unlikely(copy_to_user(name, ASHMEM_NAME_DEF, -+ sizeof(ASHMEM_NAME_DEF)))) -+ ret = -EFAULT; -+ } -+ mutex_unlock(&ashmem_mutex); -+ -+ return ret; -+} -+ -+/* -+ * ashmem_pin - pin the given ashmem region, returning whether it was -+ * previously purged (ASHMEM_WAS_PURGED) or not (ASHMEM_NOT_PURGED). -+ * -+ * Caller must hold ashmem_mutex. -+ */ -+static int ashmem_pin(struct ashmem_area *asma, size_t pgstart, size_t pgend) -+{ -+ struct ashmem_range *range, *next; -+ int ret = ASHMEM_NOT_PURGED; -+ -+ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) { -+ /* moved past last applicable page; we can short circuit */ -+ if (range_before_page(range, pgstart)) -+ break; -+ -+ /* -+ * The user can ask us to pin pages that span multiple ranges, -+ * or to pin pages that aren't even unpinned, so this is messy. -+ * -+ * Four cases: -+ * 1. The requested range subsumes an existing range, so we -+ * just remove the entire matching range. -+ * 2. The requested range overlaps the start of an existing -+ * range, so we just update that range. -+ * 3. The requested range overlaps the end of an existing -+ * range, so we just update that range. -+ * 4. The requested range punches a hole in an existing range, -+ * so we have to update one side of the range and then -+ * create a new range for the other side. -+ */ -+ if (page_range_in_range(range, pgstart, pgend)) { -+ ret |= range->purged; -+ -+ /* Case #1: Easy. Just nuke the whole thing. */ -+ if (page_range_subsumes_range(range, pgstart, pgend)) { -+ range_del(range); -+ continue; -+ } -+ -+ /* Case #2: We overlap from the start, so adjust it */ -+ if (range->pgstart >= pgstart) { -+ range_shrink(range, pgend + 1, range->pgend); -+ continue; -+ } -+ -+ /* Case #3: We overlap from the rear, so adjust it */ -+ if (range->pgend <= pgend) { -+ range_shrink(range, range->pgstart, pgstart-1); -+ continue; -+ } -+ -+ /* -+ * Case #4: We eat a chunk out of the middle. A bit -+ * more complicated, we allocate a new range for the -+ * second half and adjust the first chunk's endpoint. -+ */ -+ range_alloc(asma, range, range->purged, -+ pgend + 1, range->pgend); -+ range_shrink(range, range->pgstart, pgstart - 1); -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+/* -+ * ashmem_unpin - unpin the given range of pages. Returns zero on success. -+ * -+ * Caller must hold ashmem_mutex. -+ */ -+static int ashmem_unpin(struct ashmem_area *asma, size_t pgstart, size_t pgend) -+{ -+ struct ashmem_range *range, *next; -+ unsigned int purged = ASHMEM_NOT_PURGED; -+ -+restart: -+ list_for_each_entry_safe(range, next, &asma->unpinned_list, unpinned) { -+ /* short circuit: this is our insertion point */ -+ if (range_before_page(range, pgstart)) -+ break; -+ -+ /* -+ * The user can ask us to unpin pages that are already entirely -+ * or partially pinned. We handle those two cases here. -+ */ -+ if (page_range_subsumed_by_range(range, pgstart, pgend)) -+ return 0; -+ if (page_range_in_range(range, pgstart, pgend)) { -+ pgstart = min_t(size_t, range->pgstart, pgstart), -+ pgend = max_t(size_t, range->pgend, pgend); -+ purged |= range->purged; -+ range_del(range); -+ goto restart; -+ } -+ } -+ -+ return range_alloc(asma, range, purged, pgstart, pgend); -+} -+ -+/* -+ * ashmem_get_pin_status - Returns ASHMEM_IS_UNPINNED if _any_ pages in the -+ * given interval are unpinned and ASHMEM_IS_PINNED otherwise. -+ * -+ * Caller must hold ashmem_mutex. -+ */ -+static int ashmem_get_pin_status(struct ashmem_area *asma, size_t pgstart, -+ size_t pgend) -+{ -+ struct ashmem_range *range; -+ int ret = ASHMEM_IS_PINNED; -+ -+ list_for_each_entry(range, &asma->unpinned_list, unpinned) { -+ if (range_before_page(range, pgstart)) -+ break; -+ if (page_range_in_range(range, pgstart, pgend)) { -+ ret = ASHMEM_IS_UNPINNED; -+ break; -+ } -+ } -+ -+ return ret; -+} -+ -+static int ashmem_pin_unpin(struct ashmem_area *asma, unsigned long cmd, -+ void __user *p) -+{ -+ struct ashmem_pin pin; -+ size_t pgstart, pgend; -+ int ret = -EINVAL; -+ -+ if (unlikely(!asma->file)) -+ return -EINVAL; -+ -+ if (unlikely(copy_from_user(&pin, p, sizeof(pin)))) -+ return -EFAULT; -+ -+ /* per custom, you can pass zero for len to mean "everything onward" */ -+ if (!pin.len) -+ pin.len = PAGE_ALIGN(asma->size) - pin.offset; -+ -+ if (unlikely((pin.offset | pin.len) & ~PAGE_MASK)) -+ return -EINVAL; -+ -+ if (unlikely(((__u32) -1) - pin.offset < pin.len)) -+ return -EINVAL; -+ -+ if (unlikely(PAGE_ALIGN(asma->size) < pin.offset + pin.len)) -+ return -EINVAL; -+ -+ pgstart = pin.offset / PAGE_SIZE; -+ pgend = pgstart + (pin.len / PAGE_SIZE) - 1; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ switch (cmd) { -+ case ASHMEM_PIN: -+ ret = ashmem_pin(asma, pgstart, pgend); -+ break; -+ case ASHMEM_UNPIN: -+ ret = ashmem_unpin(asma, pgstart, pgend); -+ break; -+ case ASHMEM_GET_PIN_STATUS: -+ ret = ashmem_get_pin_status(asma, pgstart, pgend); -+ break; -+ } -+ -+ mutex_unlock(&ashmem_mutex); -+ -+ return ret; -+} -+ -+static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct ashmem_area *asma = file->private_data; -+ long ret = -ENOTTY; -+ -+ switch (cmd) { -+ case ASHMEM_SET_NAME: -+ ret = set_name(asma, (void __user *) arg); -+ break; -+ case ASHMEM_GET_NAME: -+ ret = get_name(asma, (void __user *) arg); -+ break; -+ case ASHMEM_SET_SIZE: -+ ret = -EINVAL; -+ if (!asma->file) { -+ ret = 0; -+ asma->size = (size_t) arg; -+ } -+ break; -+ case ASHMEM_GET_SIZE: -+ ret = asma->size; -+ break; -+ case ASHMEM_SET_PROT_MASK: -+ ret = set_prot_mask(asma, arg); -+ break; -+ case ASHMEM_GET_PROT_MASK: -+ ret = asma->prot_mask; -+ break; -+ case ASHMEM_PIN: -+ case ASHMEM_UNPIN: -+ case ASHMEM_GET_PIN_STATUS: -+ ret = ashmem_pin_unpin(asma, cmd, (void __user *) arg); -+ break; -+ case ASHMEM_PURGE_ALL_CACHES: -+ ret = -EPERM; -+ if (capable(CAP_SYS_ADMIN)) { -+ ret = ashmem_shrink(0, GFP_KERNEL); -+ ashmem_shrink(ret, GFP_KERNEL); -+ } -+ break; -+ } -+ -+ return ret; -+} -+ -+static struct file_operations ashmem_fops = { -+ .owner = THIS_MODULE, -+ .open = ashmem_open, -+ .release = ashmem_release, -+ .mmap = ashmem_mmap, -+ .unlocked_ioctl = ashmem_ioctl, -+ .compat_ioctl = ashmem_ioctl, -+}; -+ -+static struct miscdevice ashmem_misc = { -+ .minor = MISC_DYNAMIC_MINOR, -+ .name = "ashmem", -+ .fops = &ashmem_fops, -+}; -+ -+static int __init ashmem_init(void) -+{ -+ int ret; -+ -+ ashmem_area_cachep = kmem_cache_create("ashmem_area_cache", -+ sizeof(struct ashmem_area), -+ 0, 0, NULL); -+ if (unlikely(!ashmem_area_cachep)) { -+ printk(KERN_ERR "ashmem: failed to create slab cache\n"); -+ return -ENOMEM; -+ } -+ -+ ashmem_range_cachep = kmem_cache_create("ashmem_range_cache", -+ sizeof(struct ashmem_range), -+ 0, 0, NULL); -+ if (unlikely(!ashmem_range_cachep)) { -+ printk(KERN_ERR "ashmem: failed to create slab cache\n"); -+ return -ENOMEM; -+ } -+ -+ ret = misc_register(&ashmem_misc); -+ if (unlikely(ret)) { -+ printk(KERN_ERR "ashmem: failed to register misc device!\n"); -+ return ret; -+ } -+ -+ register_shrinker(&ashmem_shrinker); -+ -+ printk(KERN_INFO "ashmem: initialized\n"); -+ -+ return 0; -+} -+ -+static void __exit ashmem_exit(void) -+{ -+ int ret; -+ -+ unregister_shrinker(&ashmem_shrinker); -+ -+ ret = misc_deregister(&ashmem_misc); -+ if (unlikely(ret)) -+ printk(KERN_ERR "ashmem: failed to unregister misc device!\n"); -+ -+ kmem_cache_destroy(ashmem_range_cachep); -+ kmem_cache_destroy(ashmem_area_cachep); -+ -+ printk(KERN_INFO "ashmem: unloaded\n"); -+} -+ -+module_init(ashmem_init); -+module_exit(ashmem_exit); -+ -+MODULE_LICENSE("GPL"); -diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h -new file mode 100644 -index 0000000..1976b10 ---- /dev/null -+++ b/drivers/staging/android/ashmem.h -@@ -0,0 +1,48 @@ -+/* -+ * include/linux/ashmem.h -+ * -+ * Copyright 2008 Google Inc. -+ * Author: Robert Love -+ * -+ * This file is dual licensed. It may be redistributed and/or modified -+ * under the terms of the Apache 2.0 License OR version 2 of the GNU -+ * General Public License. -+ */ -+ -+#ifndef _LINUX_ASHMEM_H -+#define _LINUX_ASHMEM_H -+ -+#include -+#include -+ -+#define ASHMEM_NAME_LEN 256 -+ -+#define ASHMEM_NAME_DEF "dev/ashmem" -+ -+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ -+#define ASHMEM_NOT_PURGED 0 -+#define ASHMEM_WAS_PURGED 1 -+ -+/* Return values from ASHMEM_GET_PIN_STATUS: Is the mapping pinned? */ -+#define ASHMEM_IS_UNPINNED 0 -+#define ASHMEM_IS_PINNED 1 -+ -+struct ashmem_pin { -+ __u32 offset; /* offset into region, in bytes, page-aligned */ -+ __u32 len; /* length forward from offset, in bytes, page-aligned */ -+}; -+ -+#define __ASHMEMIOC 0x77 -+ -+#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN]) -+#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN]) -+#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t) -+#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4) -+#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long) -+#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6) -+#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin) -+#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin) -+#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9) -+#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10) -+ -+#endif /* _LINUX_ASHMEM_H */ diff --git a/patches.android/android-0028-ashmem-Implement-read-2-in-ashmem-driver.patch b/patches.android/android-0028-ashmem-Implement-read-2-in-ashmem-driver.patch deleted file mode 100644 index 0fb2f666019e..000000000000 --- a/patches.android/android-0028-ashmem-Implement-read-2-in-ashmem-driver.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 853ca7ae292f9c4809e1e42914e81453eaa15367 Mon Sep 17 00:00:00 2001 -From: Bjorn Bringert -Date: Tue, 20 Dec 2011 16:49:49 -0800 -Subject: ashmem: Implement read(2) in ashmem driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 853ca7ae292f9c4809e1e42914e81453eaa15367 - -Signed-off-by: Bjorn Bringert -[jstultz: Tweaked commit subject] -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index 5775c6c..6f1a0bb 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -211,6 +211,32 @@ static int ashmem_release(struct inode *ignored, struct file *file) - return 0; - } - -+static ssize_t ashmem_read(struct file *file, char __user *buf, -+ size_t len, loff_t *pos) -+{ -+ struct ashmem_area *asma = file->private_data; -+ int ret = 0; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ /* If size is not set, or set to 0, always return EOF. */ -+ if (asma->size == 0) { -+ goto out; -+ } -+ -+ if (!asma->file) { -+ ret = -EBADF; -+ goto out; -+ } -+ -+ ret = asma->file->f_op->read(asma->file, buf, len, pos); -+ -+out: -+ mutex_unlock(&ashmem_mutex); -+ return ret; -+} -+ -+ - static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) - { - struct ashmem_area *asma = file->private_data; -@@ -612,6 +638,7 @@ static struct file_operations ashmem_fops = { - .owner = THIS_MODULE, - .open = ashmem_open, - .release = ashmem_release, -+ .read = ashmem_read, - .mmap = ashmem_mmap, - .unlocked_ioctl = ashmem_ioctl, - .compat_ioctl = ashmem_ioctl, diff --git a/patches.android/android-0029-ashmem-Fix-ASHMEM_SET_PROT_MASK.patch b/patches.android/android-0029-ashmem-Fix-ASHMEM_SET_PROT_MASK.patch deleted file mode 100644 index d5b5e96f96fe..000000000000 --- a/patches.android/android-0029-ashmem-Fix-ASHMEM_SET_PROT_MASK.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 56f76fc68492af718fff88927bc296635d634b78 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Tue, 20 Dec 2011 16:49:50 -0800 -Subject: ashmem: Fix ASHMEM_SET_PROT_MASK. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 56f76fc68492af718fff88927bc296635d634b78 - -Signed-off-by: Arve HjønnevÃ¥g -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index 6f1a0bb..0b923b0 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -236,6 +236,13 @@ out: - return ret; - } - -+static inline unsigned long -+calc_vm_may_flags(unsigned long prot) -+{ -+ return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD ) | -+ _calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) | -+ _calc_vm_trans(prot, PROT_EXEC, VM_MAYEXEC); -+} - - static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) - { -@@ -251,10 +258,12 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) - } - - /* requested protection bits must match our allowed protection mask */ -- if (unlikely((vma->vm_flags & ~asma->prot_mask) & PROT_MASK)) { -+ if (unlikely((vma->vm_flags & ~calc_vm_prot_bits(asma->prot_mask)) & -+ calc_vm_prot_bits(PROT_MASK))) { - ret = -EPERM; - goto out; - } -+ vma->vm_flags &= ~calc_vm_may_flags(~asma->prot_mask); - - if (!asma->file) { - char *name = ASHMEM_NAME_DEF; diff --git a/patches.android/android-0030-ashmem-Update-arguments-of-shrinker-for-2.6.35.patch b/patches.android/android-0030-ashmem-Update-arguments-of-shrinker-for-2.6.35.patch deleted file mode 100644 index 2bab0eb486f2..000000000000 --- a/patches.android/android-0030-ashmem-Update-arguments-of-shrinker-for-2.6.35.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1d3f8f2da1c28709a3c494f3872b89c871906b2d Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Tue, 20 Dec 2011 16:49:51 -0800 -Subject: ashmem: Update arguments of shrinker for 2.6.35 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 1d3f8f2da1c28709a3c494f3872b89c871906b2d - -Signed-off-by: Colin Cross -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index 0b923b0..40c3dc8 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -319,7 +319,7 @@ out: - * chunks of ashmem regions LRU-wise one-at-a-time until we hit 'nr_to_scan' - * pages freed. - */ --static int ashmem_shrink(int nr_to_scan, gfp_t gfp_mask) -+static int ashmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - { - struct ashmem_range *range, *next; - -@@ -634,8 +634,8 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - case ASHMEM_PURGE_ALL_CACHES: - ret = -EPERM; - if (capable(CAP_SYS_ADMIN)) { -- ret = ashmem_shrink(0, GFP_KERNEL); -- ashmem_shrink(ret, GFP_KERNEL); -+ ret = ashmem_shrink(&ashmem_shrinker, 0, GFP_KERNEL); -+ ashmem_shrink(&ashmem_shrinker, ret, GFP_KERNEL); - } - break; - } diff --git a/patches.android/android-0031-ashmem-Support-lseek-2-in-ashmem-driver.patch b/patches.android/android-0031-ashmem-Support-lseek-2-in-ashmem-driver.patch deleted file mode 100644 index 024b4ad954a5..000000000000 --- a/patches.android/android-0031-ashmem-Support-lseek-2-in-ashmem-driver.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 5154b93b8eceb57bdab4e77030bf21ead15b42e4 Mon Sep 17 00:00:00 2001 -From: Bjorn Bringert -Date: Tue, 20 Dec 2011 16:49:52 -0800 -Subject: ashmem: Support lseek(2) in ashmem driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 5154b93b8eceb57bdab4e77030bf21ead15b42e4 - -Signed-off-by: Bjorn Bringert -[jstultz: tweaked commit subject] -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index 40c3dc8..777e2b2 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -178,7 +178,7 @@ static int ashmem_open(struct inode *inode, struct file *file) - struct ashmem_area *asma; - int ret; - -- ret = nonseekable_open(inode, file); -+ ret = generic_file_open(inode, file); - if (unlikely(ret)) - return ret; - -@@ -230,6 +230,42 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, - } - - ret = asma->file->f_op->read(asma->file, buf, len, pos); -+ if (ret < 0) { -+ goto out; -+ } -+ -+ /** Update backing file pos, since f_ops->read() doesn't */ -+ asma->file->f_pos = *pos; -+ -+out: -+ mutex_unlock(&ashmem_mutex); -+ return ret; -+} -+ -+static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin) -+{ -+ struct ashmem_area *asma = file->private_data; -+ int ret; -+ -+ mutex_lock(&ashmem_mutex); -+ -+ if (asma->size == 0) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (!asma->file) { -+ ret = -EBADF; -+ goto out; -+ } -+ -+ ret = asma->file->f_op->llseek(asma->file, offset, origin); -+ if (ret < 0) { -+ goto out; -+ } -+ -+ /** Copy f_pos from backing file, since f_ops->llseek() sets it */ -+ file->f_pos = asma->file->f_pos; - - out: - mutex_unlock(&ashmem_mutex); -@@ -648,6 +684,7 @@ static struct file_operations ashmem_fops = { - .open = ashmem_open, - .release = ashmem_release, - .read = ashmem_read, -+ .llseek = ashmem_llseek, - .mmap = ashmem_mmap, - .unlocked_ioctl = ashmem_ioctl, - .compat_ioctl = ashmem_ioctl, diff --git a/patches.android/android-0032-ashmem-Fix-arguments-to-ashmem_shrink.patch b/patches.android/android-0032-ashmem-Fix-arguments-to-ashmem_shrink.patch deleted file mode 100644 index 2403d5d45052..000000000000 --- a/patches.android/android-0032-ashmem-Fix-arguments-to-ashmem_shrink.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 33e8fc463eeec29227282e4bd2082f5928d629a5 Mon Sep 17 00:00:00 2001 -From: Colin Cross -Date: Tue, 20 Dec 2011 16:49:53 -0800 -Subject: ashmem: Fix arguments to ashmem_shrink -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 33e8fc463eeec29227282e4bd2082f5928d629a5 - -The arguments to shrink functions have changed, update -ashmem_shrink to match. - -Signed-off-by: Colin Cross -[jstultz: tweaked commit subject] -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index 777e2b2..a78ba21 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -355,14 +355,14 @@ out: - * chunks of ashmem regions LRU-wise one-at-a-time until we hit 'nr_to_scan' - * pages freed. - */ --static int ashmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) -+static int ashmem_shrink(struct shrinker *s, struct shrink_control *sc) - { - struct ashmem_range *range, *next; - - /* We might recurse into filesystem code, so bail out if necessary */ -- if (nr_to_scan && !(gfp_mask & __GFP_FS)) -+ if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_FS)) - return -1; -- if (!nr_to_scan) -+ if (!sc->nr_to_scan) - return lru_count; - - mutex_lock(&ashmem_mutex); -@@ -375,8 +375,8 @@ static int ashmem_shrink(struct shrinker *s, int nr_to_scan, gfp_t gfp_mask) - range->purged = ASHMEM_WAS_PURGED; - lru_del(range); - -- nr_to_scan -= range_size(range); -- if (nr_to_scan <= 0) -+ sc->nr_to_scan -= range_size(range); -+ if (sc->nr_to_scan <= 0) - break; - } - mutex_unlock(&ashmem_mutex); -@@ -670,8 +670,13 @@ static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - case ASHMEM_PURGE_ALL_CACHES: - ret = -EPERM; - if (capable(CAP_SYS_ADMIN)) { -- ret = ashmem_shrink(&ashmem_shrinker, 0, GFP_KERNEL); -- ashmem_shrink(&ashmem_shrinker, ret, GFP_KERNEL); -+ struct shrink_control sc = { -+ .gfp_mask = GFP_KERNEL, -+ .nr_to_scan = 0, -+ }; -+ ret = ashmem_shrink(&ashmem_shrinker, &sc); -+ sc.nr_to_scan = ret; -+ ashmem_shrink(&ashmem_shrinker, &sc); - } - break; - } diff --git a/patches.android/android-0033-ashmem-Whitespace-cleanups.patch b/patches.android/android-0033-ashmem-Whitespace-cleanups.patch deleted file mode 100644 index 37b2a421710d..000000000000 --- a/patches.android/android-0033-ashmem-Whitespace-cleanups.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 1efb34394a694b458d66f25072318c375e22afe2 Mon Sep 17 00:00:00 2001 -From: John Stultz -Date: Tue, 20 Dec 2011 16:49:54 -0800 -Subject: ashmem: Whitespace cleanups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 1efb34394a694b458d66f25072318c375e22afe2 - -Fixes checkpatch warnings with the ashmem.c file - -CC: Brian Swetland -CC: Colin Cross -CC: Arve HjønnevÃ¥g -CC: Dima Zavin -CC: Robert Love -Signed-off-by: John Stultz -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c -index a78ba21..99052bf 100644 ---- a/drivers/staging/android/ashmem.c -+++ b/drivers/staging/android/ashmem.c -@@ -41,11 +41,11 @@ - * Big Note: Mappings do NOT pin this structure; it dies on close() - */ - struct ashmem_area { -- char name[ASHMEM_FULL_NAME_LEN];/* optional name for /proc/pid/maps */ -- struct list_head unpinned_list; /* list of all ashmem areas */ -- struct file *file; /* the shmem-based backing file */ -- size_t size; /* size of the mapping, in bytes */ -- unsigned long prot_mask; /* allowed prot bits, as vm_flags */ -+ char name[ASHMEM_FULL_NAME_LEN]; /* optional name in /proc/pid/maps */ -+ struct list_head unpinned_list; /* list of all ashmem areas */ -+ struct file *file; /* the shmem-based backing file */ -+ size_t size; /* size of the mapping, in bytes */ -+ unsigned long prot_mask; /* allowed prot bits, as vm_flags */ - }; - - /* -@@ -79,26 +79,26 @@ static struct kmem_cache *ashmem_area_cachep __read_mostly; - static struct kmem_cache *ashmem_range_cachep __read_mostly; - - #define range_size(range) \ -- ((range)->pgend - (range)->pgstart + 1) -+ ((range)->pgend - (range)->pgstart + 1) - - #define range_on_lru(range) \ -- ((range)->purged == ASHMEM_NOT_PURGED) -+ ((range)->purged == ASHMEM_NOT_PURGED) - - #define page_range_subsumes_range(range, start, end) \ -- (((range)->pgstart >= (start)) && ((range)->pgend <= (end))) -+ (((range)->pgstart >= (start)) && ((range)->pgend <= (end))) - - #define page_range_subsumed_by_range(range, start, end) \ -- (((range)->pgstart <= (start)) && ((range)->pgend >= (end))) -+ (((range)->pgstart <= (start)) && ((range)->pgend >= (end))) - - #define page_in_range(range, page) \ -- (((range)->pgstart <= (page)) && ((range)->pgend >= (page))) -+ (((range)->pgstart <= (page)) && ((range)->pgend >= (page))) - - #define page_range_in_range(range, start, end) \ -- (page_in_range(range, start) || page_in_range(range, end) || \ -- page_range_subsumes_range(range, start, end)) -+ (page_in_range(range, start) || page_in_range(range, end) || \ -+ page_range_subsumes_range(range, start, end)) - - #define range_before_page(range, page) \ -- ((range)->pgend < (page)) -+ ((range)->pgend < (page)) - - #define PROT_MASK (PROT_EXEC | PROT_READ | PROT_WRITE) - -@@ -220,9 +220,8 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, - mutex_lock(&ashmem_mutex); - - /* If size is not set, or set to 0, always return EOF. */ -- if (asma->size == 0) { -+ if (asma->size == 0) - goto out; -- } - - if (!asma->file) { - ret = -EBADF; -@@ -230,9 +229,8 @@ static ssize_t ashmem_read(struct file *file, char __user *buf, - } - - ret = asma->file->f_op->read(asma->file, buf, len, pos); -- if (ret < 0) { -+ if (ret < 0) - goto out; -- } - - /** Update backing file pos, since f_ops->read() doesn't */ - asma->file->f_pos = *pos; -@@ -260,9 +258,8 @@ static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin) - } - - ret = asma->file->f_op->llseek(asma->file, offset, origin); -- if (ret < 0) { -+ if (ret < 0) - goto out; -- } - - /** Copy f_pos from backing file, since f_ops->llseek() sets it */ - file->f_pos = asma->file->f_pos; -@@ -272,10 +269,9 @@ out: - return ret; - } - --static inline unsigned long --calc_vm_may_flags(unsigned long prot) -+static inline unsigned long calc_vm_may_flags(unsigned long prot) - { -- return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD ) | -+ return _calc_vm_trans(prot, PROT_READ, VM_MAYREAD) | - _calc_vm_trans(prot, PROT_WRITE, VM_MAYWRITE) | - _calc_vm_trans(prot, PROT_EXEC, VM_MAYEXEC); - } -@@ -295,7 +291,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) - - /* requested protection bits must match our allowed protection mask */ - if (unlikely((vma->vm_flags & ~calc_vm_prot_bits(asma->prot_mask)) & -- calc_vm_prot_bits(PROT_MASK))) { -+ calc_vm_prot_bits(PROT_MASK))) { - ret = -EPERM; - goto out; - } -@@ -688,8 +684,8 @@ static struct file_operations ashmem_fops = { - .owner = THIS_MODULE, - .open = ashmem_open, - .release = ashmem_release, -- .read = ashmem_read, -- .llseek = ashmem_llseek, -+ .read = ashmem_read, -+ .llseek = ashmem_llseek, - .mmap = ashmem_mmap, - .unlocked_ioctl = ashmem_ioctl, - .compat_ioctl = ashmem_ioctl, diff --git a/patches.android/android-0034-Staging-android-fixed-a-space-warning-in-binder.h.patch b/patches.android/android-0034-Staging-android-fixed-a-space-warning-in-binder.h.patch deleted file mode 100644 index 35c9eefb7875..000000000000 --- a/patches.android/android-0034-Staging-android-fixed-a-space-warning-in-binder.h.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 29b858471b266be7e56b69cfcee7ba94d9427dd3 Mon Sep 17 00:00:00 2001 -From: Marco Navarra -Date: Thu, 22 Dec 2011 13:27:07 +0100 -Subject: Staging: android: fixed a space warning in binder.h -Patch-mainline: HEAD -Git-commit: 29b858471b266be7e56b69cfcee7ba94d9427dd3 - -This patch fixes a simple tab-space warning in binder.h found by checkpatch tool - -Signed-off-by: Marco Navarra -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.h b/drivers/staging/android/binder.h -index 863ae1a..25ab6f2 100644 ---- a/drivers/staging/android/binder.h -+++ b/drivers/staging/android/binder.h -@@ -84,7 +84,7 @@ struct binder_version { - /* This is the current protocol version. */ - #define BINDER_CURRENT_PROTOCOL_VERSION 7 - --#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) -+#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read) - #define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t) - #define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t) - #define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int) diff --git a/patches.android/android-0035-Staging-android-fixed-80-characters-warnings-in-lowmemorykil.patch b/patches.android/android-0035-Staging-android-fixed-80-characters-warnings-in-lowmemorykil.patch deleted file mode 100644 index 1e595ca4516c..000000000000 --- a/patches.android/android-0035-Staging-android-fixed-80-characters-warnings-in-lowmemorykil.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 3bf5d65f4324510231cf33e5d75654f4fb1d1892 Mon Sep 17 00:00:00 2001 -From: Marco Navarra -Date: Thu, 22 Dec 2011 13:28:23 +0100 -Subject: Staging: android: fixed 80 characters warnings in - lowmemorykiller.c -Patch-mainline: HEAD -Git-commit: 3bf5d65f4324510231cf33e5d75654f4fb1d1892 - -This patch fixes some 80 chatacters limit warnings in the lowmemorykiller.c file - -Signed-off-by: Marco Navarra -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 4098bbb..2d8d2b7 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -7,10 +7,10 @@ - * files take a comma separated list of numbers in ascending order. - * - * For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and -- * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes -- * with a oom_adj value of 8 or higher when the free memory drops below 4096 pages -- * and kill processes with a oom_adj value of 0 or higher when the free memory -- * drops below 1024 pages. -+ * "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill -+ * processes with a oom_adj value of 8 or higher when the free memory drops -+ * below 4096 pages and kill processes with a oom_adj value of 0 or higher -+ * when the free memory drops below 1024 pages. - * - * The driver considers memory used for caches to be free, but if a large - * percentage of the cached memory is locked this can be very inaccurate -@@ -119,8 +119,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) - } - if (sc->nr_to_scan > 0) - lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", -- sc->nr_to_scan, sc->gfp_mask, other_free, other_file, -- min_adj); -+ sc->nr_to_scan, sc->gfp_mask, other_free, -+ other_file, min_adj); - rem = global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + diff --git a/patches.android/android-0036-Staging-android-binder-Don-t-call-dump_stack-in-binder_vma_o.patch b/patches.android/android-0036-Staging-android-binder-Don-t-call-dump_stack-in-binder_vma_o.patch deleted file mode 100644 index 376f336fad16..000000000000 --- a/patches.android/android-0036-Staging-android-binder-Don-t-call-dump_stack-in-binder_vma_o.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 3c1b86f17068cf6476fb2d022b9c8b44dedea2e5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Fri, 20 Jan 2012 19:56:21 -0800 -Subject: Staging: android: binder: Don't call dump_stack in - binder_vma_open -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: 3c1b86f17068cf6476fb2d022b9c8b44dedea2e5 - -If user-space partially unmaps the driver, binder_vma_open -would dump the kernel stack. This is not a kernel bug however -and will be treated as if the whole area was unmapped once -binder_vma_close gets called. - -Signed-off-by: Arve HjønnevÃ¥g -Cc: stable -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 7491801..48cf27c 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -2759,7 +2759,6 @@ static void binder_vma_open(struct vm_area_struct *vma) - proc->pid, vma->vm_start, vma->vm_end, - (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, - (unsigned long)pgprot_val(vma->vm_page_prot)); -- dump_stack(); - } - - static void binder_vma_close(struct vm_area_struct *vma) diff --git a/patches.android/android-0037-Staging-android-Remove-pmem-driver.patch b/patches.android/android-0037-Staging-android-Remove-pmem-driver.patch deleted file mode 100644 index 6c4e119fbafe..000000000000 --- a/patches.android/android-0037-Staging-android-Remove-pmem-driver.patch +++ /dev/null @@ -1,1490 +0,0 @@ -From b0d017e80e9f4e6b37e699b9a944646e64deb473 Mon Sep 17 00:00:00 2001 -From: Shuah Khan -Date: Fri, 27 Jan 2012 11:40:10 -0700 -Subject: Staging: android: Remove pmem driver -Patch-mainline: HEAD -Git-commit: b0d017e80e9f4e6b37e699b9a944646e64deb473 - -Addroid pmem driver is no longer used in any of the Android products. -This patch removes pmem driver from Android staging area - -Reference: https://lkml.org/lkml/2012/1/23/183 - -Signed-off-by: Shuah Khan -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index becf711..94cb2ac 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -99,10 +99,6 @@ config ANDROID_LOW_MEMORY_KILLER - ---help--- - Register processes to be killed when memory is low - --config ANDROID_PMEM -- bool "Android pmem allocator" -- depends on ARM -- - source "drivers/staging/android/switch/Kconfig" - - endif # if ANDROID -diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile -index eaed1ff..5fcc24f 100644 ---- a/drivers/staging/android/Makefile -+++ b/drivers/staging/android/Makefile -@@ -5,5 +5,4 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o - obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o - obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o - obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o --obj-$(CONFIG_ANDROID_PMEM) += pmem.o - obj-$(CONFIG_ANDROID_SWITCH) += switch/ -diff --git a/drivers/staging/android/android_pmem.h b/drivers/staging/android/android_pmem.h -deleted file mode 100644 -index f633621..0000000 ---- a/drivers/staging/android/android_pmem.h -+++ /dev/null -@@ -1,93 +0,0 @@ --/* include/linux/android_pmem.h -- * -- * Copyright (C) 2007 Google, Inc. -- * -- * This software is licensed under the terms of the GNU General Public -- * License version 2, as published by the Free Software Foundation, and -- * may be copied, distributed, and modified under those terms. -- * -- * 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. -- * -- */ -- --#ifndef _ANDROID_PMEM_H_ --#define _ANDROID_PMEM_H_ -- --#define PMEM_IOCTL_MAGIC 'p' --#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, unsigned int) --#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, unsigned int) --#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, unsigned int) --#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, unsigned int) --/* This ioctl will allocate pmem space, backing the file, it will fail -- * if the file already has an allocation, pass it the len as the argument -- * to the ioctl */ --#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int) --/* This will connect a one pmem file to another, pass the file that is already -- * backed in memory as the argument to the ioctl -- */ --#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int) --/* Returns the total size of the pmem region it is sent to as a pmem_region -- * struct (with offset set to 0). -- */ --#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, unsigned int) --#define PMEM_CACHE_FLUSH _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int) -- --struct android_pmem_platform_data --{ -- const char* name; -- /* starting physical address of memory region */ -- unsigned long start; -- /* size of memory region */ -- unsigned long size; -- /* set to indicate the region should not be managed with an allocator */ -- unsigned no_allocator; -- /* set to indicate maps of this region should be cached, if a mix of -- * cached and uncached is desired, set this and open the device with -- * O_SYNC to get an uncached region */ -- unsigned cached; -- /* The MSM7k has bits to enable a write buffer in the bus controller*/ -- unsigned buffered; --}; -- --struct pmem_region { -- unsigned long offset; -- unsigned long len; --}; -- --#ifdef CONFIG_ANDROID_PMEM --int is_pmem_file(struct file *file); --int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, -- unsigned long *end, struct file **filp); --int get_pmem_user_addr(struct file *file, unsigned long *start, -- unsigned long *end); --void put_pmem_file(struct file* file); --void flush_pmem_file(struct file *file, unsigned long start, unsigned long len); --int pmem_setup(struct android_pmem_platform_data *pdata, -- long (*ioctl)(struct file *, unsigned int, unsigned long), -- int (*release)(struct inode *, struct file *)); --int pmem_remap(struct pmem_region *region, struct file *file, -- unsigned operation); -- --#else --static inline int is_pmem_file(struct file *file) { return 0; } --static inline int get_pmem_file(int fd, unsigned long *start, -- unsigned long *vstart, unsigned long *end, -- struct file **filp) { return -ENOSYS; } --static inline int get_pmem_user_addr(struct file *file, unsigned long *start, -- unsigned long *end) { return -ENOSYS; } --static inline void put_pmem_file(struct file* file) { return; } --static inline void flush_pmem_file(struct file *file, unsigned long start, -- unsigned long len) { return; } --static inline int pmem_setup(struct android_pmem_platform_data *pdata, -- long (*ioctl)(struct file *, unsigned int, unsigned long), -- int (*release)(struct inode *, struct file *)) { return -ENOSYS; } -- --static inline int pmem_remap(struct pmem_region *region, struct file *file, -- unsigned operation) { return -ENOSYS; } --#endif -- --#endif //_ANDROID_PPP_H_ -- -diff --git a/drivers/staging/android/pmem.c b/drivers/staging/android/pmem.c -deleted file mode 100644 -index 7d97032..0000000 ---- a/drivers/staging/android/pmem.c -+++ /dev/null -@@ -1,1345 +0,0 @@ --/* pmem.c -- * -- * Copyright (C) 2007 Google, Inc. -- * -- * This software is licensed under the terms of the GNU General Public -- * License version 2, as published by the Free Software Foundation, and -- * may be copied, distributed, and modified under those terms. -- * -- * 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. -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include "android_pmem.h" -- --#define PMEM_MAX_DEVICES 10 --#define PMEM_MAX_ORDER 128 --#define PMEM_MIN_ALLOC PAGE_SIZE -- --#define PMEM_DEBUG 1 -- --/* indicates that a refernce to this file has been taken via get_pmem_file, -- * the file should not be released until put_pmem_file is called */ --#define PMEM_FLAGS_BUSY 0x1 --/* indicates that this is a suballocation of a larger master range */ --#define PMEM_FLAGS_CONNECTED 0x1 << 1 --/* indicates this is a master and not a sub allocation and that it is mmaped */ --#define PMEM_FLAGS_MASTERMAP 0x1 << 2 --/* submap and unsubmap flags indicate: -- * 00: subregion has never been mmaped -- * 10: subregion has been mmaped, reference to the mm was taken -- * 11: subretion has ben released, refernece to the mm still held -- * 01: subretion has been released, reference to the mm has been released -- */ --#define PMEM_FLAGS_SUBMAP 0x1 << 3 --#define PMEM_FLAGS_UNSUBMAP 0x1 << 4 -- -- --struct pmem_data { -- /* in alloc mode: an index into the bitmap -- * in no_alloc mode: the size of the allocation */ -- int index; -- /* see flags above for descriptions */ -- unsigned int flags; -- /* protects this data field, if the mm_mmap sem will be held at the -- * same time as this sem, the mm sem must be taken first (as this is -- * the order for vma_open and vma_close ops */ -- struct rw_semaphore sem; -- /* info about the mmaping process */ -- struct vm_area_struct *vma; -- /* task struct of the mapping process */ -- struct task_struct *task; -- /* process id of teh mapping process */ -- pid_t pid; -- /* file descriptor of the master */ -- int master_fd; -- /* file struct of the master */ -- struct file *master_file; -- /* a list of currently available regions if this is a suballocation */ -- struct list_head region_list; -- /* a linked list of data so we can access them for debugging */ -- struct list_head list; --#if PMEM_DEBUG -- int ref; --#endif --}; -- --struct pmem_bits { -- unsigned allocated:1; /* 1 if allocated, 0 if free */ -- unsigned order:7; /* size of the region in pmem space */ --}; -- --struct pmem_region_node { -- struct pmem_region region; -- struct list_head list; --}; -- --#define PMEM_DEBUG_MSGS 0 --#if PMEM_DEBUG_MSGS --#define DLOG(fmt,args...) \ -- do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \ -- ##args); } \ -- while (0) --#else --#define DLOG(x...) do {} while (0) --#endif -- --struct pmem_info { -- struct miscdevice dev; -- /* physical start address of the remaped pmem space */ -- unsigned long base; -- /* vitual start address of the remaped pmem space */ -- unsigned char __iomem *vbase; -- /* total size of the pmem space */ -- unsigned long size; -- /* number of entries in the pmem space */ -- unsigned long num_entries; -- /* pfn of the garbage page in memory */ -- unsigned long garbage_pfn; -- /* index of the garbage page in the pmem space */ -- int garbage_index; -- /* the bitmap for the region indicating which entries are allocated -- * and which are free */ -- struct pmem_bits *bitmap; -- /* indicates the region should not be managed with an allocator */ -- unsigned no_allocator; -- /* indicates maps of this region should be cached, if a mix of -- * cached and uncached is desired, set this and open the device with -- * O_SYNC to get an uncached region */ -- unsigned cached; -- unsigned buffered; -- /* in no_allocator mode the first mapper gets the whole space and sets -- * this flag */ -- unsigned allocated; -- /* for debugging, creates a list of pmem file structs, the -- * data_list_lock should be taken before pmem_data->sem if both are -- * needed */ -- struct mutex data_list_lock; -- struct list_head data_list; -- /* pmem_sem protects the bitmap array -- * a write lock should be held when modifying entries in bitmap -- * a read lock should be held when reading data from bits or -- * dereferencing a pointer into bitmap -- * -- * pmem_data->sem protects the pmem data of a particular file -- * Many of the function that require the pmem_data->sem have a non- -- * locking version for when the caller is already holding that sem. -- * -- * IF YOU TAKE BOTH LOCKS TAKE THEM IN THIS ORDER: -- * down(pmem_data->sem) => down(bitmap_sem) -- */ -- struct rw_semaphore bitmap_sem; -- -- long (*ioctl)(struct file *, unsigned int, unsigned long); -- int (*release)(struct inode *, struct file *); --}; -- --static struct pmem_info pmem[PMEM_MAX_DEVICES]; --static int id_count; -- --#define PMEM_IS_FREE(id, index) !(pmem[id].bitmap[index].allocated) --#define PMEM_ORDER(id, index) pmem[id].bitmap[index].order --#define PMEM_BUDDY_INDEX(id, index) (index ^ (1 << PMEM_ORDER(id, index))) --#define PMEM_NEXT_INDEX(id, index) (index + (1 << PMEM_ORDER(id, index))) --#define PMEM_OFFSET(index) (index * PMEM_MIN_ALLOC) --#define PMEM_START_ADDR(id, index) (PMEM_OFFSET(index) + pmem[id].base) --#define PMEM_LEN(id, index) ((1 << PMEM_ORDER(id, index)) * PMEM_MIN_ALLOC) --#define PMEM_END_ADDR(id, index) (PMEM_START_ADDR(id, index) + \ -- PMEM_LEN(id, index)) --#define PMEM_START_VADDR(id, index) (PMEM_OFFSET(id, index) + pmem[id].vbase) --#define PMEM_END_VADDR(id, index) (PMEM_START_VADDR(id, index) + \ -- PMEM_LEN(id, index)) --#define PMEM_REVOKED(data) (data->flags & PMEM_FLAGS_REVOKED) --#define PMEM_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK))) --#define PMEM_IS_SUBMAP(data) ((data->flags & PMEM_FLAGS_SUBMAP) && \ -- (!(data->flags & PMEM_FLAGS_UNSUBMAP))) -- --static int pmem_release(struct inode *, struct file *); --static int pmem_mmap(struct file *, struct vm_area_struct *); --static int pmem_open(struct inode *, struct file *); --static long pmem_ioctl(struct file *, unsigned int, unsigned long); -- --struct file_operations pmem_fops = { -- .release = pmem_release, -- .mmap = pmem_mmap, -- .open = pmem_open, -- .unlocked_ioctl = pmem_ioctl, --}; -- --static int get_id(struct file *file) --{ -- return MINOR(file->f_dentry->d_inode->i_rdev); --} -- --int is_pmem_file(struct file *file) --{ -- int id; -- -- if (unlikely(!file || !file->f_dentry || !file->f_dentry->d_inode)) -- return 0; -- id = get_id(file); -- if (unlikely(id >= PMEM_MAX_DEVICES)) -- return 0; -- if (unlikely(file->f_dentry->d_inode->i_rdev != -- MKDEV(MISC_MAJOR, pmem[id].dev.minor))) -- return 0; -- return 1; --} -- --static int has_allocation(struct file *file) --{ -- struct pmem_data *data; -- /* check is_pmem_file first if not accessed via pmem_file_ops */ -- -- if (unlikely(!file->private_data)) -- return 0; -- data = (struct pmem_data *)file->private_data; -- if (unlikely(data->index < 0)) -- return 0; -- return 1; --} -- --static int is_master_owner(struct file *file) --{ -- struct file *master_file; -- struct pmem_data *data; -- int put_needed, ret = 0; -- -- if (!is_pmem_file(file) || !has_allocation(file)) -- return 0; -- data = (struct pmem_data *)file->private_data; -- if (PMEM_FLAGS_MASTERMAP & data->flags) -- return 1; -- master_file = fget_light(data->master_fd, &put_needed); -- if (master_file && data->master_file == master_file) -- ret = 1; -- fput_light(master_file, put_needed); -- return ret; --} -- --static int pmem_free(int id, int index) --{ -- /* caller should hold the write lock on pmem_sem! */ -- int buddy, curr = index; -- DLOG("index %d\n", index); -- -- if (pmem[id].no_allocator) { -- pmem[id].allocated = 0; -- return 0; -- } -- /* clean up the bitmap, merging any buddies */ -- pmem[id].bitmap[curr].allocated = 0; -- /* find a slots buddy Buddy# = Slot# ^ (1 << order) -- * if the buddy is also free merge them -- * repeat until the buddy is not free or end of the bitmap is reached -- */ -- do { -- buddy = PMEM_BUDDY_INDEX(id, curr); -- if (PMEM_IS_FREE(id, buddy) && -- PMEM_ORDER(id, buddy) == PMEM_ORDER(id, curr)) { -- PMEM_ORDER(id, buddy)++; -- PMEM_ORDER(id, curr)++; -- curr = min(buddy, curr); -- } else { -- break; -- } -- } while (curr < pmem[id].num_entries); -- -- return 0; --} -- --static void pmem_revoke(struct file *file, struct pmem_data *data); -- --static int pmem_release(struct inode *inode, struct file *file) --{ -- struct pmem_data *data = (struct pmem_data *)file->private_data; -- struct pmem_region_node *region_node; -- struct list_head *elt, *elt2; -- int id = get_id(file), ret = 0; -- -- -- mutex_lock(&pmem[id].data_list_lock); -- /* if this file is a master, revoke all the memory in the connected -- * files */ -- if (PMEM_FLAGS_MASTERMAP & data->flags) { -- struct pmem_data *sub_data; -- list_for_each(elt, &pmem[id].data_list) { -- sub_data = list_entry(elt, struct pmem_data, list); -- down_read(&sub_data->sem); -- if (PMEM_IS_SUBMAP(sub_data) && -- file == sub_data->master_file) { -- up_read(&sub_data->sem); -- pmem_revoke(file, sub_data); -- } else -- up_read(&sub_data->sem); -- } -- } -- list_del(&data->list); -- mutex_unlock(&pmem[id].data_list_lock); -- -- -- down_write(&data->sem); -- -- /* if its not a conencted file and it has an allocation, free it */ -- if (!(PMEM_FLAGS_CONNECTED & data->flags) && has_allocation(file)) { -- down_write(&pmem[id].bitmap_sem); -- ret = pmem_free(id, data->index); -- up_write(&pmem[id].bitmap_sem); -- } -- -- /* if this file is a submap (mapped, connected file), downref the -- * task struct */ -- if (PMEM_FLAGS_SUBMAP & data->flags) -- if (data->task) { -- put_task_struct(data->task); -- data->task = NULL; -- } -- -- file->private_data = NULL; -- -- list_for_each_safe(elt, elt2, &data->region_list) { -- region_node = list_entry(elt, struct pmem_region_node, list); -- list_del(elt); -- kfree(region_node); -- } -- BUG_ON(!list_empty(&data->region_list)); -- -- up_write(&data->sem); -- kfree(data); -- if (pmem[id].release) -- ret = pmem[id].release(inode, file); -- -- return ret; --} -- --static int pmem_open(struct inode *inode, struct file *file) --{ -- struct pmem_data *data; -- int id = get_id(file); -- int ret = 0; -- -- DLOG("current %u file %p(%d)\n", current->pid, file, file_count(file)); -- /* setup file->private_data to indicate its unmapped */ -- /* you can only open a pmem device one time */ -- if (file->private_data != NULL) -- return -1; -- data = kmalloc(sizeof(struct pmem_data), GFP_KERNEL); -- if (!data) { -- printk("pmem: unable to allocate memory for pmem metadata."); -- return -1; -- } -- data->flags = 0; -- data->index = -1; -- data->task = NULL; -- data->vma = NULL; -- data->pid = 0; -- data->master_file = NULL; --#if PMEM_DEBUG -- data->ref = 0; --#endif -- INIT_LIST_HEAD(&data->region_list); -- init_rwsem(&data->sem); -- -- file->private_data = data; -- INIT_LIST_HEAD(&data->list); -- -- mutex_lock(&pmem[id].data_list_lock); -- list_add(&data->list, &pmem[id].data_list); -- mutex_unlock(&pmem[id].data_list_lock); -- return ret; --} -- --static unsigned long pmem_order(unsigned long len) --{ -- int i; -- -- len = (len + PMEM_MIN_ALLOC - 1)/PMEM_MIN_ALLOC; -- len--; -- for (i = 0; i < sizeof(len)*8; i++) -- if (len >> i == 0) -- break; -- return i; --} -- --static int pmem_allocate(int id, unsigned long len) --{ -- /* caller should hold the write lock on pmem_sem! */ -- /* return the corresponding pdata[] entry */ -- int curr = 0; -- int end = pmem[id].num_entries; -- int best_fit = -1; -- unsigned long order = pmem_order(len); -- -- if (pmem[id].no_allocator) { -- DLOG("no allocator"); -- if ((len > pmem[id].size) || pmem[id].allocated) -- return -1; -- pmem[id].allocated = 1; -- return len; -- } -- -- if (order > PMEM_MAX_ORDER) -- return -1; -- DLOG("order %lx\n", order); -- -- /* look through the bitmap: -- * if you find a free slot of the correct order use it -- * otherwise, use the best fit (smallest with size > order) slot -- */ -- while (curr < end) { -- if (PMEM_IS_FREE(id, curr)) { -- if (PMEM_ORDER(id, curr) == (unsigned char)order) { -- /* set the not free bit and clear others */ -- best_fit = curr; -- break; -- } -- if (PMEM_ORDER(id, curr) > (unsigned char)order && -- (best_fit < 0 || -- PMEM_ORDER(id, curr) < PMEM_ORDER(id, best_fit))) -- best_fit = curr; -- } -- curr = PMEM_NEXT_INDEX(id, curr); -- } -- -- /* if best_fit < 0, there are no suitable slots, -- * return an error -- */ -- if (best_fit < 0) { -- printk("pmem: no space left to allocate!\n"); -- return -1; -- } -- -- /* now partition the best fit: -- * split the slot into 2 buddies of order - 1 -- * repeat until the slot is of the correct order -- */ -- while (PMEM_ORDER(id, best_fit) > (unsigned char)order) { -- int buddy; -- PMEM_ORDER(id, best_fit) -= 1; -- buddy = PMEM_BUDDY_INDEX(id, best_fit); -- PMEM_ORDER(id, buddy) = PMEM_ORDER(id, best_fit); -- } -- pmem[id].bitmap[best_fit].allocated = 1; -- return best_fit; --} -- --static pgprot_t pmem_access_prot(struct file *file, pgprot_t vma_prot) --{ -- int id = get_id(file); --#ifdef pgprot_noncached -- if (pmem[id].cached == 0 || file->f_flags & O_SYNC) -- return pgprot_noncached(vma_prot); --#endif --#ifdef pgprot_ext_buffered -- else if (pmem[id].buffered) -- return pgprot_ext_buffered(vma_prot); --#endif -- return vma_prot; --} -- --static unsigned long pmem_start_addr(int id, struct pmem_data *data) --{ -- if (pmem[id].no_allocator) -- return PMEM_START_ADDR(id, 0); -- else -- return PMEM_START_ADDR(id, data->index); -- --} -- --static void *pmem_start_vaddr(int id, struct pmem_data *data) --{ -- return pmem_start_addr(id, data) - pmem[id].base + pmem[id].vbase; --} -- --static unsigned long pmem_len(int id, struct pmem_data *data) --{ -- if (pmem[id].no_allocator) -- return data->index; -- else -- return PMEM_LEN(id, data->index); --} -- --static int pmem_map_garbage(int id, struct vm_area_struct *vma, -- struct pmem_data *data, unsigned long offset, -- unsigned long len) --{ -- int i, garbage_pages = len >> PAGE_SHIFT; -- -- vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP | VM_SHARED | VM_WRITE; -- for (i = 0; i < garbage_pages; i++) { -- if (vm_insert_pfn(vma, vma->vm_start + offset + (i * PAGE_SIZE), -- pmem[id].garbage_pfn)) -- return -EAGAIN; -- } -- return 0; --} -- --static int pmem_unmap_pfn_range(int id, struct vm_area_struct *vma, -- struct pmem_data *data, unsigned long offset, -- unsigned long len) --{ -- int garbage_pages; -- DLOG("unmap offset %lx len %lx\n", offset, len); -- -- BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); -- -- garbage_pages = len >> PAGE_SHIFT; -- zap_page_range(vma, vma->vm_start + offset, len, NULL); -- pmem_map_garbage(id, vma, data, offset, len); -- return 0; --} -- --static int pmem_map_pfn_range(int id, struct vm_area_struct *vma, -- struct pmem_data *data, unsigned long offset, -- unsigned long len) --{ -- DLOG("map offset %lx len %lx\n", offset, len); -- BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_start)); -- BUG_ON(!PMEM_IS_PAGE_ALIGNED(vma->vm_end)); -- BUG_ON(!PMEM_IS_PAGE_ALIGNED(len)); -- BUG_ON(!PMEM_IS_PAGE_ALIGNED(offset)); -- -- if (io_remap_pfn_range(vma, vma->vm_start + offset, -- (pmem_start_addr(id, data) + offset) >> PAGE_SHIFT, -- len, vma->vm_page_prot)) { -- return -EAGAIN; -- } -- return 0; --} -- --static int pmem_remap_pfn_range(int id, struct vm_area_struct *vma, -- struct pmem_data *data, unsigned long offset, -- unsigned long len) --{ -- /* hold the mm semp for the vma you are modifying when you call this */ -- BUG_ON(!vma); -- zap_page_range(vma, vma->vm_start + offset, len, NULL); -- return pmem_map_pfn_range(id, vma, data, offset, len); --} -- --static void pmem_vma_open(struct vm_area_struct *vma) --{ -- struct file *file = vma->vm_file; -- struct pmem_data *data = file->private_data; -- int id = get_id(file); -- /* this should never be called as we don't support copying pmem -- * ranges via fork */ -- BUG_ON(!has_allocation(file)); -- down_write(&data->sem); -- /* remap the garbage pages, forkers don't get access to the data */ -- pmem_unmap_pfn_range(id, vma, data, 0, vma->vm_start - vma->vm_end); -- up_write(&data->sem); --} -- --static void pmem_vma_close(struct vm_area_struct *vma) --{ -- struct file *file = vma->vm_file; -- struct pmem_data *data = file->private_data; -- -- DLOG("current %u ppid %u file %p count %d\n", current->pid, -- current->parent->pid, file, file_count(file)); -- if (unlikely(!is_pmem_file(file) || !has_allocation(file))) { -- printk(KERN_WARNING "pmem: something is very wrong, you are " -- "closing a vm backing an allocation that doesn't " -- "exist!\n"); -- return; -- } -- down_write(&data->sem); -- if (data->vma == vma) { -- data->vma = NULL; -- if ((data->flags & PMEM_FLAGS_CONNECTED) && -- (data->flags & PMEM_FLAGS_SUBMAP)) -- data->flags |= PMEM_FLAGS_UNSUBMAP; -- } -- /* the kernel is going to free this vma now anyway */ -- up_write(&data->sem); --} -- --static struct vm_operations_struct vm_ops = { -- .open = pmem_vma_open, -- .close = pmem_vma_close, --}; -- --static int pmem_mmap(struct file *file, struct vm_area_struct *vma) --{ -- struct pmem_data *data; -- int index; -- unsigned long vma_size = vma->vm_end - vma->vm_start; -- int ret = 0, id = get_id(file); -- -- if (vma->vm_pgoff || !PMEM_IS_PAGE_ALIGNED(vma_size)) { --#if PMEM_DEBUG -- printk(KERN_ERR "pmem: mmaps must be at offset zero, aligned" -- " and a multiple of pages_size.\n"); --#endif -- return -EINVAL; -- } -- -- data = (struct pmem_data *)file->private_data; -- down_write(&data->sem); -- /* check this file isn't already mmaped, for submaps check this file -- * has never been mmaped */ -- if ((data->flags & PMEM_FLAGS_SUBMAP) || -- (data->flags & PMEM_FLAGS_UNSUBMAP)) { --#if PMEM_DEBUG -- printk(KERN_ERR "pmem: you can only mmap a pmem file once, " -- "this file is already mmaped. %x\n", data->flags); --#endif -- ret = -EINVAL; -- goto error; -- } -- /* if file->private_data == unalloced, alloc*/ -- if (data && data->index == -1) { -- down_write(&pmem[id].bitmap_sem); -- index = pmem_allocate(id, vma->vm_end - vma->vm_start); -- up_write(&pmem[id].bitmap_sem); -- data->index = index; -- } -- /* either no space was available or an error occured */ -- if (!has_allocation(file)) { -- ret = -EINVAL; -- printk("pmem: could not find allocation for map.\n"); -- goto error; -- } -- -- if (pmem_len(id, data) < vma_size) { --#if PMEM_DEBUG -- printk(KERN_WARNING "pmem: mmap size [%lu] does not match" -- "size of backing region [%lu].\n", vma_size, -- pmem_len(id, data)); --#endif -- ret = -EINVAL; -- goto error; -- } -- -- vma->vm_pgoff = pmem_start_addr(id, data) >> PAGE_SHIFT; -- vma->vm_page_prot = pmem_access_prot(file, vma->vm_page_prot); -- -- if (data->flags & PMEM_FLAGS_CONNECTED) { -- struct pmem_region_node *region_node; -- struct list_head *elt; -- if (pmem_map_garbage(id, vma, data, 0, vma_size)) { -- printk("pmem: mmap failed in kernel!\n"); -- ret = -EAGAIN; -- goto error; -- } -- list_for_each(elt, &data->region_list) { -- region_node = list_entry(elt, struct pmem_region_node, -- list); -- DLOG("remapping file: %p %lx %lx\n", file, -- region_node->region.offset, -- region_node->region.len); -- if (pmem_remap_pfn_range(id, vma, data, -- region_node->region.offset, -- region_node->region.len)) { -- ret = -EAGAIN; -- goto error; -- } -- } -- data->flags |= PMEM_FLAGS_SUBMAP; -- get_task_struct(current->group_leader); -- data->task = current->group_leader; -- data->vma = vma; --#if PMEM_DEBUG -- data->pid = current->pid; --#endif -- DLOG("submmapped file %p vma %p pid %u\n", file, vma, -- current->pid); -- } else { -- if (pmem_map_pfn_range(id, vma, data, 0, vma_size)) { -- printk(KERN_INFO "pmem: mmap failed in kernel!\n"); -- ret = -EAGAIN; -- goto error; -- } -- data->flags |= PMEM_FLAGS_MASTERMAP; -- data->pid = current->pid; -- } -- vma->vm_ops = &vm_ops; --error: -- up_write(&data->sem); -- return ret; --} -- --/* the following are the api for accessing pmem regions by other drivers -- * from inside the kernel */ --int get_pmem_user_addr(struct file *file, unsigned long *start, -- unsigned long *len) --{ -- struct pmem_data *data; -- if (!is_pmem_file(file) || !has_allocation(file)) { --#if PMEM_DEBUG -- printk(KERN_INFO "pmem: requested pmem data from invalid" -- "file.\n"); --#endif -- return -1; -- } -- data = (struct pmem_data *)file->private_data; -- down_read(&data->sem); -- if (data->vma) { -- *start = data->vma->vm_start; -- *len = data->vma->vm_end - data->vma->vm_start; -- } else { -- *start = 0; -- *len = 0; -- } -- up_read(&data->sem); -- return 0; --} -- --int get_pmem_addr(struct file *file, unsigned long *start, -- unsigned long *vstart, unsigned long *len) --{ -- struct pmem_data *data; -- int id; -- -- if (!is_pmem_file(file) || !has_allocation(file)) { -- return -1; -- } -- -- data = (struct pmem_data *)file->private_data; -- if (data->index == -1) { --#if PMEM_DEBUG -- printk(KERN_INFO "pmem: requested pmem data from file with no " -- "allocation.\n"); -- return -1; --#endif -- } -- id = get_id(file); -- -- down_read(&data->sem); -- *start = pmem_start_addr(id, data); -- *len = pmem_len(id, data); -- *vstart = (unsigned long)pmem_start_vaddr(id, data); -- up_read(&data->sem); --#if PMEM_DEBUG -- down_write(&data->sem); -- data->ref++; -- up_write(&data->sem); --#endif -- return 0; --} -- --int get_pmem_file(int fd, unsigned long *start, unsigned long *vstart, -- unsigned long *len, struct file **filp) --{ -- struct file *file; -- -- file = fget(fd); -- if (unlikely(file == NULL)) { -- printk(KERN_INFO "pmem: requested data from file descriptor " -- "that doesn't exist."); -- return -1; -- } -- -- if (get_pmem_addr(file, start, vstart, len)) -- goto end; -- -- if (filp) -- *filp = file; -- return 0; --end: -- fput(file); -- return -1; --} -- --void put_pmem_file(struct file *file) --{ -- struct pmem_data *data; -- int id; -- -- if (!is_pmem_file(file)) -- return; -- id = get_id(file); -- data = (struct pmem_data *)file->private_data; --#if PMEM_DEBUG -- down_write(&data->sem); -- if (data->ref == 0) { -- printk("pmem: pmem_put > pmem_get %s (pid %d)\n", -- pmem[id].dev.name, data->pid); -- BUG(); -- } -- data->ref--; -- up_write(&data->sem); --#endif -- fput(file); --} -- --void flush_pmem_file(struct file *file, unsigned long offset, unsigned long len) --{ -- struct pmem_data *data; -- int id; -- void *vaddr; -- struct pmem_region_node *region_node; -- struct list_head *elt; -- void *flush_start, *flush_end; -- -- if (!is_pmem_file(file) || !has_allocation(file)) { -- return; -- } -- -- id = get_id(file); -- data = (struct pmem_data *)file->private_data; -- if (!pmem[id].cached || file->f_flags & O_SYNC) -- return; -- -- down_read(&data->sem); -- vaddr = pmem_start_vaddr(id, data); -- /* if this isn't a submmapped file, flush the whole thing */ -- if (unlikely(!(data->flags & PMEM_FLAGS_CONNECTED))) { -- dmac_flush_range(vaddr, vaddr + pmem_len(id, data)); -- goto end; -- } -- /* otherwise, flush the region of the file we are drawing */ -- list_for_each(elt, &data->region_list) { -- region_node = list_entry(elt, struct pmem_region_node, list); -- if ((offset >= region_node->region.offset) && -- ((offset + len) <= (region_node->region.offset + -- region_node->region.len))) { -- flush_start = vaddr + region_node->region.offset; -- flush_end = flush_start + region_node->region.len; -- dmac_flush_range(flush_start, flush_end); -- break; -- } -- } --end: -- up_read(&data->sem); --} -- --static int pmem_connect(unsigned long connect, struct file *file) --{ -- struct pmem_data *data = (struct pmem_data *)file->private_data; -- struct pmem_data *src_data; -- struct file *src_file; -- int ret = 0, put_needed; -- -- down_write(&data->sem); -- /* retrieve the src file and check it is a pmem file with an alloc */ -- src_file = fget_light(connect, &put_needed); -- DLOG("connect %p to %p\n", file, src_file); -- if (!src_file) { -- printk("pmem: src file not found!\n"); -- ret = -EINVAL; -- goto err_no_file; -- } -- if (unlikely(!is_pmem_file(src_file) || !has_allocation(src_file))) { -- printk(KERN_INFO "pmem: src file is not a pmem file or has no " -- "alloc!\n"); -- ret = -EINVAL; -- goto err_bad_file; -- } -- src_data = (struct pmem_data *)src_file->private_data; -- -- if (has_allocation(file) && (data->index != src_data->index)) { -- printk("pmem: file is already mapped but doesn't match this" -- " src_file!\n"); -- ret = -EINVAL; -- goto err_bad_file; -- } -- data->index = src_data->index; -- data->flags |= PMEM_FLAGS_CONNECTED; -- data->master_fd = connect; -- data->master_file = src_file; -- --err_bad_file: -- fput_light(src_file, put_needed); --err_no_file: -- up_write(&data->sem); -- return ret; --} -- --static void pmem_unlock_data_and_mm(struct pmem_data *data, -- struct mm_struct *mm) --{ -- up_write(&data->sem); -- if (mm != NULL) { -- up_write(&mm->mmap_sem); -- mmput(mm); -- } --} -- --static int pmem_lock_data_and_mm(struct file *file, struct pmem_data *data, -- struct mm_struct **locked_mm) --{ -- int ret = 0; -- struct mm_struct *mm = NULL; -- *locked_mm = NULL; --lock_mm: -- down_read(&data->sem); -- if (PMEM_IS_SUBMAP(data)) { -- mm = get_task_mm(data->task); -- if (!mm) { --#if PMEM_DEBUG -- printk("pmem: can't remap task is gone!\n"); --#endif -- up_read(&data->sem); -- return -1; -- } -- } -- up_read(&data->sem); -- -- if (mm) -- down_write(&mm->mmap_sem); -- -- down_write(&data->sem); -- /* check that the file didn't get mmaped before we could take the -- * data sem, this should be safe b/c you can only submap each file -- * once */ -- if (PMEM_IS_SUBMAP(data) && !mm) { -- pmem_unlock_data_and_mm(data, mm); -- up_write(&data->sem); -- goto lock_mm; -- } -- /* now check that vma.mm is still there, it could have been -- * deleted by vma_close before we could get the data->sem */ -- if ((data->flags & PMEM_FLAGS_UNSUBMAP) && (mm != NULL)) { -- /* might as well release this */ -- if (data->flags & PMEM_FLAGS_SUBMAP) { -- put_task_struct(data->task); -- data->task = NULL; -- /* lower the submap flag to show the mm is gone */ -- data->flags &= ~(PMEM_FLAGS_SUBMAP); -- } -- pmem_unlock_data_and_mm(data, mm); -- return -1; -- } -- *locked_mm = mm; -- return ret; --} -- --int pmem_remap(struct pmem_region *region, struct file *file, -- unsigned operation) --{ -- int ret; -- struct pmem_region_node *region_node; -- struct mm_struct *mm = NULL; -- struct list_head *elt, *elt2; -- int id = get_id(file); -- struct pmem_data *data = (struct pmem_data *)file->private_data; -- -- /* pmem region must be aligned on a page boundry */ -- if (unlikely(!PMEM_IS_PAGE_ALIGNED(region->offset) || -- !PMEM_IS_PAGE_ALIGNED(region->len))) { --#if PMEM_DEBUG -- printk("pmem: request for unaligned pmem suballocation " -- "%lx %lx\n", region->offset, region->len); --#endif -- return -EINVAL; -- } -- -- /* if userspace requests a region of len 0, there's nothing to do */ -- if (region->len == 0) -- return 0; -- -- /* lock the mm and data */ -- ret = pmem_lock_data_and_mm(file, data, &mm); -- if (ret) -- return 0; -- -- /* only the owner of the master file can remap the client fds -- * that back in it */ -- if (!is_master_owner(file)) { --#if PMEM_DEBUG -- printk("pmem: remap requested from non-master process\n"); --#endif -- ret = -EINVAL; -- goto err; -- } -- -- /* check that the requested range is within the src allocation */ -- if (unlikely((region->offset > pmem_len(id, data)) || -- (region->len > pmem_len(id, data)) || -- (region->offset + region->len > pmem_len(id, data)))) { --#if PMEM_DEBUG -- printk(KERN_INFO "pmem: suballoc doesn't fit in src_file!\n"); --#endif -- ret = -EINVAL; -- goto err; -- } -- -- if (operation == PMEM_MAP) { -- region_node = kmalloc(sizeof(struct pmem_region_node), -- GFP_KERNEL); -- if (!region_node) { -- ret = -ENOMEM; --#if PMEM_DEBUG -- printk(KERN_INFO "No space to allocate metadata!"); --#endif -- goto err; -- } -- region_node->region = *region; -- list_add(®ion_node->list, &data->region_list); -- } else if (operation == PMEM_UNMAP) { -- int found = 0; -- list_for_each_safe(elt, elt2, &data->region_list) { -- region_node = list_entry(elt, struct pmem_region_node, -- list); -- if (region->len == 0 || -- (region_node->region.offset == region->offset && -- region_node->region.len == region->len)) { -- list_del(elt); -- kfree(region_node); -- found = 1; -- } -- } -- if (!found) { --#if PMEM_DEBUG -- printk("pmem: Unmap region does not map any mapped " -- "region!"); --#endif -- ret = -EINVAL; -- goto err; -- } -- } -- -- if (data->vma && PMEM_IS_SUBMAP(data)) { -- if (operation == PMEM_MAP) -- ret = pmem_remap_pfn_range(id, data->vma, data, -- region->offset, region->len); -- else if (operation == PMEM_UNMAP) -- ret = pmem_unmap_pfn_range(id, data->vma, data, -- region->offset, region->len); -- } -- --err: -- pmem_unlock_data_and_mm(data, mm); -- return ret; --} -- --static void pmem_revoke(struct file *file, struct pmem_data *data) --{ -- struct pmem_region_node *region_node; -- struct list_head *elt, *elt2; -- struct mm_struct *mm = NULL; -- int id = get_id(file); -- int ret = 0; -- -- data->master_file = NULL; -- ret = pmem_lock_data_and_mm(file, data, &mm); -- /* if lock_data_and_mm fails either the task that mapped the fd, or -- * the vma that mapped it have already gone away, nothing more -- * needs to be done */ -- if (ret) -- return; -- /* unmap everything */ -- /* delete the regions and region list nothing is mapped any more */ -- if (data->vma) -- list_for_each_safe(elt, elt2, &data->region_list) { -- region_node = list_entry(elt, struct pmem_region_node, -- list); -- pmem_unmap_pfn_range(id, data->vma, data, -- region_node->region.offset, -- region_node->region.len); -- list_del(elt); -- kfree(region_node); -- } -- /* delete the master file */ -- pmem_unlock_data_and_mm(data, mm); --} -- --static void pmem_get_size(struct pmem_region *region, struct file *file) --{ -- struct pmem_data *data = (struct pmem_data *)file->private_data; -- int id = get_id(file); -- -- if (!has_allocation(file)) { -- region->offset = 0; -- region->len = 0; -- return; -- } else { -- region->offset = pmem_start_addr(id, data); -- region->len = pmem_len(id, data); -- } -- DLOG("offset %lx len %lx\n", region->offset, region->len); --} -- -- --static long pmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) --{ -- struct pmem_data *data; -- int id = get_id(file); -- -- switch (cmd) { -- case PMEM_GET_PHYS: -- { -- struct pmem_region region; -- DLOG("get_phys\n"); -- if (!has_allocation(file)) { -- region.offset = 0; -- region.len = 0; -- } else { -- data = (struct pmem_data *)file->private_data; -- region.offset = pmem_start_addr(id, data); -- region.len = pmem_len(id, data); -- } -- printk(KERN_INFO "pmem: request for physical address of pmem region " -- "from process %d.\n", current->pid); -- if (copy_to_user((void __user *)arg, ®ion, -- sizeof(struct pmem_region))) -- return -EFAULT; -- break; -- } -- case PMEM_MAP: -- { -- struct pmem_region region; -- if (copy_from_user(®ion, (void __user *)arg, -- sizeof(struct pmem_region))) -- return -EFAULT; -- data = (struct pmem_data *)file->private_data; -- return pmem_remap(®ion, file, PMEM_MAP); -- } -- break; -- case PMEM_UNMAP: -- { -- struct pmem_region region; -- if (copy_from_user(®ion, (void __user *)arg, -- sizeof(struct pmem_region))) -- return -EFAULT; -- data = (struct pmem_data *)file->private_data; -- return pmem_remap(®ion, file, PMEM_UNMAP); -- break; -- } -- case PMEM_GET_SIZE: -- { -- struct pmem_region region; -- DLOG("get_size\n"); -- pmem_get_size(®ion, file); -- if (copy_to_user((void __user *)arg, ®ion, -- sizeof(struct pmem_region))) -- return -EFAULT; -- break; -- } -- case PMEM_GET_TOTAL_SIZE: -- { -- struct pmem_region region; -- DLOG("get total size\n"); -- region.offset = 0; -- get_id(file); -- region.len = pmem[id].size; -- if (copy_to_user((void __user *)arg, ®ion, -- sizeof(struct pmem_region))) -- return -EFAULT; -- break; -- } -- case PMEM_ALLOCATE: -- { -- if (has_allocation(file)) -- return -EINVAL; -- data = (struct pmem_data *)file->private_data; -- data->index = pmem_allocate(id, arg); -- break; -- } -- case PMEM_CONNECT: -- DLOG("connect\n"); -- return pmem_connect(arg, file); -- break; -- case PMEM_CACHE_FLUSH: -- { -- struct pmem_region region; -- DLOG("flush\n"); -- if (copy_from_user(®ion, (void __user *)arg, -- sizeof(struct pmem_region))) -- return -EFAULT; -- flush_pmem_file(file, region.offset, region.len); -- break; -- } -- default: -- if (pmem[id].ioctl) -- return pmem[id].ioctl(file, cmd, arg); -- return -EINVAL; -- } -- return 0; --} -- --#if PMEM_DEBUG --static ssize_t debug_open(struct inode *inode, struct file *file) --{ -- file->private_data = inode->i_private; -- return 0; --} -- --static ssize_t debug_read(struct file *file, char __user *buf, size_t count, -- loff_t *ppos) --{ -- struct list_head *elt, *elt2; -- struct pmem_data *data; -- struct pmem_region_node *region_node; -- int id = (int)file->private_data; -- const int debug_bufmax = 4096; -- static char buffer[4096]; -- int n = 0; -- -- DLOG("debug open\n"); -- n = scnprintf(buffer, debug_bufmax, -- "pid #: mapped regions (offset, len) (offset,len)...\n"); -- -- mutex_lock(&pmem[id].data_list_lock); -- list_for_each(elt, &pmem[id].data_list) { -- data = list_entry(elt, struct pmem_data, list); -- down_read(&data->sem); -- n += scnprintf(buffer + n, debug_bufmax - n, "pid %u:", -- data->pid); -- list_for_each(elt2, &data->region_list) { -- region_node = list_entry(elt2, struct pmem_region_node, -- list); -- n += scnprintf(buffer + n, debug_bufmax - n, -- "(%lx,%lx) ", -- region_node->region.offset, -- region_node->region.len); -- } -- n += scnprintf(buffer + n, debug_bufmax - n, "\n"); -- up_read(&data->sem); -- } -- mutex_unlock(&pmem[id].data_list_lock); -- -- n++; -- buffer[n] = 0; -- return simple_read_from_buffer(buf, count, ppos, buffer, n); --} -- --static struct file_operations debug_fops = { -- .read = debug_read, -- .open = debug_open, --}; --#endif -- --#if 0 --static struct miscdevice pmem_dev = { -- .name = "pmem", -- .fops = &pmem_fops, --}; --#endif -- --int pmem_setup(struct android_pmem_platform_data *pdata, -- long (*ioctl)(struct file *, unsigned int, unsigned long), -- int (*release)(struct inode *, struct file *)) --{ -- int err = 0; -- int i, index = 0; -- int id = id_count; -- id_count++; -- -- pmem[id].no_allocator = pdata->no_allocator; -- pmem[id].cached = pdata->cached; -- pmem[id].buffered = pdata->buffered; -- pmem[id].base = pdata->start; -- pmem[id].size = pdata->size; -- pmem[id].ioctl = ioctl; -- pmem[id].release = release; -- init_rwsem(&pmem[id].bitmap_sem); -- mutex_init(&pmem[id].data_list_lock); -- INIT_LIST_HEAD(&pmem[id].data_list); -- pmem[id].dev.name = pdata->name; -- pmem[id].dev.minor = id; -- pmem[id].dev.fops = &pmem_fops; -- printk(KERN_INFO "%s: %d init\n", pdata->name, pdata->cached); -- -- err = misc_register(&pmem[id].dev); -- if (err) { -- printk(KERN_ALERT "Unable to register pmem driver!\n"); -- goto err_cant_register_device; -- } -- pmem[id].num_entries = pmem[id].size / PMEM_MIN_ALLOC; -- -- pmem[id].bitmap = kmalloc(pmem[id].num_entries * -- sizeof(struct pmem_bits), GFP_KERNEL); -- if (!pmem[id].bitmap) -- goto err_no_mem_for_metadata; -- -- memset(pmem[id].bitmap, 0, sizeof(struct pmem_bits) * -- pmem[id].num_entries); -- -- for (i = sizeof(pmem[id].num_entries) * 8 - 1; i >= 0; i--) { -- if ((pmem[id].num_entries) & 1<name, S_IFREG | S_IRUGO, NULL, (void *)id, -- &debug_fops); --#endif -- return 0; --error_cant_remap: -- kfree(pmem[id].bitmap); --err_no_mem_for_metadata: -- misc_deregister(&pmem[id].dev); --err_cant_register_device: -- return -1; --} -- --static int pmem_probe(struct platform_device *pdev) --{ -- struct android_pmem_platform_data *pdata; -- -- if (!pdev || !pdev->dev.platform_data) { -- printk(KERN_ALERT "Unable to probe pmem!\n"); -- return -1; -- } -- pdata = pdev->dev.platform_data; -- return pmem_setup(pdata, NULL, NULL); --} -- -- --static int pmem_remove(struct platform_device *pdev) --{ -- int id = pdev->id; -- __free_page(pfn_to_page(pmem[id].garbage_pfn)); -- misc_deregister(&pmem[id].dev); -- return 0; --} -- --static struct platform_driver pmem_driver = { -- .probe = pmem_probe, -- .remove = pmem_remove, -- .driver = { .name = "android_pmem" } --}; -- -- --static int __init pmem_init(void) --{ -- return platform_driver_register(&pmem_driver); --} -- --static void __exit pmem_exit(void) --{ -- platform_driver_unregister(&pmem_driver); --} -- --module_init(pmem_init); --module_exit(pmem_exit); -- diff --git a/patches.android/android-0038-Staging-android-binder-Fix-crashes-when-sharing-a-binder-fil.patch b/patches.android/android-0038-Staging-android-binder-Fix-crashes-when-sharing-a-binder-fil.patch deleted file mode 100644 index c4ce228223e8..000000000000 --- a/patches.android/android-0038-Staging-android-binder-Fix-crashes-when-sharing-a-binder-fil.patch +++ /dev/null @@ -1,87 +0,0 @@ -From bd1eff9741af27378b241b347041c724bb28e857 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Wed, 1 Feb 2012 15:29:13 -0800 -Subject: Staging: android: binder: Fix crashes when sharing a binder - file between processes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: bd1eff9741af27378b241b347041c724bb28e857 - -Opening the binder driver and sharing the file returned with -other processes (e.g. by calling fork) can crash the kernel. -Prevent these crashes with the following changes: -- Add a mutex to protect against two processes mmapping the - same binder_proc. -- After locking mmap_sem, check that the vma we want to access - (still) points to the same mm_struct. -- Use proc->tsk instead of current to get the files struct since - this is where we get the rlimit from. - -Signed-off-by: Arve HjønnevÃ¥g -Cc: stable -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c -index 48cf27c..f0b7e66 100644 ---- a/drivers/staging/android/binder.c -+++ b/drivers/staging/android/binder.c -@@ -38,6 +38,7 @@ - - static DEFINE_MUTEX(binder_lock); - static DEFINE_MUTEX(binder_deferred_lock); -+static DEFINE_MUTEX(binder_mmap_lock); - - static HLIST_HEAD(binder_procs); - static HLIST_HEAD(binder_deferred_list); -@@ -632,6 +633,11 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, - if (mm) { - down_write(&mm->mmap_sem); - vma = proc->vma; -+ if (vma && mm != vma->vm_mm) { -+ pr_err("binder: %d: vma mm and task mm mismatch\n", -+ proc->pid); -+ vma = NULL; -+ } - } - - if (allocate == 0) -@@ -2802,6 +2808,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) - } - vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; - -+ mutex_lock(&binder_mmap_lock); - if (proc->buffer) { - ret = -EBUSY; - failure_string = "already mapped"; -@@ -2816,6 +2823,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) - } - proc->buffer = area->addr; - proc->user_buffer_offset = vma->vm_start - (uintptr_t)proc->buffer; -+ mutex_unlock(&binder_mmap_lock); - - #ifdef CONFIG_CPU_CACHE_VIPT - if (cache_is_vipt_aliasing()) { -@@ -2848,7 +2856,7 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) - binder_insert_free_buffer(proc, buffer); - proc->free_async_space = proc->buffer_size / 2; - barrier(); -- proc->files = get_files_struct(current); -+ proc->files = get_files_struct(proc->tsk); - proc->vma = vma; - - /*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n", -@@ -2859,10 +2867,12 @@ err_alloc_small_buf_failed: - kfree(proc->pages); - proc->pages = NULL; - err_alloc_pages_failed: -+ mutex_lock(&binder_mmap_lock); - vfree(proc->buffer); - proc->buffer = NULL; - err_get_vm_area_failed: - err_already_mapped: -+ mutex_unlock(&binder_mmap_lock); - err_bad_arg: - printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n", - proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); diff --git a/patches.android/android-0039-staging-android-lowmemorykiller-Don-t-wait-more-than-one-sec.patch b/patches.android/android-0039-staging-android-lowmemorykiller-Don-t-wait-more-than-one-sec.patch deleted file mode 100644 index bbec644e3d58..000000000000 --- a/patches.android/android-0039-staging-android-lowmemorykiller-Don-t-wait-more-than-one-sec.patch +++ /dev/null @@ -1,49 +0,0 @@ -From e5d7965f88a3755b2d0c54768a17032ab3a72819 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= -Date: Fri, 13 Jan 2012 22:21:25 +0400 -Subject: staging: android: lowmemorykiller: Don't wait more than one - second for a process to die -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Patch-mainline: HEAD -Git-commit: e5d7965f88a3755b2d0c54768a17032ab3a72819 - -If a process forked and the child process was killed by the -lowmemorykiller, the lowmemory killer would be disabled until -the parent process reaped the child or it died itself. - -Signed-off-by: Arve HjønnevÃ¥g -Signed-off-by: Anton Vorontsov -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c -index 2d8d2b7..efc7dc1 100644 ---- a/drivers/staging/android/lowmemorykiller.c -+++ b/drivers/staging/android/lowmemorykiller.c -@@ -54,6 +54,7 @@ static size_t lowmem_minfree[6] = { - static int lowmem_minfree_size = 4; - - static struct task_struct *lowmem_deathpending; -+static unsigned long lowmem_deathpending_timeout; - - #define lowmem_print(level, x...) \ - do { \ -@@ -103,7 +104,8 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) - * Note: Currently you need CONFIG_PROFILING - * for this to work correctly. - */ -- if (lowmem_deathpending) -+ if (lowmem_deathpending && -+ time_before_eq(jiffies, lowmem_deathpending_timeout)) - return 0; - - if (lowmem_adj_size < array_size) -@@ -178,6 +180,7 @@ static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) - */ - #ifdef CONFIG_PROFILING - lowmem_deathpending = selected; -+ lowmem_deathpending_timeout = jiffies + HZ; - task_handoff_register(&task_nb); - #endif - force_sig(SIGKILL, selected); diff --git a/patches.android/android-0040-staging-android-ram_console-Don-t-build-on-arches-w-o-iorema.patch b/patches.android/android-0040-staging-android-ram_console-Don-t-build-on-arches-w-o-iorema.patch deleted file mode 100644 index 36ee8811930c..000000000000 --- a/patches.android/android-0040-staging-android-ram_console-Don-t-build-on-arches-w-o-iorema.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 203209ef77e4d5f0ee729557b09770bce0c2d251 Mon Sep 17 00:00:00 2001 -From: Anton Vorontsov -Date: Tue, 7 Feb 2012 09:13:27 +0400 -Subject: staging: android/ram_console: Don't build on arches w/o - ioremap -Patch-mainline: HEAD -Git-commit: 203209ef77e4d5f0ee729557b09770bce0c2d251 - -This patch fixes UML build: - - CC drivers/staging/android/ram_console.o - drivers/staging/android/ram_console.c: In function - 'ram_console_driver_probe': - drivers/staging/android/ram_console.c:358:2: error: implicit declaration - of function 'ioremap' [-Werror=implicit-function-declaration] - cc1: some warnings being treated as errors - make[3]: *** [drivers/staging/android/ram_console.o] Error 1 - -Signed-off-by: Anton Vorontsov -Signed-off-by: Greg Kroah-Hartman - -diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig -index 94cb2ac..fef3580 100644 ---- a/drivers/staging/android/Kconfig -+++ b/drivers/staging/android/Kconfig -@@ -27,6 +27,7 @@ config ANDROID_LOGGER - - config ANDROID_RAM_CONSOLE - bool "Android RAM buffer console" -+ depends on !S390 && !UML - default n - - config ANDROID_RAM_CONSOLE_ENABLE_VERBOSE diff --git a/patches.android/staging-android-add-the-code-back-to-the-build.patch b/patches.android/staging-android-add-the-code-back-to-the-build.patch deleted file mode 100644 index 0c861b9d39f8..000000000000 --- a/patches.android/staging-android-add-the-code-back-to-the-build.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f4dc23861d9da89cfb5d2b0c5b3c96c115842a6c Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman -Date: Wed, 30 Nov 2011 20:33:10 +0900 -Subject: [PATCH] Staging: android: add the code back to the build -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It builds, so ship it! - -Cc: Arve HjønnevÃ¥g -Cc: Brian Swetland -Signed-off-by: Greg Kroah-Hartman - ---- - drivers/staging/Kconfig | 2 ++ - drivers/staging/Makefile | 2 ++ - 2 files changed, 4 insertions(+) - ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -160,4 +160,6 @@ source "drivers/staging/mei/Kconfig" - - source "drivers/staging/nvec/Kconfig" - -+source "drivers/staging/android/Kconfig" -+ - endif # STAGING ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -71,3 +71,5 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_R - obj-$(CONFIG_DRM_PSB) += gma500/ - obj-$(CONFIG_INTEL_MEI) += mei/ - obj-$(CONFIG_MFD_NVEC) += nvec/ -+obj-$(CONFIG_ANDROID) += android/ -+ diff --git a/patches.armadillo800eva/0001-module.h-split-out-the-EXPORT_SYMBOL-into-export.h.patch b/patches.armadillo800eva/0001-module.h-split-out-the-EXPORT_SYMBOL-into-export.h.patch deleted file mode 100644 index eae58477b86e..000000000000 --- a/patches.armadillo800eva/0001-module.h-split-out-the-EXPORT_SYMBOL-into-export.h.patch +++ /dev/null @@ -1,247 +0,0 @@ -From b85971d89c5269f427fe46aa9336f2f18cf82b8e Mon Sep 17 00:00:00 2001 -From: Paul Gortmaker -Date: Mon, 23 May 2011 14:11:39 -0400 -Subject: module.h: split out the EXPORT_SYMBOL into export.h - -A lot of files pull in module.h when all they are really -looking for is the basic EXPORT_SYMBOL functionality. The -recent data from Ingo[1] shows that this is one of several -instances that has a significant impact on compile times, -and it should be targeted for factoring out (as done here). - -Note that several commonly used header files in include/* -directly include themselves (some 34 of them!) -The most commonly used ones of these will have to be made -independent of module.h before the full benefit of this change -can be realized. - -We also transition THIS_MODULE from module.h to export.h, -since there are lots of files with subsystem structs that -in turn will have a struct module *owner and only be doing: - - .owner = THIS_MODULE; - -and absolutely nothing else modular. So, we also want to have -the THIS_MODULE definition present in the lightweight header. - -[1] https://lkml.org/lkml/2011/5/23/76 - -Signed-off-by: Paul Gortmaker -(cherry picked from commit f50169324df4ad942e544386d136216c8617636a) - -Signed-off-by: Simon Horman ---- - include/linux/export.h | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/module.h | 68 +----------------------------------- - 2 files changed, 90 insertions(+), 67 deletions(-) - create mode 100644 include/linux/export.h - -diff --git a/include/linux/export.h b/include/linux/export.h -new file mode 100644 -index 0000000..696c0f4 ---- /dev/null -+++ b/include/linux/export.h -@@ -0,0 +1,89 @@ -+#ifndef _LINUX_EXPORT_H -+#define _LINUX_EXPORT_H -+/* -+ * Export symbols from the kernel to modules. Forked from module.h -+ * to reduce the amount of pointless cruft we feed to gcc when only -+ * exporting a simple symbol or two. -+ * -+ * If you feel the need to add #include to this file -+ * then you are doing something wrong and should go away silently. -+ */ -+ -+/* Some toolchains use a `_' prefix for all user symbols. */ -+#ifdef CONFIG_SYMBOL_PREFIX -+#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -+#else -+#define MODULE_SYMBOL_PREFIX "" -+#endif -+ -+struct kernel_symbol -+{ -+ unsigned long value; -+ const char *name; -+}; -+ -+#ifdef MODULE -+extern struct module __this_module; -+#define THIS_MODULE (&__this_module) -+#else -+#define THIS_MODULE ((struct module *)0) -+#endif -+ -+#ifdef CONFIG_MODULES -+ -+#ifndef __GENKSYMS__ -+#ifdef CONFIG_MODVERSIONS -+/* Mark the CRC weak since genksyms apparently decides not to -+ * generate a checksums for some symbols */ -+#define __CRC_SYMBOL(sym, sec) \ -+ extern void *__crc_##sym __attribute__((weak)); \ -+ static const unsigned long __kcrctab_##sym \ -+ __used \ -+ __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ -+ = (unsigned long) &__crc_##sym; -+#else -+#define __CRC_SYMBOL(sym, sec) -+#endif -+ -+/* For every exported symbol, place a struct in the __ksymtab section */ -+#define __EXPORT_SYMBOL(sym, sec) \ -+ extern typeof(sym) sym; \ -+ __CRC_SYMBOL(sym, sec) \ -+ static const char __kstrtab_##sym[] \ -+ __attribute__((section("__ksymtab_strings"), aligned(1))) \ -+ = MODULE_SYMBOL_PREFIX #sym; \ -+ static const struct kernel_symbol __ksymtab_##sym \ -+ __used \ -+ __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ -+ = { (unsigned long)&sym, __kstrtab_##sym } -+ -+#define EXPORT_SYMBOL(sym) \ -+ __EXPORT_SYMBOL(sym, "") -+ -+#define EXPORT_SYMBOL_GPL(sym) \ -+ __EXPORT_SYMBOL(sym, "_gpl") -+ -+#define EXPORT_SYMBOL_GPL_FUTURE(sym) \ -+ __EXPORT_SYMBOL(sym, "_gpl_future") -+ -+#ifdef CONFIG_UNUSED_SYMBOLS -+#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") -+#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") -+#else -+#define EXPORT_UNUSED_SYMBOL(sym) -+#define EXPORT_UNUSED_SYMBOL_GPL(sym) -+#endif -+ -+#endif /* __GENKSYMS__ */ -+ -+#else /* !CONFIG_MODULES... */ -+ -+#define EXPORT_SYMBOL(sym) -+#define EXPORT_SYMBOL_GPL(sym) -+#define EXPORT_SYMBOL_GPL_FUTURE(sym) -+#define EXPORT_UNUSED_SYMBOL(sym) -+#define EXPORT_UNUSED_SYMBOL_GPL(sym) -+ -+#endif /* CONFIG_MODULES */ -+ -+#endif /* _LINUX_EXPORT_H */ -diff --git a/include/linux/module.h b/include/linux/module.h -index d9ca2d5..e91cc65 100644 ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -25,21 +26,8 @@ - /* Not Yet Implemented */ - #define MODULE_SUPPORTED_DEVICE(name) - --/* Some toolchains use a `_' prefix for all user symbols. */ --#ifdef CONFIG_SYMBOL_PREFIX --#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX --#else --#define MODULE_SYMBOL_PREFIX "" --#endif -- - #define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN - --struct kernel_symbol --{ -- unsigned long value; -- const char *name; --}; -- - struct modversion_info - { - unsigned long crc; -@@ -96,11 +84,8 @@ void trim_init_extable(struct module *m); - extern const struct gtype##_id __mod_##gtype##_table \ - __attribute__ ((unused, alias(__stringify(name)))) - --extern struct module __this_module; --#define THIS_MODULE (&__this_module) - #else /* !MODULE */ - #define MODULE_GENERIC_TABLE(gtype,name) --#define THIS_MODULE ((struct module *)0) - #endif - - /* Generic info of form tag = "info" */ -@@ -216,52 +201,6 @@ struct module_use { - struct module *source, *target; - }; - --#ifndef __GENKSYMS__ --#ifdef CONFIG_MODVERSIONS --/* Mark the CRC weak since genksyms apparently decides not to -- * generate a checksums for some symbols */ --#define __CRC_SYMBOL(sym, sec) \ -- extern void *__crc_##sym __attribute__((weak)); \ -- static const unsigned long __kcrctab_##sym \ -- __used \ -- __attribute__((section("___kcrctab" sec "+" #sym), unused)) \ -- = (unsigned long) &__crc_##sym; --#else --#define __CRC_SYMBOL(sym, sec) --#endif -- --/* For every exported symbol, place a struct in the __ksymtab section */ --#define __EXPORT_SYMBOL(sym, sec) \ -- extern typeof(sym) sym; \ -- __CRC_SYMBOL(sym, sec) \ -- static const char __kstrtab_##sym[] \ -- __attribute__((section("__ksymtab_strings"), aligned(1))) \ -- = MODULE_SYMBOL_PREFIX #sym; \ -- static const struct kernel_symbol __ksymtab_##sym \ -- __used \ -- __attribute__((section("___ksymtab" sec "+" #sym), unused)) \ -- = { (unsigned long)&sym, __kstrtab_##sym } -- --#define EXPORT_SYMBOL(sym) \ -- __EXPORT_SYMBOL(sym, "") -- --#define EXPORT_SYMBOL_GPL(sym) \ -- __EXPORT_SYMBOL(sym, "_gpl") -- --#define EXPORT_SYMBOL_GPL_FUTURE(sym) \ -- __EXPORT_SYMBOL(sym, "_gpl_future") -- -- --#ifdef CONFIG_UNUSED_SYMBOLS --#define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") --#define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") --#else --#define EXPORT_UNUSED_SYMBOL(sym) --#define EXPORT_UNUSED_SYMBOL_GPL(sym) --#endif -- --#endif -- - enum module_state - { - MODULE_STATE_LIVE, -@@ -582,11 +521,6 @@ extern void module_update_tracepoints(void); - extern int module_get_iter_tracepoints(struct tracepoint_iter *iter); - - #else /* !CONFIG_MODULES... */ --#define EXPORT_SYMBOL(sym) --#define EXPORT_SYMBOL_GPL(sym) --#define EXPORT_SYMBOL_GPL_FUTURE(sym) --#define EXPORT_UNUSED_SYMBOL(sym) --#define EXPORT_UNUSED_SYMBOL_GPL(sym) - - /* Given an address, look for it in the exception tables. */ - static inline const struct exception_table_entry * --- -1.7.10 - diff --git a/patches.armadillo800eva/0002-arm-Add-export.h-to-ARM-specific-files-as-required.patch b/patches.armadillo800eva/0002-arm-Add-export.h-to-ARM-specific-files-as-required.patch deleted file mode 100644 index ed49702aec16..000000000000 --- a/patches.armadillo800eva/0002-arm-Add-export.h-to-ARM-specific-files-as-required.patch +++ /dev/null @@ -1,460 +0,0 @@ -From 37e7a4e1eddd663a2c5fddaabf80598f204fea62 Mon Sep 17 00:00:00 2001 -From: Paul Gortmaker -Date: Sun, 31 Jul 2011 16:17:29 -0400 -Subject: arm: Add export.h to ARM specific files as required. - -These files all make use of one of the EXPORT_SYMBOL variants -or the THIS_MODULE macro. So they will need - -Signed-off-by: Paul Gortmaker -(cherry picked from commit dc28094b905a872f8884f1f1c48ca86b3b78583a) - -Signed-off-by: Simon Horman ---- - arch/arm/common/it8152.c | 1 + - arch/arm/common/scoop.c | 1 + - arch/arm/mach-at91/cpuidle.c | 1 + - arch/arm/mach-davinci/board-dm644x-evm.c | 1 + - arch/arm/mach-davinci/board-dm646x-evm.c | 1 + - arch/arm/mach-davinci/cpufreq.c | 1 + - arch/arm/mach-davinci/cpuidle.c | 1 + - arch/arm/mach-ep93xx/core.c | 1 + - arch/arm/mach-exynos4/dev-sysmmu.c | 1 + - arch/arm/mach-iop13xx/pci.c | 1 + - arch/arm/mach-ixp2000/core.c | 1 + - arch/arm/mach-ixp4xx/common-pci.c | 1 + - arch/arm/mach-ixp4xx/common.c | 1 + - arch/arm/mach-kirkwood/cpuidle.c | 1 + - arch/arm/mach-msm/io.c | 1 + - arch/arm/mach-netx/xc.c | 1 + - arch/arm/mach-omap1/board-ams-delta.c | 1 + - arch/arm/mach-omap1/board-sx1.c | 1 + - arch/arm/mach-omap1/board-voiceblue.c | 1 + - arch/arm/mach-omap2/board-omap3evm.c | 1 + - arch/arm/mach-omap2/pm.c | 1 + - arch/arm/mach-omap2/prcm.c | 1 + - arch/arm/mach-omap2/usb-tusb6010.c | 1 + - arch/arm/mach-omap2/voltage.c | 1 + - arch/arm/mach-pxa/poodle.c | 1 + - arch/arm/mach-pxa/trizeps4.c | 1 + - arch/arm/mach-s3c2410/mach-h1940.c | 1 + - arch/arm/mach-s3c64xx/dev-audio.c | 1 + - arch/arm/mach-shmobile/clock.c | 1 + - arch/arm/mach-tegra/pcie.c | 1 + - arch/arm/mm/init.c | 1 + - arch/arm/plat-iop/gpio.c | 1 + - arch/arm/plat-iop/time.c | 1 + - arch/arm/plat-omap/clock.c | 1 + - 34 files changed, 34 insertions(+) - -diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c -index 7a21927..f8524ac 100644 ---- a/arch/arm/common/it8152.c -+++ b/arch/arm/common/it8152.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c -index c11af1e..67685fd 100644 ---- a/arch/arm/common/scoop.c -+++ b/arch/arm/common/scoop.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c -index 1cfeac1..f474272 100644 ---- a/arch/arm/mach-at91/cpuidle.c -+++ b/arch/arm/mach-at91/cpuidle.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include "pm.h" - -diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c -index 556bbd4..6b1760f 100644 ---- a/arch/arm/mach-davinci/board-dm644x-evm.c -+++ b/arch/arm/mach-davinci/board-dm644x-evm.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - -diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c -index 3cdd237..f28a884 100644 ---- a/arch/arm/mach-davinci/board-dm646x-evm.c -+++ b/arch/arm/mach-davinci/board-dm646x-evm.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c -index 41669ec..5bba707 100644 ---- a/arch/arm/mach-davinci/cpufreq.c -+++ b/arch/arm/mach-davinci/cpufreq.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-davinci/cpuidle.c b/arch/arm/mach-davinci/cpuidle.c -index bd59f31..85cc399 100644 ---- a/arch/arm/mach-davinci/cpuidle.c -+++ b/arch/arm/mach-davinci/cpuidle.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - - #include -diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c -index 6659a0d..a946b20 100644 ---- a/arch/arm/mach-ep93xx/core.c -+++ b/arch/arm/mach-ep93xx/core.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos4/dev-sysmmu.c -index 3b7cae0..781563f 100644 ---- a/arch/arm/mach-exynos4/dev-sysmmu.c -+++ b/arch/arm/mach-exynos4/dev-sysmmu.c -@@ -12,6 +12,7 @@ - - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c -index ba3dae3..0de7ad2 100644 ---- a/arch/arm/mach-iop13xx/pci.c -+++ b/arch/arm/mach-iop13xx/pci.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c -index 4068166..276391e 100644 ---- a/arch/arm/mach-ixp2000/core.c -+++ b/arch/arm/mach-ixp2000/core.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c -index e9a5893..98bebd1 100644 ---- a/arch/arm/mach-ixp4xx/common-pci.c -+++ b/arch/arm/mach-ixp4xx/common-pci.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - - #include -diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c -index 0777257..b86a005 100644 ---- a/arch/arm/mach-ixp4xx/common.c -+++ b/arch/arm/mach-ixp4xx/common.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-kirkwood/cpuidle.c b/arch/arm/mach-kirkwood/cpuidle.c -index f68d33f..864e569 100644 ---- a/arch/arm/mach-kirkwood/cpuidle.c -+++ b/arch/arm/mach-kirkwood/cpuidle.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - -diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c -index cec6ed1..8bf34bc 100644 ---- a/arch/arm/mach-msm/io.c -+++ b/arch/arm/mach-msm/io.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-netx/xc.c b/arch/arm/mach-netx/xc.c -index f009b54..e4cfb7e 100644 ---- a/arch/arm/mach-netx/xc.c -+++ b/arch/arm/mach-netx/xc.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c -index f49ce85..be8fe81 100644 ---- a/arch/arm/mach-omap1/board-ams-delta.c -+++ b/arch/arm/mach-omap1/board-ams-delta.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include - -diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c -index 0ad781d..63c550c 100644 ---- a/arch/arm/mach-omap1/board-sx1.c -+++ b/arch/arm/mach-omap1/board-sx1.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c -index 65d2420..f2e5eed 100644 ---- a/arch/arm/mach-omap1/board-voiceblue.c -+++ b/arch/arm/mach-omap1/board-voiceblue.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c -index b4d4346..0661686 100644 ---- a/arch/arm/mach-omap2/board-omap3evm.c -+++ b/arch/arm/mach-omap2/board-omap3evm.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c -index 49486f5..39ce26c 100644 ---- a/arch/arm/mach-omap2/pm.c -+++ b/arch/arm/mach-omap2/pm.c -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c -index 6be1438..1a5054e 100644 ---- a/arch/arm/mach-omap2/prcm.c -+++ b/arch/arm/mach-omap2/prcm.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c -index 8dd26b7..d7f4a00 100644 ---- a/arch/arm/mach-omap2/usb-tusb6010.c -+++ b/arch/arm/mach-omap2/usb-tusb6010.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #include - -diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c -index 9ef3789..e964cfd 100644 ---- a/arch/arm/mach-omap2/voltage.c -+++ b/arch/arm/mach-omap2/voltage.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c -index 16d14fd..46db441 100644 ---- a/arch/arm/mach-pxa/poodle.c -+++ b/arch/arm/mach-pxa/poodle.c -@@ -16,6 +16,7 @@ - */ - #include - #include -+#include - #include - #include - #include -diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c -index 687417a..3f1a258 100644 ---- a/arch/arm/mach-pxa/trizeps4.c -+++ b/arch/arm/mach-pxa/trizeps4.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c -index 2a2fa06..810a992 100644 ---- a/arch/arm/mach-s3c2410/mach-h1940.c -+++ b/arch/arm/mach-s3c2410/mach-h1940.c -@@ -35,6 +35,7 @@ - #include