diff options
author | Praneeth Bajjuri <praneeth@ti.com> | 2014-08-05 18:06:21 -0500 |
---|---|---|
committer | Praneeth Bajjuri <praneeth@ti.com> | 2014-08-05 18:07:18 -0500 |
commit | cedc4a02470fbed1f5ee9f9b41d54307b3999278 (patch) | |
tree | 4a9b95c7b38d15ecc1634b1b8cf351c63d9d73e5 | |
parent | cf03903f4012e5dd1d49110b3112cba62c827d5b (diff) | |
parent | 8aed6500ff95bd66f4a0ba80f63a9550951d1c04 (diff) | |
download | jacinto6evm-p-ti-android-3.8.y-linaro-10.tar.gz |
Merge branch 'p-ti-android-3.8.y' of git://git.omapzoom.org/kernel/omap into p-ti-android-3.8.yp-ti-android-3.8.y-linaro-10
* 'p-ti-android-3.8.y' of git://git.omapzoom.org/kernel/omap: (70 commits)
ARM: DRA7: enable the 10" display
mmc: card: fixing an false identification of SANITIZE command
mmc: card: Adding support for sanitize in eMMC 4.5
TI-EC: fix trigger key read logic
gpio: pcf857x: handle gpio->read return value
OMAPDSS: android-display: fixed sparse and compiler warnings
OMAPDSS: omapfb: Fixed sparse & compiler warnings
mm: vmscan: Fixed sparse & compiler warnings
gpu: ion: Fixed sparse & compiler warnings
backlight: generic_bl: Fixed sparse & compiler warnings
i2c: ov1063x: Fixed sparse & compiler warnings
C_CAN: D_CAN: Fixed sparse & compiler warnings
TI-VPS: Fixed sparse and compiler warnings
TI-EC: Fixed sparse & compiler warnings in early camera
mtd: onenand: omap: Fixed sparse & compiler warnings in omap2.c
ARM: OMAP: hci_tty: Fixed sparse & compiler warnings in tty_hci.c
OMAPDSS: TFCS panel: Fixed sparse & compiler warnings in TFCS panel driver
v4l: ti-vps: vip: Use TILED flag in descriptor when using TILER address
v4l: ti-vps: vip: Call subdev op for getting video field type
v4l: v4l2-core: HACK: Allow TILER2D buffers for DMA BUFF mapping
...
Signed-off-by: Praneeth Bajjuri <praneeth@ti.com>
51 files changed, 1250 insertions, 359 deletions
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 851f526ef742..a06aa6f3c09f 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -81,7 +81,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x20000000>; /* 512 MB */ + reg = <0x80000000 0x60000000>; /* 512 + 1024 MB */ }; vmmc2_fixed: fixedregulator-mmc2 { @@ -180,7 +180,6 @@ ti,media-codec = <&tlv320aic3106>; ti,media-mclk-freq = <11289600>; ti,media-slots = <2>; - ti,media-shared; /* Multichannel DAI link */ ti,multichannel-cpu = <&mcasp6>; @@ -189,6 +188,7 @@ ti,multichannel-codec-c = <&tlv320aic3106c>; ti,multichannel-slots = <8>; ti,multichannel-mclk-freq = <11289600>; + ti,multichannel-shared; /* Bluetooth */ ti,bt-cpu = <&mcasp7>; @@ -579,7 +579,7 @@ dcan1_pins: pinmux_dcan1_pins { pinctrl-single,pins = < 0x3d0 0x00000000 /* DCAN1_TX: MODE0 */ - 0x3d4 0x00060000 /* DCAN1_RX: MODE0 | INPUTENABLE | PULLUP */ + 0x418 0x00000001 /* WAKEUP0: MODE1 */ >; }; @@ -675,9 +675,9 @@ gpios = <&pcf_lcd 15 0>; /* P15, CON_LCD_PWR_DN */ }; - tlv320aic3106: tlv320aic3106@18 { + tlv320aic3106: tlv320aic3106@19 { compatible = "ti,tlv320aic3x"; - reg = <0x18>; + reg = <0x19>; adc-settle-ms = <40>; IOVDD-supply = <&vaudio_3v3>; DVDD-supply = <&vaudio_1v8>; @@ -685,9 +685,12 @@ DRVDD-supply = <&vaudio_3v3>; }; - mXT244:mXT244@4a { - reg = <0x4a>; + ldc3001:ldc3001@18 { + reg = <0x18>; + interrupt-parent = <&gpio1>; + interrupts = <2 4>; }; + }; /include/ "tps659038.dtsi" @@ -1090,17 +1093,53 @@ pinctrl-0 = <&vin1a_pins &vin1a_d16_d23_pins>; */ pinctrl-0 = <&vin1a_pins &vin1a_d16_d23_pins>; + + vin1a: port@0A { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + vin2a: port@1A { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; }; &vip2 { pinctrl-names = "default"; pinctrl-0 = <&vin3a_pins>; + + vin3a: port@0A { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + vin4a: port@1A { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; }; &vip3 { pinctrl-names = "default"; //pinctrl-0 = <&vin5a_pins &vin6a_pins>; pinctrl-0 = <&vin5a_pins>; + + vin5a: port@0A { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + vin6a: port@1A { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; }; &vin1a { @@ -1163,12 +1202,16 @@ &dpi1 { lcd { - compatible = "ti,tfc_s9700"; + compatible = "ti,tfc_lp101"; tlc = <&tlc59108>; data-lines = <24>; }; }; +&ldc3001 { + compatible = "lgphilips,ldc3001"; +}; + &hdmi { vdda_hdmi_dac-supply = <&ldo3_reg>; tpd12s015: tpd12s015 { @@ -1197,59 +1240,6 @@ }; }; -&mXT244 { - compatible = "atmel,mXT244"; - interrupts = <0 119 0x4>; - - atmel,config = < - /* MXT244_GEN_COMMAND(6) */ - 0x00 0x00 0x00 0x00 0x00 0x00 - /* MXT244_GEN_POWER(7) */ - 0x20 0xff 0x32 - /* MXT244_GEN_ACQUIRE(8) */ - 0x0a 0x00 0x05 0x00 0x00 0x00 0x09 0x23 - /* MXT244_TOUCH_MULTI(9) */ - 0x00 0x00 0x00 0x13 0x0b 0x00 0x00 0x00 0x02 0x00 - 0x00 0x01 0x01 0x0e 0x0a 0x0a 0x0a 0x0a 0x00 0x00 - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 - /* MXT244_TOUCH_KEYARRAY(15) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 - /* MXT244_COMMSCONFIG_T18(2) */ - 0x00 0x00 - /* MXT244_SPT_GPIOPWM(19) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 0x00 0x00 0x00 0x00 0x00 - /* MXT244_PROCI_GRIPFACE(20) */ - 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x50 0x28 0x04 - 0x0f 0x0a - /* MXT244_PROCG_NOISE(22) */ - 0x05 0x00 0x00 0x00 0x00 0x00 0x00 0x03 0x23 0x00 - 0x00 0x05 0x0f 0x19 0x23 0x2d 0x03 - /* MXT244_TOUCH_PROXIMITY(23) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 0x00 0x00 0x00 0x00 - /* MXT244_PROCI_ONETOUCH(24) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - /* MXT244_SPT_SELFTEST(25) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x00 0x00 0x00 0x00 - /* MXT244_PROCI_TWOTOUCH(27) */ - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - /* MXT244_SPT_CTECONFIG(28) */ - 0x00 0x00 0x02 0x08 0x10 0x00 >; - - atmel,x_line = <18>; - atmel,y_line = <12>; - atmel,x_size = <800>; - atmel,y_size = <480>; - atmel,blen = <0x01>; - atmel,threshold = <30>; - atmel,voltage = <2800000>; - atmel,orient = <0x4>; -}; &qspi { spi-max-frequency = <48000000>; m25p80@0 { diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 27ec4e4150d9..57bb8008dc5c 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -755,6 +755,7 @@ compatible = "ti,avsclass0"; reg = <0x4A0025EC 0x20>; efuse-settings = <1030000 8>; + voltage-tolerance = <1>; }; avs_gpu: regulator-avs@0x4A003B00 { @@ -769,7 +770,7 @@ avs_dspeve: regulator-avs@0x4A0025D8 { compatible = "ti,avsclass0"; reg = <0x4A0025D8 0x20>; - efuse-settings = <1055000 8 + efuse-settings = <1060000 8 1150000 12 1250000 16>; voltage-tolerance = <1>; @@ -778,7 +779,7 @@ avs_iva: regulator-avs@0x4A0025C4 { compatible = "ti,avsclass0"; reg = <0x4A0025C4 0x20>; - efuse-settings = <1055000 8 + efuse-settings = <1060000 8 1150000 12 1250000 16>; voltage-tolerance = <1>; @@ -1092,17 +1093,6 @@ <0 153 0x4>; #address-cells = <1>; #size-cells = <0>; - - vin1a: port@0A { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - }; - vin2a: port@1A { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - }; }; vip2: vip@0x48990000 { @@ -1115,17 +1105,6 @@ <0 151 0x4>; #address-cells = <1>; #size-cells = <0>; - - vin3a: port@0A { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - }; - vin4a: port@1A { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - }; }; vip3: vip@0x489b0000 { @@ -1138,17 +1117,6 @@ <0 149 0x4>; #address-cells = <1>; #size-cells = <0>; - - vin5a: port@0A { - #address-cells = <1>; - #size-cells = <0>; - reg = <0>; - }; - vin6a: port@1A { - #address-cells = <1>; - #size-cells = <0>; - reg = <1>; - }; }; vpe { diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index ab745be9f727..bd620ef0ff6c 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -92,6 +92,12 @@ ti,omap_ion_heap_nonsecure_tiler_size = <0xF00000>; }; + display_layout { + compatible = "ti, omap4-dsscomp"; + ti,num_displays = <3>; + ti,default_display = "lcd"; + }; + vmmcwl_fixed: fixedregulator-mmcwl { compatible = "regulator-fixed"; regulator-name = "vmmcwl_fixed"; @@ -102,6 +108,11 @@ enable-active-high; }; + wlcore { + compatible = "wlcore"; + gpio = <135>; + }; + vaudio_1v8: fixedregulator-vaudio-dig { compatible = "regulator-fixed"; regulator-name = "vdac_fixed"; @@ -167,6 +178,17 @@ ti,bt-bclk-freq = <512000>; }; + radio { + compatible = "ti,dra7xx_radio"; + gpios = <&gpio6 20 0>; + + radio_helper1 { + compatible = "ti,dra7xx_radio_subdev"; + ti,hwmods = "mcasp2"; + status = "okay"; + }; + }; + sound_hdmi { compatible = "ti,omap-hdmi-tpd12s015-audio"; ti,model = "OMAP5HDMI"; @@ -188,6 +210,18 @@ dr_mode = "host"; }; + kim { + compatible = "kim"; + nshutdown_gpio = <132>; + dev_name = "/dev/ttyO2"; + flow_cntrl = <1>; + baud_rate = <3686400>; + gpios = <&pcf_lcd3 14 0>; /* pcf8575@21 P16 */ + }; + + btwilink { + compatible = "btwilink"; + }; }; @@ -201,6 +235,10 @@ &mcasp7_pins &vout1_pins &usb_pins + &wl_pins + &wlirq_pins + &bt_uart3_pins + &radio_pins >; i2c1_pins: pinmux_i2c1_pins { @@ -210,6 +248,13 @@ >; }; + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + 0x408 0x60001 /* hdmi_sda INPUT | MODE1 */ + 0x40C 0x60001 /* hdmi_scl INPUT | MODE1 */ + >; + }; + i2c3_pins: pinmux_i2c3_pins { pinctrl-single,pins = < 0x410 0x60000 /* i2c3_sda INPUT | MODE0 */ @@ -231,6 +276,66 @@ >; }; + wl_pins: pinmux_wl_pins { + pinctrl-single,pins = < + 0x3e8 0x60003 /* MMC4_CLK: INPUTENABLE | PULLUP | MODE3 */ + 0x3ec 0x60003 /* MMC4_CMD: INPUTENABLE | PULLUP | MODE3 */ + 0x3f0 0x60003 /* MMC4_DAT0: INPUTENABLE | PULLUP | MODE3 */ + 0x3f4 0x60003 /* MMC4_DAT1: INPUTENABLE | PULLUP | MODE3 */ + 0x3f8 0x60003 /* MMC4_DAT2: INPUTENABLE | PULLUP | MODE3 */ + 0x3fc 0x60003 /* MMC4_DAT3: INPUTENABLE | PULLUP | MODE3 */ + 0x2cc 0x2000E /* WLAN_EN: OUTPUT | MODE14 */ + >; + }; + + wlirq_pins: pinmux_wlirq_pins { + pinctrl-single,pins = < + 0x2c8 0x106000E /* WLAN_IRQ: INPUT | WAKEUP_ENABLE | MODE 14 */ + >; + }; + + bt_uart3_pins: pinmux_bt_uart3_pins { + pinctrl-single,pins = < + 0x3c0 0x60001 /* uart3_rx.spi2_sclk: INPUT | PULLUP | MODE 1 */ + 0x3c4 0x1 /* uart3_tx.spi2.d1: OUTPUT | MODE 1 */ + 0x3c8 0x40001 /* uart3_rts.spi2.c0: OUTPUT | PULLUP | MODE 1 */ + 0x3cc 0x60001 /* uart3_cts.spi2.d0: INPUT | MODE 1 */ + 0x2bc 0xE /* BT_EN.gp5_4: OUTPUT | MODE 14 */ + >; + }; + + dcan1_pins: pinmux_dcan1_pins { + pinctrl-single,pins = < + 0x3d0 0x00000000 /* DCAN1_TX: MODE0 */ + 0x418 0x00000001 /* WAKEUP0: MODE1 */ + >; + }; + + dcan2_pins: pinmux_dcan2_pins { + pinctrl-single,pins = < + 0x288 0x00000002 /* DCAN2_TX: MODE2 */ + 0x28C 0x00060002 /* DCAN2_RX: MODE2 | INPUTENABLE | PULLUP */ + >; + }; + + radio_pins: pinmux_radio_pins { + pinctrl-single,pins = < + 0x02F4 0x40000 /* MCASP2_ACLKX: MODE0 */ + 0x02F8 0xc0000 /* MCASP2_AFSX: MODE0 */ + 0x0304 0x40000 /* MCASP2_AXR0: MODE0 */ + 0x0308 0x40000 /* MCASP2_AXR1: MODE0 */ + 0x030C 0xc0000 /* MCASP2_AXR2: MODE0 */ + 0x0310 0xc0000 /* MCASP2_AXR3: MODE0 */ + 0x0314 0x40000 /* MCASP2_AXR4: MODE0 */ + 0x0318 0x40000 /* MCASP2_AXR5: MODE0 */ + 0x031c 0x40000 /* MCASP2_AXR6: MODE0 */ + 0x0320 0x40000 /* MCASP2_AXR7: MODE0 */ + 0x0334 0x70004 /* I2C4_SDA: MODE4 */ + 0x0338 0x70004 /* I2C4_SCL: MODE4 */ + 0x02A0 0x5000e /* GPIO6_20: MODE14 */ + >; + }; + vout1_pins: pinmux_vout1_pins { pinctrl-single,pins = < 0x1C8 0x0 /* vout1_clk OUTPUT | MODE0 */ @@ -340,6 +445,31 @@ >; }; + cpsw_default_pins: pinmux_cpsw_default_pins { + pinctrl-single,pins = < + /* Slave 1 */ + 0x250 0x0 /* rgmii1_tclk PIN_OUTPUT | MUX_MODE0 */ + 0x254 0x0 /* rgmii1_tctl PIN_OUTPUT | MUX_MODE0 */ + 0x258 0x0 /* rgmii1_td3 PIN_OUTPUT | MUX_MODE0 */ + 0x25c 0x0 /* rgmii1_td2 PIN_OUTPUT | MUX_MODE0 */ + 0x260 0x0 /* rgmii1_td1 PIN_OUTPUT | MUX_MODE0 */ + 0x264 0x0 /* rgmii1_td0 PIN_OUTPUT | MUX_MODE0 */ + 0x268 0x00040000 /* rgmii1_rclk PIN_INPUT | MUX_MODE0 */ + 0x26c 0x00040000 /* rgmii1_rctl PIN_INPUT | MUX_MODE0 */ + 0x270 0x00040000 /* rgmii1_rd3 PIN_INPUT | MUX_MODE0 */ + 0x274 0x00040000 /* rgmii1_rd2 PIN_INPUT | MUX_MODE0 */ + 0x278 0x00040000 /* rgmii1_rd1 PIN_INPUT | MUX_MODE0 */ + 0x27c 0x00040000 /* rgmii1_rd0 PIN_INPUT | MUX_MODE0 */ + >; + }; + + davinci_mdio_default_pins: pinmux_davinci_mdio_default_pins { + pinctrl-single,pins = < + 0x23C 0x30000 /* mdio_data PIN_OUTPUT_PULLUP | MUX_MODE0 */ + 0x240 0x70000 /* mdio_clk PIN_INPUT_PULLUP | MUX_MODE0 */ + >; + }; + mcasp3_pins: pinmux_mcasp3_pins { pinctrl-single,pins = < 0x324 0x00000180 /* mcasp3_aclkx.mcasp3_aclkx OUTPUT | MODE0 */ @@ -393,7 +523,7 @@ reg = <0x21>; gpio-controller; #gpio-cells = <2>; - n_latch = <0x1408>; + n_latch = <0x1418>; interrupt-parent = <&gpio6>; interrupts = <14 2>; interrupt-controller; @@ -546,7 +676,7 @@ reg = <0x26>; gpio-controller; #gpio-cells = <2>; - n_latch = <0xfffb>; + n_latch = <0xff7b>; }; tlv320aic3106a: tlv320aic3106@18 { @@ -584,7 +714,8 @@ <&gpio4 14 0>, <&gpio4 15 0>, <&gpio4 16 0>, - <&gpio6 17 0>; + <&gpio6 17 0>, + <&pcf_hdmi 6 0>; }; ov10633@37 { @@ -600,6 +731,26 @@ }; }; + camera_tvp5158: camera_tvp5158 { + compatible = "ti,tvp5158"; + reg = <0x58>; + gpios = <&pcf_hdmi 3 0>, + <&pcf_lcd3 8 0>, + <&pcf_hdmi 2 0>, + <&pcf_hdmi 6 0>; + port { + tvp5158: endpoint { + // No props incase of BT656 + }; + }; + }; + +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + clock-frequency = <400000>; }; &i2c3 { @@ -614,10 +765,28 @@ clock-frequency = <400000>; }; +&dcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&dcan1_pins>; + status = "okay"; +}; + +&dcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&dcan2_pins>; + status = "okay"; +}; + &vip1 { pinctrl-names = "default"; pinctrl-0 = <&vin1a_pins &vin2a_pins>; + + vin2a: port@1A { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; }; &vin2a { @@ -625,6 +794,30 @@ slave-mode; remote-endpoint = <&onboardLI>; }; + + endpoint@1 { + slave-mode; + remote-endpoint = <&tvp5158>; + }; +}; + +&gmac { + status="okay"; + pinctrl-names = "default"; + pinctrl-0 = <&cpsw_default_pins>; +}; + +&davinci_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&davinci_mdio_default_pins>; +}; + +&cpsw_emac0 { + phy_id = <&davinci_mdio>, <3>; +}; + +&cpsw_emac1 { + phy_id = <&davinci_mdio>, <2>; }; &mmc1 { @@ -678,7 +871,7 @@ <&pcf_hdmi 5 0>, /* pcf8575@22 P5, LS_OE */ <&gpio7 12 0>; /* gpio7_12/sp1_cs2, HPD */ - hdmi_ddc = <&i2c5>; + hdmi_ddc = <&i2c2>; hdmi-monitor { compatible = "ti,hdmi_panel"; diff --git a/arch/arm/boot/dts/tps659038.dtsi b/arch/arm/boot/dts/tps659038.dtsi index 39f70ed114c1..e19c6de5c6ed 100644 --- a/arch/arm/boot/dts/tps659038.dtsi +++ b/arch/arm/boot/dts/tps659038.dtsi @@ -50,8 +50,8 @@ smps7_reg: smps7 { regulator-name = "smps7"; - regulator-min-microvolt = <1030000>; - regulator-max-microvolt = <1030000>; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1060000>; regulator-always-on; regulator-boot-on; }; diff --git a/arch/arm/configs/android_omap_defconfig b/arch/arm/configs/android_omap_defconfig index 6765ad23b5ba..5246906a4745 100644 --- a/arch/arm/configs/android_omap_defconfig +++ b/arch/arm/configs/android_omap_defconfig @@ -35,7 +35,7 @@ CONFIG_PREEMPT=y CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/mmcblk0p2 rw rootwait console=ttyO0,115200 androidboot.console=ttyO0 mem=1500M init=/init omapfb.fb_opt=-1,-1,-1,-1,-1,-1 cma=96M no_console_suspend androidboot.selinux=permissive" +CONFIG_CMDLINE="root=/dev/mmcblk0p2 rw rootwait console=ttyO0,115200 androidboot.console=ttyO0 init=/init omapfb.fb_opt=-1,-1,-1,-1,-1,-1 cma=96M no_console_suspend androidboot.selinux=permissive" # CONFIG_CMDLINE_FORCE is not set CONFIG_CMDLINE_EXTEND=y CONFIG_KEXEC=y @@ -262,10 +262,12 @@ CONFIG_MFD_PALMAS_PWM=y CONFIG_MFD_PALMAS_RESOURCE=y CONFIG_REGULATOR_PALMAS=y CONFIG_MFD_TPS65910=y +CONFIG_MFD_TPS65917=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65910=y +CONFIG_REGULATOR_TPS65917=y CONFIG_REGULATOR_TI_ABB=y CONFIG_REGULATOR_TIAVSCLASS0=y CONFIG_MEDIA_SUPPORT=y @@ -468,6 +470,7 @@ CONFIG_TI_DAVINCI_MDIO=y CONFIG_TI_DAVINCI_CPDMA=y CONFIG_PM_WAKELOCKS=y CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_TOUCHSCREEN_LDC3001=y CONFIG_PANEL_LG_101=y CONFIG_PANEL_SERLINK=y CONFIG_PANEL_DSERLINK=y diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 398e5fdc21de..3028087905fe 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -12,6 +12,7 @@ config ARCH_OMAP2PLUS_TYPICAL select MENELAUS if ARCH_OMAP2 select NEON if CPU_V7 select PM_RUNTIME + select SOC_BUS select REGULATOR select SERIAL_OMAP select SERIAL_OMAP_CONSOLE diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index a9f8ce65fdc6..824f9be7e37b 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -123,6 +123,14 @@ int omap2_common_pm_late_init(void); void dra7xx_init_early(void); void dra7xx_init_late(void); +#ifdef CONFIG_SOC_BUS +void omap_soc_device_init(void); +#else +static inline void omap_soc_device_init(void) +{ +} +#endif + #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430) void omap2xxx_restart(char mode, const char *cmd); #else diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 0aabee9cd58c..63f5a54fd857 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -749,7 +749,6 @@ static int __init omap2_init_devices(void) */ omap_init_audio(); omap_init_camera(); - omap_init_mbox(); gcxxx_init(); /* If dtb is there, the devices will be created dynamically */ if (!of_have_populated_dt()) { diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index fd505a32d88f..349aa731e3f8 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -18,6 +18,11 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/slab.h> + +#ifdef CONFIG_SOC_BUS +#include <linux/sys_soc.h> +#endif #include <asm/cputype.h> @@ -31,8 +36,11 @@ #define OMAP4_SILICON_TYPE_STANDARD 0x01 #define OMAP4_SILICON_TYPE_PERFORMANCE 0x02 +#define OMAP_SOC_MAX_NAME_LENGTH 16 + static unsigned int omap_revision; -static const char *cpu_rev; +static char soc_name[OMAP_SOC_MAX_NAME_LENGTH]; +static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH]; u32 omap_features; unsigned int omap_rev(void) @@ -197,9 +205,12 @@ void __init omap2xxx_check_revision(void) j = i; } - pr_info("OMAP%04x", omap_rev() >> 16); + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf); + + pr_info("%s", soc_name); if ((omap_rev() >> 8) & 0x0f) - pr_info("ES%x", (omap_rev() >> 12) & 0xf); + pr_info("%s", soc_rev); pr_info("\n"); } @@ -239,8 +250,10 @@ static void __init omap3_cpuinfo(void) cpu_name = "OMAP3503"; } + sprintf(soc_name, "%s", cpu_name); + /* Print verbose information */ - pr_info("%s ES%s (", cpu_name, cpu_rev); + pr_info("%s %s (", soc_name, soc_rev); OMAP3_SHOW_FEATURE(l2cache); OMAP3_SHOW_FEATURE(iva); @@ -332,6 +345,7 @@ void __init am33xx_check_features(void) void __init omap3xxx_check_revision(void) { + const char *cpu_rev; u32 cpuid, idcode; u16 hawkeye; u8 rev; @@ -483,6 +497,7 @@ void __init omap3xxx_check_revision(void) cpu_rev = "1.2"; pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n"); } + sprintf(soc_rev, "ES%s", cpu_rev); } void __init omap4xxx_check_revision(void) @@ -557,8 +572,10 @@ void __init omap4xxx_check_revision(void) omap_revision = OMAP4430_REV_ES2_3; } - pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, - ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, + (omap_rev() >> 8) & 0xf); + pr_info("%s %s\n", soc_name, soc_rev); } void __init omap5xxx_check_revision(void) @@ -605,8 +622,10 @@ void __init omap5xxx_check_revision(void) omap_revision = OMAP5430_REV_ES2_0; } - pr_info("OMAP%04x ES%d.0\n", - omap_rev() >> 16, ((omap_rev() >> 12) & 0xf)); + sprintf(soc_name, "OMAP%04x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf); + + pr_info("%s %s\n", soc_name, soc_rev); } void __init dra7xx_check_revision(void) @@ -631,13 +650,29 @@ void __init dra7xx_check_revision(void) omap_revision = DRA752_REV_ES1_0; } break; + + case 0xb9bc: + switch (rev) { + case 0: + omap_revision = DRA722_REV_ES1_0; + break; + default: + /* If we have no new revisions */ + omap_revision = DRA722_REV_ES1_0; + break; + } + break; + default: /* Unknown. Default to latest silicon revision */ omap_revision = DRA752_REV_ES1_0; } - pr_info("DRA%03x ES%d.%d\n", omap_rev() >> 16, - ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); + sprintf(soc_name, "DRA%03x", omap_rev() >> 16); + sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf, + (omap_rev() >> 8) & 0xf); + + pr_info("%s %s\n", soc_name, soc_rev); } /* @@ -658,3 +693,65 @@ void __init omap2_set_globals_tap(u32 class, void __iomem *tap) else tap_prod_id = 0x0208; } + +#ifdef CONFIG_SOC_BUS + +static const char const *omap_types[] = { + [OMAP2_DEVICE_TYPE_TEST] = "TST", + [OMAP2_DEVICE_TYPE_EMU] = "EMU", + [OMAP2_DEVICE_TYPE_SEC] = "HS", + [OMAP2_DEVICE_TYPE_GP] = "GP", + [OMAP2_DEVICE_TYPE_BAD] = "BAD", +}; + +static const char * __init omap_get_family(void) +{ + if (cpu_is_omap24xx()) + return kasprintf(GFP_KERNEL, "OMAP2"); + else if (cpu_is_omap34xx()) + return kasprintf(GFP_KERNEL, "OMAP3"); + else if (cpu_is_omap44xx()) + return kasprintf(GFP_KERNEL, "OMAP4"); + else if (soc_is_omap54xx()) + return kasprintf(GFP_KERNEL, "OMAP5"); + else if (soc_is_dra7xx()) + return kasprintf(GFP_KERNEL, "DRA7"); + else + return kasprintf(GFP_KERNEL, "Unknown"); +} + +static ssize_t omap_get_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", omap_types[omap_type()]); +} + +static struct device_attribute omap_soc_attr = + __ATTR(type, S_IRUGO, omap_get_type, NULL); + +void __init omap_soc_device_init(void) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return; + + soc_dev_attr->machine = soc_name; + soc_dev_attr->family = omap_get_family(); + soc_dev_attr->revision = soc_rev; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr); + return; + } + + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &omap_soc_attr); +} +#endif /* CONFIG_SOC_BUS */ diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 216f19694003..090aaa852404 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -451,6 +451,7 @@ void __init omap2430_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap2_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -524,6 +525,7 @@ void __init omap3_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -532,6 +534,7 @@ void __init omap3430_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -540,6 +543,7 @@ void __init omap35xx_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -548,6 +552,7 @@ void __init omap3630_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -556,6 +561,7 @@ void __init am35xx_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -564,6 +570,7 @@ void __init ti81xx_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap3_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -592,6 +599,7 @@ void __init am33xx_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); am33xx_pm_init(); } #endif @@ -624,6 +632,7 @@ void __init omap4430_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap4_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -657,6 +666,7 @@ void __init omap5_init_late(void) { omap_mux_late_init(); omap2_common_pm_late_init(); + omap_soc_device_init(); omap4_pm_init(); omap2_clk_enable_autoidle_all(); } @@ -687,6 +697,7 @@ void __init dra7xx_init_early(void) void __init dra7xx_init_late(void) { omap2_common_pm_late_init(); + omap_soc_device_init(); omap4_pm_init(); omap2_clk_enable_autoidle_all(); } diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c9143562ba65..2e2b2c25129d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -660,7 +660,6 @@ static struct omap_hwmod omap44xx_dsp_hwmod = { .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET, .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET, .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; @@ -1686,7 +1685,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET, .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET, .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index e72d91183ab4..81e577137e1e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -631,7 +631,6 @@ static struct omap_hwmod omap54xx_dsp_hwmod = { .clkctrl_offs = OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET, .rstctrl_offs = OMAP54XX_RM_DSP_RSTCTRL_OFFSET, .context_offs = OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; @@ -1727,7 +1726,6 @@ static struct omap_hwmod omap54xx_ipu_hwmod = { .clkctrl_offs = OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET, .rstctrl_offs = OMAP54XX_RM_IPU_RSTCTRL_OFFSET, .context_offs = OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 7096bc248569..d56c7b6a2f6d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -580,7 +580,6 @@ static struct omap_hwmod dra7xx_dsp1_hwmod = { .clkctrl_offs = DRA7XX_CM_DSP1_DSP1_CLKCTRL_OFFSET, .rstctrl_offs = DRA7XX_RM_DSP1_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_DSP1_DSP1_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; @@ -598,7 +597,6 @@ static struct omap_hwmod dra7xx_dsp2_hwmod = { .clkctrl_offs = DRA7XX_CM_DSP2_DSP2_CLKCTRL_OFFSET, .rstctrl_offs = DRA7XX_RM_DSP2_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_DSP2_DSP2_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, }; @@ -1458,7 +1456,6 @@ static struct omap_hwmod dra7xx_ipu1_hwmod = { .clkctrl_offs = DRA7XX_CM_IPU1_IPU1_CLKCTRL_OFFSET, .rstctrl_offs = DRA7XX_RM_IPU1_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_IPU1_IPU1_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, #if defined(CONFIG_OMAP_REMOTEPROC_LATE_ATTACH_IPU1) || \ @@ -1480,7 +1477,6 @@ static struct omap_hwmod dra7xx_ipu2_hwmod = { .clkctrl_offs = DRA7XX_CM_IPU2_IPU2_CLKCTRL_OFFSET, .rstctrl_offs = DRA7XX_RM_IPU2_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_IPU2_IPU2_CONTEXT_OFFSET, - .modulemode = MODULEMODE_HWCTRL, }, }, #ifdef CONFIG_OMAP_REMOTEPROC_LATE_ATTACH_IPU2 @@ -2118,8 +2114,8 @@ static struct omap_hwmod_irq_info dra7xx_mmc3_irqs[] = { }; static struct omap_hwmod_dma_info dra7xx_mmc3_sdma_reqs[] = { - { .name = "77", .dma_req = 76 + DRA7XX_DMA_REQ_START }, - { .name = "78", .dma_req = 77 + DRA7XX_DMA_REQ_START }, + { .name = "tx", .dma_req = 76 + DRA7XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 77 + DRA7XX_DMA_REQ_START }, { .dma_req = -1 } }; diff --git a/arch/arm/mach-omap2/remoteproc.c b/arch/arm/mach-omap2/remoteproc.c index d56449ecfc02..3446249f9ab5 100644 --- a/arch/arm/mach-omap2/remoteproc.c +++ b/arch/arm/mach-omap2/remoteproc.c @@ -18,6 +18,7 @@ #include <linux/kernel.h> #include <linux/err.h> #include <linux/remoteproc.h> +#include <linux/interrupt.h> #include <linux/dma-contiguous.h> #include <linux/dma-mapping.h> #include <linux/of.h> @@ -94,19 +95,38 @@ static void dra7_ctrl_write_dsp2_boot_addr(u32 bootaddr); * identifying the timer as well as a matching logic to be used * to lookup the specific timer device node from the DT blob. */ -static struct omap_rproc_timers_info ipu_timers[] = { +static struct omap_rproc_timers_info omap4_ipu_timers[] = { { .name = "timer3", .id = 3, }, +#ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG + { .name = "timer4", .id = 4, .is_wdt = 1, }, + { .name = "timer9", .id = 9, .is_wdt = 1, }, +#endif }; -static struct omap_rproc_timers_info dsp_timers[] = { +static struct omap_rproc_timers_info omap4_dsp_timers[] = { { .name = "timer5", .id = 5, }, +#ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG + { .name = "timer6", .id = 6, .is_wdt = 1, }, +#endif +}; + +static struct omap_rproc_timers_info dra7_ipu2_timers[] = { + { .name = "timer3", .id = 3, }, +#ifdef CONFIG_OMAP_REMOTEPROC_WATCHDOG + { .name = "timer4", .id = 4, .is_wdt = 1, }, + { .name = "timer9", .id = 9, .is_wdt = 1, }, +#endif +}; + +static struct omap_rproc_timers_info dra7_dsp1_timers[] = { + { .name = "timer5", .id = 5}, }; -static struct omap_rproc_timers_info ipu1_timers[] = { +static struct omap_rproc_timers_info dra7_ipu1_timers[] = { { .name = "timer11", .id = 11, }, }; -static struct omap_rproc_timers_info dsp2_timers[] = { +static struct omap_rproc_timers_info dra7_dsp2_timers[] = { { .name = "timer6", .id = 6, }, }; @@ -186,8 +206,8 @@ static struct omap_rproc_pdata omap4_rproc_data[] = { .firmware = "tesla-dsp.xe64T", .mbox_name = "mbox-dsp", .oh_name = "dsp", - .timers = dsp_timers, - .timers_cnt = ARRAY_SIZE(dsp_timers), + .timers = omap4_dsp_timers, + .timers_cnt = ARRAY_SIZE(omap4_dsp_timers), .set_bootaddr = omap_ctrl_write_dsp_boot_addr, }, { @@ -195,8 +215,8 @@ static struct omap_rproc_pdata omap4_rproc_data[] = { .firmware = "ducati-m3-core0.xem3", .mbox_name = "mbox-ipu", .oh_name = "ipu", - .timers = ipu_timers, - .timers_cnt = ARRAY_SIZE(ipu_timers), + .timers = omap4_ipu_timers, + .timers_cnt = ARRAY_SIZE(omap4_ipu_timers), }, }; @@ -206,8 +226,8 @@ static struct omap_rproc_pdata dra7_rproc_data[] = { .firmware = "dra7-dsp1-fw.xe66", .mbox_name = "mbox-dsp1", .oh_name = "dsp1", - .timers = dsp_timers, - .timers_cnt = ARRAY_SIZE(dsp_timers), + .timers = dra7_dsp1_timers, + .timers_cnt = ARRAY_SIZE(dra7_dsp1_timers), .set_bootaddr = dra7_ctrl_write_dsp1_boot_addr, .carveouts = dsp1_carveouts, .carveouts_cnt = ARRAY_SIZE(dsp1_carveouts), @@ -217,10 +237,10 @@ static struct omap_rproc_pdata dra7_rproc_data[] = { .firmware = "dra7-ipu2-fw.xem4", .mbox_name = "mbox-ipu2", .oh_name = "ipu2", - .timers = ipu_timers, - .timers_cnt = ARRAY_SIZE(ipu_timers), + .timers = dra7_ipu2_timers, + .timers_cnt = ARRAY_SIZE(dra7_ipu2_timers), #ifdef CONFIG_OMAP_REMOTEPROC_LATE_ATTACH_IPU2 - .late_attach = 1, + .late_attach = 1, #endif }, { @@ -228,8 +248,8 @@ static struct omap_rproc_pdata dra7_rproc_data[] = { .firmware = "dra7-dsp2-fw.xe66", .mbox_name = "mbox-dsp2", .oh_name = "dsp2", - .timers = dsp2_timers, - .timers_cnt = ARRAY_SIZE(dsp2_timers), + .timers = dra7_dsp2_timers, + .timers_cnt = ARRAY_SIZE(dra7_dsp2_timers), .set_bootaddr = dra7_ctrl_write_dsp2_boot_addr, .carveouts = dsp2_carveouts, .carveouts_cnt = ARRAY_SIZE(dsp2_carveouts), @@ -239,10 +259,10 @@ static struct omap_rproc_pdata dra7_rproc_data[] = { .firmware = "dra7-ipu1-fw.xem4", .mbox_name = "mbox-ipu1", .oh_name = "ipu1", - .timers = ipu1_timers, - .timers_cnt = ARRAY_SIZE(ipu1_timers), + .timers = dra7_ipu1_timers, + .timers_cnt = ARRAY_SIZE(dra7_ipu1_timers), #ifdef CONFIG_OMAP_REMOTEPROC_LATE_ATTACH_IPU1 - .late_attach = 1, + .late_attach = 1, #endif }, }; @@ -500,6 +520,62 @@ out: } /** + * omap_rproc_watchdog_isr - Watchdog ISR handler for remoteproc device + * @irq: IRQ number associated with a watchdog timer + * @data: IRQ handler data + * + * This ISR routine executes the required necessary low-level code to + * acknowledge a watchdog timer interrupt. There can be multiple watchdog + * timers associated with a rproc (like IPUs which have 2 watchdog timers, + * one per Cortex M3/M4 core), so a lookup has to be performed to identify + * the timer to acknowledge its interrupt. + * + * The function also invokes a report watchdog ops, plugged in by the OMAP + * remoteproc driver code to be able to report this watchdog error to trigger + * a recovery. Ideally, this ISR should be present with the OMAP remoteproc + * driver code, but is implemented here because of the dependencies against + * the omap_dmtimer API which can only be invoked through some platform data + * functions ops. + * + * Return: IRQ_HANDLED or IRQ_NONE + */ +static irqreturn_t omap_rproc_watchdog_isr(int irq, void *data) +{ + struct platform_device *pdev = data; + struct rproc *rproc = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct omap_rproc_pdata *pdata = dev->platform_data; + struct omap_rproc_timers_info *timers = pdata->timers; + struct omap_dm_timer *timer = NULL; + int i; + + for (i = 0; i < pdata->timers_cnt; i++) { + if (irq == omap_dm_timer_get_irq(timers[i].odt)) { + timer = timers[i].odt; + break; + } + } + + if (!timer) { + dev_err(dev, "invalid timer\n"); + return IRQ_NONE; + } + omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW); + + /* + * rproc_report_crash needs to be invoked to recover a triggery, but + * since remoteproc core can be built as a module, use a platform + * data ops to break the dependency. This usage is non-standard, but + * given the dependencies, is the best possible solution to minimize + * adding more code. + */ + if (pdata->report_watchdog) + pdata->report_watchdog(rproc, RPROC_WATCHDOG); + + return IRQ_HANDLED; +} + +/** * of_dev_timer_lookup - look up needed timer node from dt blob * @np: parent device_node of all the searchable nodes * @hwmod_name: hwmod name of the desired timer @@ -589,6 +665,21 @@ check_timer: goto free_timers; } omap_dm_timer_set_source(timers[i].odt, OMAP_TIMER_SRC_SYS_CLK); + + if (timers[i].is_wdt) { + ret = request_irq(omap_dm_timer_get_irq(timers[i].odt), + omap_rproc_watchdog_isr, IRQF_SHARED, + "rproc-wdt", pdev); + if (ret) { + dev_err(&pdev->dev, "error requesting irq for timer %s\n", + timers[i].name); + omap_dm_timer_free(timers[i].odt); + timers[i].odt = NULL; + goto free_timers; + } + /* clean counter, remoteproc code will set the value */ + omap_dm_timer_set_load(timers[i].odt, 0, 0); + } } start_timers: @@ -598,6 +689,9 @@ start_timers: free_timers: while (i--) { + if (timers[i].is_wdt) + free_irq(omap_dm_timer_get_irq(timers[i].odt), pdev); + omap_dm_timer_free(timers[i].odt); timers[i].odt = NULL; } @@ -625,6 +719,10 @@ static int omap_rproc_disable_timers(struct platform_device *pdev, for (i = 0; i < pdata->timers_cnt; i++) { omap_dm_timer_stop(timers[i].odt); if (configure) { + if (timers[i].is_wdt) { + free_irq(omap_dm_timer_get_irq(timers[i].odt), + pdev); + } omap_dm_timer_free(timers[i].odt); timers[i].odt = NULL; } diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 98181124c7f7..cbd86d1e7556 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -460,6 +460,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define DRA7XX_CLASS 0x07000007 #define DRA752_REV_ES1_0 (DRA7XX_CLASS | (0x52 << 16) | (0x10 << 8)) #define DRA752_REV_ES1_1 (DRA7XX_CLASS | (0x52 << 16) | (0x11 << 8)) +#define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8)) void omap2xxx_check_revision(void); void omap3xxx_check_revision(void); diff --git a/arch/arm/plat-omap/android-display.c b/arch/arm/plat-omap/android-display.c index 815ba4b32176..076b2736ec1b 100644 --- a/arch/arm/plat-omap/android-display.c +++ b/arch/arm/plat-omap/android-display.c @@ -169,10 +169,6 @@ void omap_android_display_setup(struct omap_dss_board_info *dss, num_configs = sgx->num_configs; for (i = 0; i < num_configs; ++i) { - if (!sgx || !sgx->configs) - p_sgx_config = sgx_omaplfb_get(i); - else - p_sgx_config = &(sgx->configs[i]); struct omap_android_display_data mem = { .bpp = 4, @@ -180,6 +176,11 @@ void omap_android_display_setup(struct omap_dss_board_info *dss, .height = 720, }; + if (!sgx || !sgx->configs) + p_sgx_config = sgx_omaplfb_get(i); + else + p_sgx_config = &(sgx->configs[i]); + if (i == 0 && i < dss->num_devices) get_display_size(dss->devices[i], &mem); diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 49cceed07177..e5731cb7d984 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -134,7 +134,7 @@ static int pcf857x_get(struct gpio_chip *chip, unsigned offset) int value; value = gpio->read(gpio->client); - return (value < 0) ? 0 : (value & (1 << offset)); + return (value > 0) ? (value & (1 << offset)) : value; } static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) @@ -178,23 +178,28 @@ static void pcf857x_irq_demux_work(struct work_struct *work) struct pcf857x *gpio = container_of(work, struct pcf857x, work); - unsigned long change, i, status, flags; + unsigned long change, i, flags; + int status; status = gpio->read(gpio->client); - spin_lock_irqsave(&gpio->slock, flags); + if (status >= 0) { + spin_lock_irqsave(&gpio->slock, flags); - /* - * call the interrupt handler iff gpio is used as - * interrupt source, just to avoid bad irqs - */ + /* + * call the interrupt handler iff gpio is used as + * interrupt source, just to avoid bad irqs + */ - change = ((gpio->status ^ status) & gpio->irq_mapped); - for_each_set_bit(i, &change, gpio->chip.ngpio) - generic_handle_irq(irq_find_mapping(gpio->irq_domain, i)); - gpio->status = status; + change = ((gpio->status ^ status) & gpio->irq_mapped); + for_each_set_bit(i, &change, gpio->chip.ngpio) + generic_handle_irq( + irq_find_mapping(gpio->irq_domain, i)); + gpio->status = status; - spin_unlock_irqrestore(&gpio->slock, flags); + spin_unlock_irqrestore(&gpio->slock, flags); + } else + pr_err("failed to read gpio status %x\n", status); } static irqreturn_t pcf857x_irq_demux(int irq, void *data) diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c index d7c780ff35b4..0d25b7259aaa 100644 --- a/drivers/gpu/ion/ion.c +++ b/drivers/gpu/ion/ion.c @@ -520,7 +520,7 @@ static int ion_debug_client_show(struct seq_file *s, void *unused) struct ion_client *client = s->private; struct rb_node *n; size_t sizes[ION_NUM_HEAP_IDS] = {0}; - const char *names[ION_NUM_HEAP_IDS] = {0}; + const char *names[ION_NUM_HEAP_IDS] = {NULL}; int i; mutex_lock(&client->lock); @@ -726,7 +726,7 @@ static void ion_buffer_sync_for_device(struct ion_buffer *buffer, mutex_unlock(&buffer->lock); } -int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +static int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct ion_buffer *buffer = vma->vm_private_data; struct scatterlist *sg; @@ -780,7 +780,7 @@ static void ion_vm_close(struct vm_area_struct *vma) mutex_unlock(&buffer->lock); } -struct vm_operations_struct ion_vma_ops = { +static struct vm_operations_struct ion_vma_ops = { .open = ion_vm_open, .close = ion_vm_close, .fault = ion_vm_fault, @@ -871,7 +871,7 @@ static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, mutex_unlock(&buffer->lock); } -struct dma_buf_ops dma_buf_ops = { +static struct dma_buf_ops dma_buf_ops = { .map_dma_buf = ion_map_dma_buf, .unmap_dma_buf = ion_unmap_dma_buf, .mmap = ion_mmap, diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c index ce8d311968f6..473e9ba7c569 100644 --- a/drivers/gpu/ion/ion_carveout_heap.c +++ b/drivers/gpu/ion/ion_carveout_heap.c @@ -84,7 +84,7 @@ static void ion_carveout_heap_free(struct ion_buffer *buffer) buffer->priv_phys = ION_CARVEOUT_ALLOCATE_FAIL; } -struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, +static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { struct sg_table *table; @@ -103,13 +103,13 @@ struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, return table; } -void ion_carveout_heap_unmap_dma(struct ion_heap *heap, +static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { sg_free_table(buffer->sg_table); } -void *ion_carveout_heap_map_kernel(struct ion_heap *heap, +static void *ion_carveout_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { int mtype = MT_MEMORY_NONCACHED; @@ -121,7 +121,7 @@ void *ion_carveout_heap_map_kernel(struct ion_heap *heap, mtype); } -void ion_carveout_heap_unmap_kernel(struct ion_heap *heap, +static void ion_carveout_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { __arm_iounmap(buffer->vaddr); @@ -129,8 +129,9 @@ void ion_carveout_heap_unmap_kernel(struct ion_heap *heap, return; } -int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, - struct vm_area_struct *vma) +static int ion_carveout_heap_map_user(struct ion_heap *heap, + struct ion_buffer *buffer, + struct vm_area_struct *vma) { return remap_pfn_range(vma, vma->vm_start, __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff, diff --git a/drivers/gpu/ion/ion_chunk_heap.c b/drivers/gpu/ion/ion_chunk_heap.c index 3e77de59223c..b2dce96717e9 100644 --- a/drivers/gpu/ion/ion_chunk_heap.c +++ b/drivers/gpu/ion/ion_chunk_heap.c @@ -116,13 +116,13 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer) kfree(table); } -struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, +static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { return buffer->priv_virt; } -void ion_chunk_heap_unmap_dma(struct ion_heap *heap, +static void ion_chunk_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { return; @@ -162,7 +162,7 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); chunk_heap->heap.ops = &chunk_heap_ops; chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; - pr_info("%s: base %lu size %ld align %ld\n", __func__, chunk_heap->base, + pr_info("%s: base %lu size %u align %ld\n", __func__, chunk_heap->base, heap_data->size, heap_data->align); return &chunk_heap->heap; diff --git a/drivers/gpu/ion/ion_heap.c b/drivers/gpu/ion/ion_heap.c index 225ef94655db..c7e36d179146 100644 --- a/drivers/gpu/ion/ion_heap.c +++ b/drivers/gpu/ion/ion_heap.c @@ -34,7 +34,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap, struct page **tmp = pages; if (!pages) - return 0; + return NULL; if (buffer->flags & ION_FLAG_CACHED) pgprot = PAGE_KERNEL; diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c index a9d809e55731..2177e51a8af6 100644 --- a/drivers/gpu/ion/ion_system_heap.c +++ b/drivers/gpu/ion/ion_system_heap.c @@ -26,12 +26,12 @@ #include <linux/vmalloc.h> #include "ion_priv.h" -static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | +static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_WAIT; -static unsigned int low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | +static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); -static const unsigned int orders[] = {8, 4, 0}; +static const unsigned int orders[] = {8, 4, 3, 2, 1, 0}; static const int num_orders = ARRAY_SIZE(orders); static int order_to_index(unsigned int order) { @@ -77,13 +77,13 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap, gfp_flags = high_order_gfp_flags; page = alloc_pages(gfp_flags, order); if (!page) - return 0; + return NULL; arm_dma_ops.sync_single_for_device(NULL, pfn_to_dma(NULL, page_to_pfn(page)), PAGE_SIZE << order, DMA_BIDIRECTIONAL); } if (!page) - return 0; + return NULL; if (split_pages) split_page(page, order); @@ -208,7 +208,7 @@ err: return -ENOMEM; } -void ion_system_heap_free(struct ion_buffer *buffer) +static void ion_system_heap_free(struct ion_buffer *buffer) { struct ion_heap *heap = buffer->heap; struct ion_system_heap *sys_heap = container_of(heap, @@ -232,13 +232,13 @@ void ion_system_heap_free(struct ion_buffer *buffer) kfree(table); } -struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, +static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { return buffer->priv_virt; } -void ion_system_heap_unmap_dma(struct ion_heap *heap, +static void ion_system_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { return; @@ -336,7 +336,7 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, return 0; } -void ion_system_contig_heap_free(struct ion_buffer *buffer) +static void ion_system_contig_heap_free(struct ion_buffer *buffer) { kfree(buffer->priv_virt); } @@ -350,7 +350,7 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap, return 0; } -struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, +static struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { struct sg_table *table; @@ -369,14 +369,14 @@ struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, return table; } -void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, +static void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { sg_free_table(buffer->sg_table); kfree(buffer->sg_table); } -int ion_system_contig_heap_map_user(struct ion_heap *heap, +static int ion_system_contig_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, struct vm_area_struct *vma) { diff --git a/drivers/gpu/ion/omap/omap_tiler_heap.c b/drivers/gpu/ion/omap/omap_tiler_heap.c index cbd16cf6c522..13408796c39c 100644 --- a/drivers/gpu/ion/omap/omap_tiler_heap.c +++ b/drivers/gpu/ion/omap/omap_tiler_heap.c @@ -378,7 +378,7 @@ static void sg_free(struct scatterlist *sg, unsigned int nents) -struct sg_table *omap_tiler_heap_map_dma(struct ion_heap *heap, +static struct sg_table *omap_tiler_heap_map_dma(struct ion_heap *heap, struct ion_buffer *buffer) { int ret, i; @@ -420,13 +420,13 @@ struct sg_table *omap_tiler_heap_map_dma(struct ion_heap *heap, return table; } -void omap_tiler_heap_unmap_dma(struct ion_heap *heap, +static void omap_tiler_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { __sg_free_table(buffer->sg_table, -1, sg_free); } -void *ion_tiler_heap_map_kernel(struct ion_heap *heap, +static void *ion_tiler_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { /* todo: Need to see how to implement this api. Seems like it is @@ -435,7 +435,7 @@ void *ion_tiler_heap_map_kernel(struct ion_heap *heap, return NULL; } -void ion_tiler_heap_unmap_kernel(struct ion_heap *heap, +static void ion_tiler_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { /* todo: Need to see how to implement this api. Seems like it is diff --git a/drivers/media/i2c/ov1063x.c b/drivers/media/i2c/ov1063x.c index 8fb028520764..dc527562526b 100644 --- a/drivers/media/i2c/ov1063x.c +++ b/drivers/media/i2c/ov1063x.c @@ -106,13 +106,14 @@ struct ov1063x_priv { int cam_fpd_mux_s0_gpio; int vin2_s0_gpio; int ov_pwdn_gpio; + int vin2_s2_gpio; }; static int ov1063x_init_sensor(struct i2c_client *client); static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val, int cam_fpd_mux_s0_val, int mux1_sel0_val, int mux1_sel1_val, - int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val); + int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val, int vin2_s2_val); static const struct ov1063x_reg ov1063x_regs_default[] = { /* Register configuration for full resolution : 1280x720 */ @@ -1412,6 +1413,22 @@ static int ov1063x_enum_fmt(struct v4l2_subdev *sd, unsigned int index, return 0; } +static int ov1063x_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *f) +{ + /* For now, hard coded resolutions for OV10635 sensor */ + int cam_width[7] = { 1280, 1280, 752, 640, 600, 352, 320 }; + int cam_height[7] = { 800, 720, 480, 480, 400, 288, 240 }; + + if (f->index >= 7) + return -EINVAL; + + f->type = V4L2_FRMSIZE_TYPE_DISCRETE; + f->discrete.width = cam_width[f->index]; + f->discrete.height = cam_height[f->index]; + return 0; +} + static int ov1063x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1520,41 +1537,43 @@ static int ov1063x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val, int cam_fpd_mux_s0_val, int mux1_sel0_val, int mux1_sel1_val, - int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val) { + int mux2_sel0_val, int mux2_sel1_val, int ov_pwdn_val, + int vin2_s2_val) { struct ov1063x_priv *priv = to_ov1063x(client); int ret = 0, X = -1, idx = 0; struct gpio gpios[10]; - if (vin2_s0_val != X) { + if ((vin2_s0_val != X) && gpio_is_valid(priv->vin2_s0_gpio)) { gpios[idx].gpio = priv->vin2_s0_gpio; gpios[idx].flags = vin2_s0_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; gpios[idx].label = "vin2_s0"; idx++; } - if (cam_fpd_mux_s0_val != X) { + if ((cam_fpd_mux_s0_val != X) && + gpio_is_valid(priv->cam_fpd_mux_s0_gpio)) { gpios[idx].gpio = priv->cam_fpd_mux_s0_gpio; gpios[idx].flags = cam_fpd_mux_s0_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; gpios[idx].label = "cam_fpd_mux_s0"; idx++; } - if (mux1_sel0_val != X) { + if ((mux1_sel0_val != X) && gpio_is_valid(priv->mux1_sel0_gpio)) { gpios[idx].gpio = priv->mux1_sel0_gpio; gpios[idx].flags = mux1_sel0_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; gpios[idx].label = "mux1_sel0"; idx++; } - if (mux1_sel1_val != X) { + if ((mux1_sel1_val != X) && gpio_is_valid(priv->mux1_sel1_gpio)) { gpios[idx].gpio = priv->mux1_sel1_gpio; gpios[idx].flags = mux1_sel0_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; gpios[idx].label = "mux1_sel1"; idx++; } - if (mux2_sel0_val != X) { + if ((mux2_sel0_val != X) && gpio_is_valid(priv->mux2_sel0_gpio)) { gpios[idx].gpio = priv->mux2_sel0_gpio; gpios[idx].flags = mux2_sel0_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; @@ -1562,7 +1581,7 @@ static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val, idx++; } - if (mux2_sel1_val != X) { + if ((mux2_sel1_val != X) && gpio_is_valid(priv->mux2_sel1_gpio)) { gpios[idx].gpio = priv->mux2_sel1_gpio; gpios[idx].flags = mux2_sel1_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; @@ -1570,7 +1589,7 @@ static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val, idx++; } - if (ov_pwdn_val != X) { + if ((ov_pwdn_val != X) && gpio_is_valid(priv->ov_pwdn_gpio)) { gpios[idx].gpio = priv->ov_pwdn_gpio; gpios[idx].flags = ov_pwdn_val == 1 ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; @@ -1578,6 +1597,14 @@ static int ov1063x_set_gpios(struct i2c_client *client, int vin2_s0_val, idx++; } + if ((vin2_s2_val != X) && gpio_is_valid(priv->vin2_s2_gpio)) { + gpios[idx].gpio = priv->vin2_s2_gpio; + gpios[idx].flags = vin2_s2_val == 1 ? GPIOF_OUT_INIT_HIGH : + GPIOF_OUT_INIT_LOW; + gpios[idx].label = "vin2_s2"; + idx++; + } + ret = gpio_request_array(gpios, idx); if (ret) return ret; @@ -1622,27 +1649,26 @@ static int ov1063x_detect_sensor(struct i2c_client *client) static int ov1063x_init_sensor(struct i2c_client *client) { struct ov1063x_priv *priv = to_ov1063x(client); - int ret, X = -1; + int ret = -EINVAL, X = -1; switch (priv->sensor_connector) { case VIS_OVCAM: - ret = ov1063x_set_gpios(client, X, 1, 1, 0, 0, 0, 1); + ret = ov1063x_set_gpios(client, X, 1, 1, 0, 0, 0, 1, X); break; case VIS_SERDES: if (client->addr == 0x39) - ret = ov1063x_set_gpios(client, 0, 1, X, X, X, X, 1); + ret = ov1063x_set_gpios(client, 0, 1, X, X, X, X, 1, X); else - ret = ov1063x_set_gpios(client, X, 1, X, X, 0, 1, 1); + ret = ov1063x_set_gpios(client, X, 1, X, X, 0, 1, 1, X); break; case VIS_LI: - ret = ov1063x_set_gpios(client, X, 1, 0, 0, 1, 0, 1); + ret = ov1063x_set_gpios(client, X, 1, 0, 0, 1, 0, 1, X); break; case BASE_LI: - ret = ov1063x_set_gpios(client, X, 0, X, X, X, X, X); + ret = ov1063x_set_gpios(client, 1, 0, X, X, X, X, X, 0); break; default: dev_err(&client->dev, "Unknown connector!\n"); - return -EINVAL; } return ret; @@ -1713,6 +1739,13 @@ static int sensor_get_gpios(struct device_node *node, struct i2c_client *client) return -EINVAL; } + gpio = of_get_gpio(node, 7); + if (gpio_is_valid(gpio)) { + priv->vin2_s2_gpio = gpio; + } else { + priv->vin2_s2_gpio = -1; + dev_err(&client->dev, "failed to parse VIN2_S2 gpio\n"); + } return 0; } @@ -1851,6 +1884,7 @@ static struct v4l2_subdev_video_ops ov1063x_video_ops = { .s_mbus_fmt = ov1063x_s_fmt, .try_mbus_fmt = ov1063x_try_fmt, .enum_mbus_fmt = ov1063x_enum_fmt, + .enum_framesizes = ov1063x_enum_framesizes, .cropcap = ov1063x_cropcap, .g_crop = ov1063x_g_crop, .s_crop = ov1063x_s_crop, diff --git a/drivers/media/i2c/tvp5158.c b/drivers/media/i2c/tvp5158.c index ff74a3365be3..12ac07a13831 100644 --- a/drivers/media/i2c/tvp5158.c +++ b/drivers/media/i2c/tvp5158.c @@ -202,6 +202,8 @@ struct tvp5158_priv { const char *sensor_name; int cam_fpd_mux_s0_gpio; int sel_tvp_fpd_s0; + int vin2_s0_gpio; + int vin2_s2_gpio; enum tvp5158_std current_std; enum tvp5158_signal_present signal_present; const struct tvp5158_std_info *std_list; @@ -426,6 +428,27 @@ static int tvp5158_enum_fmt(struct v4l2_subdev *sd, unsigned int index, return 0; } +static int tvp5158_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *f) +{ + + /* For now, hard coded resolutions for TVP5158 NTSC decoder */ + int cam_width[] = { 720, 640,}; + int cam_height[] = { 240, 240,}; + + if (f->index >= 2) + return -EINVAL; + + f->type = V4L2_FRMSIZE_TYPE_DISCRETE; + f->discrete.width = cam_width[f->index]; + /* tvp5158 sensor outputs interlaced data, hence, in the timings + * we listed down the field height. In the framesize query we need + * to publish the frame height, so multiply the field height by 2 */ + f->discrete.height = 2 * cam_height[f->index]; + + return 0; +} + static int tvp5158_get_gpios(struct device_node *node, struct i2c_client *client) { @@ -448,6 +471,22 @@ static int tvp5158_get_gpios(struct device_node *node, return -EINVAL; } + gpio = of_get_gpio(node, 2); + if (gpio_is_valid(gpio)) + priv->vin2_s0_gpio = gpio; + else { + priv->vin2_s0_gpio = -1; + dev_err(&client->dev, "failed to parse VIN2_S0 gpio\n"); + } + + gpio = of_get_gpio(node, 3); + if (gpio_is_valid(gpio)) + priv->vin2_s2_gpio = gpio; + else { + priv->vin2_s2_gpio = -1; + dev_err(&client->dev, "failed to parse VIN2_S2 gpio\n"); + } + return 0; } @@ -455,19 +494,42 @@ static int tvp5158_set_gpios(struct i2c_client *client) { struct tvp5158_priv *priv = to_tvp5158(client); - struct gpio gpios[] = { - { priv->sel_tvp_fpd_s0, GPIOF_OUT_INIT_LOW, - "tvp_fpd_mux_s0" }, - { priv->cam_fpd_mux_s0_gpio, GPIOF_OUT_INIT_HIGH, - "cam_fpd_mux_s0" }, - }; - int ret = -1; + struct gpio gpios[10]; + int ret = -1, i = 0; + + if (gpio_is_valid(priv->sel_tvp_fpd_s0)) { + gpios[i].gpio = priv->sel_tvp_fpd_s0; + gpios[i].flags = GPIOF_OUT_INIT_LOW; + gpios[i].label = "tvp_fpd_mux_s0"; + i++; + } + + if (gpio_is_valid(priv->cam_fpd_mux_s0_gpio)) { + gpios[i].gpio = priv->cam_fpd_mux_s0_gpio; + gpios[i].flags = GPIOF_OUT_INIT_HIGH; + gpios[i].label = "cam_fpd_mux_s0"; + i++; + } + + if (gpio_is_valid(priv->vin2_s0_gpio)) { + gpios[i].gpio = priv->vin2_s0_gpio; + gpios[i].flags = GPIOF_OUT_INIT_LOW; + gpios[i].label = "vin2_s0"; + i++; + } + + if (gpio_is_valid(priv->vin2_s2_gpio)) { + gpios[i].gpio = priv->vin2_s2_gpio; + gpios[i].flags = GPIOF_OUT_INIT_HIGH; + gpios[i].label = "vin2_s2"; + i++; + } - ret = gpio_request_array(gpios, ARRAY_SIZE(gpios)); + ret = gpio_request_array(gpios, i); if (ret) return ret; - gpio_free_array(gpios, ARRAY_SIZE(gpios)); + gpio_free_array(gpios, i); return 0; } @@ -475,6 +537,7 @@ static int tvp5158_set_gpios(struct i2c_client *client) static struct v4l2_subdev_video_ops tvp5158_video_ops = { .querystd = tvp5158_querystd, .enum_mbus_fmt = tvp5158_enum_fmt, + .enum_framesizes = tvp5158_enum_framesizes, .g_parm = tvp5158_g_parm, .s_parm = tvp5158_s_parm, .s_stream = tvp5158_s_stream, diff --git a/drivers/media/platform/ti-vps/vip.c b/drivers/media/platform/ti-vps/vip.c index e6e487b23e35..742caca874a4 100644 --- a/drivers/media/platform/ti-vps/vip.c +++ b/drivers/media/platform/ti-vps/vip.c @@ -21,6 +21,7 @@ #include <linux/of_i2c.h> #include "vip.h" +#include "../../../drivers/gpu/drm/omapdrm/omap_dmm_tiler.h" #define VIP_MODULE_NAME "dra7xx-vip" #define VIP_INPUT_NAME "Vin0" @@ -796,6 +797,8 @@ static int add_out_dtd(struct vip_stream *stream, int srce_type) return -1; } + if (is_tiler_addr(dma_addr)) + flags |= VPDMA_DATA_MODE_TILED; /* * Use VPDMA_MAX_SIZE1 or VPDMA_MAX_SIZE2 register for slice0/1 */ @@ -904,7 +907,7 @@ static void start_dma(struct vip_dev *dev, struct vip_buffer *buf) dma_addr = vb2_dma_contig_plane_dma_addr(&buf->vb, 0); drop_data = 0; } else { - dma_addr = NULL; + dma_addr = 0; drop_data = 1; } @@ -966,7 +969,7 @@ static void vip_process_buffer_complete(struct vip_stream *stream) vpdma_buf_unmap(dev->shared->vpdma, &dev->desc_list.buf); fld = dtd_get_field(dev->write_desc); - stream->field = fld ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; + stream->field = fld ? V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP; vpdma_buf_map(dev->shared->vpdma, &dev->desc_list.buf); } @@ -1162,18 +1165,15 @@ static int vip_enum_fmt_vid_cap(struct file *file, void *priv, static int vip_enum_framesizes(struct file *file, void *priv, struct v4l2_frmsizeenum *f) { - /* For now, hard coded resolutions for OV10635 sensor */ - int cam_width[7] = { 1280, 1280, 752, 640, 600, 352, 320 }; - int cam_height[7] = { 800, 720, 480, 480, 400, 288, 240 }; - - if (f->index >= 7) - return -EINVAL; + struct vip_stream *stream = file2stream(file); + struct vip_dev *dev = stream->port->dev; + int ret; - f->type = V4L2_FRMSIZE_TYPE_DISCRETE; - f->discrete.width = cam_width[f->index]; - f->discrete.height = cam_height[f->index]; + ret = v4l2_subdev_call(dev->sensor, video, enum_framesizes, f); + if (ret) + vip_dprintk(dev, "enum_framesizes failed in subdev\n"); - return 0; + return ret; } static int vip_enum_frameintervals(struct file *file, void *priv, @@ -1205,15 +1205,24 @@ static int vip_g_fmt_vid_cap(struct file *file, void *priv, { struct vip_stream *stream = file2stream(file); struct vip_port *port = stream->port; + struct vip_dev *dev = stream->port->dev; + struct v4l2_mbus_framefmt mbus_fmt; + int ret; f->fmt.pix.width = stream->width; f->fmt.pix.height = stream->height; f->fmt.pix.pixelformat = port->fmt->fourcc; - f->fmt.pix.field = stream->sup_field; + f->fmt.pix.field = stream->sup_field; f->fmt.pix.colorspace = port->fmt->colorspace; f->fmt.pix.bytesperline = stream->bytesperline; f->fmt.pix.sizeimage = stream->sizeimage; + ret = v4l2_subdev_call(dev->sensor, video, g_mbus_fmt, &mbus_fmt); + if (ret) + vip_dprintk(dev, "g_mbus_fmt failed in subdev\n"); + + f->fmt.pix.field = mbus_fmt.field; + return 0; } @@ -1543,6 +1552,14 @@ static int vip_start_streaming(struct vb2_queue *vq, unsigned int count) list_add_tail(&buf->dq_list, &dev->vip_bufs); spin_unlock_irqrestore(&dev->slock, flags); + /* It can so happen on some HW devices that start_dma completes, and + * even generates IRQ before we return from here or before vq->streaming + * is updated in videobuf2-core.c. If that happens, the vip_irq + * doesn't process the buffer as it thinks there was no stream started. + * In order handle this situation, we are updating the streaming status + * before starting the dma */ + vq->streaming = 1; + start_dma(dev, buf); return 0; @@ -1558,12 +1575,6 @@ static int vip_stop_streaming(struct vb2_queue *vq) struct vip_dev *dev = port->dev; struct vip_buffer *buf; - if (!vb2_is_streaming(vq)) - return 0; - - vpdma_buf_unmap(dev->shared->vpdma, &dev->desc_list.buf); - vpdma_reset_desc_list(&dev->desc_list); - disable_irqs(dev, dev->slice_id); /* release all active buffers */ while (!list_empty(&dev->vip_bufs)) { @@ -1577,6 +1588,13 @@ static int vip_stop_streaming(struct vb2_queue *vq) list_del(&buf->list); vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); } + + if (!vb2_is_streaming(vq)) + return 0; + + vpdma_buf_unmap(dev->shared->vpdma, &dev->desc_list.buf); + vpdma_reset_desc_list(&dev->desc_list); + return 0; } @@ -1720,6 +1738,8 @@ static int vip_setup_parser(struct vip_port *port) vip_set_data_interface(port, iface); vip_sync_type(port, sync_type); + + return 0; } static int vip_init_port(struct vip_port *port) diff --git a/drivers/media/platform/ti-vps/vpdma.c b/drivers/media/platform/ti-vps/vpdma.c index 6314621250f6..3452d61b97be 100644 --- a/drivers/media/platform/ti-vps/vpdma.c +++ b/drivers/media/platform/ti-vps/vpdma.c @@ -25,6 +25,8 @@ #include "vpdma.h" #include "vpdma_priv.h" +#include "../../../drivers/gpu/drm/omapdrm/omap_dmm_tiler.h" + #define VPDMA_FIRMWARE "vpdma-1b8.fw" @@ -700,7 +702,16 @@ int vpdma_add_out_dtd(struct vpdma_desc_list *list, int width, fmt->data_type == DATA_TYPE_C420) depth = 8; - stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + if (!is_tiler_addr(dma_addr)) + stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + else { + enum tiler_fmt fmt; + tiler_get_fmt(dma_addr, &fmt); + if (fmt != TILFMT_PAGE) + stride = tiler_stride(fmt, 0); + else + stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + } dtd = list->next; WARN_ON((void *)(dtd + 1) > (list->buf.addr + list->buf.size)); @@ -772,7 +783,16 @@ void vpdma_add_in_dtd(struct vpdma_desc_list *list, int width, depth = 8; } - stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + if (!is_tiler_addr(dma_addr)) + stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + else { + enum tiler_fmt fmt; + tiler_get_fmt(dma_addr, &fmt); + if (fmt != TILFMT_PAGE) + stride = tiler_stride(fmt, 0); + else + stride = ALIGN((depth * width) >> 3, VPDMA_DESC_ALIGN); + } dma_addr += rect.top * stride + (rect.left * depth >> 3); diff --git a/drivers/media/platform/ti-vps/vpe.c b/drivers/media/platform/ti-vps/vpe.c index 2256a8bbbd6b..7eaa2802ad6d 100644 --- a/drivers/media/platform/ti-vps/vpe.c +++ b/drivers/media/platform/ti-vps/vpe.c @@ -1855,7 +1855,7 @@ static void set_dei_shadow_registers(struct vpe_ctx *ctx) { struct vpe_mmr_adb *mmr_adb = ctx->mmr_adb.addr; u32 *dei_mmr = &mmr_adb->dei_regs[0]; - struct vpe_dei_regs *cur = &dei_regs; + struct vpe_dei_regs *cur = (struct vpe_dei_regs *) &dei_regs; dei_mmr[2] = cur->mdt_spacial_freq_thr_reg; dei_mmr[3] = cur->edi_config_reg; diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index 10beaee7f0ae..1917231a31eb 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -651,6 +651,14 @@ static int vb2_dc_map_dmabuf(void *mem_priv) /* checking if dmabuf is big enough to store contiguous chunk */ contig_size = vb2_dc_get_contiguous_size(sgt); + + /* HACK: In order to allow TILER-2D buffers, which are always + * contiguous, lets check the sgt size, and it is of one LINUX PAGE + * size, assume it is TILER2D and assign buf size to contig_size + */ + if (contig_size == 4096) + contig_size = buf->size; + if (contig_size < buf->size) { pr_err("contiguous chunk is too small %lu/%lu b\n", contig_size, buf->size); diff --git a/drivers/misc/ti-ec/earlycam.c b/drivers/misc/ti-ec/earlycam.c index abed840a35c6..3cf82ef55c9e 100644 --- a/drivers/misc/ti-ec/earlycam.c +++ b/drivers/misc/ti-ec/earlycam.c @@ -60,7 +60,7 @@ static int main_fn(void *); static int init_mmap(struct file *fp); static void earlycam_isr(void *arg, unsigned int irqstatus); -int thread_init(void) +static int thread_init(void) { char our_thread[16] = "earlycam_thread"; @@ -73,7 +73,7 @@ int thread_init(void) return 0; } -int display_init() +static int display_init(void) { int ret = 0, i; struct omap_dss_device *dssdev = NULL; @@ -118,7 +118,7 @@ err_dss_init: return ret; } -int display_disable(struct earlycam_setup_dispc_data data) +static int display_disable(struct earlycam_setup_dispc_data data) { struct omap_overlay *ovl; ovl = earlycam_dev->overlays[data.ovls[0].cfg.ix]; @@ -154,7 +154,7 @@ static void earlycam_isr(void *arg, unsigned int irqstatus) } } -int display_queue(struct earlycam_setup_dispc_data data) +static int display_queue(struct earlycam_setup_dispc_data data) { int ret = 0; int retry; @@ -235,7 +235,7 @@ int display_queue(struct earlycam_setup_dispc_data data) return ret; } -int init_mmap(struct file *fp) +static int init_mmap(struct file *fp) { int i; struct v4l2_requestbuffers req = {0}; @@ -263,7 +263,7 @@ int init_mmap(struct file *fp) return 0; } -int capture_image(struct file *fp, int init) +static int capture_image(struct file *fp, int init) { struct v4l2_buffer buf = {0}; int i; @@ -321,7 +321,6 @@ int capture_image(struct file *fp, int init) int main_fn(void *arg) { - int i; int ret; int cam_init = 1; int val; @@ -329,16 +328,6 @@ int main_fn(void *arg) struct dentry dtr; struct file fp; - /* - * Creates a file pointer to the VIP video device - * This is hardcoded to open up the first instance - * of the VIP which should be registered as /dev/video1 - * since the VPE module will be registered as /dev/video0 - */ - in.i_rdev = MKDEV(VIDEO_MAJOR, 1); - dtr.d_inode = ∈ - fp.f_path.dentry = &dtr; - /* need base address for in-page offset */ struct earlycam_setup_dispc_data comp = { .num_mgrs = 1, @@ -360,6 +349,16 @@ int main_fn(void *arg) .ovls[0].ba = (u32) dma_addr_global_complete[buffer_index], }; + /* + * Creates a file pointer to the VIP video device + * This is hardcoded to open up the first instance + * of the VIP which should be registered as /dev/video1 + * since the VPE module will be registered as /dev/video0 + */ + in.i_rdev = MKDEV(VIDEO_MAJOR, 1); + dtr.d_inode = ∈ + fp.f_path.dentry = &dtr; + ret = display_init(); if (ret) { pr_err("display_init failed with error %d", ret); @@ -369,12 +368,11 @@ int main_fn(void *arg) cam_init = 2; while (1) { - while ((val = - gpio_get_value_cansleep( - earlycam_dev->reverse_gpio)) == - 1) { + + do { /* Spin inside this loop, sleeping for 100 mS - * everytime until the user presses the gpio. + * everytime until the user presses the gpio OR + * in case there was an error reading the value. * This should be replaced by interrupt based * mechanism to avoid waking up the cpu * frequently @@ -397,7 +395,9 @@ int main_fn(void *arg) once = 1; } msleep(100); - } + val = gpio_get_value_cansleep + (earlycam_dev->reverse_gpio); + } while (val == 1 || val < 0); /* So we got a gpio press, start by initializing camera first */ if (cam_init == 2) { diff --git a/drivers/misc/ti-st/tty_hci.c b/drivers/misc/ti-st/tty_hci.c index 0c5cf9399769..ca24acaa7f8c 100644 --- a/drivers/misc/ti-st/tty_hci.c +++ b/drivers/misc/ti-st/tty_hci.c @@ -133,7 +133,7 @@ static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = { * Returns 0 - on success * else suitable error code */ -int hci_tty_open(struct inode *inod, struct file *file) +static int hci_tty_open(struct inode *inod, struct file *file) { int i = 0, err = 0; unsigned long timeleft; @@ -229,7 +229,7 @@ error: * Returns 0 - on success * else suitable error code */ -int hci_tty_release(struct inode *inod, struct file *file) +static int hci_tty_release(struct inode *inod, struct file *file) { int err, i; struct ti_st *hst = file->private_data; @@ -259,7 +259,7 @@ int hci_tty_release(struct inode *inod, struct file *file) * Returns Size of packet received - on success * else suitable error code */ -ssize_t hci_tty_read(struct file *file, char __user *data, size_t size, +static ssize_t hci_tty_read(struct file *file, char __user *data, size_t size, loff_t *offset) { int len = 0, tout; @@ -343,7 +343,7 @@ ssize_t hci_tty_read(struct file *file, char __user *data, size_t size, * Returns Size of packet on success * else suitable error code */ -ssize_t hci_tty_write(struct file *file, const char __user *data, +static ssize_t hci_tty_write(struct file *file, const char __user *data, size_t size, loff_t *offset) { struct ti_st *hst = file->private_data; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 3e3557694e55..1b75d8fd1657 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -58,6 +58,8 @@ MODULE_ALIAS("mmc:block"); #define INAND_CMD38_ARG_SECTRIM1 0x81 #define INAND_CMD38_ARG_SECTRIM2 0x88 #define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ +#define MMC_SANITIZE_REQ_TIMEOUT 240000 +#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) static DEFINE_MUTEX(block_mutex); @@ -390,6 +392,35 @@ static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, return err; } +static int ioctl_do_sanitize(struct mmc_card *card) +{ + int err; + + if (!(mmc_can_sanitize(card) && + (card->host->caps2 & MMC_CAP2_SANITIZE))) { + pr_warn("%s: %s - SANITIZE is not supported\n", + mmc_hostname(card->host), __func__); + err = -EOPNOTSUPP; + goto out; + } + + pr_debug("%s: %s - SANITIZE IN PROGRESS...\n", + mmc_hostname(card->host), __func__); + + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, + MMC_SANITIZE_REQ_TIMEOUT); + + if (err) + pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n", + mmc_hostname(card->host), __func__, err); + + pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host), + __func__); +out: + return err; +} + static int mmc_blk_ioctl_cmd(struct block_device *bdev, struct mmc_ioc_cmd __user *ic_ptr) { @@ -492,6 +523,17 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, goto cmd_rel_host; } + if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && + (cmd.opcode == MMC_SWITCH)) { + err = ioctl_do_sanitize(card); + + if (err) + pr_err("%s: ioctl_do_sanitize() failed. err = %d", + __func__, err); + + goto cmd_rel_host; + } + mmc_wait_for_req(card->host, &mrq); if (cmd.error) { @@ -925,10 +967,10 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg, trim_arg, erase_arg; + unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; - if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { + if (!(mmc_can_secure_erase_trim(card))) { err = -EOPNOTSUPP; goto out; } @@ -936,23 +978,11 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, from = blk_rq_pos(req); nr = blk_rq_sectors(req); - /* The sanitize operation is supported at v4.5 only */ - if (mmc_can_sanitize(card)) { - erase_arg = MMC_ERASE_ARG; - trim_arg = MMC_TRIM_ARG; - } else { - erase_arg = MMC_SECURE_ERASE_ARG; - trim_arg = MMC_SECURE_TRIM1_ARG; - } + if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) + arg = MMC_SECURE_TRIM1_ARG; + else + arg = MMC_SECURE_ERASE_ARG; - if (mmc_erase_group_aligned(card, from, nr)) - arg = erase_arg; - else if (mmc_can_trim(card)) - arg = trim_arg; - else { - err = -EINVAL; - goto out; - } retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -988,9 +1018,6 @@ retry: goto out; } - if (mmc_can_sanitize(card)) - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); out_retry: if (err && !mmc_blk_reset(md, card->host, type)) goto retry; diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 71b8d7bcdf79..14e36d6a28f6 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -148,7 +148,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, /* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) q->limits.discard_granularity = 0; - if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card)) + if (mmc_can_secure_erase_trim(card)) queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 039503d53454..1cd78b8d6ab7 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -347,6 +347,24 @@ static void mmc_wait_for_req_done(struct mmc_host *host, wait_for_completion(&mrq->completion); cmd = mrq->cmd; + + /* + * If host has timed out waiting for the sanitize + * to complete, card might be still in programming state + * so let's try to bring the card out of programming + * state. + */ + if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) { + if (!mmc_interrupt_hpi(host->card)) { + pr_warning("%s: %s: Interrupted sanitize\n", + mmc_hostname(host), __func__); + cmd->error = 0; + break; + } else { + pr_err("%s: %s: Failed to interrupt sanitize\n", + mmc_hostname(host), __func__); + } + } if (!cmd->error || !cmd->retries || mmc_card_removed(host->card)) break; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 6d8f7012d73a..7b9fc225301a 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -430,6 +430,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, cmd.cmd_timeout_ms = timeout_ms; + if (index == EXT_CSD_SANITIZE_START) + cmd.sanitize_busy = true; err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); if (err) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 6a1c7c41e3da..aa0440817c50 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -44,6 +44,7 @@ /* OMAP HSMMC Host Controller Registers */ #define OMAP_HSMMC_SYSSTATUS 0x0014 #define OMAP_HSMMC_CON 0x002C +#define OMAP_HSMMC_SDMASA 0x0100 #define OMAP_HSMMC_BLK 0x0104 #define OMAP_HSMMC_ARG 0x0108 #define OMAP_HSMMC_CMD 0x010C @@ -57,7 +58,9 @@ #define OMAP_HSMMC_STAT 0x0130 #define OMAP_HSMMC_IE 0x0134 #define OMAP_HSMMC_ISE 0x0138 +#define OMAP_HSMMC_AC12 0x013C #define OMAP_HSMMC_CAPA 0x0140 +#define OMAP_HSMMC_REV 0x01FC #define VS18 (1 << 26) #define VS30 (1 << 25) @@ -79,6 +82,8 @@ #define DTO_MASK 0x000F0000 #define DTO_SHIFT 16 #define INIT_STREAM (1 << 1) +#define ACEN_ACMD12 (1 << 2) +#define ACEN_ACMD23 (2 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMAE 0x1 @@ -110,6 +115,7 @@ #define DTO_EN (1 << 20) #define DCRC_EN (1 << 21) #define DEB_EN (1 << 22) +#define ACE_EN (1 << 24) #define CERR_EN (1 << 28) #define BADA_EN (1 << 29) @@ -117,12 +123,26 @@ DTO_EN | CIE_EN | CEB_EN | CCRC_EN | CTO_EN | \ BRR_EN | BWR_EN | TC_EN | CC_EN) +#define CNI (1 << 7) +#define ACIE (1 << 4) +#define ACEB (1 << 3) +#define ACCE (1 << 2) +#define ACTO (1 << 1) +#define ACNE (1 << 0) + #define MMC_AUTOSUSPEND_DELAY 100 #define MMC_TIMEOUT_MS 20 #define OMAP_MMC_MIN_CLOCK 400000 #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" +#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ +#define AUTO_CMD23 (1 << 1) /* Auto CMD23 support */ + +#define OMAP_HSMMC_REV_SHIFT 24 +/* HSMMC controller revision on OMAP5, DRA7 */ +#define OMAP_HSMMC_REV_33 0x33 + /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -180,11 +200,20 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; + unsigned long clk_rate; + unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; }; +static int +omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req); + +static void set_data_timeout(struct omap_hsmmc_host *host, + unsigned int timeout_ns, + unsigned int timeout_clks); + static int omap_hsmmc_card_detect(struct device *dev, int slot) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); @@ -765,7 +794,7 @@ static DEVICE_ATTR(slot_name, S_IRUGO, omap_hsmmc_show_slot_name, NULL); */ static void omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, - struct mmc_data *data) + struct mmc_data *data, bool autocmd12) { int cmdreg = 0, resptype = 0, cmdtype = 0; @@ -795,6 +824,13 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); + if ((host->flags & AUTO_CMD23) && mmc_op_multi(cmd->opcode) && + host->mrq->sbc) { + cmdreg |= ACEN_ACMD23; + OMAP_HSMMC_WRITE(host->base, SDMASA, host->mrq->sbc->arg); + } else if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode) && + autocmd12) + cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -873,11 +909,38 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (!data->stop) { + if (data->stop && (data->error || (!(host->flags & AUTO_CMD12) && + !host->mrq->sbc))) { + /* + * If there is any error or open-end read/write with autocmd12 + * disabled + */ + omap_hsmmc_start_command(host, data->stop, NULL, 0); + } else { + /* status update for autocmd12 of open-end read/write */ + if (data->stop && !host->mrq->sbc) + data->stop->resp[0] = OMAP_HSMMC_READ(host->base, + RSP76); omap_hsmmc_request_done(host, data->mrq); - return; } - omap_hsmmc_start_command(host, data->stop, NULL); + + return; +} + +static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host) +{ + struct mmc_request *req; + struct dma_chan *chan; + req = host->mrq; + + if (!req->data) + return; + OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) + | (req->data->blocks << 16)); + set_data_timeout(host, req->data->timeout_ns, + req->data->timeout_clks); + chan = omap_hsmmc_get_dma_chan(host, req->data); + dma_async_issue_pending(chan); } /* @@ -886,6 +949,18 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) static void omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) { + struct mmc_request *req; + req = host->mrq; + + if (host->mrq->sbc && (host->cmd == host->mrq->sbc) && + !host->mrq->sbc->error && !(host->flags & AUTO_CMD23)) { + host->cmd = NULL; + omap_hsmmc_start_dma_transfer(host); + omap_hsmmc_start_command(host, host->mrq->cmd, + host->mrq->data, 0); + return; + } + host->cmd = NULL; if (cmd->flags & MMC_RSP_PRESENT) { @@ -1025,6 +1100,7 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) { struct mmc_data *data; int end_cmd = 0, end_trans = 0; + int error = 0; data = host->data; dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); @@ -1039,6 +1115,29 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) else if (status & (CCRC_EN | DCRC_EN)) hsmmc_command_incomplete(host, -EILSEQ, end_cmd); + if (status & ACE_EN) { + u32 ac12; + ac12 = OMAP_HSMMC_READ(host->base, AC12); + if (!(ac12 & ACNE) && host->mrq->sbc) { + end_cmd = 1; + if (ac12 & ACTO) + error = -ETIMEDOUT; + else if (ac12 & (ACCE | ACEB | ACIE)) + error = -EILSEQ; + host->mrq->sbc->error = error; + hsmmc_command_incomplete(host, error, end_cmd); + } + if (!(ac12 & ACNE) && !host->mrq->sbc && + host->mrq->data) { + end_trans = 1; + if (ac12 & ACTO) + host->mrq->data->error = -ETIMEDOUT; + else if (ac12 & (ACCE | ACEB | ACIE)) + host->mrq->data->error = -EILSEQ; + omap_hsmmc_reset_controller_fsm(host, SRC); + } + dev_dbg(mmc_dev(host->mmc), "AC12 err: 0x%x\n", ac12); + } if (host->data || host->response_busy) { end_trans = !end_cmd; host->response_busy = 0; @@ -1275,7 +1374,7 @@ static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host, /* * Routine to configure and start DMA for the MMC card */ -static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, +static int omap_hsmmc_setup_dma_transfer(struct omap_hsmmc_host *host, struct mmc_request *req) { struct dma_slave_config cfg; @@ -1334,8 +1433,6 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, host->dma_ch = 1; - dma_async_issue_pending(chan); - return 0; } @@ -1351,7 +1448,7 @@ static void set_data_timeout(struct omap_hsmmc_host *host, if (clkd == 0) clkd = 1; - cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); + cycle_ns = 1000000000 / (host->clk_rate / clkd); timeout = timeout_ns / cycle_ns; timeout += timeout_clks; if (timeout) { @@ -1396,12 +1493,8 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req) return 0; } - OMAP_HSMMC_WRITE(host->base, BLK, (req->data->blksz) - | (req->data->blocks << 16)); - set_data_timeout(host, req->data->timeout_ns, req->data->timeout_clks); - if (host->use_dma) { - ret = omap_hsmmc_start_dma_transfer(host, req); + ret = omap_hsmmc_setup_dma_transfer(host, req); if (ret != 0) { dev_err(mmc_dev(host->mmc), "MMC start dma failure\n"); return ret; @@ -1475,6 +1568,7 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) host->reqs_blocked = 0; WARN_ON(host->mrq != NULL); host->mrq = req; + host->clk_rate = clk_get_rate(host->fclk); err = omap_hsmmc_prepare_data(host, req); if (err) { req->cmd->error = err; @@ -1484,8 +1578,12 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) mmc_request_done(mmc, req); return; } - - omap_hsmmc_start_command(host, req->cmd, req->data); + if (req->sbc && !(host->flags & AUTO_CMD23)) { + omap_hsmmc_start_command(host, req->sbc, NULL, 0); + return; + } + omap_hsmmc_start_dma_transfer(host); + omap_hsmmc_start_command(host, req->cmd, req->data, 1); } /* Routine to configure clock values. Exposed API to core */ @@ -1782,6 +1880,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) unsigned tx_req, rx_req; struct dmaengine_chan_caps *dma_chan_caps; struct pinctrl *pinctrl; + u32 revision; match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev); if (match) { @@ -1977,6 +2076,12 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host->use_reg = 1; } + revision = OMAP_HSMMC_READ(host->base, REV); + if ((revision >> OMAP_HSMMC_REV_SHIFT) >= OMAP_HSMMC_REV_33) { + mmc->caps |= MMC_CAP_CMD23; + host->flags |= AUTO_CMD23 | AUTO_CMD12; + } + mmc->ocr_avail = mmc_slot(host).ocr_mask; /* Request IRQ for card detect */ diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 065f3fe02a2f..b63b95d878b6 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -589,7 +589,7 @@ static int __adjust_timing(struct device *dev, void *data) return ret; } -int omap2_onenand_rephase(void) +static int omap2_onenand_rephase(void) { return driver_for_each_device(&omap2_onenand_driver.driver, NULL, NULL, __adjust_timing); diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 84c1e915eb9e..37323b5b52af 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -92,7 +92,7 @@ static void c_can_hw_raminit_dra7(const struct c_can_priv *priv, bool enable) { u32 start_set, start_clr; DEFINE_SPINLOCK(raminit_lock); - unsigned long flags; + unsigned long flags = 0; start_set = start_clr = readl(priv->raminit_ctrlreg); start_set |= CAN_RAMINIT_BIT_MASK(priv->raminit_bits.start); diff --git a/drivers/regulator/ti-avs-class0-regulator.c b/drivers/regulator/ti-avs-class0-regulator.c index 3ccba8a3bf90..efbfe19cb54d 100644 --- a/drivers/regulator/ti-avs-class0-regulator.c +++ b/drivers/regulator/ti-avs-class0-regulator.c @@ -261,6 +261,13 @@ static int tiavs_class0_probe(struct platform_device *pdev) readl(base + efuse_offset) : readw(base + efuse_offset) * 1000; + /* Handle efuse == 0 Case */ + if (data->volt_set_table[i] == 0) { + dev_err(&pdev->dev, "efuse=0 @ 0x%08x reverting to device tree bindings volt_table=%d\n", + (base + efuse_offset), volt_table[i]); + data->volt_set_table[i] = volt_table[i]; + } + /* Find min/max for the voltage sets */ if (min_uV > volt_table[i]) min_uV = volt_table[i]; diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 9bcbd3a54c8c..89e7e53dedb6 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -116,6 +116,18 @@ config OMAP_REMOTEPROC_DSP2 audio or any other algorithm (by DSP) or just want a bare minimum kernel. +config OMAP_REMOTEPROC_WATCHDOG + bool "OMAP remoteproc watchdog timer" + depends on OMAP_REMOTEPROC_IPU || OMAP_REMOTEPROC_DSP || OMAP_REMOTEPROC_IPU1 || OMAP_REMOTEPROC_DSP2 + default n + help + Say Y here to enable watchdog timer for remote processors. + + This option controls the watchdog functionality for the remote + processors in OMAP. Dedicated timers are used by the remote + processors and triggers the timer interrupt upon a watchdog + detection. + config STE_MODEM_RPROC tristate "STE-Modem remoteproc support" depends on HAS_DMA diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index fdba982cb4a0..efc89ccea973 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -74,8 +74,12 @@ static int omap_rproc_mbox_callback(struct notifier_block *this, switch (msg_data) { case RP_MBOX_CRASH: - /* just log this for now. later, we'll also do recovery */ + /* + * remoteproc detected an exception, notify the rproc core. + * The remoteproc core will handle the recovery. + */ dev_err(dev, "omap rproc %s crashed\n", name); + rproc_report_crash(oproc->rproc, RPROC_EXCEPTION); break; case RP_MBOX_ECHO_REPLY: dev_info(dev, "received echo reply from %s\n", name); @@ -234,6 +238,7 @@ static int omap_rproc_probe(struct platform_device *pdev) oproc = rproc->priv; oproc->rproc = rproc; + pdata->report_watchdog = rproc_report_crash; platform_set_drvdata(pdev, rproc); ret = rproc_add(rproc); diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 486776e9f8b2..e00c09ea460e 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -41,6 +41,7 @@ #include <linux/virtio_ids.h> #include <linux/virtio_ring.h> #include <linux/platform_device.h> +#include <linux/vmalloc.h> #include <asm/byteorder.h> #include "remoteproc_internal.h" @@ -55,6 +56,8 @@ static DEFINE_IDA(rproc_dev_index); static const char * const rproc_crash_names[] = { [RPROC_MMUFAULT] = "mmufault", + [RPROC_WATCHDOG] = "watchdog", + [RPROC_EXCEPTION] = "device exception", }; /* translate rproc_crash_type to string */ @@ -423,6 +426,103 @@ free_rvdev: } /** + * rproc_handle_last_trace() - setup a buffer to capture the trace snapshot + * before recovery + * @rproc: the remote processor + * @trace: the trace resource descriptor + * @count: the index of the trace under process + * + * The last trace is allocated and the contents of the trace buffer are + * copied during a recovery cleanup. Once, the contents get copied, the + * trace buffers are cleaned up for re-use. + * + * It might also happen that the remoteproc binary changes between the + * time that it was loaded and the time that it crashed. In this case, + * the trace descriptors might have changed too. The last traces are + * re-built as required in this case. + * + * Returns 0 on success, or an appropriate error code otherwise + */ +static int rproc_handle_last_trace(struct rproc *rproc, + struct rproc_mem_entry *trace, int count) +{ + struct rproc_mem_entry *trace_last, *tmp_trace; + struct device *dev = &rproc->dev; + char name[15]; + int i = 0; + bool new_trace = false; + + if (!rproc || !trace) + return -EINVAL; + + /* we need a new trace in this case */ + if (count > rproc->num_last_traces) { + new_trace = true; + /* + * make sure snprintf always null terminates, even if truncating + */ + snprintf(name, sizeof(name), "trace%d_last", (count - 1)); + trace_last = kzalloc(sizeof(*trace_last), GFP_KERNEL); + if (!trace_last) { + dev_err(dev, "kzalloc failed for trace%d_last\n", + count); + return -ENOMEM; + } + } else { + /* try to reuse buffers here */ + list_for_each_entry_safe(trace_last, tmp_trace, + &rproc->last_traces, node) { + if (++i == count) + break; + } + + /* if we can reuse the trace, copy buffer and exit */ + if (trace_last->len == trace->len) + goto copy_and_exit; + + /* can reuse the trace struct but not the buffer */ + vfree(trace_last->va); + trace_last->va = NULL; + trace_last->len = 0; + } + + trace_last->len = trace->len; + trace_last->va = vmalloc(sizeof(u32) * trace_last->len); + if (!trace_last->va) { + dev_err(dev, "vmalloc failed for trace%d_last\n", count); + if (!new_trace) { + list_del(&trace_last->node); + rproc->num_last_traces--; + } + kfree(trace_last); + return -ENOMEM; + } + + /* create the debugfs entry */ + if (new_trace) { + trace_last->priv = rproc_create_trace_file(name, rproc, + trace_last); + if (!trace_last->priv) { + dev_err(dev, "trace%d_last create debugfs failed\n", + count); + vfree(trace_last->va); + kfree(trace_last); + return -EINVAL; + } + + /* add it to the trace list */ + list_add_tail(&trace_last->node, &rproc->last_traces); + rproc->num_last_traces++; + } + +copy_and_exit: + /* copy the trace to last trace */ + memcpy(trace_last->va, trace->va, trace->len); + + return 0; +} + +/** * rproc_handle_trace() - handle a shared trace buffer resource * @rproc: the remote processor * @rsc: the trace resource descriptor @@ -883,6 +983,18 @@ rproc_handle_fw_version(struct rproc *rproc, const char *version, int versz) } /** + * rproc_free_last_trace() - helper function to cleanup a last trace entry + * @trace: the last trace element to be cleaned up + */ +static void rproc_free_last_trace(struct rproc_mem_entry *trace) +{ + rproc_remove_trace_file(trace->priv); + list_del(&trace->node); + vfree(trace->va); + kfree(trace); +} + +/** * rproc_resource_cleanup() - clean up and free all acquired resources * @rproc: rproc handle * @@ -893,14 +1005,32 @@ static void rproc_resource_cleanup(struct rproc *rproc) { struct rproc_mem_entry *entry, *tmp; struct device *dev = &rproc->dev; + int count = 0, i = rproc->num_traces; /* clean up debugfs trace entries */ list_for_each_entry_safe(entry, tmp, &rproc->traces, node) { + /* handle last trace here */ + if (rproc->state == RPROC_CRASHED) + rproc_handle_last_trace(rproc, entry, ++count); + rproc_remove_trace_file(entry->priv); - rproc->num_traces--; list_del(&entry->node); kfree(entry); } + rproc->num_traces = 0; + + /* + * clean up debugfs last trace entries. This either deletes all last + * trace entries during cleanup or just the remaining entries, if any, + * in case of a crash. + */ + list_for_each_entry_safe(entry, tmp, &rproc->last_traces, node) { + /* skip the valid traces */ + if ((i--) && (rproc->state == RPROC_CRASHED)) + continue; + rproc_free_last_trace(entry); + rproc->num_last_traces--; + } /* clean up iommu mapping entries */ list_for_each_entry_safe(entry, tmp, &rproc->mappings, node) { @@ -1410,9 +1540,16 @@ EXPORT_SYMBOL(rproc_add); static void rproc_type_release(struct device *dev) { struct rproc *rproc = container_of(dev, struct rproc, dev); + struct rproc_mem_entry *entry, *tmp; dev_info(&rproc->dev, "releasing %s\n", rproc->name); + /* clean up debugfs last trace entries */ + list_for_each_entry_safe(entry, tmp, &rproc->last_traces, node) { + rproc_free_last_trace(entry); + rproc->num_last_traces--; + } + rproc_delete_debug_dir(rproc); idr_remove_all(&rproc->notifyids); @@ -1518,6 +1655,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, INIT_LIST_HEAD(&rproc->carveouts); INIT_LIST_HEAD(&rproc->mappings); INIT_LIST_HEAD(&rproc->traces); + INIT_LIST_HEAD(&rproc->last_traces); INIT_LIST_HEAD(&rproc->rvdevs); INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work); diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 0ae155be9c89..8a5ee1a9a9fa 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -58,7 +58,7 @@ static int genericbl_get_intensity(struct backlight_device *bd) * Called when the battery is low to limit the backlight intensity. * If limit==0 clear any limit, otherwise limit the intensity */ -void genericbl_limit_intensity(int limit) +static void genericbl_limit_intensity(int limit) { struct backlight_device *bd = generic_backlight_device; diff --git a/drivers/video/omap2/displays/panel-tfcs9700.c b/drivers/video/omap2/displays/panel-tfcs9700.c index f746c2d92dc2..a17c723f1654 100644 --- a/drivers/video/omap2/displays/panel-tfcs9700.c +++ b/drivers/video/omap2/displays/panel-tfcs9700.c @@ -399,7 +399,7 @@ static struct omap_dss_driver tfc_s9700_driver = { }, }; -struct regmap_config tlc59108_regmap_config = { +static struct regmap_config tlc59108_regmap_config = { .reg_bits = 8, .val_bits = 8, }; diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 08135fc9e4fc..2c4b1fb3709d 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -43,6 +43,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +#include <mach-omap2/soc.h> #include "ti_hdmi_4xxx_ip.h" #include "ti_hdmi.h" #include "dss.h" @@ -2021,7 +2022,8 @@ static void init_sel_i2c_hdmi(void) void __iomem *clk_base = ioremap(0x4A009000, SZ_4K); void __iomem *mcasp8_base = ioremap(0x4847C000, SZ_1K); - if (omapdss_get_version() != OMAPDSS_VER_DRA7xx) + if (omapdss_get_version() != OMAPDSS_VER_DRA7xx || + soc_is_dra72x()) goto err; if (!clk_base || !mcasp8_base) @@ -2057,7 +2059,8 @@ void sel_i2c(void) void __iomem *mcasp8_base = ioremap(0x4847C000, SZ_1K); void __iomem *core_base = ioremap(0x4a003400, SZ_1K); - if (omapdss_get_version() != OMAPDSS_VER_DRA7xx) + if (omapdss_get_version() != OMAPDSS_VER_DRA7xx || + soc_is_dra72x()) goto err; /* set CM_L4PER2_CLKSTCTRL to sw supervised wkup */ @@ -2095,7 +2098,8 @@ void sel_hdmi(void) void __iomem *mcasp8_base = ioremap(0x4847C000, SZ_1K); void __iomem *core_base = ioremap(0x4a003400, SZ_1K); - if (omapdss_get_version() != OMAPDSS_VER_DRA7xx) + if (omapdss_get_version() != OMAPDSS_VER_DRA7xx || + soc_is_dra72x()) goto err; /* drive MCASP8_PDOUT to high to select HDMI*/ diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index e8471f7fb5ec..fa3ef081d1a0 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -814,7 +814,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) } -bool check_fb_scale(struct omap_dss_device *dssdev) +static bool check_fb_scale(struct omap_dss_device *dssdev) { u16 fb_w, fb_h , pn_w , pn_h; struct omap_dss_driver *dssdrv; @@ -1757,10 +1757,10 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev) rg = ofbi->region; DBG("region%d phys %08x virt %p size=%lu\n", - i, - rg->paddr, - rg->vaddr, - rg->size); + i, + rg->paddr, + rg->vaddr, + rg->size); } return 0; @@ -2059,7 +2059,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) fbdev->num_fbs = 0; - DBG("create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS); + DBG("create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS); /* allocate fb_infos */ for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) { @@ -2104,7 +2104,7 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev) struct omap_overlay_manager *mgr = fbdev->managers[i]; ofbi->overlays[0] = fbdev->overlays[i]; ofbi->num_overlays = 1; - if (mgr->output) { + if (mgr && mgr->output) { ofbi->overlays[0]->unset_manager(ofbi->overlays[0]); ofbi->overlays[0]->set_manager(ofbi->overlays[0], mgr); DBG("ofbi%d assigned dev %s", @@ -2568,17 +2568,19 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev, for (i = 0; i < fbdev->num_displays; ++i) { struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; - struct omap_dss_output *out = dssdev->output; + if (dssdev) { + struct omap_dss_output *out = dssdev->output; - mgr = omap_dss_get_overlay_manager(dssdev->channel); + mgr = omap_dss_get_overlay_manager(dssdev->channel); - if (!mgr || !out) - continue; + if (!mgr || !out) + continue; - if (mgr->output) - mgr->unset_output(mgr); + if (mgr->output) + mgr->unset_output(mgr); - mgr->set_output(mgr, out); + mgr->set_output(mgr, out); + } } mgr = def_dssdev->output->manager; @@ -2589,6 +2591,7 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev, } for (i = 0; i < fbdev->num_overlays; i++) { + struct omap_overlay *ovl = fbdev->overlays[i]; if (ovl->manager) @@ -2655,12 +2658,14 @@ static int __init omapfb_probe(struct platform_device *pdev) struct omapfb2_device *fbdev = NULL; int r = 0; int i; - struct omap_dss_device *def_display; - struct omap_dss_device *dssdev; + struct omap_dss_device *init_displays[3]; + struct omap_dss_device *dssdev = NULL; u16 fb_ov_start_ix = 0; + const char *def_disp = omapdss_get_default_display_name(); DBG("omapfb_probe\n"); + memset(init_displays, 0, sizeof(init_displays)); if (pdev->num_resources != 0) { dev_err(&pdev->dev, "probed for an unknown device\n"); r = -ENODEV; @@ -2690,7 +2695,6 @@ static int __init omapfb_probe(struct platform_device *pdev) platform_set_drvdata(pdev, fbdev); fbdev->num_displays = 0; - dssdev = NULL; for_each_dss_dev(dssdev) { struct omapfb_display_data *d; @@ -2703,12 +2707,47 @@ static int __init omapfb_probe(struct platform_device *pdev) continue; } - d = &fbdev->displays[fbdev->num_displays++]; + d = &fbdev->displays[dssdev->display_id]; d->dssdev = dssdev; if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) d->update_mode = OMAPFB_MANUAL_UPDATE; else d->update_mode = OMAPFB_AUTO_UPDATE; + + /* select the displays that need to be intialized at boot up + * 1. display_id[0] is the default display + * 2. display_id[1] is set to HDMI due to limitations in HWC + * 3. HDMI can either be primary or external attachable display + * 4. LCD/FPDLINK can be either primary and/or secondary + * attached displays. + */ + switch (dssdev->display_id) { + case 0: + init_displays[dssdev->display_id] = dssdev; + break; + case 1: + case 2: + case 3: + if (!def_disp) { + if (strcmp("lcd", dssdev->name) == 0 || + strcmp("fpdlink", dssdev->name) == 0) + init_displays[dssdev->display_id-1] = dssdev; + break; + } else + dev_err(&pdev->dev, + "default display set to %s\n", + def_disp); + default: + dev_err(&pdev->dev, + "ignoring from initialization display[%d]=%s\n", + dssdev->display_id, dssdev->name); + break; + } + fbdev->num_displays++; + dev_err(&pdev->dev, " display(%d) = %s, driver_name = %s\n", + dssdev->display_id, + dssdev->name, + dssdev->driver->driver.name); } if (fbdev->num_displays == 0) { @@ -2719,34 +2758,26 @@ static int __init omapfb_probe(struct platform_device *pdev) fbdev->num_overlays = omap_dss_get_num_overlays(); for (i = 0; i < fbdev->num_overlays; i++) fbdev->overlays[i] = omap_dss_get_overlay(i); + fbdev->num_managers = omap_dss_get_num_overlay_managers(); for (i = 0; i < fbdev->num_managers; i++) - fbdev->managers[i] = omap_dss_get_overlay_manager(i); - - def_display = NULL; - - for (i = 0; i < fbdev->num_displays; ++i) { - struct omap_dss_device *dssdev; - const char *def_name; - - def_name = omapdss_get_default_display_name(); - - dssdev = fbdev->displays[i].dssdev; - - if (def_name == NULL || - (dssdev->name && strcmp(def_name, dssdev->name) == 0)) { - def_display = dssdev; - break; + if (fbdev->displays[i].dssdev) { + fbdev->managers[i] = + omap_dss_get_overlay_manager(fbdev->displays[i].dssdev->channel); + dev_err(fbdev->dev, "fbdev->mgr[%d] = %s, display_id[%d]=%s, channel=%d\n", + i, fbdev->managers[i]->name, + fbdev->displays[i].dssdev->display_id, + fbdev->displays[i].dssdev->name, + fbdev->displays[i].dssdev->channel); } - } - if (def_display == NULL) { + if (init_displays[0] == NULL) { dev_err(fbdev->dev, "failed to find default display\n"); r = -EINVAL; goto cleanup; } - r = omapfb_init_connections(fbdev, def_display); + r = omapfb_init_connections(fbdev, init_displays[0]); if (r) { dev_err(fbdev->dev, "failed to init overlay connections\n"); goto cleanup; @@ -2770,15 +2801,17 @@ static int __init omapfb_probe(struct platform_device *pdev) } for (i = 0; i < fbdev->num_displays; i++) { - if (!intialize_dev_fb_resolution(i, fbdev->displays[i].dssdev)) + if (fbdev->displays[i].dssdev && + !intialize_dev_fb_resolution(i, fbdev->displays[i].dssdev)) goto cleanup; } fbdev->num_overlays = omap_dss_get_num_overlays(); - if (def_display && check_fb_scale(def_display)) { + if (init_displays[0] && check_fb_scale(init_displays[0])) { fb_ov_start_ix = 1; fbdev->num_overlays -= 1; } + for (i = 0; i < fbdev->num_overlays; i++) fbdev->overlays[i] = omap_dss_get_overlay(i+fb_ov_start_ix); r = omapfb_create_framebuffers(fbdev); @@ -2788,20 +2821,27 @@ static int __init omapfb_probe(struct platform_device *pdev) for (i = 0; i < fbdev->num_managers; i++) { struct omap_overlay_manager *mgr; mgr = fbdev->managers[i]; - r = mgr->apply(mgr); - if (r) - dev_warn(fbdev->dev, "failed to apply dispc config\n"); + if (mgr) { + r = mgr->apply(mgr); + if (r) + dev_warn(fbdev->dev, "failed to apply dispc config\n"); + } } DBG("mgr->apply'ed\n"); - if (def_display) { - r = omapfb_init_display(fbdev, def_display); - if (r) { - dev_err(fbdev->dev, - "failed to initialize default " - "display\n"); - goto cleanup; + for (i = 0; i < fbdev->num_displays; i++) { + if (init_displays[i]) { + r = omapfb_init_display(fbdev, init_displays[i]); + if (r) { + dev_err(fbdev->dev, + "failed to initialize default " + "display(%d): %s, err = %d\n", + init_displays[i]->display_id, + init_displays[i]->name, r); + if (!i) + goto cleanup; + } } } diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 5bf7c2274fcb..9da5dd02bd71 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -93,6 +93,8 @@ struct mmc_command { */ unsigned int cmd_timeout_ms; /* in milliseconds */ + /* Set this flag only for blocking sanitize request */ + bool sanitize_busy; struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 24d8cfd23241..6830b56dce09 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -259,6 +259,7 @@ struct mmc_host { #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ +#define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */ mmc_pm_flag_t pm_caps; /* supported pm features */ diff --git a/include/linux/platform_data/remoteproc-omap.h b/include/linux/platform_data/remoteproc-omap.h index ba9dff37662e..1176f0052ee8 100644 --- a/include/linux/platform_data/remoteproc-omap.h +++ b/include/linux/platform_data/remoteproc-omap.h @@ -17,19 +17,25 @@ #ifndef _PLAT_REMOTEPROC_H #define _PLAT_REMOTEPROC_H +struct rproc; struct rproc_ops; struct platform_device; +enum rproc_crash_type; /** * struct omap_rproc_timers_info - timers for the omap rproc * @name: hwmod name of the timer * @id: timer id to use by the remoteproc (only for non-DT and temporary) * @odt: timer pointer + * @is_wdt: flag to indicate a watchdog timer + * 0 - regular timer + * 1 - watchdog timer */ struct omap_rproc_timers_info { const char *name; int id; struct omap_dm_timer *odt; + int is_wdt; }; /** @@ -47,6 +53,7 @@ struct omap_rproc_timers_info { * @set_bootaddr: omap-specific handler for setting the rproc boot address * @enable_timers: omap-specific handler for requesting & enabling rproc timers * @disable_timers: omap-specific handler for disabling & freeing rproc timers + * @report_watchdog: handler to invoke upon a watchdog error */ struct omap_rproc_pdata { const char *name; @@ -66,6 +73,9 @@ struct omap_rproc_pdata { int (*enable_timers)(struct platform_device *pdev, bool configure); int (*disable_timers)(struct platform_device *pdev, bool configure); + + void (*report_watchdog)(struct rproc *rproc, + enum rproc_crash_type type); }; #if defined(CONFIG_OMAP_REMOTEPROC) || defined(CONFIG_OMAP_REMOTEPROC_MODULE) diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 29760eaa2187..d7a8992eff93 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -401,14 +401,18 @@ enum rproc_state { /** * enum rproc_crash_type - remote processor crash types * @RPROC_MMUFAULT: iommu fault + * @RPROC_WATCHDOG: watchdog error + * @RPROC_EXCEPTION: generic device exception * - * Each element of the enum is used as an array index. So that, the value of + * Each element of the enum is used as an array index. So, the value of * the elements should be always something sane. * * Feel free to add more types when needed. */ enum rproc_crash_type { RPROC_MMUFAULT, + RPROC_WATCHDOG, + RPROC_EXCEPTION, }; /** @@ -427,6 +431,8 @@ enum rproc_crash_type { * @dbg_dir: debugfs directory of this rproc device * @traces: list of trace buffers * @num_traces: number of trace buffers + * @last_traces: list of last trace buffers + * @num_last_traces: number of last trace buffers * @carveouts: list of physically contiguous memory allocations * @mappings: list of iommu mappings we initiated, needed on shutdown * @firmware_loading_complete: marks e/o asynchronous firmware loading @@ -460,6 +466,8 @@ struct rproc { struct dentry *dbg_dir; struct list_head traces; int num_traces; + struct list_head last_traces; + int num_last_traces; struct list_head carveouts; struct list_head mappings; struct completion firmware_loading_complete; diff --git a/mm/vmscan.c b/mm/vmscan.c index e31d09df9eb3..3c17364ed328 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -166,7 +166,6 @@ static int debug_shrinker_show(struct seq_file *s, void *unused) down_read(&shrinker_rwsem); list_for_each_entry(shrinker, &shrinker_list, list) { - char name[64]; int num_objs; num_objs = shrinker->shrink(shrinker, &sc); |