Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'staging-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging fixes from Greg Kroah-Hartman:
"Here are a number of small fixes to staging drivers for your 3.8-rc3
tree.

Well, the omapdrm fixes aren't really "small" but they were waiting on
a number of other drm patches to go in through the drm tree, and got
delayed by my vacation over the holidays. They are totally
self-contained, everyone involved have acked them, and they fix issues
that people have been having with the driver.

Other than that one, it's a bunch of tiny bugfixes for a number of
reported issues.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"

* tag 'staging-3.8-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (36 commits)
staging: zram: fix invalid memory references during disk write
staging: tidspbridge: use prepare/unprepare on dsp clocks
staging: tidspbridge: Fix build breakage due to splitting CM functions.
staging: comedi: comedi_test: fix race when cancelling command
staging: comedi: Kconfig: COMEDI_NI_AT_A2150 should select COMEDI_FC
staging: comedi: prevent auto-unconfig of manually configured devices
staging: comedi: fix minimum AO period for NI 625x and NI 628x
staging: vme_pio2: fix oops on module unloading
staging: speakup: avoid out-of-range access in synth_add()
staging: speakup: avoid out-of-range access in synth_init()
staging: rtl8192e: Fix failure to check pci_map_single()
staging: rtl8187se: Fix failure to check pci_map_single()
staging: drm/imx: fix double free bug in error path
staging: drm/imx: several bug fixes
staging: drm/imx: check return value of ipu_reset()
staging: drm/omap: fix flags in dma buf exporting
staging: drm/omap: use omapdss low level API
staging/fwserial: Update TODO file per reviewer comments
staging/fwserial: Limit tx/rx to 1394-2008 spec maximum
staging/fwserial: Refine Kconfig help text
...

+1405 -998
+1
drivers/iio/accel/Kconfig
··· 8 8 select IIO_BUFFER 9 9 select IIO_TRIGGERED_BUFFER 10 10 select HID_SENSOR_IIO_COMMON 11 + select HID_SENSOR_IIO_TRIGGER 11 12 tristate "HID Accelerometers 3D" 12 13 help 13 14 Say yes here to build support for the HID SENSOR
+5 -1
drivers/iio/adc/ad7266.c
··· 411 411 if (ret) 412 412 goto error_put_reg; 413 413 414 - st->vref_uv = regulator_get_voltage(st->reg); 414 + ret = regulator_get_voltage(st->reg); 415 + if (ret < 0) 416 + goto error_disable_reg; 417 + 418 + st->vref_uv = ret; 415 419 } else { 416 420 /* Use internal reference */ 417 421 st->vref_uv = 2500000;
+1 -1
drivers/iio/adc/at91_adc.c
··· 80 80 *timestamp = pf->timestamp; 81 81 } 82 82 83 - iio_push_to_buffers(indio_dev, (u8 *)st->buffer); 83 + iio_push_to_buffers(idev, (u8 *)st->buffer); 84 84 85 85 iio_trigger_notify_done(idev->trig); 86 86
+6 -7
drivers/iio/adc/max1363.c
··· 1605 1605 1606 1606 return 0; 1607 1607 error_free_irq: 1608 - free_irq(st->client->irq, indio_dev); 1608 + if (client->irq) 1609 + free_irq(st->client->irq, indio_dev); 1609 1610 error_uninit_buffer: 1610 1611 iio_buffer_unregister(indio_dev); 1611 1612 error_cleanup_buffer: 1612 1613 max1363_buffer_cleanup(indio_dev); 1613 1614 error_free_available_scan_masks: 1614 1615 kfree(indio_dev->available_scan_masks); 1615 - error_unregister_map: 1616 - iio_map_array_unregister(indio_dev, client->dev.platform_data); 1617 1616 error_disable_reg: 1618 1617 regulator_disable(st->reg); 1619 1618 error_put_reg: 1620 1619 regulator_put(st->reg); 1620 + error_unregister_map: 1621 + iio_map_array_unregister(indio_dev, client->dev.platform_data); 1621 1622 error_free_device: 1622 1623 iio_device_free(indio_dev); 1623 1624 error_out: ··· 1636 1635 iio_buffer_unregister(indio_dev); 1637 1636 max1363_buffer_cleanup(indio_dev); 1638 1637 kfree(indio_dev->available_scan_masks); 1639 - if (!IS_ERR(st->reg)) { 1640 - regulator_disable(st->reg); 1641 - regulator_put(st->reg); 1642 - } 1638 + regulator_disable(st->reg); 1639 + regulator_put(st->reg); 1643 1640 iio_map_array_unregister(indio_dev, client->dev.platform_data); 1644 1641 iio_device_free(indio_dev); 1645 1642
+12 -1
drivers/iio/common/hid-sensors/Kconfig
··· 6 6 config HID_SENSOR_IIO_COMMON 7 7 tristate "Common modules for all HID Sensor IIO drivers" 8 8 depends on HID_SENSOR_HUB 9 - select IIO_TRIGGER if IIO_BUFFER 9 + select HID_SENSOR_IIO_TRIGGER if IIO_BUFFER 10 10 help 11 11 Say yes here to build support for HID sensor to use 12 12 HID sensor common processing for attributes and IIO triggers. 13 13 There are many attributes which can be shared among multiple 14 14 HID sensor drivers, this module contains processing for those 15 15 attributes. 16 + 17 + config HID_SENSOR_IIO_TRIGGER 18 + tristate "Common module (trigger) for all HID Sensor IIO drivers" 19 + depends on HID_SENSOR_HUB && HID_SENSOR_IIO_COMMON 20 + select IIO_TRIGGER 21 + help 22 + Say yes here to build trigger support for HID sensors. 23 + Triggers will be send if all requested attributes were read. 24 + 25 + If this driver is compiled as a module, it will be named 26 + hid-sensor-trigger. 16 27 17 28 config HID_SENSOR_ENUM_BASE_QUIRKS 18 29 bool "ENUM base quirks for HID Sensor IIO drivers"
+2 -1
drivers/iio/common/hid-sensors/Makefile
··· 3 3 # 4 4 5 5 obj-$(CONFIG_HID_SENSOR_IIO_COMMON) += hid-sensor-iio-common.o 6 - hid-sensor-iio-common-y := hid-sensor-attributes.o hid-sensor-trigger.o 6 + obj-$(CONFIG_HID_SENSOR_IIO_TRIGGER) += hid-sensor-trigger.o 7 + hid-sensor-iio-common-y := hid-sensor-attributes.o
+5 -1
drivers/iio/dac/ad5380.c
··· 406 406 goto error_free_reg; 407 407 } 408 408 409 - st->vref = regulator_get_voltage(st->vref_reg); 409 + ret = regulator_get_voltage(st->vref_reg); 410 + if (ret < 0) 411 + goto error_disable_reg; 412 + 413 + st->vref = ret; 410 414 } else { 411 415 st->vref = st->chip_info->int_vref; 412 416 ctrl |= AD5380_CTRL_INT_VREF_EN;
+5 -1
drivers/iio/dac/ad5446.c
··· 226 226 if (ret) 227 227 goto error_put_reg; 228 228 229 - voltage_uv = regulator_get_voltage(reg); 229 + ret = regulator_get_voltage(reg); 230 + if (ret < 0) 231 + goto error_disable_reg; 232 + 233 + voltage_uv = ret; 230 234 } 231 235 232 236 indio_dev = iio_device_alloc(sizeof(*st));
+5 -1
drivers/iio/dac/ad5504.c
··· 296 296 if (ret) 297 297 goto error_put_reg; 298 298 299 - voltage_uv = regulator_get_voltage(reg); 299 + ret = regulator_get_voltage(reg); 300 + if (ret < 0) 301 + goto error_disable_reg; 302 + 303 + voltage_uv = ret; 300 304 } 301 305 302 306 spi_set_drvdata(spi, indio_dev);
+5 -1
drivers/iio/dac/ad5624r_spi.c
··· 238 238 if (ret) 239 239 goto error_put_reg; 240 240 241 - voltage_uv = regulator_get_voltage(st->reg); 241 + ret = regulator_get_voltage(st->reg); 242 + if (ret < 0) 243 + goto error_disable_reg; 244 + 245 + voltage_uv = ret; 242 246 } 243 247 244 248 spi_set_drvdata(spi, indio_dev);
+5 -1
drivers/iio/dac/ad5686.c
··· 332 332 if (ret) 333 333 goto error_put_reg; 334 334 335 - voltage_uv = regulator_get_voltage(st->reg); 335 + ret = regulator_get_voltage(st->reg); 336 + if (ret < 0) 337 + goto error_disable_reg; 338 + 339 + voltage_uv = ret; 336 340 } 337 341 338 342 st->chip_info =
+11 -2
drivers/iio/dac/ad5791.c
··· 365 365 if (ret) 366 366 goto error_put_reg_pos; 367 367 368 - pos_voltage_uv = regulator_get_voltage(st->reg_vdd); 368 + ret = regulator_get_voltage(st->reg_vdd); 369 + if (ret < 0) 370 + goto error_disable_reg_pos; 371 + 372 + pos_voltage_uv = ret; 369 373 } 370 374 371 375 st->reg_vss = regulator_get(&spi->dev, "vss"); ··· 378 374 if (ret) 379 375 goto error_put_reg_neg; 380 376 381 - neg_voltage_uv = regulator_get_voltage(st->reg_vss); 377 + ret = regulator_get_voltage(st->reg_vss); 378 + if (ret < 0) 379 + goto error_disable_reg_neg; 380 + 381 + neg_voltage_uv = ret; 382 382 } 383 383 384 384 st->pwr_down = true; ··· 436 428 if (!IS_ERR(st->reg_vss)) 437 429 regulator_put(st->reg_vss); 438 430 431 + error_disable_reg_pos: 439 432 if (!IS_ERR(st->reg_vdd)) 440 433 regulator_disable(st->reg_vdd); 441 434 error_put_reg_pos:
+1 -1
drivers/iio/frequency/adf4350.c
··· 173 173 } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); 174 174 } while (r_cnt == 0); 175 175 176 - tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); 176 + tmp = freq * (u64)st->r1_mod + (st->fpfd >> 1); 177 177 do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ 178 178 st->r0_fract = do_div(tmp, st->r1_mod); 179 179 st->r0_int = tmp;
+1
drivers/iio/gyro/Kconfig
··· 17 17 select IIO_BUFFER 18 18 select IIO_TRIGGERED_BUFFER 19 19 select HID_SENSOR_IIO_COMMON 20 + select HID_SENSOR_IIO_TRIGGER 20 21 tristate "HID Gyroscope 3D" 21 22 help 22 23 Say yes here to build support for the HID SENSOR
+1
drivers/iio/light/Kconfig
··· 47 47 select IIO_BUFFER 48 48 select IIO_TRIGGERED_BUFFER 49 49 select HID_SENSOR_IIO_COMMON 50 + select HID_SENSOR_IIO_TRIGGER 50 51 tristate "HID ALS" 51 52 help 52 53 Say yes here to build support for the HID SENSOR
+1
drivers/iio/magnetometer/Kconfig
··· 8 8 select IIO_BUFFER 9 9 select IIO_TRIGGERED_BUFFER 10 10 select HID_SENSOR_IIO_COMMON 11 + select HID_SENSOR_IIO_TRIGGER 11 12 tristate "HID Magenetometer 3D" 12 13 help 13 14 Say yes here to build support for the HID SENSOR
+1
drivers/staging/comedi/Kconfig
··· 444 444 445 445 config COMEDI_NI_AT_A2150 446 446 tristate "NI AT-A2150 ISA card support" 447 + select COMEDI_FC 447 448 depends on VIRT_TO_BUS 448 449 ---help--- 449 450 Enable support for National Instruments AT-A2150 cards
+3
drivers/staging/comedi/comedi_fops.c
··· 1549 1549 if (cmd == COMEDI_DEVCONFIG) { 1550 1550 rc = do_devconfig_ioctl(dev, 1551 1551 (struct comedi_devconfig __user *)arg); 1552 + if (rc == 0) 1553 + /* Evade comedi_auto_unconfig(). */ 1554 + dev_file_info->hardware_device = NULL; 1552 1555 goto done; 1553 1556 } 1554 1557
+1 -1
drivers/staging/comedi/drivers/comedi_test.c
··· 345 345 struct waveform_private *devpriv = dev->private; 346 346 347 347 devpriv->timer_running = 0; 348 - del_timer(&devpriv->timer); 348 + del_timer_sync(&devpriv->timer); 349 349 return 0; 350 350 } 351 351
+8 -8
drivers/staging/comedi/drivers/ni_pcimio.c
··· 963 963 .ao_range_table = &range_ni_M_625x_ao, 964 964 .reg_type = ni_reg_625x, 965 965 .ao_unipolar = 0, 966 - .ao_speed = 357, 966 + .ao_speed = 350, 967 967 .num_p0_dio_channels = 8, 968 968 .caldac = {caldac_none}, 969 969 .has_8255 = 0, ··· 982 982 .ao_range_table = &range_ni_M_625x_ao, 983 983 .reg_type = ni_reg_625x, 984 984 .ao_unipolar = 0, 985 - .ao_speed = 357, 985 + .ao_speed = 350, 986 986 .num_p0_dio_channels = 8, 987 987 .caldac = {caldac_none}, 988 988 .has_8255 = 0, ··· 1001 1001 .ao_range_table = &range_ni_M_625x_ao, 1002 1002 .reg_type = ni_reg_625x, 1003 1003 .ao_unipolar = 0, 1004 - .ao_speed = 357, 1004 + .ao_speed = 350, 1005 1005 .num_p0_dio_channels = 8, 1006 1006 .caldac = {caldac_none}, 1007 1007 .has_8255 = 0, ··· 1037 1037 .ao_range_table = &range_ni_M_625x_ao, 1038 1038 .reg_type = ni_reg_625x, 1039 1039 .ao_unipolar = 0, 1040 - .ao_speed = 357, 1040 + .ao_speed = 350, 1041 1041 .num_p0_dio_channels = 32, 1042 1042 .caldac = {caldac_none}, 1043 1043 .has_8255 = 0, ··· 1056 1056 .ao_range_table = &range_ni_M_625x_ao, 1057 1057 .reg_type = ni_reg_625x, 1058 1058 .ao_unipolar = 0, 1059 - .ao_speed = 357, 1059 + .ao_speed = 350, 1060 1060 .num_p0_dio_channels = 32, 1061 1061 .caldac = {caldac_none}, 1062 1062 .has_8255 = 0, ··· 1092 1092 .ao_range_table = &range_ni_M_628x_ao, 1093 1093 .reg_type = ni_reg_628x, 1094 1094 .ao_unipolar = 1, 1095 - .ao_speed = 357, 1095 + .ao_speed = 350, 1096 1096 .num_p0_dio_channels = 8, 1097 1097 .caldac = {caldac_none}, 1098 1098 .has_8255 = 0, ··· 1111 1111 .ao_range_table = &range_ni_M_628x_ao, 1112 1112 .reg_type = ni_reg_628x, 1113 1113 .ao_unipolar = 1, 1114 - .ao_speed = 357, 1114 + .ao_speed = 350, 1115 1115 .num_p0_dio_channels = 8, 1116 1116 .caldac = {caldac_none}, 1117 1117 .has_8255 = 0, ··· 1147 1147 .ao_range_table = &range_ni_M_628x_ao, 1148 1148 .reg_type = ni_reg_628x, 1149 1149 .ao_unipolar = 1, 1150 - .ao_speed = 357, 1150 + .ao_speed = 350, 1151 1151 .num_p0_dio_channels = 32, 1152 1152 .caldac = {caldac_none}, 1153 1153 .has_8255 = 0,
+3 -1
drivers/staging/fwserial/Kconfig
··· 3 3 depends on FIREWIRE 4 4 help 5 5 This enables TTY over IEEE 1394, providing high-speed serial 6 - connectivity to cabled peers. 6 + connectivity to cabled peers. This driver implements a 7 + ad-hoc transport protocol and is currently limited to 8 + Linux-to-Linux communication. 7 9 8 10 To compile this driver as a module, say M here: the module will 9 11 be called firewire-serial.
+3 -11
drivers/staging/fwserial/TODO
··· 1 - TODOs 2 - ----- 1 + TODOs prior to this driver moving out of staging 2 + ------------------------------------------------ 3 3 1. Implement retries for RCODE_BUSY, RCODE_NO_ACK and RCODE_SEND_ERROR 4 4 - I/O is handled asynchronously which presents some issues when error 5 5 conditions occur. ··· 11 11 -- Issues with firewire stack -- 12 12 1. This driver uses the same unregistered vendor id that the firewire core does 13 13 (0xd00d1e). Perhaps this could be exposed as a define in 14 - firewire-constants.h? 15 - 2. MAX_ASYNC_PAYLOAD needs to be publicly exposed by core/ohci 16 - - otherwise how will this driver know the max size of address window to 17 - open for one packet write? 14 + firewire.h? 18 15 3. Maybe device_max_receive() and link_speed_to_max_payload() should be 19 16 taken up by the firewire core? 20 - 4. To avoid dropping rx data while still limiting the maximum buffering, 21 - the size of the AR context must be known. How to expose this to drivers? 22 - 5. Explore if bigger AR context will reduce RCODE_BUSY responses 23 - (or auto-grow to certain max size -- but this would require major surgery 24 - as the current AR is contiguously mapped) 25 17 26 18 -- Issues with TTY core -- 27 19 1. Hack for alternate device name scheme
+1 -1
drivers/staging/fwserial/fwserial.c
··· 179 179 /* Returns the max receive packet size for the given card */ 180 180 static inline int device_max_receive(struct fw_device *fw_device) 181 181 { 182 - return 1 << (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1); 182 + return 1 << (clamp_t(int, fw_device->max_rec, 8U, 11U) + 1); 183 183 } 184 184 185 185 static void fwtty_log_tx_error(struct fwtty_port *port, int rcode)
+3 -3
drivers/staging/fwserial/fwserial.h
··· 374 374 */ 375 375 static inline int link_speed_to_max_payload(unsigned speed) 376 376 { 377 - static const int max_async[] = { 307, 614, 1229, 2458, 4916, 9832, }; 378 - BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_3200); 377 + static const int max_async[] = { 307, 614, 1229, 2458, }; 378 + BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_800); 379 379 380 - speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_3200); 380 + speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_800); 381 381 if (limit_bw) 382 382 return max_async[speed]; 383 383 else
+2 -2
drivers/staging/iio/gyro/Kconfig
··· 27 27 config ADIS16260 28 28 tristate "Analog Devices ADIS16260 Digital Gyroscope Sensor SPI driver" 29 29 depends on SPI 30 - select IIO_TRIGGER if IIO_BUFFER 31 - select IIO_SW_RING if IIO_BUFFER 30 + select IIO_ADIS_LIB 31 + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER 32 32 help 33 33 Say yes here to build support for Analog Devices ADIS16260 ADIS16265 34 34 ADIS16250 ADIS16255 and ADIS16251 programmable digital gyroscope sensors.
-1
drivers/staging/imx-drm/imx-drm-core.c
··· 584 584 585 585 ret = imx_drm_encoder_register(imx_drm_encoder); 586 586 if (ret) { 587 - kfree(imx_drm_encoder); 588 587 ret = -ENOMEM; 589 588 goto err_register; 590 589 }
+4 -1
drivers/staging/imx-drm/ipu-v3/ipu-common.c
··· 1104 1104 if (ret) 1105 1105 goto out_failed_irq; 1106 1106 1107 - ipu_reset(ipu); 1107 + ret = ipu_reset(ipu); 1108 + if (ret) 1109 + goto out_failed_reset; 1108 1110 1109 1111 /* Set MCU_T to divide MCU access window into 2 */ 1110 1112 ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18), ··· 1131 1129 ipu_submodules_exit(ipu); 1132 1130 failed_submodules_init: 1133 1131 ipu_irq_exit(ipu); 1132 + out_failed_reset: 1134 1133 out_failed_irq: 1135 1134 clk_disable_unprepare(ipu->clk); 1136 1135 failed_clk_get:
+4 -2
drivers/staging/imx-drm/ipuv3-crtc.c
··· 452 452 int ret; 453 453 454 454 ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]); 455 - if (IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) { 455 + if (IS_ERR(ipu_crtc->ipu_ch)) { 456 456 ret = PTR_ERR(ipu_crtc->ipu_ch); 457 457 goto err_out; 458 458 } ··· 472 472 if (pdata->dp >= 0) { 473 473 ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp); 474 474 if (IS_ERR(ipu_crtc->dp)) { 475 - ret = PTR_ERR(ipu_crtc->ipu_ch); 475 + ret = PTR_ERR(ipu_crtc->dp); 476 476 goto err_out; 477 477 } 478 478 } ··· 548 548 ipu_crtc->dev = &pdev->dev; 549 549 550 550 ret = ipu_crtc_init(ipu_crtc, pdata); 551 + if (ret) 552 + return ret; 551 553 552 554 platform_set_drvdata(pdev, ipu_crtc); 553 555
+1
drivers/staging/omapdrm/Makefile
··· 5 5 6 6 ccflags-y := -Iinclude/drm -Werror 7 7 omapdrm-y := omap_drv.o \ 8 + omap_irq.o \ 8 9 omap_debugfs.o \ 9 10 omap_crtc.o \ 10 11 omap_plane.o \
-3
drivers/staging/omapdrm/TODO
··· 17 17 . Revisit GEM sync object infrastructure.. TTM has some framework for this 18 18 already. Possibly this could be refactored out and made more common? 19 19 There should be some way to do this with less wheel-reinvention. 20 - . Review DSS vs KMS mismatches. The omap_dss_device is sort of part encoder, 21 - part connector. Which results in a bit of duct tape to fwd calls from 22 - encoder to connector. Possibly this could be done a bit better. 23 20 . Solve PM sequencing on resume. DMM/TILER must be reloaded before any 24 21 access is made from any component in the system. Which means on suspend 25 22 CRTC's should be disabled, and on resume the LUT should be reprogrammed
+10 -101
drivers/staging/omapdrm/omap_connector.c
··· 31 31 struct omap_connector { 32 32 struct drm_connector base; 33 33 struct omap_dss_device *dssdev; 34 + struct drm_encoder *encoder; 34 35 }; 35 36 36 - static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode, 37 + void copy_timings_omap_to_drm(struct drm_display_mode *mode, 37 38 struct omap_video_timings *timings) 38 39 { 39 40 mode->clock = timings->pixel_clock; ··· 65 64 mode->flags |= DRM_MODE_FLAG_NVSYNC; 66 65 } 67 66 68 - static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, 67 + void copy_timings_drm_to_omap(struct omap_video_timings *timings, 69 68 struct drm_display_mode *mode) 70 69 { 71 70 timings->pixel_clock = mode->clock; ··· 97 96 timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; 98 97 } 99 98 100 - static void omap_connector_dpms(struct drm_connector *connector, int mode) 101 - { 102 - struct omap_connector *omap_connector = to_omap_connector(connector); 103 - struct omap_dss_device *dssdev = omap_connector->dssdev; 104 - int old_dpms; 105 - 106 - DBG("%s: %d", dssdev->name, mode); 107 - 108 - old_dpms = connector->dpms; 109 - 110 - /* from off to on, do from crtc to connector */ 111 - if (mode < old_dpms) 112 - drm_helper_connector_dpms(connector, mode); 113 - 114 - if (mode == DRM_MODE_DPMS_ON) { 115 - /* store resume info for suspended displays */ 116 - switch (dssdev->state) { 117 - case OMAP_DSS_DISPLAY_SUSPENDED: 118 - dssdev->activate_after_resume = true; 119 - break; 120 - case OMAP_DSS_DISPLAY_DISABLED: { 121 - int ret = dssdev->driver->enable(dssdev); 122 - if (ret) { 123 - DBG("%s: failed to enable: %d", 124 - dssdev->name, ret); 125 - dssdev->driver->disable(dssdev); 126 - } 127 - break; 128 - } 129 - default: 130 - break; 131 - } 132 - } else { 133 - /* TODO */ 134 - } 135 - 136 - /* from on to off, do from connector to crtc */ 137 - if (mode > old_dpms) 138 - drm_helper_connector_dpms(connector, mode); 139 - } 140 - 141 - enum drm_connector_status omap_connector_detect( 99 + static enum drm_connector_status omap_connector_detect( 142 100 struct drm_connector *connector, bool force) 143 101 { 144 102 struct omap_connector *omap_connector = to_omap_connector(connector); ··· 123 163 { 124 164 struct omap_connector *omap_connector = to_omap_connector(connector); 125 165 struct omap_dss_device *dssdev = omap_connector->dssdev; 126 - 127 - dssdev->driver->disable(dssdev); 128 166 129 167 DBG("%s", omap_connector->dssdev->name); 130 168 drm_sysfs_connector_remove(connector); ··· 219 261 struct drm_encoder *omap_connector_attached_encoder( 220 262 struct drm_connector *connector) 221 263 { 222 - int i; 223 264 struct omap_connector *omap_connector = to_omap_connector(connector); 224 - 225 - for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 226 - struct drm_mode_object *obj; 227 - 228 - if (connector->encoder_ids[i] == 0) 229 - break; 230 - 231 - obj = drm_mode_object_find(connector->dev, 232 - connector->encoder_ids[i], 233 - DRM_MODE_OBJECT_ENCODER); 234 - 235 - if (obj) { 236 - struct drm_encoder *encoder = obj_to_encoder(obj); 237 - struct omap_overlay_manager *mgr = 238 - omap_encoder_get_manager(encoder); 239 - DBG("%s: found %s", omap_connector->dssdev->name, 240 - mgr->name); 241 - return encoder; 242 - } 243 - } 244 - 245 - DBG("%s: no encoder", omap_connector->dssdev->name); 246 - 247 - return NULL; 265 + return omap_connector->encoder; 248 266 } 249 267 250 268 static const struct drm_connector_funcs omap_connector_funcs = { 251 - .dpms = omap_connector_dpms, 269 + .dpms = drm_helper_connector_dpms, 252 270 .detect = omap_connector_detect, 253 271 .fill_modes = drm_helper_probe_single_connector_modes, 254 272 .destroy = omap_connector_destroy, ··· 235 301 .mode_valid = omap_connector_mode_valid, 236 302 .best_encoder = omap_connector_attached_encoder, 237 303 }; 238 - 239 - /* called from encoder when mode is set, to propagate settings to the dssdev */ 240 - void omap_connector_mode_set(struct drm_connector *connector, 241 - struct drm_display_mode *mode) 242 - { 243 - struct drm_device *dev = connector->dev; 244 - struct omap_connector *omap_connector = to_omap_connector(connector); 245 - struct omap_dss_device *dssdev = omap_connector->dssdev; 246 - struct omap_dss_driver *dssdrv = dssdev->driver; 247 - struct omap_video_timings timings = {0}; 248 - 249 - copy_timings_drm_to_omap(&timings, mode); 250 - 251 - DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 252 - omap_connector->dssdev->name, 253 - mode->base.id, mode->name, mode->vrefresh, mode->clock, 254 - mode->hdisplay, mode->hsync_start, 255 - mode->hsync_end, mode->htotal, 256 - mode->vdisplay, mode->vsync_start, 257 - mode->vsync_end, mode->vtotal, mode->type, mode->flags); 258 - 259 - if (dssdrv->check_timings(dssdev, &timings)) { 260 - dev_err(dev->dev, "could not set timings\n"); 261 - return; 262 - } 263 - 264 - dssdrv->set_timings(dssdev, &timings); 265 - } 266 304 267 305 /* flush an area of the framebuffer (in case of manual update display that 268 306 * is not automatically flushed) ··· 250 344 251 345 /* initialize connector */ 252 346 struct drm_connector *omap_connector_init(struct drm_device *dev, 253 - int connector_type, struct omap_dss_device *dssdev) 347 + int connector_type, struct omap_dss_device *dssdev, 348 + struct drm_encoder *encoder) 254 349 { 255 350 struct drm_connector *connector = NULL; 256 351 struct omap_connector *omap_connector; ··· 267 360 } 268 361 269 362 omap_connector->dssdev = dssdev; 363 + omap_connector->encoder = encoder; 364 + 270 365 connector = &omap_connector->base; 271 366 272 367 drm_connector_init(dev, connector, &omap_connector_funcs,
+449 -60
drivers/staging/omapdrm/omap_crtc.c
··· 28 28 struct omap_crtc { 29 29 struct drm_crtc base; 30 30 struct drm_plane *plane; 31 + 31 32 const char *name; 32 - int id; 33 + int pipe; 34 + enum omap_channel channel; 35 + struct omap_overlay_manager_info info; 36 + 37 + /* 38 + * Temporary: eventually this will go away, but it is needed 39 + * for now to keep the output's happy. (They only need 40 + * mgr->id.) Eventually this will be replaced w/ something 41 + * more common-panel-framework-y 42 + */ 43 + struct omap_overlay_manager mgr; 44 + 45 + struct omap_video_timings timings; 46 + bool enabled; 47 + bool full_update; 48 + 49 + struct omap_drm_apply apply; 50 + 51 + struct omap_drm_irq apply_irq; 52 + struct omap_drm_irq error_irq; 53 + 54 + /* list of in-progress apply's: */ 55 + struct list_head pending_applies; 56 + 57 + /* list of queued apply's: */ 58 + struct list_head queued_applies; 59 + 60 + /* for handling queued and in-progress applies: */ 61 + struct work_struct apply_work; 33 62 34 63 /* if there is a pending flip, these will be non-null: */ 35 64 struct drm_pending_vblank_event *event; 36 65 struct drm_framebuffer *old_fb; 66 + 67 + /* for handling page flips without caring about what 68 + * the callback is called from. Possibly we should just 69 + * make omap_gem always call the cb from the worker so 70 + * we don't have to care about this.. 71 + * 72 + * XXX maybe fold into apply_work?? 73 + */ 74 + struct work_struct page_flip_work; 37 75 }; 76 + 77 + /* 78 + * Manager-ops, callbacks from output when they need to configure 79 + * the upstream part of the video pipe. 80 + * 81 + * Most of these we can ignore until we add support for command-mode 82 + * panels.. for video-mode the crtc-helpers already do an adequate 83 + * job of sequencing the setup of the video pipe in the proper order 84 + */ 85 + 86 + /* we can probably ignore these until we support command-mode panels: */ 87 + static void omap_crtc_start_update(struct omap_overlay_manager *mgr) 88 + { 89 + } 90 + 91 + static int omap_crtc_enable(struct omap_overlay_manager *mgr) 92 + { 93 + return 0; 94 + } 95 + 96 + static void omap_crtc_disable(struct omap_overlay_manager *mgr) 97 + { 98 + } 99 + 100 + static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, 101 + const struct omap_video_timings *timings) 102 + { 103 + struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); 104 + DBG("%s", omap_crtc->name); 105 + omap_crtc->timings = *timings; 106 + omap_crtc->full_update = true; 107 + } 108 + 109 + static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr, 110 + const struct dss_lcd_mgr_config *config) 111 + { 112 + struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); 113 + DBG("%s", omap_crtc->name); 114 + dispc_mgr_set_lcd_config(omap_crtc->channel, config); 115 + } 116 + 117 + static int omap_crtc_register_framedone_handler( 118 + struct omap_overlay_manager *mgr, 119 + void (*handler)(void *), void *data) 120 + { 121 + return 0; 122 + } 123 + 124 + static void omap_crtc_unregister_framedone_handler( 125 + struct omap_overlay_manager *mgr, 126 + void (*handler)(void *), void *data) 127 + { 128 + } 129 + 130 + static const struct dss_mgr_ops mgr_ops = { 131 + .start_update = omap_crtc_start_update, 132 + .enable = omap_crtc_enable, 133 + .disable = omap_crtc_disable, 134 + .set_timings = omap_crtc_set_timings, 135 + .set_lcd_config = omap_crtc_set_lcd_config, 136 + .register_framedone_handler = omap_crtc_register_framedone_handler, 137 + .unregister_framedone_handler = omap_crtc_unregister_framedone_handler, 138 + }; 139 + 140 + /* 141 + * CRTC funcs: 142 + */ 38 143 39 144 static void omap_crtc_destroy(struct drm_crtc *crtc) 40 145 { 41 146 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 147 + 148 + DBG("%s", omap_crtc->name); 149 + 150 + WARN_ON(omap_crtc->apply_irq.registered); 151 + omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); 152 + 42 153 omap_crtc->plane->funcs->destroy(omap_crtc->plane); 43 154 drm_crtc_cleanup(crtc); 155 + 44 156 kfree(omap_crtc); 45 157 } 46 158 ··· 160 48 { 161 49 struct omap_drm_private *priv = crtc->dev->dev_private; 162 50 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 51 + bool enabled = (mode == DRM_MODE_DPMS_ON); 163 52 int i; 164 53 165 - WARN_ON(omap_plane_dpms(omap_crtc->plane, mode)); 54 + DBG("%s: %d", omap_crtc->name, mode); 166 55 167 - for (i = 0; i < priv->num_planes; i++) { 168 - struct drm_plane *plane = priv->planes[i]; 169 - if (plane->crtc == crtc) 170 - WARN_ON(omap_plane_dpms(plane, mode)); 56 + if (enabled != omap_crtc->enabled) { 57 + omap_crtc->enabled = enabled; 58 + omap_crtc->full_update = true; 59 + omap_crtc_apply(crtc, &omap_crtc->apply); 60 + 61 + /* also enable our private plane: */ 62 + WARN_ON(omap_plane_dpms(omap_crtc->plane, mode)); 63 + 64 + /* and any attached overlay planes: */ 65 + for (i = 0; i < priv->num_planes; i++) { 66 + struct drm_plane *plane = priv->planes[i]; 67 + if (plane->crtc == crtc) 68 + WARN_ON(omap_plane_dpms(plane, mode)); 69 + } 171 70 } 172 71 } 173 72 ··· 196 73 struct drm_framebuffer *old_fb) 197 74 { 198 75 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 199 - struct drm_plane *plane = omap_crtc->plane; 200 76 201 - return omap_plane_mode_set(plane, crtc, crtc->fb, 77 + mode = adjusted_mode; 78 + 79 + DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 80 + omap_crtc->name, mode->base.id, mode->name, 81 + mode->vrefresh, mode->clock, 82 + mode->hdisplay, mode->hsync_start, 83 + mode->hsync_end, mode->htotal, 84 + mode->vdisplay, mode->vsync_start, 85 + mode->vsync_end, mode->vtotal, 86 + mode->type, mode->flags); 87 + 88 + copy_timings_drm_to_omap(&omap_crtc->timings, mode); 89 + omap_crtc->full_update = true; 90 + 91 + return omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 202 92 0, 0, mode->hdisplay, mode->vdisplay, 203 93 x << 16, y << 16, 204 - mode->hdisplay << 16, mode->vdisplay << 16); 94 + mode->hdisplay << 16, mode->vdisplay << 16, 95 + NULL, NULL); 205 96 } 206 97 207 98 static void omap_crtc_prepare(struct drm_crtc *crtc) ··· 239 102 struct drm_plane *plane = omap_crtc->plane; 240 103 struct drm_display_mode *mode = &crtc->mode; 241 104 242 - return plane->funcs->update_plane(plane, crtc, crtc->fb, 105 + return omap_plane_mode_set(plane, crtc, crtc->fb, 243 106 0, 0, mode->hdisplay, mode->vdisplay, 244 107 x << 16, y << 16, 245 - mode->hdisplay << 16, mode->vdisplay << 16); 108 + mode->hdisplay << 16, mode->vdisplay << 16, 109 + NULL, NULL); 246 110 } 247 111 248 112 static void omap_crtc_load_lut(struct drm_crtc *crtc) ··· 252 114 253 115 static void vblank_cb(void *arg) 254 116 { 255 - static uint32_t sequence; 256 117 struct drm_crtc *crtc = arg; 257 118 struct drm_device *dev = crtc->dev; 258 119 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 259 - struct drm_pending_vblank_event *event = omap_crtc->event; 260 120 unsigned long flags; 261 - struct timeval now; 262 121 263 - WARN_ON(!event); 264 - 265 - omap_crtc->event = NULL; 122 + spin_lock_irqsave(&dev->event_lock, flags); 266 123 267 124 /* wakeup userspace */ 268 - if (event) { 269 - do_gettimeofday(&now); 125 + if (omap_crtc->event) 126 + drm_send_vblank_event(dev, omap_crtc->pipe, omap_crtc->event); 270 127 271 - spin_lock_irqsave(&dev->event_lock, flags); 272 - /* TODO: we can't yet use the vblank time accounting, 273 - * because omapdss lower layer is the one that knows 274 - * the irq # and registers the handler, which more or 275 - * less defeats how drm_irq works.. for now just fake 276 - * the sequence number and use gettimeofday.. 277 - * 278 - event->event.sequence = drm_vblank_count_and_time( 279 - dev, omap_crtc->id, &now); 280 - */ 281 - event->event.sequence = sequence++; 282 - event->event.tv_sec = now.tv_sec; 283 - event->event.tv_usec = now.tv_usec; 284 - list_add_tail(&event->base.link, 285 - &event->base.file_priv->event_list); 286 - wake_up_interruptible(&event->base.file_priv->event_wait); 287 - spin_unlock_irqrestore(&dev->event_lock, flags); 288 - } 128 + omap_crtc->event = NULL; 129 + omap_crtc->old_fb = NULL; 130 + 131 + spin_unlock_irqrestore(&dev->event_lock, flags); 132 + } 133 + 134 + static void page_flip_worker(struct work_struct *work) 135 + { 136 + struct omap_crtc *omap_crtc = 137 + container_of(work, struct omap_crtc, page_flip_work); 138 + struct drm_crtc *crtc = &omap_crtc->base; 139 + struct drm_device *dev = crtc->dev; 140 + struct drm_display_mode *mode = &crtc->mode; 141 + struct drm_gem_object *bo; 142 + 143 + mutex_lock(&dev->mode_config.mutex); 144 + omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 145 + 0, 0, mode->hdisplay, mode->vdisplay, 146 + crtc->x << 16, crtc->y << 16, 147 + mode->hdisplay << 16, mode->vdisplay << 16, 148 + vblank_cb, crtc); 149 + mutex_unlock(&dev->mode_config.mutex); 150 + 151 + bo = omap_framebuffer_bo(crtc->fb, 0); 152 + drm_gem_object_unreference_unlocked(bo); 289 153 } 290 154 291 155 static void page_flip_cb(void *arg) 292 156 { 293 157 struct drm_crtc *crtc = arg; 294 158 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 295 - struct drm_framebuffer *old_fb = omap_crtc->old_fb; 296 - struct drm_gem_object *bo; 159 + struct omap_drm_private *priv = crtc->dev->dev_private; 297 160 298 - omap_crtc->old_fb = NULL; 299 - 300 - omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb); 301 - 302 - /* really we'd like to setup the callback atomically w/ setting the 303 - * new scanout buffer to avoid getting stuck waiting an extra vblank 304 - * cycle.. for now go for correctness and later figure out speed.. 305 - */ 306 - omap_plane_on_endwin(omap_crtc->plane, vblank_cb, crtc); 307 - 308 - bo = omap_framebuffer_bo(crtc->fb, 0); 309 - drm_gem_object_unreference_unlocked(bo); 161 + /* avoid assumptions about what ctxt we are called from: */ 162 + queue_work(priv->wq, &omap_crtc->page_flip_work); 310 163 } 311 164 312 165 static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, ··· 308 179 struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 309 180 struct drm_gem_object *bo; 310 181 311 - DBG("%d -> %d", crtc->fb ? crtc->fb->base.id : -1, fb->base.id); 182 + DBG("%d -> %d (event=%p)", crtc->fb ? crtc->fb->base.id : -1, 183 + fb->base.id, event); 312 184 313 - if (omap_crtc->event) { 185 + if (omap_crtc->old_fb) { 314 186 dev_err(dev->dev, "already a pending flip\n"); 315 187 return -EINVAL; 316 188 } 317 189 318 - omap_crtc->old_fb = crtc->fb; 319 190 omap_crtc->event = event; 320 191 crtc->fb = fb; 321 192 ··· 363 234 .load_lut = omap_crtc_load_lut, 364 235 }; 365 236 237 + const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc) 238 + { 239 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 240 + return &omap_crtc->timings; 241 + } 242 + 243 + enum omap_channel omap_crtc_channel(struct drm_crtc *crtc) 244 + { 245 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 246 + return omap_crtc->channel; 247 + } 248 + 249 + static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 250 + { 251 + struct omap_crtc *omap_crtc = 252 + container_of(irq, struct omap_crtc, error_irq); 253 + struct drm_crtc *crtc = &omap_crtc->base; 254 + DRM_ERROR("%s: errors: %08x\n", omap_crtc->name, irqstatus); 255 + /* avoid getting in a flood, unregister the irq until next vblank */ 256 + omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); 257 + } 258 + 259 + static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 260 + { 261 + struct omap_crtc *omap_crtc = 262 + container_of(irq, struct omap_crtc, apply_irq); 263 + struct drm_crtc *crtc = &omap_crtc->base; 264 + 265 + if (!omap_crtc->error_irq.registered) 266 + omap_irq_register(crtc->dev, &omap_crtc->error_irq); 267 + 268 + if (!dispc_mgr_go_busy(omap_crtc->channel)) { 269 + struct omap_drm_private *priv = 270 + crtc->dev->dev_private; 271 + DBG("%s: apply done", omap_crtc->name); 272 + omap_irq_unregister(crtc->dev, &omap_crtc->apply_irq); 273 + queue_work(priv->wq, &omap_crtc->apply_work); 274 + } 275 + } 276 + 277 + static void apply_worker(struct work_struct *work) 278 + { 279 + struct omap_crtc *omap_crtc = 280 + container_of(work, struct omap_crtc, apply_work); 281 + struct drm_crtc *crtc = &omap_crtc->base; 282 + struct drm_device *dev = crtc->dev; 283 + struct omap_drm_apply *apply, *n; 284 + bool need_apply; 285 + 286 + /* 287 + * Synchronize everything on mode_config.mutex, to keep 288 + * the callbacks and list modification all serialized 289 + * with respect to modesetting ioctls from userspace. 290 + */ 291 + mutex_lock(&dev->mode_config.mutex); 292 + dispc_runtime_get(); 293 + 294 + /* 295 + * If we are still pending a previous update, wait.. when the 296 + * pending update completes, we get kicked again. 297 + */ 298 + if (omap_crtc->apply_irq.registered) 299 + goto out; 300 + 301 + /* finish up previous apply's: */ 302 + list_for_each_entry_safe(apply, n, 303 + &omap_crtc->pending_applies, pending_node) { 304 + apply->post_apply(apply); 305 + list_del(&apply->pending_node); 306 + } 307 + 308 + need_apply = !list_empty(&omap_crtc->queued_applies); 309 + 310 + /* then handle the next round of of queued apply's: */ 311 + list_for_each_entry_safe(apply, n, 312 + &omap_crtc->queued_applies, queued_node) { 313 + apply->pre_apply(apply); 314 + list_del(&apply->queued_node); 315 + apply->queued = false; 316 + list_add_tail(&apply->pending_node, 317 + &omap_crtc->pending_applies); 318 + } 319 + 320 + if (need_apply) { 321 + enum omap_channel channel = omap_crtc->channel; 322 + 323 + DBG("%s: GO", omap_crtc->name); 324 + 325 + if (dispc_mgr_is_enabled(channel)) { 326 + omap_irq_register(dev, &omap_crtc->apply_irq); 327 + dispc_mgr_go(channel); 328 + } else { 329 + struct omap_drm_private *priv = dev->dev_private; 330 + queue_work(priv->wq, &omap_crtc->apply_work); 331 + } 332 + } 333 + 334 + out: 335 + dispc_runtime_put(); 336 + mutex_unlock(&dev->mode_config.mutex); 337 + } 338 + 339 + int omap_crtc_apply(struct drm_crtc *crtc, 340 + struct omap_drm_apply *apply) 341 + { 342 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 343 + struct drm_device *dev = crtc->dev; 344 + 345 + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); 346 + 347 + /* no need to queue it again if it is already queued: */ 348 + if (apply->queued) 349 + return 0; 350 + 351 + apply->queued = true; 352 + list_add_tail(&apply->queued_node, &omap_crtc->queued_applies); 353 + 354 + /* 355 + * If there are no currently pending updates, then go ahead and 356 + * kick the worker immediately, otherwise it will run again when 357 + * the current update finishes. 358 + */ 359 + if (list_empty(&omap_crtc->pending_applies)) { 360 + struct omap_drm_private *priv = crtc->dev->dev_private; 361 + queue_work(priv->wq, &omap_crtc->apply_work); 362 + } 363 + 364 + return 0; 365 + } 366 + 367 + /* called only from apply */ 368 + static void set_enabled(struct drm_crtc *crtc, bool enable) 369 + { 370 + struct drm_device *dev = crtc->dev; 371 + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); 372 + enum omap_channel channel = omap_crtc->channel; 373 + struct omap_irq_wait *wait = NULL; 374 + 375 + if (dispc_mgr_is_enabled(channel) == enable) 376 + return; 377 + 378 + /* ignore sync-lost irqs during enable/disable */ 379 + omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); 380 + 381 + if (dispc_mgr_get_framedone_irq(channel)) { 382 + if (!enable) { 383 + wait = omap_irq_wait_init(dev, 384 + dispc_mgr_get_framedone_irq(channel), 1); 385 + } 386 + } else { 387 + /* 388 + * When we disable digit output, we need to wait until fields 389 + * are done. Otherwise the DSS is still working, and turning 390 + * off the clocks prevents DSS from going to OFF mode. And when 391 + * enabling, we need to wait for the extra sync losts 392 + */ 393 + wait = omap_irq_wait_init(dev, 394 + dispc_mgr_get_vsync_irq(channel), 2); 395 + } 396 + 397 + dispc_mgr_enable(channel, enable); 398 + 399 + if (wait) { 400 + int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); 401 + if (ret) { 402 + dev_err(dev->dev, "%s: timeout waiting for %s\n", 403 + omap_crtc->name, enable ? "enable" : "disable"); 404 + } 405 + } 406 + 407 + omap_irq_register(crtc->dev, &omap_crtc->error_irq); 408 + } 409 + 410 + static void omap_crtc_pre_apply(struct omap_drm_apply *apply) 411 + { 412 + struct omap_crtc *omap_crtc = 413 + container_of(apply, struct omap_crtc, apply); 414 + struct drm_crtc *crtc = &omap_crtc->base; 415 + struct drm_encoder *encoder = NULL; 416 + 417 + DBG("%s: enabled=%d, full=%d", omap_crtc->name, 418 + omap_crtc->enabled, omap_crtc->full_update); 419 + 420 + if (omap_crtc->full_update) { 421 + struct omap_drm_private *priv = crtc->dev->dev_private; 422 + int i; 423 + for (i = 0; i < priv->num_encoders; i++) { 424 + if (priv->encoders[i]->crtc == crtc) { 425 + encoder = priv->encoders[i]; 426 + break; 427 + } 428 + } 429 + } 430 + 431 + if (!omap_crtc->enabled) { 432 + set_enabled(&omap_crtc->base, false); 433 + if (encoder) 434 + omap_encoder_set_enabled(encoder, false); 435 + } else { 436 + if (encoder) { 437 + omap_encoder_set_enabled(encoder, false); 438 + omap_encoder_update(encoder, &omap_crtc->mgr, 439 + &omap_crtc->timings); 440 + omap_encoder_set_enabled(encoder, true); 441 + omap_crtc->full_update = false; 442 + } 443 + 444 + dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info); 445 + dispc_mgr_set_timings(omap_crtc->channel, 446 + &omap_crtc->timings); 447 + set_enabled(&omap_crtc->base, true); 448 + } 449 + 450 + omap_crtc->full_update = false; 451 + } 452 + 453 + static void omap_crtc_post_apply(struct omap_drm_apply *apply) 454 + { 455 + /* nothing needed for post-apply */ 456 + } 457 + 458 + static const char *channel_names[] = { 459 + [OMAP_DSS_CHANNEL_LCD] = "lcd", 460 + [OMAP_DSS_CHANNEL_DIGIT] = "tv", 461 + [OMAP_DSS_CHANNEL_LCD2] = "lcd2", 462 + }; 463 + 366 464 /* initialize crtc */ 367 465 struct drm_crtc *omap_crtc_init(struct drm_device *dev, 368 - struct omap_overlay *ovl, int id) 466 + struct drm_plane *plane, enum omap_channel channel, int id) 369 467 { 370 468 struct drm_crtc *crtc = NULL; 371 - struct omap_crtc *omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); 469 + struct omap_crtc *omap_crtc; 470 + struct omap_overlay_manager_info *info; 372 471 373 - DBG("%s", ovl->name); 472 + DBG("%s", channel_names[channel]); 473 + 474 + omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); 374 475 375 476 if (!omap_crtc) { 376 477 dev_err(dev->dev, "could not allocate CRTC\n"); ··· 609 250 610 251 crtc = &omap_crtc->base; 611 252 612 - omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true); 253 + INIT_WORK(&omap_crtc->page_flip_work, page_flip_worker); 254 + INIT_WORK(&omap_crtc->apply_work, apply_worker); 255 + 256 + INIT_LIST_HEAD(&omap_crtc->pending_applies); 257 + INIT_LIST_HEAD(&omap_crtc->queued_applies); 258 + 259 + omap_crtc->apply.pre_apply = omap_crtc_pre_apply; 260 + omap_crtc->apply.post_apply = omap_crtc_post_apply; 261 + 262 + omap_crtc->apply_irq.irqmask = pipe2vbl(id); 263 + omap_crtc->apply_irq.irq = omap_crtc_apply_irq; 264 + 265 + omap_crtc->error_irq.irqmask = 266 + dispc_mgr_get_sync_lost_irq(channel); 267 + omap_crtc->error_irq.irq = omap_crtc_error_irq; 268 + omap_irq_register(dev, &omap_crtc->error_irq); 269 + 270 + omap_crtc->channel = channel; 271 + omap_crtc->plane = plane; 613 272 omap_crtc->plane->crtc = crtc; 614 - omap_crtc->name = ovl->name; 615 - omap_crtc->id = id; 273 + omap_crtc->name = channel_names[channel]; 274 + omap_crtc->pipe = id; 275 + 276 + /* temporary: */ 277 + omap_crtc->mgr.id = channel; 278 + 279 + dss_install_mgr_ops(&mgr_ops); 280 + 281 + /* TODO: fix hard-coded setup.. add properties! */ 282 + info = &omap_crtc->info; 283 + info->default_color = 0x00000000; 284 + info->trans_key = 0x00000000; 285 + info->trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST; 286 + info->trans_enabled = false; 616 287 617 288 drm_crtc_init(dev, crtc, &omap_crtc_funcs); 618 289 drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);
+92 -375
drivers/staging/omapdrm/omap_drv.c
··· 74 74 } 75 75 } 76 76 77 - #if 0 /* enable when dss2 supports hotplug */ 78 - static int omap_drm_notifier(struct notifier_block *nb, 79 - unsigned long evt, void *arg) 80 - { 81 - switch (evt) { 82 - case OMAP_DSS_SIZE_CHANGE: 83 - case OMAP_DSS_HOTPLUG_CONNECT: 84 - case OMAP_DSS_HOTPLUG_DISCONNECT: { 85 - struct drm_device *dev = drm_device; 86 - DBG("hotplug event: evt=%d, dev=%p", evt, dev); 87 - if (dev) 88 - drm_sysfs_hotplug_event(dev); 89 - 90 - return NOTIFY_OK; 91 - } 92 - default: /* don't care about other events for now */ 93 - return NOTIFY_DONE; 94 - } 95 - } 96 - #endif 97 - 98 - static void dump_video_chains(void) 99 - { 100 - int i; 101 - 102 - DBG("dumping video chains: "); 103 - for (i = 0; i < omap_dss_get_num_overlays(); i++) { 104 - struct omap_overlay *ovl = omap_dss_get_overlay(i); 105 - struct omap_overlay_manager *mgr = ovl->manager; 106 - struct omap_dss_device *dssdev = mgr ? 107 - mgr->get_device(mgr) : NULL; 108 - if (dssdev) { 109 - DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, 110 - dssdev->name); 111 - } else if (mgr) { 112 - DBG("%d: %s -> %s", i, ovl->name, mgr->name); 113 - } else { 114 - DBG("%d: %s", i, ovl->name); 115 - } 116 - } 117 - } 118 - 119 - /* create encoders for each manager */ 120 - static int create_encoder(struct drm_device *dev, 121 - struct omap_overlay_manager *mgr) 122 - { 123 - struct omap_drm_private *priv = dev->dev_private; 124 - struct drm_encoder *encoder = omap_encoder_init(dev, mgr); 125 - 126 - if (!encoder) { 127 - dev_err(dev->dev, "could not create encoder: %s\n", 128 - mgr->name); 129 - return -ENOMEM; 130 - } 131 - 132 - BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); 133 - 134 - priv->encoders[priv->num_encoders++] = encoder; 135 - 136 - return 0; 137 - } 138 - 139 - /* create connectors for each display device */ 140 - static int create_connector(struct drm_device *dev, 141 - struct omap_dss_device *dssdev) 142 - { 143 - struct omap_drm_private *priv = dev->dev_private; 144 - static struct notifier_block *notifier; 145 - struct drm_connector *connector; 146 - int j; 147 - 148 - if (!dssdev->driver) { 149 - dev_warn(dev->dev, "%s has no driver.. skipping it\n", 150 - dssdev->name); 151 - return 0; 152 - } 153 - 154 - if (!(dssdev->driver->get_timings || 155 - dssdev->driver->read_edid)) { 156 - dev_warn(dev->dev, "%s driver does not support " 157 - "get_timings or read_edid.. skipping it!\n", 158 - dssdev->name); 159 - return 0; 160 - } 161 - 162 - connector = omap_connector_init(dev, 163 - get_connector_type(dssdev), dssdev); 164 - 165 - if (!connector) { 166 - dev_err(dev->dev, "could not create connector: %s\n", 167 - dssdev->name); 168 - return -ENOMEM; 169 - } 170 - 171 - BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); 172 - 173 - priv->connectors[priv->num_connectors++] = connector; 174 - 175 - #if 0 /* enable when dss2 supports hotplug */ 176 - notifier = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); 177 - notifier->notifier_call = omap_drm_notifier; 178 - omap_dss_add_notify(dssdev, notifier); 179 - #else 180 - notifier = NULL; 181 - #endif 182 - 183 - for (j = 0; j < priv->num_encoders; j++) { 184 - struct omap_overlay_manager *mgr = 185 - omap_encoder_get_manager(priv->encoders[j]); 186 - if (mgr->get_device(mgr) == dssdev) { 187 - drm_mode_connector_attach_encoder(connector, 188 - priv->encoders[j]); 189 - } 190 - } 191 - 192 - return 0; 193 - } 194 - 195 - /* create up to max_overlays CRTCs mapping to overlays.. by default, 196 - * connect the overlays to different managers/encoders, giving priority 197 - * to encoders connected to connectors with a detected connection 198 - */ 199 - static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, 200 - int *j, unsigned int connected_connectors) 201 - { 202 - struct omap_drm_private *priv = dev->dev_private; 203 - struct omap_overlay_manager *mgr = NULL; 204 - struct drm_crtc *crtc; 205 - 206 - /* find next best connector, ones with detected connection first 207 - */ 208 - while (*j < priv->num_connectors && !mgr) { 209 - if (connected_connectors & (1 << *j)) { 210 - struct drm_encoder *encoder = 211 - omap_connector_attached_encoder( 212 - priv->connectors[*j]); 213 - if (encoder) 214 - mgr = omap_encoder_get_manager(encoder); 215 - 216 - } 217 - (*j)++; 218 - } 219 - 220 - /* if we couldn't find another connected connector, lets start 221 - * looking at the unconnected connectors: 222 - * 223 - * note: it might not be immediately apparent, but thanks to 224 - * the !mgr check in both this loop and the one above, the only 225 - * way to enter this loop is with *j == priv->num_connectors, 226 - * so idx can never go negative. 227 - */ 228 - while (*j < 2 * priv->num_connectors && !mgr) { 229 - int idx = *j - priv->num_connectors; 230 - if (!(connected_connectors & (1 << idx))) { 231 - struct drm_encoder *encoder = 232 - omap_connector_attached_encoder( 233 - priv->connectors[idx]); 234 - if (encoder) 235 - mgr = omap_encoder_get_manager(encoder); 236 - 237 - } 238 - (*j)++; 239 - } 240 - 241 - crtc = omap_crtc_init(dev, ovl, priv->num_crtcs); 242 - 243 - if (!crtc) { 244 - dev_err(dev->dev, "could not create CRTC: %s\n", 245 - ovl->name); 246 - return -ENOMEM; 247 - } 248 - 249 - BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 250 - 251 - priv->crtcs[priv->num_crtcs++] = crtc; 252 - 253 - return 0; 254 - } 255 - 256 - static int create_plane(struct drm_device *dev, struct omap_overlay *ovl, 257 - unsigned int possible_crtcs) 258 - { 259 - struct omap_drm_private *priv = dev->dev_private; 260 - struct drm_plane *plane = 261 - omap_plane_init(dev, ovl, possible_crtcs, false); 262 - 263 - if (!plane) { 264 - dev_err(dev->dev, "could not create plane: %s\n", 265 - ovl->name); 266 - return -ENOMEM; 267 - } 268 - 269 - BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); 270 - 271 - priv->planes[priv->num_planes++] = plane; 272 - 273 - return 0; 274 - } 275 - 276 - static int match_dev_name(struct omap_dss_device *dssdev, void *data) 277 - { 278 - return !strcmp(dssdev->name, data); 279 - } 280 - 281 - static unsigned int detect_connectors(struct drm_device *dev) 282 - { 283 - struct omap_drm_private *priv = dev->dev_private; 284 - unsigned int connected_connectors = 0; 285 - int i; 286 - 287 - for (i = 0; i < priv->num_connectors; i++) { 288 - struct drm_connector *connector = priv->connectors[i]; 289 - if (omap_connector_detect(connector, true) == 290 - connector_status_connected) { 291 - connected_connectors |= (1 << i); 292 - } 293 - } 294 - 295 - return connected_connectors; 296 - } 297 - 298 77 static int omap_modeset_init(struct drm_device *dev) 299 78 { 300 - const struct omap_drm_platform_data *pdata = dev->dev->platform_data; 301 - struct omap_kms_platform_data *kms_pdata = NULL; 302 79 struct omap_drm_private *priv = dev->dev_private; 303 80 struct omap_dss_device *dssdev = NULL; 304 - int i, j; 305 - unsigned int connected_connectors = 0; 81 + int num_ovls = dss_feat_get_num_ovls(); 82 + int id; 306 83 307 84 drm_mode_config_init(dev); 308 85 309 - if (pdata && pdata->kms_pdata) { 310 - kms_pdata = pdata->kms_pdata; 86 + omap_drm_irq_install(dev); 311 87 312 - /* if platform data is provided by the board file, use it to 313 - * control which overlays, managers, and devices we own. 314 - */ 315 - for (i = 0; i < kms_pdata->mgr_cnt; i++) { 316 - struct omap_overlay_manager *mgr = 317 - omap_dss_get_overlay_manager( 318 - kms_pdata->mgr_ids[i]); 319 - create_encoder(dev, mgr); 320 - } 88 + /* 89 + * Create private planes and CRTCs for the last NUM_CRTCs overlay 90 + * plus manager: 91 + */ 92 + for (id = 0; id < min(num_crtc, num_ovls); id++) { 93 + struct drm_plane *plane; 94 + struct drm_crtc *crtc; 321 95 322 - for (i = 0; i < kms_pdata->dev_cnt; i++) { 323 - struct omap_dss_device *dssdev = 324 - omap_dss_find_device( 325 - (void *)kms_pdata->dev_names[i], 326 - match_dev_name); 327 - if (!dssdev) { 328 - dev_warn(dev->dev, "no such dssdev: %s\n", 329 - kms_pdata->dev_names[i]); 330 - continue; 331 - } 332 - create_connector(dev, dssdev); 333 - } 96 + plane = omap_plane_init(dev, id, true); 97 + crtc = omap_crtc_init(dev, plane, pipe2chan(id), id); 334 98 335 - connected_connectors = detect_connectors(dev); 99 + BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 100 + priv->crtcs[id] = crtc; 101 + priv->num_crtcs++; 336 102 337 - j = 0; 338 - for (i = 0; i < kms_pdata->ovl_cnt; i++) { 339 - struct omap_overlay *ovl = 340 - omap_dss_get_overlay(kms_pdata->ovl_ids[i]); 341 - create_crtc(dev, ovl, &j, connected_connectors); 342 - } 343 - 344 - for (i = 0; i < kms_pdata->pln_cnt; i++) { 345 - struct omap_overlay *ovl = 346 - omap_dss_get_overlay(kms_pdata->pln_ids[i]); 347 - create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); 348 - } 349 - } else { 350 - /* otherwise just grab up to CONFIG_DRM_OMAP_NUM_CRTCS and try 351 - * to make educated guesses about everything else 352 - */ 353 - int max_overlays = min(omap_dss_get_num_overlays(), num_crtc); 354 - 355 - for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) 356 - create_encoder(dev, omap_dss_get_overlay_manager(i)); 357 - 358 - for_each_dss_dev(dssdev) { 359 - create_connector(dev, dssdev); 360 - } 361 - 362 - connected_connectors = detect_connectors(dev); 363 - 364 - j = 0; 365 - for (i = 0; i < max_overlays; i++) { 366 - create_crtc(dev, omap_dss_get_overlay(i), 367 - &j, connected_connectors); 368 - } 369 - 370 - /* use any remaining overlays as drm planes */ 371 - for (; i < omap_dss_get_num_overlays(); i++) { 372 - struct omap_overlay *ovl = omap_dss_get_overlay(i); 373 - create_plane(dev, ovl, (1 << priv->num_crtcs) - 1); 374 - } 103 + priv->planes[id] = plane; 104 + priv->num_planes++; 375 105 } 376 106 377 - /* for now keep the mapping of CRTCs and encoders static.. */ 378 - for (i = 0; i < priv->num_encoders; i++) { 379 - struct drm_encoder *encoder = priv->encoders[i]; 380 - struct omap_overlay_manager *mgr = 381 - omap_encoder_get_manager(encoder); 107 + /* 108 + * Create normal planes for the remaining overlays: 109 + */ 110 + for (; id < num_ovls; id++) { 111 + struct drm_plane *plane = omap_plane_init(dev, id, false); 382 112 383 - encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; 384 - 385 - DBG("%s: possible_crtcs=%08x", mgr->name, 386 - encoder->possible_crtcs); 113 + BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes)); 114 + priv->planes[priv->num_planes++] = plane; 387 115 } 388 116 389 - dump_video_chains(); 117 + for_each_dss_dev(dssdev) { 118 + struct drm_connector *connector; 119 + struct drm_encoder *encoder; 120 + 121 + if (!dssdev->driver) { 122 + dev_warn(dev->dev, "%s has no driver.. skipping it\n", 123 + dssdev->name); 124 + return 0; 125 + } 126 + 127 + if (!(dssdev->driver->get_timings || 128 + dssdev->driver->read_edid)) { 129 + dev_warn(dev->dev, "%s driver does not support " 130 + "get_timings or read_edid.. skipping it!\n", 131 + dssdev->name); 132 + return 0; 133 + } 134 + 135 + encoder = omap_encoder_init(dev, dssdev); 136 + 137 + if (!encoder) { 138 + dev_err(dev->dev, "could not create encoder: %s\n", 139 + dssdev->name); 140 + return -ENOMEM; 141 + } 142 + 143 + connector = omap_connector_init(dev, 144 + get_connector_type(dssdev), dssdev, encoder); 145 + 146 + if (!connector) { 147 + dev_err(dev->dev, "could not create connector: %s\n", 148 + dssdev->name); 149 + return -ENOMEM; 150 + } 151 + 152 + BUG_ON(priv->num_encoders >= ARRAY_SIZE(priv->encoders)); 153 + BUG_ON(priv->num_connectors >= ARRAY_SIZE(priv->connectors)); 154 + 155 + priv->encoders[priv->num_encoders++] = encoder; 156 + priv->connectors[priv->num_connectors++] = connector; 157 + 158 + drm_mode_connector_attach_encoder(connector, encoder); 159 + 160 + /* figure out which crtc's we can connect the encoder to: */ 161 + encoder->possible_crtcs = 0; 162 + for (id = 0; id < priv->num_crtcs; id++) { 163 + enum omap_dss_output_id supported_outputs = 164 + dss_feat_get_supported_outputs(pipe2chan(id)); 165 + if (supported_outputs & dssdev->output->id) 166 + encoder->possible_crtcs |= (1 << id); 167 + } 168 + } 390 169 391 170 dev->mode_config.min_width = 32; 392 171 dev->mode_config.min_height = 32; ··· 229 450 struct drm_file *file_priv) 230 451 { 231 452 struct drm_omap_gem_new *args = data; 232 - DBG("%p:%p: size=0x%08x, flags=%08x", dev, file_priv, 453 + VERB("%p:%p: size=0x%08x, flags=%08x", dev, file_priv, 233 454 args->size.bytes, args->flags); 234 455 return omap_gem_new_handle(dev, file_priv, args->size, 235 456 args->flags, &args->handle); ··· 289 510 struct drm_gem_object *obj; 290 511 int ret = 0; 291 512 292 - DBG("%p:%p: handle=%d", dev, file_priv, args->handle); 513 + VERB("%p:%p: handle=%d", dev, file_priv, args->handle); 293 514 294 515 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 295 516 if (!obj) ··· 344 565 345 566 dev->dev_private = priv; 346 567 347 - ret = omapdss_compat_init(); 348 - if (ret) { 349 - dev_err(dev->dev, "coult not init omapdss\n"); 350 - dev->dev_private = NULL; 351 - kfree(priv); 352 - return ret; 353 - } 354 - 355 568 priv->wq = alloc_ordered_workqueue("omapdrm", 0); 356 569 357 570 INIT_LIST_HEAD(&priv->obj_list); ··· 355 584 dev_err(dev->dev, "omap_modeset_init failed: ret=%d\n", ret); 356 585 dev->dev_private = NULL; 357 586 kfree(priv); 358 - omapdss_compat_uninit(); 359 587 return ret; 360 588 } 589 + 590 + ret = drm_vblank_init(dev, priv->num_crtcs); 591 + if (ret) 592 + dev_warn(dev->dev, "could not init vblank\n"); 361 593 362 594 priv->fbdev = omap_fbdev_init(dev); 363 595 if (!priv->fbdev) { ··· 369 595 } 370 596 371 597 drm_kms_helper_poll_init(dev); 372 - 373 - ret = drm_vblank_init(dev, priv->num_crtcs); 374 - if (ret) 375 - dev_warn(dev->dev, "could not init vblank\n"); 376 598 377 599 return 0; 378 600 } ··· 379 609 380 610 DBG("unload: dev=%p", dev); 381 611 382 - drm_vblank_cleanup(dev); 383 612 drm_kms_helper_poll_fini(dev); 613 + drm_vblank_cleanup(dev); 614 + omap_drm_irq_uninstall(dev); 384 615 385 616 omap_fbdev_free(dev); 386 617 omap_modeset_free(dev); ··· 389 618 390 619 flush_workqueue(priv->wq); 391 620 destroy_workqueue(priv->wq); 392 - 393 - omapdss_compat_uninit(); 394 621 395 622 kfree(dev->dev_private); 396 623 dev->dev_private = NULL; ··· 449 680 } 450 681 } 451 682 683 + mutex_lock(&dev->mode_config.mutex); 452 684 ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); 685 + mutex_unlock(&dev->mode_config.mutex); 453 686 if (ret) 454 687 DBG("failed to restore crtc mode"); 455 688 } ··· 464 693 static void dev_postclose(struct drm_device *dev, struct drm_file *file) 465 694 { 466 695 DBG("postclose: dev=%p, file=%p", dev, file); 467 - } 468 - 469 - /** 470 - * enable_vblank - enable vblank interrupt events 471 - * @dev: DRM device 472 - * @crtc: which irq to enable 473 - * 474 - * Enable vblank interrupts for @crtc. If the device doesn't have 475 - * a hardware vblank counter, this routine should be a no-op, since 476 - * interrupts will have to stay on to keep the count accurate. 477 - * 478 - * RETURNS 479 - * Zero on success, appropriate errno if the given @crtc's vblank 480 - * interrupt cannot be enabled. 481 - */ 482 - static int dev_enable_vblank(struct drm_device *dev, int crtc) 483 - { 484 - DBG("enable_vblank: dev=%p, crtc=%d", dev, crtc); 485 - return 0; 486 - } 487 - 488 - /** 489 - * disable_vblank - disable vblank interrupt events 490 - * @dev: DRM device 491 - * @crtc: which irq to enable 492 - * 493 - * Disable vblank interrupts for @crtc. If the device doesn't have 494 - * a hardware vblank counter, this routine should be a no-op, since 495 - * interrupts will have to stay on to keep the count accurate. 496 - */ 497 - static void dev_disable_vblank(struct drm_device *dev, int crtc) 498 - { 499 - DBG("disable_vblank: dev=%p, crtc=%d", dev, crtc); 500 - } 501 - 502 - static irqreturn_t dev_irq_handler(DRM_IRQ_ARGS) 503 - { 504 - return IRQ_HANDLED; 505 - } 506 - 507 - static void dev_irq_preinstall(struct drm_device *dev) 508 - { 509 - DBG("irq_preinstall: dev=%p", dev); 510 - } 511 - 512 - static int dev_irq_postinstall(struct drm_device *dev) 513 - { 514 - DBG("irq_postinstall: dev=%p", dev); 515 - return 0; 516 - } 517 - 518 - static void dev_irq_uninstall(struct drm_device *dev) 519 - { 520 - DBG("irq_uninstall: dev=%p", dev); 521 696 } 522 697 523 698 static const struct vm_operations_struct omap_gem_vm_ops = { ··· 495 778 .preclose = dev_preclose, 496 779 .postclose = dev_postclose, 497 780 .get_vblank_counter = drm_vblank_count, 498 - .enable_vblank = dev_enable_vblank, 499 - .disable_vblank = dev_disable_vblank, 500 - .irq_preinstall = dev_irq_preinstall, 501 - .irq_postinstall = dev_irq_postinstall, 502 - .irq_uninstall = dev_irq_uninstall, 503 - .irq_handler = dev_irq_handler, 781 + .enable_vblank = omap_irq_enable_vblank, 782 + .disable_vblank = omap_irq_disable_vblank, 783 + .irq_preinstall = omap_irq_preinstall, 784 + .irq_postinstall = omap_irq_postinstall, 785 + .irq_uninstall = omap_irq_uninstall, 786 + .irq_handler = omap_irq_handler, 504 787 #ifdef CONFIG_DEBUG_FS 505 788 .debugfs_init = omap_debugfs_init, 506 789 .debugfs_cleanup = omap_debugfs_cleanup,
+117 -23
drivers/staging/omapdrm/omap_drv.h
··· 28 28 #include <linux/platform_data/omap_drm.h> 29 29 #include "omap_drm.h" 30 30 31 + 31 32 #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 32 33 #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt, ##__VA_ARGS__) /* verbose debug */ 33 34 ··· 39 38 * data.. 40 39 */ 41 40 #define MAX_MAPPERS 2 41 + 42 + /* parameters which describe (unrotated) coordinates of scanout within a fb: */ 43 + struct omap_drm_window { 44 + uint32_t rotation; 45 + int32_t crtc_x, crtc_y; /* signed because can be offscreen */ 46 + uint32_t crtc_w, crtc_h; 47 + uint32_t src_x, src_y; 48 + uint32_t src_w, src_h; 49 + }; 50 + 51 + /* Once GO bit is set, we can't make further updates to shadowed registers 52 + * until the GO bit is cleared. So various parts in the kms code that need 53 + * to update shadowed registers queue up a pair of callbacks, pre_apply 54 + * which is called before setting GO bit, and post_apply that is called 55 + * after GO bit is cleared. The crtc manages the queuing, and everyone 56 + * else goes thru omap_crtc_apply() using these callbacks so that the 57 + * code which has to deal w/ GO bit state is centralized. 58 + */ 59 + struct omap_drm_apply { 60 + struct list_head pending_node, queued_node; 61 + bool queued; 62 + void (*pre_apply)(struct omap_drm_apply *apply); 63 + void (*post_apply)(struct omap_drm_apply *apply); 64 + }; 65 + 66 + /* For transiently registering for different DSS irqs that various parts 67 + * of the KMS code need during setup/configuration. We these are not 68 + * necessarily the same as what drm_vblank_get/put() are requesting, and 69 + * the hysteresis in drm_vblank_put() is not necessarily desirable for 70 + * internal housekeeping related irq usage. 71 + */ 72 + struct omap_drm_irq { 73 + struct list_head node; 74 + uint32_t irqmask; 75 + bool registered; 76 + void (*irq)(struct omap_drm_irq *irq, uint32_t irqstatus); 77 + }; 78 + 79 + /* For KMS code that needs to wait for a certain # of IRQs: 80 + */ 81 + struct omap_irq_wait; 82 + struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev, 83 + uint32_t irqmask, int count); 84 + int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, 85 + unsigned long timeout); 42 86 43 87 struct omap_drm_private { 44 88 uint32_t omaprev; ··· 104 58 105 59 struct workqueue_struct *wq; 106 60 61 + /* list of GEM objects: */ 107 62 struct list_head obj_list; 108 63 109 64 bool has_dmm; ··· 112 65 /* properties: */ 113 66 struct drm_property *rotation_prop; 114 67 struct drm_property *zorder_prop; 68 + 69 + /* irq handling: */ 70 + struct list_head irq_list; /* list of omap_drm_irq */ 71 + uint32_t vblank_mask; /* irq bits set for userspace vblank */ 72 + struct omap_drm_irq error_handler; 115 73 }; 116 74 117 75 /* this should probably be in drm-core to standardize amongst drivers */ ··· 127 75 #define DRM_REFLECT_X 4 128 76 #define DRM_REFLECT_Y 5 129 77 130 - /* parameters which describe (unrotated) coordinates of scanout within a fb: */ 131 - struct omap_drm_window { 132 - uint32_t rotation; 133 - int32_t crtc_x, crtc_y; /* signed because can be offscreen */ 134 - uint32_t crtc_w, crtc_h; 135 - uint32_t src_x, src_y; 136 - uint32_t src_w, src_h; 137 - }; 138 - 139 78 #ifdef CONFIG_DEBUG_FS 140 79 int omap_debugfs_init(struct drm_minor *minor); 141 80 void omap_debugfs_cleanup(struct drm_minor *minor); ··· 135 92 void omap_gem_describe_objects(struct list_head *list, struct seq_file *m); 136 93 #endif 137 94 95 + int omap_irq_enable_vblank(struct drm_device *dev, int crtc); 96 + void omap_irq_disable_vblank(struct drm_device *dev, int crtc); 97 + irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); 98 + void omap_irq_preinstall(struct drm_device *dev); 99 + int omap_irq_postinstall(struct drm_device *dev); 100 + void omap_irq_uninstall(struct drm_device *dev); 101 + void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq); 102 + void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq); 103 + int omap_drm_irq_uninstall(struct drm_device *dev); 104 + int omap_drm_irq_install(struct drm_device *dev); 105 + 138 106 struct drm_fb_helper *omap_fbdev_init(struct drm_device *dev); 139 107 void omap_fbdev_free(struct drm_device *dev); 140 108 109 + const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc); 110 + enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); 111 + int omap_crtc_apply(struct drm_crtc *crtc, 112 + struct omap_drm_apply *apply); 141 113 struct drm_crtc *omap_crtc_init(struct drm_device *dev, 142 - struct omap_overlay *ovl, int id); 114 + struct drm_plane *plane, enum omap_channel channel, int id); 143 115 144 116 struct drm_plane *omap_plane_init(struct drm_device *dev, 145 - struct omap_overlay *ovl, unsigned int possible_crtcs, 146 - bool priv); 117 + int plane_id, bool private_plane); 147 118 int omap_plane_dpms(struct drm_plane *plane, int mode); 148 119 int omap_plane_mode_set(struct drm_plane *plane, 149 120 struct drm_crtc *crtc, struct drm_framebuffer *fb, 150 121 int crtc_x, int crtc_y, 151 122 unsigned int crtc_w, unsigned int crtc_h, 152 123 uint32_t src_x, uint32_t src_y, 153 - uint32_t src_w, uint32_t src_h); 154 - void omap_plane_on_endwin(struct drm_plane *plane, 124 + uint32_t src_w, uint32_t src_h, 155 125 void (*fxn)(void *), void *arg); 156 126 void omap_plane_install_properties(struct drm_plane *plane, 157 127 struct drm_mode_object *obj); ··· 172 116 struct drm_property *property, uint64_t val); 173 117 174 118 struct drm_encoder *omap_encoder_init(struct drm_device *dev, 175 - struct omap_overlay_manager *mgr); 176 - struct omap_overlay_manager *omap_encoder_get_manager( 119 + struct omap_dss_device *dssdev); 120 + int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled); 121 + int omap_encoder_update(struct drm_encoder *encoder, 122 + struct omap_overlay_manager *mgr, 123 + struct omap_video_timings *timings); 124 + 125 + struct drm_connector *omap_connector_init(struct drm_device *dev, 126 + int connector_type, struct omap_dss_device *dssdev, 177 127 struct drm_encoder *encoder); 178 128 struct drm_encoder *omap_connector_attached_encoder( 179 129 struct drm_connector *connector); 180 - enum drm_connector_status omap_connector_detect( 181 - struct drm_connector *connector, bool force); 182 - 183 - struct drm_connector *omap_connector_init(struct drm_device *dev, 184 - int connector_type, struct omap_dss_device *dssdev); 185 - void omap_connector_mode_set(struct drm_connector *connector, 186 - struct drm_display_mode *mode); 187 130 void omap_connector_flush(struct drm_connector *connector, 188 131 int x, int y, int w, int h); 132 + 133 + void copy_timings_omap_to_drm(struct drm_display_mode *mode, 134 + struct omap_video_timings *timings); 135 + void copy_timings_drm_to_omap(struct omap_video_timings *timings, 136 + struct drm_display_mode *mode); 189 137 190 138 uint32_t omap_framebuffer_get_formats(uint32_t *pixel_formats, 191 139 uint32_t max_formats, enum omap_color_mode supported_modes); ··· 265 205 * restrictive stride requirement.. 266 206 */ 267 207 return ALIGN(pitch, 8 * bytespp); 208 + } 209 + 210 + static inline enum omap_channel pipe2chan(int pipe) 211 + { 212 + int num_mgrs = dss_feat_get_num_mgrs(); 213 + 214 + /* 215 + * We usually don't want to create a CRTC for each manager, 216 + * at least not until we have a way to expose private planes 217 + * to userspace. Otherwise there would not be enough video 218 + * pipes left for drm planes. The higher #'d managers tend 219 + * to have more features so start in reverse order. 220 + */ 221 + return num_mgrs - pipe - 1; 222 + } 223 + 224 + /* map crtc to vblank mask */ 225 + static inline uint32_t pipe2vbl(int crtc) 226 + { 227 + enum omap_channel channel = pipe2chan(crtc); 228 + return dispc_mgr_get_vsync_irq(channel); 229 + } 230 + 231 + static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc) 232 + { 233 + struct omap_drm_private *priv = dev->dev_private; 234 + int i; 235 + 236 + for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++) 237 + if (priv->crtcs[i] == crtc) 238 + return i; 239 + 240 + BUG(); /* bogus CRTC ptr */ 241 + return -1; 268 242 } 269 243 270 244 /* should these be made into common util helpers?
+66 -66
drivers/staging/omapdrm/omap_encoder.c
··· 22 22 #include "drm_crtc.h" 23 23 #include "drm_crtc_helper.h" 24 24 25 + #include <linux/list.h> 26 + 27 + 25 28 /* 26 29 * encoder funcs 27 30 */ 28 31 29 32 #define to_omap_encoder(x) container_of(x, struct omap_encoder, base) 30 33 34 + /* The encoder and connector both map to same dssdev.. the encoder 35 + * handles the 'active' parts, ie. anything the modifies the state 36 + * of the hw, and the connector handles the 'read-only' parts, like 37 + * detecting connection and reading edid. 38 + */ 31 39 struct omap_encoder { 32 40 struct drm_encoder base; 33 - struct omap_overlay_manager *mgr; 41 + struct omap_dss_device *dssdev; 34 42 }; 35 43 36 44 static void omap_encoder_destroy(struct drm_encoder *encoder) 37 45 { 38 46 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 39 - DBG("%s", omap_encoder->mgr->name); 40 47 drm_encoder_cleanup(encoder); 41 48 kfree(omap_encoder); 42 49 } 43 50 51 + static const struct drm_encoder_funcs omap_encoder_funcs = { 52 + .destroy = omap_encoder_destroy, 53 + }; 54 + 55 + /* 56 + * The CRTC drm_crtc_helper_set_mode() doesn't really give us the right 57 + * order.. the easiest way to work around this for now is to make all 58 + * the encoder-helper's no-op's and have the omap_crtc code take care 59 + * of the sequencing and call us in the right points. 60 + * 61 + * Eventually to handle connecting CRTCs to different encoders properly, 62 + * either the CRTC helpers need to change or we need to replace 63 + * drm_crtc_helper_set_mode(), but lets wait until atomic-modeset for 64 + * that. 65 + */ 66 + 44 67 static void omap_encoder_dpms(struct drm_encoder *encoder, int mode) 45 68 { 46 - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 47 - DBG("%s: %d", omap_encoder->mgr->name, mode); 48 69 } 49 70 50 71 static bool omap_encoder_mode_fixup(struct drm_encoder *encoder, 51 72 const struct drm_display_mode *mode, 52 73 struct drm_display_mode *adjusted_mode) 53 74 { 54 - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 55 - DBG("%s", omap_encoder->mgr->name); 56 75 return true; 57 76 } 58 77 ··· 79 60 struct drm_display_mode *mode, 80 61 struct drm_display_mode *adjusted_mode) 81 62 { 82 - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 83 - struct drm_device *dev = encoder->dev; 84 - struct omap_drm_private *priv = dev->dev_private; 85 - int i; 86 - 87 - mode = adjusted_mode; 88 - 89 - DBG("%s: set mode: %dx%d", omap_encoder->mgr->name, 90 - mode->hdisplay, mode->vdisplay); 91 - 92 - for (i = 0; i < priv->num_connectors; i++) { 93 - struct drm_connector *connector = priv->connectors[i]; 94 - if (connector->encoder == encoder) 95 - omap_connector_mode_set(connector, mode); 96 - 97 - } 98 63 } 99 64 100 65 static void omap_encoder_prepare(struct drm_encoder *encoder) 101 66 { 102 - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 103 - struct drm_encoder_helper_funcs *encoder_funcs = 104 - encoder->helper_private; 105 - DBG("%s", omap_encoder->mgr->name); 106 - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); 107 67 } 108 68 109 69 static void omap_encoder_commit(struct drm_encoder *encoder) 110 70 { 111 - struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 112 - struct drm_encoder_helper_funcs *encoder_funcs = 113 - encoder->helper_private; 114 - DBG("%s", omap_encoder->mgr->name); 115 - omap_encoder->mgr->apply(omap_encoder->mgr); 116 - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); 117 71 } 118 - 119 - static const struct drm_encoder_funcs omap_encoder_funcs = { 120 - .destroy = omap_encoder_destroy, 121 - }; 122 72 123 73 static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = { 124 74 .dpms = omap_encoder_dpms, ··· 97 109 .commit = omap_encoder_commit, 98 110 }; 99 111 100 - struct omap_overlay_manager *omap_encoder_get_manager( 101 - struct drm_encoder *encoder) 112 + /* 113 + * Instead of relying on the helpers for modeset, the omap_crtc code 114 + * calls these functions in the proper sequence. 115 + */ 116 + 117 + int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled) 102 118 { 103 119 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 104 - return omap_encoder->mgr; 120 + struct omap_dss_device *dssdev = omap_encoder->dssdev; 121 + struct omap_dss_driver *dssdrv = dssdev->driver; 122 + 123 + if (enabled) { 124 + return dssdrv->enable(dssdev); 125 + } else { 126 + dssdrv->disable(dssdev); 127 + return 0; 128 + } 129 + } 130 + 131 + int omap_encoder_update(struct drm_encoder *encoder, 132 + struct omap_overlay_manager *mgr, 133 + struct omap_video_timings *timings) 134 + { 135 + struct drm_device *dev = encoder->dev; 136 + struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 137 + struct omap_dss_device *dssdev = omap_encoder->dssdev; 138 + struct omap_dss_driver *dssdrv = dssdev->driver; 139 + int ret; 140 + 141 + dssdev->output->manager = mgr; 142 + 143 + ret = dssdrv->check_timings(dssdev, timings); 144 + if (ret) { 145 + dev_err(dev->dev, "could not set timings: %d\n", ret); 146 + return ret; 147 + } 148 + 149 + dssdrv->set_timings(dssdev, timings); 150 + 151 + return 0; 105 152 } 106 153 107 154 /* initialize encoder */ 108 155 struct drm_encoder *omap_encoder_init(struct drm_device *dev, 109 - struct omap_overlay_manager *mgr) 156 + struct omap_dss_device *dssdev) 110 157 { 111 158 struct drm_encoder *encoder = NULL; 112 159 struct omap_encoder *omap_encoder; 113 - struct omap_overlay_manager_info info; 114 - int ret; 115 - 116 - DBG("%s", mgr->name); 117 160 118 161 omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL); 119 162 if (!omap_encoder) { ··· 152 133 goto fail; 153 134 } 154 135 155 - omap_encoder->mgr = mgr; 136 + omap_encoder->dssdev = dssdev; 137 + 156 138 encoder = &omap_encoder->base; 157 139 158 140 drm_encoder_init(dev, encoder, &omap_encoder_funcs, 159 141 DRM_MODE_ENCODER_TMDS); 160 142 drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs); 161 - 162 - mgr->get_manager_info(mgr, &info); 163 - 164 - /* TODO: fix hard-coded setup.. */ 165 - info.default_color = 0x00000000; 166 - info.trans_key = 0x00000000; 167 - info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST; 168 - info.trans_enabled = false; 169 - 170 - ret = mgr->set_manager_info(mgr, &info); 171 - if (ret) { 172 - dev_err(dev->dev, "could not set manager info\n"); 173 - goto fail; 174 - } 175 - 176 - ret = mgr->apply(mgr); 177 - if (ret) { 178 - dev_err(dev->dev, "could not apply\n"); 179 - goto fail; 180 - } 181 143 182 144 return encoder; 183 145
+1 -1
drivers/staging/omapdrm/omap_gem_dmabuf.c
··· 194 194 struct dma_buf *omap_gem_prime_export(struct drm_device *dev, 195 195 struct drm_gem_object *obj, int flags) 196 196 { 197 - return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600); 197 + return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags); 198 198 } 199 199 200 200 struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
+322
drivers/staging/omapdrm/omap_irq.c
··· 1 + /* 2 + * drivers/staging/omapdrm/omap_irq.c 3 + * 4 + * Copyright (C) 2012 Texas Instruments 5 + * Author: Rob Clark <rob.clark@linaro.org> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License version 2 as published by 9 + * the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope that it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include "omap_drv.h" 21 + 22 + static DEFINE_SPINLOCK(list_lock); 23 + 24 + static void omap_irq_error_handler(struct omap_drm_irq *irq, 25 + uint32_t irqstatus) 26 + { 27 + DRM_ERROR("errors: %08x\n", irqstatus); 28 + } 29 + 30 + /* call with list_lock and dispc runtime held */ 31 + static void omap_irq_update(struct drm_device *dev) 32 + { 33 + struct omap_drm_private *priv = dev->dev_private; 34 + struct omap_drm_irq *irq; 35 + uint32_t irqmask = priv->vblank_mask; 36 + 37 + BUG_ON(!spin_is_locked(&list_lock)); 38 + 39 + list_for_each_entry(irq, &priv->irq_list, node) 40 + irqmask |= irq->irqmask; 41 + 42 + DBG("irqmask=%08x", irqmask); 43 + 44 + dispc_write_irqenable(irqmask); 45 + dispc_read_irqenable(); /* flush posted write */ 46 + } 47 + 48 + void omap_irq_register(struct drm_device *dev, struct omap_drm_irq *irq) 49 + { 50 + struct omap_drm_private *priv = dev->dev_private; 51 + unsigned long flags; 52 + 53 + dispc_runtime_get(); 54 + spin_lock_irqsave(&list_lock, flags); 55 + 56 + if (!WARN_ON(irq->registered)) { 57 + irq->registered = true; 58 + list_add(&irq->node, &priv->irq_list); 59 + omap_irq_update(dev); 60 + } 61 + 62 + spin_unlock_irqrestore(&list_lock, flags); 63 + dispc_runtime_put(); 64 + } 65 + 66 + void omap_irq_unregister(struct drm_device *dev, struct omap_drm_irq *irq) 67 + { 68 + unsigned long flags; 69 + 70 + dispc_runtime_get(); 71 + spin_lock_irqsave(&list_lock, flags); 72 + 73 + if (!WARN_ON(!irq->registered)) { 74 + irq->registered = false; 75 + list_del(&irq->node); 76 + omap_irq_update(dev); 77 + } 78 + 79 + spin_unlock_irqrestore(&list_lock, flags); 80 + dispc_runtime_put(); 81 + } 82 + 83 + struct omap_irq_wait { 84 + struct omap_drm_irq irq; 85 + int count; 86 + }; 87 + 88 + static DECLARE_WAIT_QUEUE_HEAD(wait_event); 89 + 90 + static void wait_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 91 + { 92 + struct omap_irq_wait *wait = 93 + container_of(irq, struct omap_irq_wait, irq); 94 + wait->count--; 95 + wake_up_all(&wait_event); 96 + } 97 + 98 + struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev, 99 + uint32_t irqmask, int count) 100 + { 101 + struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL); 102 + wait->irq.irq = wait_irq; 103 + wait->irq.irqmask = irqmask; 104 + wait->count = count; 105 + omap_irq_register(dev, &wait->irq); 106 + return wait; 107 + } 108 + 109 + int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait, 110 + unsigned long timeout) 111 + { 112 + int ret = wait_event_timeout(wait_event, (wait->count <= 0), timeout); 113 + omap_irq_unregister(dev, &wait->irq); 114 + kfree(wait); 115 + if (ret == 0) 116 + return -1; 117 + return 0; 118 + } 119 + 120 + /** 121 + * enable_vblank - enable vblank interrupt events 122 + * @dev: DRM device 123 + * @crtc: which irq to enable 124 + * 125 + * Enable vblank interrupts for @crtc. If the device doesn't have 126 + * a hardware vblank counter, this routine should be a no-op, since 127 + * interrupts will have to stay on to keep the count accurate. 128 + * 129 + * RETURNS 130 + * Zero on success, appropriate errno if the given @crtc's vblank 131 + * interrupt cannot be enabled. 132 + */ 133 + int omap_irq_enable_vblank(struct drm_device *dev, int crtc) 134 + { 135 + struct omap_drm_private *priv = dev->dev_private; 136 + unsigned long flags; 137 + 138 + DBG("dev=%p, crtc=%d", dev, crtc); 139 + 140 + dispc_runtime_get(); 141 + spin_lock_irqsave(&list_lock, flags); 142 + priv->vblank_mask |= pipe2vbl(crtc); 143 + omap_irq_update(dev); 144 + spin_unlock_irqrestore(&list_lock, flags); 145 + dispc_runtime_put(); 146 + 147 + return 0; 148 + } 149 + 150 + /** 151 + * disable_vblank - disable vblank interrupt events 152 + * @dev: DRM device 153 + * @crtc: which irq to enable 154 + * 155 + * Disable vblank interrupts for @crtc. If the device doesn't have 156 + * a hardware vblank counter, this routine should be a no-op, since 157 + * interrupts will have to stay on to keep the count accurate. 158 + */ 159 + void omap_irq_disable_vblank(struct drm_device *dev, int crtc) 160 + { 161 + struct omap_drm_private *priv = dev->dev_private; 162 + unsigned long flags; 163 + 164 + DBG("dev=%p, crtc=%d", dev, crtc); 165 + 166 + dispc_runtime_get(); 167 + spin_lock_irqsave(&list_lock, flags); 168 + priv->vblank_mask &= ~pipe2vbl(crtc); 169 + omap_irq_update(dev); 170 + spin_unlock_irqrestore(&list_lock, flags); 171 + dispc_runtime_put(); 172 + } 173 + 174 + irqreturn_t omap_irq_handler(DRM_IRQ_ARGS) 175 + { 176 + struct drm_device *dev = (struct drm_device *) arg; 177 + struct omap_drm_private *priv = dev->dev_private; 178 + struct omap_drm_irq *handler, *n; 179 + unsigned long flags; 180 + unsigned int id; 181 + u32 irqstatus; 182 + 183 + irqstatus = dispc_read_irqstatus(); 184 + dispc_clear_irqstatus(irqstatus); 185 + dispc_read_irqstatus(); /* flush posted write */ 186 + 187 + VERB("irqs: %08x", irqstatus); 188 + 189 + for (id = 0; id < priv->num_crtcs; id++) 190 + if (irqstatus & pipe2vbl(id)) 191 + drm_handle_vblank(dev, id); 192 + 193 + spin_lock_irqsave(&list_lock, flags); 194 + list_for_each_entry_safe(handler, n, &priv->irq_list, node) { 195 + if (handler->irqmask & irqstatus) { 196 + spin_unlock_irqrestore(&list_lock, flags); 197 + handler->irq(handler, handler->irqmask & irqstatus); 198 + spin_lock_irqsave(&list_lock, flags); 199 + } 200 + } 201 + spin_unlock_irqrestore(&list_lock, flags); 202 + 203 + return IRQ_HANDLED; 204 + } 205 + 206 + void omap_irq_preinstall(struct drm_device *dev) 207 + { 208 + DBG("dev=%p", dev); 209 + dispc_runtime_get(); 210 + dispc_clear_irqstatus(0xffffffff); 211 + dispc_runtime_put(); 212 + } 213 + 214 + int omap_irq_postinstall(struct drm_device *dev) 215 + { 216 + struct omap_drm_private *priv = dev->dev_private; 217 + struct omap_drm_irq *error_handler = &priv->error_handler; 218 + 219 + DBG("dev=%p", dev); 220 + 221 + INIT_LIST_HEAD(&priv->irq_list); 222 + 223 + error_handler->irq = omap_irq_error_handler; 224 + error_handler->irqmask = DISPC_IRQ_OCP_ERR; 225 + 226 + /* for now ignore DISPC_IRQ_SYNC_LOST_DIGIT.. really I think 227 + * we just need to ignore it while enabling tv-out 228 + */ 229 + error_handler->irqmask &= ~DISPC_IRQ_SYNC_LOST_DIGIT; 230 + 231 + omap_irq_register(dev, error_handler); 232 + 233 + return 0; 234 + } 235 + 236 + void omap_irq_uninstall(struct drm_device *dev) 237 + { 238 + DBG("dev=%p", dev); 239 + // TODO prolly need to call drm_irq_uninstall() somewhere too 240 + } 241 + 242 + /* 243 + * We need a special version, instead of just using drm_irq_install(), 244 + * because we need to register the irq via omapdss. Once omapdss and 245 + * omapdrm are merged together we can assign the dispc hwmod data to 246 + * ourselves and drop these and just use drm_irq_{install,uninstall}() 247 + */ 248 + 249 + int omap_drm_irq_install(struct drm_device *dev) 250 + { 251 + int ret; 252 + 253 + mutex_lock(&dev->struct_mutex); 254 + 255 + if (dev->irq_enabled) { 256 + mutex_unlock(&dev->struct_mutex); 257 + return -EBUSY; 258 + } 259 + dev->irq_enabled = 1; 260 + mutex_unlock(&dev->struct_mutex); 261 + 262 + /* Before installing handler */ 263 + if (dev->driver->irq_preinstall) 264 + dev->driver->irq_preinstall(dev); 265 + 266 + ret = dispc_request_irq(dev->driver->irq_handler, dev); 267 + 268 + if (ret < 0) { 269 + mutex_lock(&dev->struct_mutex); 270 + dev->irq_enabled = 0; 271 + mutex_unlock(&dev->struct_mutex); 272 + return ret; 273 + } 274 + 275 + /* After installing handler */ 276 + if (dev->driver->irq_postinstall) 277 + ret = dev->driver->irq_postinstall(dev); 278 + 279 + if (ret < 0) { 280 + mutex_lock(&dev->struct_mutex); 281 + dev->irq_enabled = 0; 282 + mutex_unlock(&dev->struct_mutex); 283 + dispc_free_irq(dev); 284 + } 285 + 286 + return ret; 287 + } 288 + 289 + int omap_drm_irq_uninstall(struct drm_device *dev) 290 + { 291 + unsigned long irqflags; 292 + int irq_enabled, i; 293 + 294 + mutex_lock(&dev->struct_mutex); 295 + irq_enabled = dev->irq_enabled; 296 + dev->irq_enabled = 0; 297 + mutex_unlock(&dev->struct_mutex); 298 + 299 + /* 300 + * Wake up any waiters so they don't hang. 301 + */ 302 + if (dev->num_crtcs) { 303 + spin_lock_irqsave(&dev->vbl_lock, irqflags); 304 + for (i = 0; i < dev->num_crtcs; i++) { 305 + DRM_WAKEUP(&dev->vbl_queue[i]); 306 + dev->vblank_enabled[i] = 0; 307 + dev->last_vblank[i] = 308 + dev->driver->get_vblank_counter(dev, i); 309 + } 310 + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 311 + } 312 + 313 + if (!irq_enabled) 314 + return -EINVAL; 315 + 316 + if (dev->driver->irq_uninstall) 317 + dev->driver->irq_uninstall(dev); 318 + 319 + dispc_free_irq(dev); 320 + 321 + return 0; 322 + }
+172 -280
drivers/staging/omapdrm/omap_plane.c
··· 41 41 42 42 struct omap_plane { 43 43 struct drm_plane base; 44 - struct omap_overlay *ovl; 44 + int id; /* TODO rename omap_plane -> omap_plane_id in omapdss so I can use the enum */ 45 + const char *name; 45 46 struct omap_overlay_info info; 47 + struct omap_drm_apply apply; 46 48 47 49 /* position/orientation of scanout within the fb: */ 48 50 struct omap_drm_window win; 49 - 51 + bool enabled; 50 52 51 53 /* last fb that we pinned: */ 52 54 struct drm_framebuffer *pinned_fb; ··· 56 54 uint32_t nformats; 57 55 uint32_t formats[32]; 58 56 59 - /* for synchronizing access to unpins fifo */ 60 - struct mutex unpin_mutex; 57 + struct omap_drm_irq error_irq; 61 58 62 - /* set of bo's pending unpin until next END_WIN irq */ 59 + /* set of bo's pending unpin until next post_apply() */ 63 60 DECLARE_KFIFO_PTR(unpin_fifo, struct drm_gem_object *); 64 - int num_unpins, pending_num_unpins; 65 61 66 - /* for deferred unpin when we need to wait for scanout complete irq */ 67 - struct work_struct work; 68 - 69 - /* callback on next endwin irq */ 70 - struct callback endwin; 62 + // XXX maybe get rid of this and handle vblank in crtc too? 63 + struct callback apply_done_cb; 71 64 }; 72 - 73 - /* map from ovl->id to the irq we are interested in for scanout-done */ 74 - static const uint32_t id2irq[] = { 75 - [OMAP_DSS_GFX] = DISPC_IRQ_GFX_END_WIN, 76 - [OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_END_WIN, 77 - [OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_END_WIN, 78 - [OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_END_WIN, 79 - }; 80 - 81 - static void dispc_isr(void *arg, uint32_t mask) 82 - { 83 - struct drm_plane *plane = arg; 84 - struct omap_plane *omap_plane = to_omap_plane(plane); 85 - struct omap_drm_private *priv = plane->dev->dev_private; 86 - 87 - omap_dispc_unregister_isr(dispc_isr, plane, 88 - id2irq[omap_plane->ovl->id]); 89 - 90 - queue_work(priv->wq, &omap_plane->work); 91 - } 92 - 93 - static void unpin_worker(struct work_struct *work) 94 - { 95 - struct omap_plane *omap_plane = 96 - container_of(work, struct omap_plane, work); 97 - struct callback endwin; 98 - 99 - mutex_lock(&omap_plane->unpin_mutex); 100 - DBG("unpinning %d of %d", omap_plane->num_unpins, 101 - omap_plane->num_unpins + omap_plane->pending_num_unpins); 102 - while (omap_plane->num_unpins > 0) { 103 - struct drm_gem_object *bo = NULL; 104 - int ret = kfifo_get(&omap_plane->unpin_fifo, &bo); 105 - WARN_ON(!ret); 106 - omap_gem_put_paddr(bo); 107 - drm_gem_object_unreference_unlocked(bo); 108 - omap_plane->num_unpins--; 109 - } 110 - endwin = omap_plane->endwin; 111 - omap_plane->endwin.fxn = NULL; 112 - mutex_unlock(&omap_plane->unpin_mutex); 113 - 114 - if (endwin.fxn) 115 - endwin.fxn(endwin.arg); 116 - } 117 - 118 - static void install_irq(struct drm_plane *plane) 119 - { 120 - struct omap_plane *omap_plane = to_omap_plane(plane); 121 - struct omap_overlay *ovl = omap_plane->ovl; 122 - int ret; 123 - 124 - ret = omap_dispc_register_isr(dispc_isr, plane, id2irq[ovl->id]); 125 - 126 - /* 127 - * omapdss has upper limit on # of registered irq handlers, 128 - * which we shouldn't hit.. but if we do the limit should 129 - * be raised or bad things happen: 130 - */ 131 - WARN_ON(ret == -EBUSY); 132 - } 133 - 134 - /* push changes down to dss2 */ 135 - static int commit(struct drm_plane *plane) 136 - { 137 - struct drm_device *dev = plane->dev; 138 - struct omap_plane *omap_plane = to_omap_plane(plane); 139 - struct omap_overlay *ovl = omap_plane->ovl; 140 - struct omap_overlay_info *info = &omap_plane->info; 141 - int ret; 142 - 143 - DBG("%s", ovl->name); 144 - DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width, 145 - info->out_height, info->screen_width); 146 - DBG("%d,%d %08x %08x", info->pos_x, info->pos_y, 147 - info->paddr, info->p_uv_addr); 148 - 149 - /* NOTE: do we want to do this at all here, or just wait 150 - * for dpms(ON) since other CRTC's may not have their mode 151 - * set yet, so fb dimensions may still change.. 152 - */ 153 - ret = ovl->set_overlay_info(ovl, info); 154 - if (ret) { 155 - dev_err(dev->dev, "could not set overlay info\n"); 156 - return ret; 157 - } 158 - 159 - mutex_lock(&omap_plane->unpin_mutex); 160 - omap_plane->num_unpins += omap_plane->pending_num_unpins; 161 - omap_plane->pending_num_unpins = 0; 162 - mutex_unlock(&omap_plane->unpin_mutex); 163 - 164 - /* our encoder doesn't necessarily get a commit() after this, in 165 - * particular in the dpms() and mode_set_base() cases, so force the 166 - * manager to update: 167 - * 168 - * could this be in the encoder somehow? 169 - */ 170 - if (ovl->manager) { 171 - ret = ovl->manager->apply(ovl->manager); 172 - if (ret) { 173 - dev_err(dev->dev, "could not apply settings\n"); 174 - return ret; 175 - } 176 - 177 - /* 178 - * NOTE: really this should be atomic w/ mgr->apply() but 179 - * omapdss does not expose such an API 180 - */ 181 - if (omap_plane->num_unpins > 0) 182 - install_irq(plane); 183 - 184 - } else { 185 - struct omap_drm_private *priv = dev->dev_private; 186 - queue_work(priv->wq, &omap_plane->work); 187 - } 188 - 189 - 190 - if (ovl->is_enabled(ovl)) { 191 - omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y, 192 - info->out_width, info->out_height); 193 - } 194 - 195 - return 0; 196 - } 197 - 198 - /* when CRTC that we are attached to has potentially changed, this checks 199 - * if we are attached to proper manager, and if necessary updates. 200 - */ 201 - static void update_manager(struct drm_plane *plane) 202 - { 203 - struct omap_drm_private *priv = plane->dev->dev_private; 204 - struct omap_plane *omap_plane = to_omap_plane(plane); 205 - struct omap_overlay *ovl = omap_plane->ovl; 206 - struct omap_overlay_manager *mgr = NULL; 207 - int i; 208 - 209 - if (plane->crtc) { 210 - for (i = 0; i < priv->num_encoders; i++) { 211 - struct drm_encoder *encoder = priv->encoders[i]; 212 - if (encoder->crtc == plane->crtc) { 213 - mgr = omap_encoder_get_manager(encoder); 214 - break; 215 - } 216 - } 217 - } 218 - 219 - if (ovl->manager != mgr) { 220 - bool enabled = ovl->is_enabled(ovl); 221 - 222 - /* don't switch things around with enabled overlays: */ 223 - if (enabled) 224 - omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); 225 - 226 - if (ovl->manager) { 227 - DBG("disconnecting %s from %s", ovl->name, 228 - ovl->manager->name); 229 - ovl->unset_manager(ovl); 230 - } 231 - 232 - if (mgr) { 233 - DBG("connecting %s to %s", ovl->name, mgr->name); 234 - ovl->set_manager(ovl, mgr); 235 - } 236 - 237 - if (enabled && mgr) 238 - omap_plane_dpms(plane, DRM_MODE_DPMS_ON); 239 - } 240 - } 241 65 242 66 static void unpin(void *arg, struct drm_gem_object *bo) 243 67 { ··· 72 244 73 245 if (kfifo_put(&omap_plane->unpin_fifo, 74 246 (const struct drm_gem_object **)&bo)) { 75 - omap_plane->pending_num_unpins++; 76 247 /* also hold a ref so it isn't free'd while pinned */ 77 248 drm_gem_object_reference(bo); 78 249 } else { ··· 91 264 92 265 DBG("%p -> %p", pinned_fb, fb); 93 266 94 - mutex_lock(&omap_plane->unpin_mutex); 267 + if (fb) 268 + drm_framebuffer_reference(fb); 269 + 95 270 ret = omap_framebuffer_replace(pinned_fb, fb, plane, unpin); 96 - mutex_unlock(&omap_plane->unpin_mutex); 271 + 272 + if (pinned_fb) 273 + drm_framebuffer_unreference(pinned_fb); 97 274 98 275 if (ret) { 99 276 dev_err(plane->dev->dev, "could not swap %p -> %p\n", 100 277 omap_plane->pinned_fb, fb); 278 + if (fb) 279 + drm_framebuffer_unreference(fb); 101 280 omap_plane->pinned_fb = NULL; 102 281 return ret; 103 282 } ··· 114 281 return 0; 115 282 } 116 283 117 - /* update parameters that are dependent on the framebuffer dimensions and 118 - * position within the fb that this plane scans out from. This is called 119 - * when framebuffer or x,y base may have changed. 120 - */ 121 - static void update_scanout(struct drm_plane *plane) 284 + static void omap_plane_pre_apply(struct omap_drm_apply *apply) 122 285 { 123 - struct omap_plane *omap_plane = to_omap_plane(plane); 124 - struct omap_overlay_info *info = &omap_plane->info; 286 + struct omap_plane *omap_plane = 287 + container_of(apply, struct omap_plane, apply); 125 288 struct omap_drm_window *win = &omap_plane->win; 289 + struct drm_plane *plane = &omap_plane->base; 290 + struct drm_device *dev = plane->dev; 291 + struct omap_overlay_info *info = &omap_plane->info; 292 + struct drm_crtc *crtc = plane->crtc; 293 + enum omap_channel channel; 294 + bool enabled = omap_plane->enabled && crtc; 295 + bool ilace, replication; 126 296 int ret; 127 297 128 - ret = update_pin(plane, plane->fb); 129 - if (ret) { 130 - dev_err(plane->dev->dev, 131 - "could not pin fb: %d\n", ret); 132 - omap_plane_dpms(plane, DRM_MODE_DPMS_OFF); 298 + DBG("%s, enabled=%d", omap_plane->name, enabled); 299 + 300 + /* if fb has changed, pin new fb: */ 301 + update_pin(plane, enabled ? plane->fb : NULL); 302 + 303 + if (!enabled) { 304 + dispc_ovl_enable(omap_plane->id, false); 133 305 return; 134 306 } 135 307 308 + channel = omap_crtc_channel(crtc); 309 + 310 + /* update scanout: */ 136 311 omap_framebuffer_update_scanout(plane->fb, win, info); 137 312 138 - DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name, 139 - win->src_x, win->src_y, 140 - (u32)info->paddr, (u32)info->p_uv_addr, 313 + DBG("%dx%d -> %dx%d (%d)", info->width, info->height, 314 + info->out_width, info->out_height, 141 315 info->screen_width); 316 + DBG("%d,%d %08x %08x", info->pos_x, info->pos_y, 317 + info->paddr, info->p_uv_addr); 318 + 319 + /* TODO: */ 320 + ilace = false; 321 + replication = false; 322 + 323 + /* and finally, update omapdss: */ 324 + ret = dispc_ovl_setup(omap_plane->id, info, 325 + replication, omap_crtc_timings(crtc), false); 326 + if (ret) { 327 + dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret); 328 + return; 329 + } 330 + 331 + dispc_ovl_enable(omap_plane->id, true); 332 + dispc_ovl_set_channel_out(omap_plane->id, channel); 333 + } 334 + 335 + static void omap_plane_post_apply(struct omap_drm_apply *apply) 336 + { 337 + struct omap_plane *omap_plane = 338 + container_of(apply, struct omap_plane, apply); 339 + struct drm_plane *plane = &omap_plane->base; 340 + struct omap_overlay_info *info = &omap_plane->info; 341 + struct drm_gem_object *bo = NULL; 342 + struct callback cb; 343 + 344 + cb = omap_plane->apply_done_cb; 345 + omap_plane->apply_done_cb.fxn = NULL; 346 + 347 + while (kfifo_get(&omap_plane->unpin_fifo, &bo)) { 348 + omap_gem_put_paddr(bo); 349 + drm_gem_object_unreference_unlocked(bo); 350 + } 351 + 352 + if (cb.fxn) 353 + cb.fxn(cb.arg); 354 + 355 + if (omap_plane->enabled) { 356 + omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y, 357 + info->out_width, info->out_height); 358 + } 359 + } 360 + 361 + static int apply(struct drm_plane *plane) 362 + { 363 + if (plane->crtc) { 364 + struct omap_plane *omap_plane = to_omap_plane(plane); 365 + return omap_crtc_apply(plane->crtc, &omap_plane->apply); 366 + } 367 + return 0; 142 368 } 143 369 144 370 int omap_plane_mode_set(struct drm_plane *plane, ··· 205 313 int crtc_x, int crtc_y, 206 314 unsigned int crtc_w, unsigned int crtc_h, 207 315 uint32_t src_x, uint32_t src_y, 208 - uint32_t src_w, uint32_t src_h) 316 + uint32_t src_w, uint32_t src_h, 317 + void (*fxn)(void *), void *arg) 209 318 { 210 319 struct omap_plane *omap_plane = to_omap_plane(plane); 211 320 struct omap_drm_window *win = &omap_plane->win; ··· 222 329 win->src_w = src_w >> 16; 223 330 win->src_h = src_h >> 16; 224 331 225 - /* note: this is done after this fxn returns.. but if we need 226 - * to do a commit/update_scanout, etc before this returns we 227 - * need the current value. 228 - */ 332 + if (fxn) { 333 + /* omap_crtc should ensure that a new page flip 334 + * isn't permitted while there is one pending: 335 + */ 336 + BUG_ON(omap_plane->apply_done_cb.fxn); 337 + 338 + omap_plane->apply_done_cb.fxn = fxn; 339 + omap_plane->apply_done_cb.arg = arg; 340 + } 341 + 229 342 plane->fb = fb; 230 343 plane->crtc = crtc; 231 344 232 - update_scanout(plane); 233 - update_manager(plane); 234 - 235 - return 0; 345 + return apply(plane); 236 346 } 237 347 238 348 static int omap_plane_update(struct drm_plane *plane, ··· 245 349 uint32_t src_x, uint32_t src_y, 246 350 uint32_t src_w, uint32_t src_h) 247 351 { 248 - omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, 249 - src_x, src_y, src_w, src_h); 250 - return omap_plane_dpms(plane, DRM_MODE_DPMS_ON); 352 + struct omap_plane *omap_plane = to_omap_plane(plane); 353 + omap_plane->enabled = true; 354 + return omap_plane_mode_set(plane, crtc, fb, 355 + crtc_x, crtc_y, crtc_w, crtc_h, 356 + src_x, src_y, src_w, src_h, 357 + NULL, NULL); 251 358 } 252 359 253 360 static int omap_plane_disable(struct drm_plane *plane) ··· 263 364 static void omap_plane_destroy(struct drm_plane *plane) 264 365 { 265 366 struct omap_plane *omap_plane = to_omap_plane(plane); 266 - DBG("%s", omap_plane->ovl->name); 367 + 368 + DBG("%s", omap_plane->name); 369 + 370 + omap_irq_unregister(plane->dev, &omap_plane->error_irq); 371 + 267 372 omap_plane_disable(plane); 268 373 drm_plane_cleanup(plane); 269 - WARN_ON(omap_plane->pending_num_unpins + omap_plane->num_unpins > 0); 374 + 375 + WARN_ON(!kfifo_is_empty(&omap_plane->unpin_fifo)); 270 376 kfifo_free(&omap_plane->unpin_fifo); 377 + 271 378 kfree(omap_plane); 272 379 } 273 380 274 381 int omap_plane_dpms(struct drm_plane *plane, int mode) 275 382 { 276 383 struct omap_plane *omap_plane = to_omap_plane(plane); 277 - struct omap_overlay *ovl = omap_plane->ovl; 278 - int r; 384 + bool enabled = (mode == DRM_MODE_DPMS_ON); 385 + int ret = 0; 279 386 280 - DBG("%s: %d", omap_plane->ovl->name, mode); 281 - 282 - if (mode == DRM_MODE_DPMS_ON) { 283 - update_scanout(plane); 284 - r = commit(plane); 285 - if (!r) 286 - r = ovl->enable(ovl); 287 - } else { 288 - struct omap_drm_private *priv = plane->dev->dev_private; 289 - r = ovl->disable(ovl); 290 - update_pin(plane, NULL); 291 - queue_work(priv->wq, &omap_plane->work); 387 + if (enabled != omap_plane->enabled) { 388 + omap_plane->enabled = enabled; 389 + ret = apply(plane); 292 390 } 293 391 294 - return r; 295 - } 296 - 297 - void omap_plane_on_endwin(struct drm_plane *plane, 298 - void (*fxn)(void *), void *arg) 299 - { 300 - struct omap_plane *omap_plane = to_omap_plane(plane); 301 - 302 - mutex_lock(&omap_plane->unpin_mutex); 303 - omap_plane->endwin.fxn = fxn; 304 - omap_plane->endwin.arg = arg; 305 - mutex_unlock(&omap_plane->unpin_mutex); 306 - 307 - install_irq(plane); 392 + return ret; 308 393 } 309 394 310 395 /* helper to install properties which are common to planes and crtcs */ ··· 337 454 int ret = -EINVAL; 338 455 339 456 if (property == priv->rotation_prop) { 340 - struct omap_overlay *ovl = omap_plane->ovl; 341 - 342 - DBG("%s: rotation: %02x", ovl->name, (uint32_t)val); 457 + DBG("%s: rotation: %02x", omap_plane->name, (uint32_t)val); 343 458 omap_plane->win.rotation = val; 344 - 345 - if (ovl->is_enabled(ovl)) 346 - ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); 347 - else 348 - ret = 0; 459 + ret = apply(plane); 349 460 } else if (property == priv->zorder_prop) { 350 - struct omap_overlay *ovl = omap_plane->ovl; 351 - 352 - DBG("%s: zorder: %d", ovl->name, (uint32_t)val); 461 + DBG("%s: zorder: %02x", omap_plane->name, (uint32_t)val); 353 462 omap_plane->info.zorder = val; 354 - 355 - if (ovl->is_enabled(ovl)) 356 - ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON); 357 - else 358 - ret = 0; 463 + ret = apply(plane); 359 464 } 360 465 361 466 return ret; ··· 356 485 .set_property = omap_plane_set_property, 357 486 }; 358 487 488 + static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) 489 + { 490 + struct omap_plane *omap_plane = 491 + container_of(irq, struct omap_plane, error_irq); 492 + DRM_ERROR("%s: errors: %08x\n", omap_plane->name, irqstatus); 493 + } 494 + 495 + static const char *plane_names[] = { 496 + [OMAP_DSS_GFX] = "gfx", 497 + [OMAP_DSS_VIDEO1] = "vid1", 498 + [OMAP_DSS_VIDEO2] = "vid2", 499 + [OMAP_DSS_VIDEO3] = "vid3", 500 + }; 501 + 502 + static const uint32_t error_irqs[] = { 503 + [OMAP_DSS_GFX] = DISPC_IRQ_GFX_FIFO_UNDERFLOW, 504 + [OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_FIFO_UNDERFLOW, 505 + [OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_FIFO_UNDERFLOW, 506 + [OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_FIFO_UNDERFLOW, 507 + }; 508 + 359 509 /* initialize plane */ 360 510 struct drm_plane *omap_plane_init(struct drm_device *dev, 361 - struct omap_overlay *ovl, unsigned int possible_crtcs, 362 - bool priv) 511 + int id, bool private_plane) 363 512 { 513 + struct omap_drm_private *priv = dev->dev_private; 364 514 struct drm_plane *plane = NULL; 365 515 struct omap_plane *omap_plane; 516 + struct omap_overlay_info *info; 366 517 int ret; 367 518 368 - DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name, 369 - possible_crtcs, priv); 370 - 371 - /* friendly reminder to update table for future hw: */ 372 - WARN_ON(ovl->id >= ARRAY_SIZE(id2irq)); 519 + DBG("%s: priv=%d", plane_names[id], private_plane); 373 520 374 521 omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); 375 522 if (!omap_plane) { ··· 395 506 goto fail; 396 507 } 397 508 398 - mutex_init(&omap_plane->unpin_mutex); 399 - 400 509 ret = kfifo_alloc(&omap_plane->unpin_fifo, 16, GFP_KERNEL); 401 510 if (ret) { 402 511 dev_err(dev->dev, "could not allocate unpin FIFO\n"); 403 512 goto fail; 404 513 } 405 514 406 - INIT_WORK(&omap_plane->work, unpin_worker); 407 - 408 515 omap_plane->nformats = omap_framebuffer_get_formats( 409 516 omap_plane->formats, ARRAY_SIZE(omap_plane->formats), 410 - ovl->supported_modes); 411 - omap_plane->ovl = ovl; 517 + dss_feat_get_supported_color_modes(id)); 518 + omap_plane->id = id; 519 + omap_plane->name = plane_names[id]; 520 + 412 521 plane = &omap_plane->base; 413 522 414 - drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, 415 - omap_plane->formats, omap_plane->nformats, priv); 523 + omap_plane->apply.pre_apply = omap_plane_pre_apply; 524 + omap_plane->apply.post_apply = omap_plane_post_apply; 525 + 526 + omap_plane->error_irq.irqmask = error_irqs[id]; 527 + omap_plane->error_irq.irq = omap_plane_error_irq; 528 + omap_irq_register(dev, &omap_plane->error_irq); 529 + 530 + drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &omap_plane_funcs, 531 + omap_plane->formats, omap_plane->nformats, private_plane); 416 532 417 533 omap_plane_install_properties(plane, &plane->base); 418 534 419 535 /* get our starting configuration, set defaults for parameters 420 536 * we don't currently use, etc: 421 537 */ 422 - ovl->get_overlay_info(ovl, &omap_plane->info); 423 - omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA; 424 - omap_plane->info.rotation = OMAP_DSS_ROT_0; 425 - omap_plane->info.global_alpha = 0xff; 426 - omap_plane->info.mirror = 0; 538 + info = &omap_plane->info; 539 + info->rotation_type = OMAP_DSS_ROT_DMA; 540 + info->rotation = OMAP_DSS_ROT_0; 541 + info->global_alpha = 0xff; 542 + info->mirror = 0; 427 543 428 544 /* Set defaults depending on whether we are a CRTC or overlay 429 545 * layer. 430 546 * TODO add ioctl to give userspace an API to change this.. this 431 547 * will come in a subsequent patch. 432 548 */ 433 - if (priv) 549 + if (private_plane) 434 550 omap_plane->info.zorder = 0; 435 551 else 436 - omap_plane->info.zorder = ovl->id; 437 - 438 - update_manager(plane); 552 + omap_plane->info.zorder = id; 439 553 440 554 return plane; 441 555
+2 -1
drivers/staging/rtl8187se/r8180_core.c
··· 937 937 938 938 dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8), 939 939 PCI_DMA_FROMDEVICE); 940 - 940 + if (pci_dma_mapping_error(pdev, dma_tmp)) 941 + return -1; 941 942 if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp, 942 943 &(priv->rxbufferhead))) { 943 944 DMESGE("Unable to allocate mem RX buf");
+4
drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c
··· 1183 1183 pTxFwInfo->TxRate, 1184 1184 cb_desc); 1185 1185 1186 + if (pci_dma_mapping_error(priv->pdev, mapping)) 1187 + RT_TRACE(COMP_ERR, "DMA Mapping error\n");; 1186 1188 if (cb_desc->bAMPDUEnable) { 1187 1189 pTxFwInfo->AllowAggregation = 1; 1188 1190 pTxFwInfo->RxMF = cb_desc->ampdu_factor; ··· 1282 1280 dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, 1283 1281 PCI_DMA_TODEVICE); 1284 1282 1283 + if (pci_dma_mapping_error(priv->pdev, mapping)) 1284 + RT_TRACE(COMP_ERR, "DMA Mapping error\n");; 1285 1285 memset(entry, 0, 12); 1286 1286 entry->LINIP = cb_desc->bLastIniPkt; 1287 1287 entry->FirstSeg = 1;
+9 -2
drivers/staging/rtl8192e/rtl8192e/rtl_core.c
··· 2104 2104 skb_tail_pointer_rsl(skb), 2105 2105 priv->rxbuffersize, 2106 2106 PCI_DMA_FROMDEVICE); 2107 - 2107 + if (pci_dma_mapping_error(priv->pdev, *mapping)) { 2108 + dev_kfree_skb_any(skb); 2109 + return -1; 2110 + } 2108 2111 entry->BufferAddress = cpu_to_le32(*mapping); 2109 2112 2110 2113 entry->Length = priv->rxbuffersize; ··· 2400 2397 skb_tail_pointer_rsl(skb), 2401 2398 priv->rxbuffersize, 2402 2399 PCI_DMA_FROMDEVICE); 2403 - 2400 + if (pci_dma_mapping_error(priv->pdev, 2401 + *((dma_addr_t *)skb->cb))) { 2402 + dev_kfree_skb_any(skb); 2403 + return; 2404 + } 2404 2405 } 2405 2406 done: 2406 2407 pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
+2
drivers/staging/rtl8712/usb_intf.c
··· 63 63 {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ 64 64 /* Belkin */ 65 65 {USB_DEVICE(0x050D, 0x945A)}, 66 + /* ISY IWL - Belkin clone */ 67 + {USB_DEVICE(0x050D, 0x11F1)}, 66 68 /* Corega */ 67 69 {USB_DEVICE(0x07AA, 0x0047)}, 68 70 /* D-Link */
+1
drivers/staging/sb105x/Kconfig
··· 2 2 tristate "SystemBase PCI Multiport UART" 3 3 select SERIAL_CORE 4 4 depends on PCI 5 + depends on X86 5 6 help 6 7 A driver for the SystemBase Multi-2/PCI serial card 7 8
+2
drivers/staging/sb105x/sb_pci_mp.c
··· 3054 3054 sbdev->nr_ports = ((portnum_hex/16)*10) + (portnum_hex % 16); 3055 3055 } 3056 3056 break; 3057 + #ifdef CONFIG_PARPORT 3057 3058 case PCI_DEVICE_ID_MP2S1P : 3058 3059 sbdev->nr_ports = 2; 3059 3060 ··· 3074 3073 /* add PC compatible parallel port */ 3075 3074 parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); 3076 3075 break; 3076 + #endif 3077 3077 } 3078 3078 3079 3079 ret = request_region(sbdev->uart_access_addr, (8*sbdev->nr_ports), sbdev->name);
+2 -2
drivers/staging/speakup/synth.c
··· 342 342 343 343 mutex_lock(&spk_mutex); 344 344 /* First, check if we already have it loaded. */ 345 - for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) 345 + for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) 346 346 if (strcmp(synths[i]->name, synth_name) == 0) 347 347 synth = synths[i]; 348 348 ··· 423 423 int i; 424 424 int status = 0; 425 425 mutex_lock(&spk_mutex); 426 - for (i = 0; synths[i] != NULL && i < MAXSYNTHS; i++) 426 + for (i = 0; i < MAXSYNTHS && synths[i] != NULL; i++) 427 427 /* synth_remove() is responsible for rotating the array down */ 428 428 if (in_synth == synths[i]) { 429 429 mutex_unlock(&spk_mutex);
+1 -1
drivers/staging/tidspbridge/core/_tiomap.h
··· 31 31 * driver should read or write to PRM/CM registers directly; they 32 32 * should rely on OMAP core code to do this. 33 33 */ 34 - #include <mach-omap2/cm2xxx_3xxx.h> 34 + #include <mach-omap2/cm3xxx.h> 35 35 #include <mach-omap2/prm-regbits-34xx.h> 36 36 #include <mach-omap2/cm-regbits-34xx.h> 37 37 #include <dspbridge/devdefs.h>
+12 -1
drivers/staging/tidspbridge/core/dsp-clock.c
··· 121 121 for (i = 0; i < DM_TIMER_CLOCKS; i++) 122 122 omap_dm_timer_free(timer[i]); 123 123 124 + clk_unprepare(iva2_clk); 124 125 clk_put(iva2_clk); 126 + clk_unprepare(ssi.sst_fck); 125 127 clk_put(ssi.sst_fck); 128 + clk_unprepare(ssi.ssr_fck); 126 129 clk_put(ssi.ssr_fck); 130 + clk_unprepare(ssi.ick); 127 131 clk_put(ssi.ick); 128 132 } 129 133 ··· 149 145 iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); 150 146 if (IS_ERR(iva2_clk)) 151 147 dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); 148 + else 149 + clk_prepare(iva2_clk); 152 150 153 151 ssi.sst_fck = clk_get(&dspbridge_device.dev, "ssi_sst_fck"); 154 152 ssi.ssr_fck = clk_get(&dspbridge_device.dev, "ssi_ssr_fck"); 155 153 ssi.ick = clk_get(&dspbridge_device.dev, "ssi_ick"); 156 154 157 - if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) 155 + if (IS_ERR(ssi.sst_fck) || IS_ERR(ssi.ssr_fck) || IS_ERR(ssi.ick)) { 158 156 dev_err(bridge, "failed to get ssi: sst %p, ssr %p, ick %p\n", 159 157 ssi.sst_fck, ssi.ssr_fck, ssi.ick); 158 + } else { 159 + clk_prepare(ssi.sst_fck); 160 + clk_prepare(ssi.ssr_fck); 161 + clk_prepare(ssi.ick); 162 + } 160 163 } 161 164 162 165 /**
+10 -2
drivers/staging/tidspbridge/core/wdt.c
··· 63 63 dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); 64 64 65 65 if (!IS_ERR(dsp_wdt.fclk)) { 66 + clk_prepare(dsp_wdt.fclk); 67 + 66 68 dsp_wdt.iclk = clk_get(NULL, "wdt3_ick"); 67 69 if (IS_ERR(dsp_wdt.iclk)) { 68 70 clk_put(dsp_wdt.fclk); 69 71 dsp_wdt.fclk = NULL; 70 72 ret = -EFAULT; 73 + } else { 74 + clk_prepare(dsp_wdt.iclk); 71 75 } 72 76 } else 73 77 ret = -EFAULT; ··· 99 95 free_irq(INT_34XX_WDT3_IRQ, &dsp_wdt); 100 96 tasklet_kill(&dsp_wdt.wdt3_tasklet); 101 97 102 - if (dsp_wdt.fclk) 98 + if (dsp_wdt.fclk) { 99 + clk_unprepare(dsp_wdt.fclk); 103 100 clk_put(dsp_wdt.fclk); 104 - if (dsp_wdt.iclk) 101 + } 102 + if (dsp_wdt.iclk) { 103 + clk_unprepare(dsp_wdt.iclk); 105 104 clk_put(dsp_wdt.iclk); 105 + } 106 106 107 107 dsp_wdt.fclk = NULL; 108 108 dsp_wdt.iclk = NULL;
+2 -12
drivers/staging/vme/devices/vme_pio2_core.c
··· 162 162 163 163 static int __init pio2_init(void) 164 164 { 165 - int retval = 0; 166 - 167 165 if (bus_num == 0) { 168 166 pr_err("No cards, skipping registration\n"); 169 - goto err_nocard; 167 + return -ENODEV; 170 168 } 171 169 172 170 if (bus_num > PIO2_CARDS_MAX) { ··· 174 176 } 175 177 176 178 /* Register the PIO2 driver */ 177 - retval = vme_register_driver(&pio2_driver, bus_num); 178 - if (retval != 0) 179 - goto err_reg; 180 - 181 - return retval; 182 - 183 - err_reg: 184 - err_nocard: 185 - return retval; 179 + return vme_register_driver(&pio2_driver, bus_num); 186 180 } 187 181 188 182 static int pio2_match(struct vme_dev *vdev)
+4 -3
drivers/staging/wlan-ng/cfg80211.c
··· 638 638 } 639 639 640 640 641 - int prism2_set_tx_power(struct wiphy *wiphy, enum nl80211_tx_power_setting type, 642 - int mbm) 641 + int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 642 + enum nl80211_tx_power_setting type, int mbm) 643 643 { 644 644 struct prism2_wiphy_private *priv = wiphy_priv(wiphy); 645 645 wlandevice_t *wlandev = priv->wlandev; ··· 665 665 return err; 666 666 } 667 667 668 - int prism2_get_tx_power(struct wiphy *wiphy, int *dbm) 668 + int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, 669 + int *dbm) 669 670 { 670 671 struct prism2_wiphy_private *priv = wiphy_priv(wiphy); 671 672 wlandevice_t *wlandev = priv->wlandev;
+24 -15
drivers/staging/zram/zram_drv.c
··· 265 265 static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, 266 266 int offset) 267 267 { 268 - int ret; 268 + int ret = 0; 269 269 size_t clen; 270 270 unsigned long handle; 271 271 struct page *page; ··· 286 286 goto out; 287 287 } 288 288 ret = zram_decompress_page(zram, uncmem, index); 289 - if (ret) { 290 - kfree(uncmem); 289 + if (ret) 291 290 goto out; 292 - } 293 291 } 294 292 295 293 /* ··· 300 302 301 303 user_mem = kmap_atomic(page); 302 304 303 - if (is_partial_io(bvec)) 305 + if (is_partial_io(bvec)) { 304 306 memcpy(uncmem + offset, user_mem + bvec->bv_offset, 305 307 bvec->bv_len); 306 - else 308 + kunmap_atomic(user_mem); 309 + user_mem = NULL; 310 + } else { 307 311 uncmem = user_mem; 312 + } 308 313 309 314 if (page_zero_filled(uncmem)) { 310 - kunmap_atomic(user_mem); 311 - if (is_partial_io(bvec)) 312 - kfree(uncmem); 315 + if (!is_partial_io(bvec)) 316 + kunmap_atomic(user_mem); 313 317 zram_stat_inc(&zram->stats.pages_zero); 314 318 zram_set_flag(zram, index, ZRAM_ZERO); 315 319 ret = 0; ··· 321 321 ret = lzo1x_1_compress(uncmem, PAGE_SIZE, src, &clen, 322 322 zram->compress_workmem); 323 323 324 - kunmap_atomic(user_mem); 325 - if (is_partial_io(bvec)) 326 - kfree(uncmem); 324 + if (!is_partial_io(bvec)) { 325 + kunmap_atomic(user_mem); 326 + user_mem = NULL; 327 + uncmem = NULL; 328 + } 327 329 328 330 if (unlikely(ret != LZO_E_OK)) { 329 331 pr_err("Compression failed! err=%d\n", ret); ··· 334 332 335 333 if (unlikely(clen > max_zpage_size)) { 336 334 zram_stat_inc(&zram->stats.bad_compress); 337 - src = uncmem; 338 335 clen = PAGE_SIZE; 336 + src = NULL; 337 + if (is_partial_io(bvec)) 338 + src = uncmem; 339 339 } 340 340 341 341 handle = zs_malloc(zram->mem_pool, clen); ··· 349 345 } 350 346 cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_WO); 351 347 348 + if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) 349 + src = kmap_atomic(page); 352 350 memcpy(cmem, src, clen); 351 + if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) 352 + kunmap_atomic(src); 353 353 354 354 zs_unmap_object(zram->mem_pool, handle); 355 355 ··· 366 358 if (clen <= PAGE_SIZE / 2) 367 359 zram_stat_inc(&zram->stats.good_compress); 368 360 369 - return 0; 370 - 371 361 out: 362 + if (is_partial_io(bvec)) 363 + kfree(uncmem); 364 + 372 365 if (ret) 373 366 zram_stat64_inc(zram, &zram->stats.failed_writes); 374 367 return ret;