diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index b20e829d350f..6e02c5029152 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -197,6 +197,19 @@ Description: Raw pressure measurement from channel Y. Units after application of scale and offset are kilopascal. +What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_raw +KernelVersion: 3.14 +Contact: linux-iio@vger.kernel.org +Description: + Raw humidity measurement of air. Units after application of + scale and offset are milli percent. + +What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_input +KernelVersion: 3.14 +Contact: linux-iio@vger.kernel.org +Description: + Scaled humidity measurement in milli percent. + What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index b1cb3415e6f1..c65f71cfaa5c 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -16,6 +16,7 @@ adt7461 +/-1C TDM Extended Temp Range I.C at,24c08 i2c serial eeprom (24cxx) atmel,24c02 i2c serial eeprom (24cxx) atmel,at97sc3204t i2c trusted platform module (TPM) +capella,cm32181 CM32181: Ambient Light Sensor catalyst,24c32 i2c serial eeprom dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock dallas,ds1338 I2C RTC with 56-Byte NV RAM diff --git a/Documentation/devicetree/bindings/iio/humidity/dht11.txt b/Documentation/devicetree/bindings/iio/humidity/dht11.txt new file mode 100644 index 000000000000..ecc24c199fd6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/humidity/dht11.txt @@ -0,0 +1,14 @@ +* DHT11 humidity/temperature sensor (and compatibles like DHT22) + +Required properties: + - compatible: Should be "dht11" + - gpios: Should specify the GPIO connected to the sensor's data + line, see "gpios property" in + Documentation/devicetree/bindings/gpio/gpio.txt. + +Example: + +humidity_sensor { + compatible = "dht11"; + gpios = <&gpio0 6 0>; +} diff --git a/Documentation/devicetree/bindings/iio/light/tsl2563.txt b/Documentation/devicetree/bindings/iio/light/tsl2563.txt new file mode 100644 index 000000000000..f91e809e736e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/tsl2563.txt @@ -0,0 +1,19 @@ +* AMS TAOS TSL2563 ambient light sensor + +Required properties: + + - compatible : should be "amstaos,tsl2563" + - reg : the I2C address of the sensor + +Optional properties: + + - amstaos,cover-comp-gain : integer used as multiplier for gain + compensation (default = 1) + +Example: + +tsl2563@29 { + compatible = "amstaos,tsl2563"; + reg = <0x29>; + amstaos,cover-comp-gain = <16>; +}; diff --git a/Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt b/Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt new file mode 100644 index 000000000000..90d5f34db04e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/magnetometer/hmc5843.txt @@ -0,0 +1,17 @@ +* Honeywell HMC5843 magnetometer sensor + +Required properties: + + - compatible : should be "honeywell,hmc5843" + - reg : the I2C address of the magnetometer - typically 0x1e + +Optional properties: + + - gpios : should be device tree identifier of the magnetometer DRDY pin + +Example: + +hmc5843@1e { + compatible = "honeywell,hmc5843" + reg = <0x1e>; +}; diff --git a/Documentation/devicetree/bindings/staging/xillybus.txt b/Documentation/devicetree/bindings/staging/xillybus.txt new file mode 100644 index 000000000000..9e316dc2e40f --- /dev/null +++ b/Documentation/devicetree/bindings/staging/xillybus.txt @@ -0,0 +1,20 @@ +* Xillybus driver for generic FPGA interface + +Required properties: +- compatible: Should be "xillybus,xillybus-1.00.a" +- reg: Address and length of the register set for the device +- interrupts: Contains one interrupt node, typically consisting of three cells. +- interrupt-parent: the phandle for the interrupt controller that + services interrupts for this device. + +Optional properties: +- dma-coherent: Present if DMA operations are coherent + +Example: + + xillybus@ff200400 { + compatible = "xillybus,xillybus-1.00.a"; + reg = < 0xff200400 0x00000080 >; + interrupts = < 0 40 1 >; + interrupt-parent = <&intc>; + } ; diff --git a/Documentation/devicetree/bindings/staging/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt similarity index 70% rename from Documentation/devicetree/bindings/staging/dwc2.txt rename to Documentation/devicetree/bindings/usb/dwc2.txt index 1a1b7cfa4845..8b60e90efe33 100644 --- a/Documentation/devicetree/bindings/staging/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -2,7 +2,9 @@ Platform DesignWare HS OTG USB 2.0 controller ----------------------------------------------------- Required properties: -- compatible : "snps,dwc2" +- compatible : One of: + - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. + - snps,dwc2: A generic DWC2 USB controller with default parameters. - reg : Should contain 1 register range (address and length) - interrupts : Should contain 1 interrupt diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index edbb8d88c85e..f29cd78b6698 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -9,6 +9,7 @@ aeroflexgaisler Aeroflex Gaisler AB ak Asahi Kasei Corp. altr Altera Corp. amcc Applied Micro Circuits Corporation (APM, formally AMCC) +amstaos AMS-Taos Inc. apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. atmel Atmel Corporation diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 5bdc8cb5fc28..4f7897e99cba 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -242,6 +242,8 @@ IIO devm_iio_device_free() devm_iio_trigger_alloc() devm_iio_trigger_free() + devm_iio_device_register() + devm_iio_device_unregister() IO region devm_request_region() diff --git a/Documentation/vme_api.txt b/Documentation/vme_api.txt index 856efa35f6e3..ffe6e22a2ccd 100644 --- a/Documentation/vme_api.txt +++ b/Documentation/vme_api.txt @@ -393,4 +393,14 @@ Slot Detection This function returns the slot ID of the provided bridge. - int vme_slot_get(struct vme_dev *dev); + int vme_slot_num(struct vme_dev *dev); + + +Bus Detection +============= + +This function returns the bus ID of the provided bridge. + + int vme_bus_num(struct vme_dev *dev); + + diff --git a/MAINTAINERS b/MAINTAINERS index 12da4885e753..88ae0eca7cd8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2638,7 +2638,7 @@ DESIGNWARE USB2 DRD IP DRIVER M: Paul Zimmerman L: linux-usb@vger.kernel.org S: Maintained -F: drivers/staging/dwc2/ +F: drivers/usb/dwc2/ DESIGNWARE USB3 DRD IP DRIVER M: Felipe Balbi diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 90cf0cda50c4..5dd0e120a504 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -65,9 +65,11 @@ source "drivers/iio/common/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/humidity/Kconfig" source "drivers/iio/imu/Kconfig" source "drivers/iio/light/Kconfig" source "drivers/iio/magnetometer/Kconfig" +source "drivers/iio/orientation/Kconfig" if IIO_TRIGGER source "drivers/iio/trigger/Kconfig" endif #IIO_TRIGGER diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index bcf7e9e3b053..887d39090d75 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -18,9 +18,11 @@ obj-y += common/ obj-y += dac/ obj-y += gyro/ obj-y += frequency/ +obj-y += humidity/ obj-y += imu/ obj-y += light/ obj-y += magnetometer/ +obj-y += orientation/ obj-y += pressure/ obj-y += temperature/ obj-y += trigger/ diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 28b39283bccf..3bec9220df04 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -455,7 +455,12 @@ static const struct iio_chan_spec_ext_info bma180_ext_info[] = { BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .scan_index = (_index), \ - .scan_type = IIO_ST('s', 14, 16, 2), \ + .scan_type = { \ + .sign = 's', \ + .realbits = 14, \ + .storagebits = 16, \ + .shift = 2, \ + }, \ .ext_info = bma180_ext_info, \ } diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 1cae4e920c9b..3dcdbad65456 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -262,6 +262,18 @@ static int accel_3d_parse_report(struct platform_device *pdev, st->accel[1].index, st->accel[1].report_id, st->accel[2].index, st->accel[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ACCELERATION, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } + return ret; } diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index 58e945594c7b..70f78c3062a7 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -43,19 +43,22 @@ struct ad7266_state { * The buffer needs to be large enough to hold two samples (4 bytes) and * the naturally aligned timestamp (8 bytes). */ - uint8_t data[ALIGN(4, sizeof(s64)) + sizeof(s64)] ____cacheline_aligned; + struct { + __be16 sample[2]; + s64 timestamp; + } data ____cacheline_aligned; }; static int ad7266_wakeup(struct ad7266_state *st) { /* Any read with >= 2 bytes will wake the device */ - return spi_read(st->spi, st->data, 2); + return spi_read(st->spi, &st->data.sample[0], 2); } static int ad7266_powerdown(struct ad7266_state *st) { /* Any read with < 2 bytes will powerdown the device */ - return spi_read(st->spi, st->data, 1); + return spi_read(st->spi, &st->data.sample[0], 1); } static int ad7266_preenable(struct iio_dev *indio_dev) @@ -84,9 +87,9 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) struct ad7266_state *st = iio_priv(indio_dev); int ret; - ret = spi_read(st->spi, st->data, 4); + ret = spi_read(st->spi, st->data.sample, 4); if (ret == 0) { - iio_push_to_buffers_with_timestamp(indio_dev, st->data, + iio_push_to_buffers_with_timestamp(indio_dev, &st->data, pf->timestamp); } @@ -137,7 +140,7 @@ static int ad7266_read_single(struct ad7266_state *st, int *val, ad7266_select_input(st, address); ret = spi_sync(st->spi, &st->single_msg); - *val = be16_to_cpu(st->data[address % 2]); + *val = be16_to_cpu(st->data.sample[address % 2]); return ret; } @@ -442,15 +445,15 @@ static int ad7266_probe(struct spi_device *spi) ad7266_init_channels(indio_dev); /* wakeup */ - st->single_xfer[0].rx_buf = &st->data; + st->single_xfer[0].rx_buf = &st->data.sample[0]; st->single_xfer[0].len = 2; st->single_xfer[0].cs_change = 1; /* conversion */ - st->single_xfer[1].rx_buf = &st->data; + st->single_xfer[1].rx_buf = st->data.sample; st->single_xfer[1].len = 4; st->single_xfer[1].cs_change = 1; /* powerdown */ - st->single_xfer[2].tx_buf = &st->data; + st->single_xfer[2].tx_buf = &st->data.sample[0]; st->single_xfer[2].len = 1; spi_message_init(&st->single_msg); diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c index 6118dced02b6..e283f2f2ee2f 100644 --- a/drivers/iio/adc/max1363.c +++ b/drivers/iio/adc/max1363.c @@ -1039,10 +1039,10 @@ static const struct iio_info max1238_info = { }; static const struct iio_info max1363_info = { - .read_event_value_new = &max1363_read_thresh, - .write_event_value_new = &max1363_write_thresh, - .read_event_config_new = &max1363_read_event_config, - .write_event_config_new = &max1363_write_event_config, + .read_event_value = &max1363_read_thresh, + .write_event_value = &max1363_write_thresh, + .read_event_config = &max1363_read_event_config, + .write_event_config = &max1363_write_event_config, .read_raw = &max1363_read_raw, .update_scan_mode = &max1363_update_scan_mode, .driver_module = THIS_MODULE, diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index c8c1baaec6c1..47dcb34ff44c 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -362,7 +362,7 @@ static int mcp3422_probe(struct i2c_client *client, | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); mcp3422_update_config(adc, config); - err = iio_device_register(indio_dev); + err = devm_iio_device_register(&client->dev, indio_dev); if (err < 0) return err; @@ -371,12 +371,6 @@ static int mcp3422_probe(struct i2c_client *client, return 0; } -static int mcp3422_remove(struct i2c_client *client) -{ - iio_device_unregister(i2c_get_clientdata(client)); - return 0; -} - static const struct i2c_device_id mcp3422_id[] = { { "mcp3422", 2 }, { "mcp3423", 3 }, @@ -400,7 +394,6 @@ static struct i2c_driver mcp3422_driver = { .of_match_table = of_match_ptr(mcp3422_of_match), }, .probe = mcp3422_probe, - .remove = mcp3422_remove, .id_table = mcp3422_id, }; module_i2c_driver(mcp3422_driver); diff --git a/drivers/iio/adc/viperboard_adc.c b/drivers/iio/adc/viperboard_adc.c index 09727a71e9fa..d0add8f9416b 100644 --- a/drivers/iio/adc/viperboard_adc.c +++ b/drivers/iio/adc/viperboard_adc.c @@ -42,12 +42,6 @@ struct vprbrd_adc { .indexed = 1, \ .channel = _index, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .scan_index = _index, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 8, \ - .storagebits = 8, \ - }, \ } static struct iio_chan_spec const vprbrd_adc_iio_channels[] = { @@ -73,7 +67,7 @@ static int vprbrd_iio_read_raw(struct iio_dev *iio_dev, mutex_lock(&vb->lock); admsg->cmd = VPRBRD_ADC_CMD_GET; - admsg->chan = chan->scan_index; + admsg->chan = chan->channel; admsg->val = 0x00; ret = usb_control_msg(vb->usb_dev, @@ -139,7 +133,7 @@ static int vprbrd_adc_probe(struct platform_device *pdev) indio_dev->channels = vprbrd_adc_iio_channels; indio_dev->num_channels = ARRAY_SIZE(vprbrd_adc_iio_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&pdev->dev, indio_dev); if (ret) { dev_err(&pdev->dev, "could not register iio (adc)"); return ret; @@ -150,22 +144,12 @@ static int vprbrd_adc_probe(struct platform_device *pdev) return 0; } -static int vprbrd_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *indio_dev = platform_get_drvdata(pdev); - - iio_device_unregister(indio_dev); - - return 0; -} - static struct platform_driver vprbrd_adc_driver = { .driver = { .name = "viperboard-adc", .owner = THIS_MODULE, }, .probe = vprbrd_adc_probe, - .remove = vprbrd_adc_remove, }; module_platform_driver(vprbrd_adc_driver); diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index cb9c6366032c..f03b92fd3803 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -299,7 +299,12 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ .address = addr, \ - .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = 20 - bits, \ + }, \ .ext_info = ad5064_ext_info, \ } diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index b968af50db0a..64634d7f578e 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -107,7 +107,12 @@ enum ad5360_type { BIT(IIO_CHAN_INFO_OFFSET) | \ BIT(IIO_CHAN_INFO_CALIBSCALE) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ - .scan_type = IIO_ST('u', (bits), 16, 16 - (bits)) \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = 16 - (bits), \ + }, \ } static const struct ad5360_chip_info ad5360_chip_info_tbl[] = { diff --git a/drivers/iio/dac/ad5380.c b/drivers/iio/dac/ad5380.c index a59ff0e7b888..9de4c4d38280 100644 --- a/drivers/iio/dac/ad5380.c +++ b/drivers/iio/dac/ad5380.c @@ -261,7 +261,12 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = { BIT(IIO_CHAN_INFO_CALIBSCALE) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = 16, \ + .shift = 14 - (_bits), \ + }, \ .ext_info = ad5380_ext_info, \ } diff --git a/drivers/iio/dac/ad5421.c b/drivers/iio/dac/ad5421.c index 3eeaa82075f7..787ef1d859c6 100644 --- a/drivers/iio/dac/ad5421.c +++ b/drivers/iio/dac/ad5421.c @@ -75,7 +75,7 @@ struct ad5421_state { * transfer buffers to live in their own cache lines. */ union { - u32 d32; + __be32 d32; u8 d8[4]; } data[2] ____cacheline_aligned; }; @@ -114,7 +114,11 @@ static const struct iio_chan_spec ad5421_channels[] = { BIT(IIO_CHAN_INFO_CALIBBIAS), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET), - .scan_type = IIO_ST('u', 16, 16, 0), + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + }, .event_spec = ad5421_current_event, .num_event_specs = ARRAY_SIZE(ad5421_current_event), }, @@ -458,9 +462,9 @@ static int ad5421_read_event_value(struct iio_dev *indio_dev, static const struct iio_info ad5421_info = { .read_raw = ad5421_read_raw, .write_raw = ad5421_write_raw, - .read_event_config_new = ad5421_read_event_config, - .write_event_config_new = ad5421_write_event_config, - .read_event_value_new = ad5421_read_event_value, + .read_event_config = ad5421_read_event_config, + .write_event_config = ad5421_write_event_config, + .read_event_value = ad5421_read_event_value, .driver_module = THIS_MODULE, }; @@ -514,16 +518,7 @@ static int ad5421_probe(struct spi_device *spi) return ret; } - return iio_device_register(indio_dev); -} - -static int ad5421_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver ad5421_driver = { @@ -532,7 +527,6 @@ static struct spi_driver ad5421_driver = { .owner = THIS_MODULE, }, .probe = ad5421_probe, - .remove = ad5421_remove, }; module_spi_driver(ad5421_driver); diff --git a/drivers/iio/dac/ad5446.c b/drivers/iio/dac/ad5446.c index 1263b0e5ad84..46bb62a5c1d4 100644 --- a/drivers/iio/dac/ad5446.c +++ b/drivers/iio/dac/ad5446.c @@ -139,14 +139,19 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { { }, }; -#define _AD5446_CHANNEL(bits, storage, shift, ext) { \ +#define _AD5446_CHANNEL(bits, storage, _shift, ext) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ .channel = 0, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ - .scan_type = IIO_ST('u', (bits), (storage), (shift)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = (storage), \ + .shift = (_shift), \ + }, \ .ext_info = (ext), \ } diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index 82e208f6cde2..64d7256cbb6d 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -204,7 +204,12 @@ static const struct iio_info ad5449_info = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ .address = (chan), \ - .scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = 12 - (bits), \ + }, \ } #define DECLARE_AD5449_CHANNELS(name, bits) \ diff --git a/drivers/iio/dac/ad5504.c b/drivers/iio/dac/ad5504.c index c0957a918e17..1e6449346b50 100644 --- a/drivers/iio/dac/ad5504.c +++ b/drivers/iio/dac/ad5504.c @@ -47,14 +47,16 @@ * @vref_mv: actual reference voltage used * @pwr_down_mask power down mask * @pwr_down_mode current power down mode + * @data: transfer buffer */ - struct ad5504_state { struct spi_device *spi; struct regulator *reg; unsigned short vref_mv; unsigned pwr_down_mask; unsigned pwr_down_mode; + + __be16 data[2] ____cacheline_aligned; }; /** @@ -66,31 +68,29 @@ enum ad5504_supported_device_ids { ID_AD5501, }; -static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val) +static int ad5504_spi_write(struct ad5504_state *st, u8 addr, u16 val) { - u16 tmp = cpu_to_be16(AD5504_CMD_WRITE | - AD5504_ADDR(addr) | + st->data[0] = cpu_to_be16(AD5504_CMD_WRITE | AD5504_ADDR(addr) | (val & AD5504_RES_MASK)); - return spi_write(spi, (u8 *)&tmp, 2); + return spi_write(st->spi, &st->data[0], 2); } -static int ad5504_spi_read(struct spi_device *spi, u8 addr) +static int ad5504_spi_read(struct ad5504_state *st, u8 addr) { - u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr)); - u16 val; int ret; - struct spi_transfer t = { - .tx_buf = &tmp, - .rx_buf = &val, - .len = 2, - }; - ret = spi_sync_transfer(spi, &t, 1); + struct spi_transfer t = { + .tx_buf = &st->data[0], + .rx_buf = &st->data[1], + .len = 2, + }; + st->data[0] = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr)); + ret = spi_sync_transfer(st->spi, &t, 1); if (ret < 0) return ret; - return be16_to_cpu(val) & AD5504_RES_MASK; + return be16_to_cpu(st->data[1]) & AD5504_RES_MASK; } static int ad5504_read_raw(struct iio_dev *indio_dev, @@ -104,7 +104,7 @@ static int ad5504_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_RAW: - ret = ad5504_spi_read(st->spi, chan->address); + ret = ad5504_spi_read(st, chan->address); if (ret < 0) return ret; @@ -133,7 +133,7 @@ static int ad5504_write_raw(struct iio_dev *indio_dev, if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; - return ad5504_spi_write(st->spi, chan->address, val); + return ad5504_spi_write(st, chan->address, val); default: ret = -EINVAL; } @@ -197,12 +197,12 @@ static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev, else st->pwr_down_mask &= ~(1 << chan->channel); - ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL, + ret = ad5504_spi_write(st, AD5504_ADDR_CTRL, AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | AD5504_DAC_PWR(st->pwr_down_mask)); /* writes to the CTRL register must be followed by a NOOP */ - ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0); + ad5504_spi_write(st, AD5504_ADDR_NOOP, 0); return ret ? ret : len; } @@ -261,7 +261,11 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = AD5504_ADDR_DAC(_chan), \ - .scan_type = IIO_ST('u', 12, 16, 0), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ .ext_info = ad5504_ext_info, \ } diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c index 774dd968145b..e8199cce2aea 100644 --- a/drivers/iio/dac/ad5624r_spi.c +++ b/drivers/iio/dac/ad5624r_spi.c @@ -176,7 +176,12 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ .address = (_chan), \ - .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = 16, \ + .shift = 16 - (_bits), \ + }, \ .ext_info = ad5624r_ext_info, \ } diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 30e506e37dd2..17aca4d9bd06 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -78,7 +78,7 @@ struct ad5686_state { */ union { - u32 d32; + __be32 d32; u8 d8[4]; } data[3] ____cacheline_aligned; }; @@ -267,7 +267,7 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { { }, }; -#define AD5868_CHANNEL(chan, bits, shift) { \ +#define AD5868_CHANNEL(chan, bits, _shift) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ @@ -275,7 +275,12 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ .address = AD5686_ADDR_DAC(chan), \ - .scan_type = IIO_ST('u', bits, 16, shift), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .shift = (_shift), \ + }, \ .ext_info = ad5686_ext_info, \ } diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c index 9a78d5abb2f6..a7c851f62d7c 100644 --- a/drivers/iio/dac/ad5755.c +++ b/drivers/iio/dac/ad5755.c @@ -97,7 +97,7 @@ struct ad5755_state { */ union { - u32 d32; + __be32 d32; u8 d8[4]; } data[2] ____cacheline_aligned; }; @@ -392,7 +392,12 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { BIT(IIO_CHAN_INFO_OFFSET) | \ BIT(IIO_CHAN_INFO_CALIBSCALE) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ - .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = 16, \ + .shift = 16 - (_bits), \ + }, \ .ext_info = ad5755_ext_info, \ } @@ -589,16 +594,7 @@ static int ad5755_probe(struct spi_device *spi) if (ret) return ret; - return iio_device_register(indio_dev); -} - -static int ad5755_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - - iio_device_unregister(indio_dev); - - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static const struct spi_device_id ad5755_id[] = { @@ -617,7 +613,6 @@ static struct spi_driver ad5755_driver = { .owner = THIS_MODULE, }, .probe = ad5755_probe, - .remove = ad5755_remove, .id_table = ad5755_id, }; module_spi_driver(ad5755_driver); diff --git a/drivers/iio/dac/ad5764.c b/drivers/iio/dac/ad5764.c index a8ff5b2ed13e..d0d38165339d 100644 --- a/drivers/iio/dac/ad5764.c +++ b/drivers/iio/dac/ad5764.c @@ -83,7 +83,12 @@ enum ad5764_type { BIT(IIO_CHAN_INFO_CALIBSCALE) | \ BIT(IIO_CHAN_INFO_CALIBBIAS), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET), \ - .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)) \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = 16, \ + .shift = 16 - (_bits), \ + }, \ } #define DECLARE_AD5764_CHANNELS(_name, _bits) \ diff --git a/drivers/iio/dac/ad5791.c b/drivers/iio/dac/ad5791.c index d64acbd89482..ae49afe2b380 100644 --- a/drivers/iio/dac/ad5791.c +++ b/drivers/iio/dac/ad5791.c @@ -91,6 +91,11 @@ struct ad5791_state { unsigned ctrl; unsigned pwr_down_mode; bool pwr_down; + + union { + __be32 d32; + u8 d8[4]; + } data[3] ____cacheline_aligned; }; /** @@ -104,48 +109,39 @@ enum ad5791_supported_device_ids { ID_AD5791, }; -static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val) +static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val) { - union { - u32 d32; - u8 d8[4]; - } data; - - data.d32 = cpu_to_be32(AD5791_CMD_WRITE | + st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE | AD5791_ADDR(addr) | (val & AD5791_DAC_MASK)); - return spi_write(spi, &data.d8[1], 3); + return spi_write(st->spi, &st->data[0].d8[1], 3); } -static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val) +static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val) { - union { - u32 d32; - u8 d8[4]; - } data[3]; int ret; struct spi_transfer xfers[] = { { - .tx_buf = &data[0].d8[1], + .tx_buf = &st->data[0].d8[1], .bits_per_word = 8, .len = 3, .cs_change = 1, }, { - .tx_buf = &data[1].d8[1], - .rx_buf = &data[2].d8[1], + .tx_buf = &st->data[1].d8[1], + .rx_buf = &st->data[2].d8[1], .bits_per_word = 8, .len = 3, }, }; - data[0].d32 = cpu_to_be32(AD5791_CMD_READ | + st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ | AD5791_ADDR(addr)); - data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP)); + st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP)); - ret = spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); + ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); - *val = be32_to_cpu(data[2].d32); + *val = be32_to_cpu(st->data[2].d32); return ret; } @@ -210,7 +206,7 @@ static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev, } st->pwr_down = pwr_down; - ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl); + ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl); return ret ? ret : len; } @@ -263,7 +259,7 @@ static int ad5791_read_raw(struct iio_dev *indio_dev, switch (m) { case IIO_CHAN_INFO_RAW: - ret = ad5791_spi_read(st->spi, chan->address, val); + ret = ad5791_spi_read(st, chan->address, val); if (ret) return ret; *val &= AD5791_DAC_MASK; @@ -297,7 +293,7 @@ static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { { }, }; -#define AD5791_CHAN(bits, shift) { \ +#define AD5791_CHAN(bits, _shift) { \ .type = IIO_VOLTAGE, \ .output = 1, \ .indexed = 1, \ @@ -306,7 +302,12 @@ static const struct iio_chan_spec_ext_info ad5791_ext_info[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OFFSET), \ - .scan_type = IIO_ST('u', bits, 24, shift), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 24, \ + .shift = (_shift), \ + }, \ .ext_info = ad5791_ext_info, \ } @@ -330,7 +331,7 @@ static int ad5791_write_raw(struct iio_dev *indio_dev, val &= AD5791_RES_MASK(chan->scan_type.realbits); val <<= chan->scan_type.shift; - return ad5791_spi_write(st->spi, chan->address, val); + return ad5791_spi_write(st, chan->address, val); default: return -EINVAL; @@ -393,7 +394,7 @@ static int ad5791_probe(struct spi_device *spi) dev_warn(&spi->dev, "reference voltage unspecified\n"); } - ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); + ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET); if (ret) goto error_disable_reg_neg; @@ -405,7 +406,7 @@ static int ad5791_probe(struct spi_device *spi) | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) | AD5791_CTRL_BIN2SC; - ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl | + ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl | AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI); if (ret) goto error_disable_reg_neg; diff --git a/drivers/iio/dac/max517.c b/drivers/iio/dac/max517.c index 6e1903537950..de76e6a34c1e 100644 --- a/drivers/iio/dac/max517.c +++ b/drivers/iio/dac/max517.c @@ -146,7 +146,6 @@ static const struct iio_info max517_info = { .channel = (chan), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE), \ - .scan_type = IIO_ST('u', 8, 8, 0), \ } static const struct iio_chan_spec max517_channels[] = { diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index 9f57ae84ab89..7d9f5c31d2fc 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c @@ -209,7 +209,6 @@ static const struct iio_chan_spec mcp4725_channel = { .channel = 0, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), - .scan_type = IIO_ST('u', 12, 16, 0), .ext_info = mcp4725_ext_info, }; diff --git a/drivers/iio/gyro/adis16130.c b/drivers/iio/gyro/adis16130.c index 445c2aecfadd..8d08c7ed1ea6 100644 --- a/drivers/iio/gyro/adis16130.c +++ b/drivers/iio/gyro/adis16130.c @@ -161,13 +161,7 @@ static int adis16130_probe(struct spi_device *spi) indio_dev->info = &adis16130_info; indio_dev->modes = INDIO_DIRECT_MODE; - return iio_device_register(indio_dev); -} - -static int adis16130_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - return 0; + return devm_iio_device_register(&spi->dev, indio_dev); } static struct spi_driver adis16130_driver = { @@ -176,7 +170,6 @@ static struct spi_driver adis16130_driver = { .owner = THIS_MODULE, }, .probe = adis16130_probe, - .remove = adis16130_remove, }; module_spi_driver(adis16130_driver); diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c index 1e546ba7ba45..eb0e08ec9e20 100644 --- a/drivers/iio/gyro/adxrs450.c +++ b/drivers/iio/gyro/adxrs450.c @@ -434,23 +434,14 @@ static int adxrs450_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels); indio_dev->name = spi->dev.driver->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; /* Get the device into a sane initial state */ ret = adxrs450_initial_setup(indio_dev); if (ret) - goto error_initial; - return 0; -error_initial: - iio_device_unregister(indio_dev); - return ret; -} - -static int adxrs450_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); + return ret; return 0; } @@ -468,7 +459,6 @@ static struct spi_driver adxrs450_driver = { .owner = THIS_MODULE, }, .probe = adxrs450_probe, - .remove = adxrs450_remove, .id_table = adxrs450_id, }; module_spi_driver(adxrs450_driver); diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index e54f0f4959d3..59d6bc3e04df 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -262,6 +262,17 @@ static int gyro_3d_parse_report(struct platform_device *pdev, st->gyro[1].index, st->gyro[1].report_id, st->gyro[2].index, st->gyro[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ANGL_VELOCITY, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } return ret; } diff --git a/drivers/iio/humidity/Kconfig b/drivers/iio/humidity/Kconfig new file mode 100644 index 000000000000..463c4d9da79e --- /dev/null +++ b/drivers/iio/humidity/Kconfig @@ -0,0 +1,15 @@ +# +# humidity sensor drivers +# +menu "Humidity sensors" + +config DHT11 + tristate "DHT11 (and compatible sensors) driver" + depends on GPIOLIB + help + This driver supports reading data via a single interrupt + generating GPIO line. Currently tested are DHT11 and DHT22. + Other sensors should work as well as long as they speak the + same protocol. + +endmenu diff --git a/drivers/iio/humidity/Makefile b/drivers/iio/humidity/Makefile new file mode 100644 index 000000000000..d5d36c0c95f9 --- /dev/null +++ b/drivers/iio/humidity/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for IIO humidity sensor drivers +# + +obj-$(CONFIG_DHT11) += dht11.o diff --git a/drivers/iio/humidity/dht11.c b/drivers/iio/humidity/dht11.c new file mode 100644 index 000000000000..d8771f546bf2 --- /dev/null +++ b/drivers/iio/humidity/dht11.c @@ -0,0 +1,294 @@ +/* + * DHT11/DHT22 bit banging GPIO driver + * + * Copyright (c) Harald Geyer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "dht11" + +#define DHT11_DATA_VALID_TIME 2000000000 /* 2s in ns */ + +#define DHT11_EDGES_PREAMBLE 4 +#define DHT11_BITS_PER_READ 40 +#define DHT11_EDGES_PER_READ (2*DHT11_BITS_PER_READ + DHT11_EDGES_PREAMBLE + 1) + +/* Data transmission timing (nano seconds) */ +#define DHT11_START_TRANSMISSION 18 /* ms */ +#define DHT11_SENSOR_RESPONSE 80000 +#define DHT11_START_BIT 50000 +#define DHT11_DATA_BIT_LOW 27000 +#define DHT11_DATA_BIT_HIGH 70000 + +struct dht11 { + struct device *dev; + + int gpio; + int irq; + + struct completion completion; + + s64 timestamp; + int temperature; + int humidity; + + /* num_edges: -1 means "no transmission in progress" */ + int num_edges; + struct {s64 ts; int value; } edges[DHT11_EDGES_PER_READ]; +}; + +static unsigned char dht11_decode_byte(int *timing, int threshold) +{ + unsigned char ret = 0; + int i; + + for (i = 0; i < 8; ++i) { + ret <<= 1; + if (timing[i] >= threshold) + ++ret; + } + + return ret; +} + +static int dht11_decode(struct dht11 *dht11, int offset) +{ + int i, t, timing[DHT11_BITS_PER_READ], threshold, + timeres = DHT11_SENSOR_RESPONSE; + unsigned char temp_int, temp_dec, hum_int, hum_dec, checksum; + + /* Calculate timestamp resolution */ + for (i = 0; i < dht11->num_edges; ++i) { + t = dht11->edges[i].ts - dht11->edges[i-1].ts; + if (t > 0 && t < timeres) + timeres = t; + } + if (2*timeres > DHT11_DATA_BIT_HIGH) { + pr_err("dht11: timeresolution %d too bad for decoding\n", + timeres); + return -EIO; + } + threshold = DHT11_DATA_BIT_HIGH / timeres; + if (DHT11_DATA_BIT_LOW/timeres + 1 >= threshold) + pr_err("dht11: WARNING: decoding ambiguous\n"); + + /* scale down with timeres and check validity */ + for (i = 0; i < DHT11_BITS_PER_READ; ++i) { + t = dht11->edges[offset + 2*i + 2].ts - + dht11->edges[offset + 2*i + 1].ts; + if (!dht11->edges[offset + 2*i + 1].value) + return -EIO; /* lost synchronisation */ + timing[i] = t / timeres; + } + + hum_int = dht11_decode_byte(timing, threshold); + hum_dec = dht11_decode_byte(&timing[8], threshold); + temp_int = dht11_decode_byte(&timing[16], threshold); + temp_dec = dht11_decode_byte(&timing[24], threshold); + checksum = dht11_decode_byte(&timing[32], threshold); + + if (((hum_int + hum_dec + temp_int + temp_dec) & 0xff) != checksum) + return -EIO; + + dht11->timestamp = iio_get_time_ns(); + if (hum_int < 20) { /* DHT22 */ + dht11->temperature = (((temp_int & 0x7f) << 8) + temp_dec) * + ((temp_int & 0x80) ? -100 : 100); + dht11->humidity = ((hum_int << 8) + hum_dec) * 100; + } else if (temp_dec == 0 && hum_dec == 0) { /* DHT11 */ + dht11->temperature = temp_int * 1000; + dht11->humidity = hum_int * 1000; + } else { + dev_err(dht11->dev, + "Don't know how to decode data: %d %d %d %d\n", + hum_int, hum_dec, temp_int, temp_dec); + return -EIO; + } + + return 0; +} + +static int dht11_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long m) +{ + struct dht11 *dht11 = iio_priv(iio_dev); + int ret; + + if (dht11->timestamp + DHT11_DATA_VALID_TIME < iio_get_time_ns()) { + reinit_completion(&dht11->completion); + + dht11->num_edges = 0; + ret = gpio_direction_output(dht11->gpio, 0); + if (ret) + goto err; + msleep(DHT11_START_TRANSMISSION); + ret = gpio_direction_input(dht11->gpio); + if (ret) + goto err; + + ret = wait_for_completion_killable_timeout(&dht11->completion, + HZ); + if (ret == 0 && dht11->num_edges < DHT11_EDGES_PER_READ - 1) { + dev_err(&iio_dev->dev, + "Only %d signal edges detected\n", + dht11->num_edges); + ret = -ETIMEDOUT; + } + if (ret < 0) + goto err; + + ret = dht11_decode(dht11, + dht11->num_edges == DHT11_EDGES_PER_READ ? + DHT11_EDGES_PREAMBLE : + DHT11_EDGES_PREAMBLE - 2); + if (ret) + goto err; + } + + ret = IIO_VAL_INT; + if (chan->type == IIO_TEMP) + *val = dht11->temperature; + else if (chan->type == IIO_HUMIDITYRELATIVE) + *val = dht11->humidity; + else + ret = -EINVAL; +err: + dht11->num_edges = -1; + return ret; +} + +static const struct iio_info dht11_iio_info = { + .driver_module = THIS_MODULE, + .read_raw = dht11_read_raw, +}; + +/* + * IRQ handler called on GPIO edges +*/ +static irqreturn_t dht11_handle_irq(int irq, void *data) +{ + struct iio_dev *iio = data; + struct dht11 *dht11 = iio_priv(iio); + + /* TODO: Consider making the handler safe for IRQ sharing */ + if (dht11->num_edges < DHT11_EDGES_PER_READ && dht11->num_edges >= 0) { + dht11->edges[dht11->num_edges].ts = iio_get_time_ns(); + dht11->edges[dht11->num_edges++].value = + gpio_get_value(dht11->gpio); + + if (dht11->num_edges >= DHT11_EDGES_PER_READ) + complete(&dht11->completion); + } + + return IRQ_HANDLED; +} + +static const struct iio_chan_spec dht11_chan_spec[] = { + { .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), }, + { .type = IIO_HUMIDITYRELATIVE, + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), } +}; + +static const struct of_device_id dht11_dt_ids[] = { + { .compatible = "dht11", }, + { } +}; +MODULE_DEVICE_TABLE(of, dht11_dt_ids); + +static int dht11_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct dht11 *dht11; + struct iio_dev *iio; + int ret; + + iio = devm_iio_device_alloc(dev, sizeof(*dht11)); + if (!iio) { + dev_err(dev, "Failed to allocate IIO device\n"); + return -ENOMEM; + } + + dht11 = iio_priv(iio); + dht11->dev = dev; + + dht11->gpio = ret = of_get_gpio(node, 0); + if (ret < 0) + return ret; + ret = devm_gpio_request_one(dev, dht11->gpio, GPIOF_IN, pdev->name); + if (ret) + return ret; + + dht11->irq = gpio_to_irq(dht11->gpio); + if (dht11->irq < 0) { + dev_err(dev, "GPIO %d has no interrupt\n", dht11->gpio); + return -EINVAL; + } + ret = devm_request_irq(dev, dht11->irq, dht11_handle_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + pdev->name, iio); + if (ret) + return ret; + + dht11->timestamp = iio_get_time_ns() - DHT11_DATA_VALID_TIME - 1; + dht11->num_edges = -1; + + platform_set_drvdata(pdev, iio); + + init_completion(&dht11->completion); + iio->name = pdev->name; + iio->dev.parent = &pdev->dev; + iio->info = &dht11_iio_info; + iio->modes = INDIO_DIRECT_MODE; + iio->channels = dht11_chan_spec; + iio->num_channels = ARRAY_SIZE(dht11_chan_spec); + + return devm_iio_device_register(dev, iio); +} + +static struct platform_driver dht11_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = dht11_dt_ids, + }, + .probe = dht11_probe, +}; + +module_platform_driver(dht11_driver); + +MODULE_AUTHOR("Harald Geyer "); +MODULE_DESCRIPTION("DHT11 humidity/temperature sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 7f9152c3c4d3..c67d83bdc8f0 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -37,6 +37,14 @@ static bool iio_buffer_is_active(struct iio_buffer *buf) return !list_empty(&buf->buffer_list); } +static bool iio_buffer_data_available(struct iio_buffer *buf) +{ + if (buf->access->data_available) + return buf->access->data_available(buf); + + return buf->stufftoread; +} + /** * iio_buffer_read_first_n_outer() - chrdev read for buffer access * @@ -48,13 +56,34 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf, { struct iio_dev *indio_dev = filp->private_data; struct iio_buffer *rb = indio_dev->buffer; + int ret; if (!indio_dev->info) return -ENODEV; if (!rb || !rb->access->read_first_n) return -EINVAL; - return rb->access->read_first_n(rb, n, buf); + + do { + if (!iio_buffer_data_available(rb)) { + if (filp->f_flags & O_NONBLOCK) + return -EAGAIN; + + ret = wait_event_interruptible(rb->pollq, + iio_buffer_data_available(rb) || + indio_dev->info == NULL); + if (ret) + return ret; + if (indio_dev->info == NULL) + return -ENODEV; + } + + ret = rb->access->read_first_n(rb, n, buf); + if (ret == 0 && (filp->f_flags & O_NONBLOCK)) + ret = -EAGAIN; + } while (ret == 0); + + return ret; } /** @@ -70,7 +99,7 @@ unsigned int iio_buffer_poll(struct file *filp, return -ENODEV; poll_wait(filp, &rb->pollq, wait); - if (rb->stufftoread) + if (iio_buffer_data_available(rb)) return POLLIN | POLLRDNORM; /* need a way of knowing if there may be enough data... */ return 0; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 18f72e3d0ed6..acc911a836ca 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -69,6 +69,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ALTVOLTAGE] = "altvoltage", [IIO_CCT] = "cct", [IIO_PRESSURE] = "pressure", + [IIO_HUMIDITYRELATIVE] = "humidityrelative", }; static const char * const iio_modifier_names[] = { @@ -107,6 +108,11 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_INT_TIME] = "integration_time", }; +/** + * iio_find_channel_from_si() - get channel from its scan index + * @indio_dev: device + * @si: scan index to match + */ const struct iio_chan_spec *iio_find_channel_from_si(struct iio_dev *indio_dev, int si) { @@ -922,6 +928,10 @@ struct device_type iio_device_type = { .release = iio_dev_release, }; +/** + * iio_device_alloc() - allocate an iio_dev from a driver + * @sizeof_priv: Space to allocate for private structure. + **/ struct iio_dev *iio_device_alloc(int sizeof_priv) { struct iio_dev *dev; @@ -962,6 +972,10 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) } EXPORT_SYMBOL(iio_device_alloc); +/** + * iio_device_free() - free an iio_dev from a driver + * @dev: the iio_dev associated with the device + **/ void iio_device_free(struct iio_dev *dev) { if (dev) @@ -984,6 +998,20 @@ static int devm_iio_device_match(struct device *dev, void *res, void *data) return *r == data; } +/** + * devm_iio_device_alloc - Resource-managed iio_device_alloc() + * @dev: Device to allocate iio_dev for + * @sizeof_priv: Space to allocate for private structure. + * + * Managed iio_device_alloc. iio_dev allocated with this function is + * automatically freed on driver detach. + * + * If an iio_dev allocated with this function needs to be freed separately, + * devm_iio_device_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_dev on success, NULL on failure. + */ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) { struct iio_dev **ptr, *iio_dev; @@ -1006,6 +1034,13 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv) } EXPORT_SYMBOL_GPL(devm_iio_device_alloc); +/** + * devm_iio_device_free - Resource-managed iio_device_free() + * @dev: Device this iio_dev belongs to + * @iio_dev: the iio_dev associated with the device + * + * Free iio_dev allocated with devm_iio_device_alloc(). + */ void devm_iio_device_free(struct device *dev, struct iio_dev *iio_dev) { int rc; @@ -1080,6 +1115,10 @@ static const struct file_operations iio_buffer_fileops = { static const struct iio_buffer_setup_ops noop_ring_setup_ops; +/** + * iio_device_register() - register a device with the IIO subsystem + * @indio_dev: Device structure filled by the device driver + **/ int iio_device_register(struct iio_dev *indio_dev) { int ret; @@ -1141,6 +1180,10 @@ error_ret: } EXPORT_SYMBOL(iio_device_register); +/** + * iio_device_unregister() - unregister a device from the IIO subsystem + * @indio_dev: Device structure representing the device. + **/ void iio_device_unregister(struct iio_dev *indio_dev) { mutex_lock(&indio_dev->info_exist_lock); @@ -1161,6 +1204,65 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_unlock(&indio_dev->info_exist_lock); } EXPORT_SYMBOL(iio_device_unregister); + +static void devm_iio_device_unreg(struct device *dev, void *res) +{ + iio_device_unregister(*(struct iio_dev **)res); +} + +/** + * devm_iio_device_register - Resource-managed iio_device_register() + * @dev: Device to allocate iio_dev for + * @indio_dev: Device structure filled by the device driver + * + * Managed iio_device_register. The IIO device registered with this + * function is automatically unregistered on driver detach. This function + * calls iio_device_register() internally. Refer to that function for more + * information. + * + * If an iio_dev registered with this function needs to be unregistered + * separately, devm_iio_device_unregister() must be used. + * + * RETURNS: + * 0 on success, negative error number on failure. + */ +int devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev) +{ + struct iio_dev **ptr; + int ret; + + ptr = devres_alloc(devm_iio_device_unreg, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + *ptr = indio_dev; + ret = iio_device_register(indio_dev); + if (!ret) + devres_add(dev, ptr); + else + devres_free(ptr); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_iio_device_register); + +/** + * devm_iio_device_unregister - Resource-managed iio_device_unregister() + * @dev: Device this iio_dev belongs to + * @indio_dev: the iio_dev associated with the device + * + * Unregister iio_dev registered with devm_iio_device_register(). + */ +void devm_iio_device_unregister(struct device *dev, struct iio_dev *indio_dev) +{ + int rc; + + rc = devres_release(dev, devm_iio_device_unreg, + devm_iio_device_match, indio_dev); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_iio_device_unregister); + subsys_initcall(iio_init); module_exit(iio_exit); diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index c10eab64bc05..c9c1419fe6e0 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -42,6 +42,12 @@ struct iio_event_interface { struct attribute_group group; }; +/** + * iio_push_event() - try to add event to the list for userspace reading + * @indio_dev: IIO device structure + * @ev_code: What event + * @timestamp: When the event occurred + **/ int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp) { struct iio_event_interface *ev_int = indio_dev->event_interface; @@ -236,13 +242,9 @@ static ssize_t iio_ev_state_store(struct device *dev, if (ret < 0) return ret; - if (indio_dev->info->write_event_config) - ret = indio_dev->info->write_event_config(indio_dev, - this_attr->address, val); - else - ret = indio_dev->info->write_event_config_new(indio_dev, - this_attr->c, iio_ev_attr_type(this_attr), - iio_ev_attr_dir(this_attr), val); + ret = indio_dev->info->write_event_config(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr), val); return (ret < 0) ? ret : len; } @@ -255,13 +257,9 @@ static ssize_t iio_ev_state_show(struct device *dev, struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int val; - if (indio_dev->info->read_event_config) - val = indio_dev->info->read_event_config(indio_dev, - this_attr->address); - else - val = indio_dev->info->read_event_config_new(indio_dev, - this_attr->c, iio_ev_attr_type(this_attr), - iio_ev_attr_dir(this_attr)); + val = indio_dev->info->read_event_config(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr)); if (val < 0) return val; else @@ -277,21 +275,13 @@ static ssize_t iio_ev_value_show(struct device *dev, int val, val2; int ret; - if (indio_dev->info->read_event_value) { - ret = indio_dev->info->read_event_value(indio_dev, - this_attr->address, &val); - if (ret < 0) - return ret; - return sprintf(buf, "%d\n", val); - } else { - ret = indio_dev->info->read_event_value_new(indio_dev, - this_attr->c, iio_ev_attr_type(this_attr), - iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), - &val, &val2); - if (ret < 0) - return ret; - return iio_format_value(buf, ret, val, val2); - } + ret = indio_dev->info->read_event_value(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), + &val, &val2); + if (ret < 0) + return ret; + return iio_format_value(buf, ret, val, val2); } static ssize_t iio_ev_value_store(struct device *dev, @@ -304,25 +294,16 @@ static ssize_t iio_ev_value_store(struct device *dev, int val, val2; int ret; - if (!indio_dev->info->write_event_value && - !indio_dev->info->write_event_value_new) + if (!indio_dev->info->write_event_value) return -EINVAL; - if (indio_dev->info->write_event_value) { - ret = kstrtoint(buf, 10, &val); - if (ret) - return ret; - ret = indio_dev->info->write_event_value(indio_dev, - this_attr->address, val); - } else { - ret = iio_str_to_fixpoint(buf, 100000, &val, &val2); - if (ret) - return ret; - ret = indio_dev->info->write_event_value_new(indio_dev, - this_attr->c, iio_ev_attr_type(this_attr), - iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), - val, val2); - } + ret = iio_str_to_fixpoint(buf, 100000, &val, &val2); + if (ret) + return ret; + ret = indio_dev->info->write_event_value(indio_dev, + this_attr->c, iio_ev_attr_type(this_attr), + iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr), + val, val2); if (ret < 0) return ret; @@ -371,7 +352,7 @@ static int iio_device_add_event(struct iio_dev *indio_dev, return attrcount; } -static int iio_device_add_event_sysfs_new(struct iio_dev *indio_dev, +static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, struct iio_chan_spec const *chan) { int ret = 0, i, attrcount = 0; @@ -414,89 +395,6 @@ error_ret: return ret; } -static int iio_device_add_event_sysfs_old(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - int ret = 0, i, attrcount = 0; - u64 mask = 0; - char *postfix; - if (!chan->event_mask) - return 0; - - for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) { - postfix = kasprintf(GFP_KERNEL, "%s_%s_en", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - if (chan->modified) - mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel2, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - else if (chan->differential) - mask = IIO_EVENT_CODE(chan->type, - 0, 0, - i%IIO_EV_DIR_MAX, - i/IIO_EV_DIR_MAX, - 0, - chan->channel, - chan->channel2); - else - mask = IIO_UNMOD_EVENT_CODE(chan->type, - chan->channel, - i/IIO_EV_DIR_MAX, - i%IIO_EV_DIR_MAX); - - ret = __iio_add_chan_devattr(postfix, - chan, - &iio_ev_state_show, - iio_ev_state_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - postfix = kasprintf(GFP_KERNEL, "%s_%s_value", - iio_ev_type_text[i/IIO_EV_DIR_MAX], - iio_ev_dir_text[i%IIO_EV_DIR_MAX]); - if (postfix == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = __iio_add_chan_devattr(postfix, chan, - iio_ev_value_show, - iio_ev_value_store, - mask, - 0, - &indio_dev->dev, - &indio_dev->event_interface-> - dev_attr_list); - kfree(postfix); - if (ret) - goto error_ret; - attrcount++; - } - ret = attrcount; -error_ret: - return ret; -} - - -static int iio_device_add_event_sysfs(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan) -{ - if (chan->event_mask) - return iio_device_add_event_sysfs_old(indio_dev, chan); - else - return iio_device_add_event_sysfs_new(indio_dev, chan); -} - static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) { int j, ret, attrcount = 0; @@ -517,8 +415,6 @@ static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) int j; for (j = 0; j < indio_dev->num_channels; j++) { - if (indio_dev->channels[j].event_mask != 0) - return true; if (indio_dev->channels[j].num_event_specs != 0) return true; } diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index bf5e70a32d3f..766fab24b720 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -55,15 +55,7 @@ static struct attribute *iio_trig_dev_attrs[] = { &dev_attr_name.attr, NULL, }; - -static struct attribute_group iio_trig_attr_group = { - .attrs = iio_trig_dev_attrs, -}; - -static const struct attribute_group *iio_trig_attr_groups[] = { - &iio_trig_attr_group, - NULL -}; +ATTRIBUTE_GROUPS(iio_trig_dev); int iio_trigger_register(struct iio_trigger *trig_info) { @@ -318,7 +310,7 @@ static ssize_t iio_trigger_read_current(struct device *dev, * iio_trigger_write_current() - trigger consumer sysfs set current trigger * * For trigger consumers the current_trigger interface allows the trigger - * used for this device to be specified at run time based on the triggers + * used for this device to be specified at run time based on the trigger's * name. **/ static ssize_t iio_trigger_write_current(struct device *dev, @@ -356,7 +348,7 @@ static ssize_t iio_trigger_write_current(struct device *dev, indio_dev->trig = trig; - if (oldtrig && indio_dev->trig != oldtrig) + if (oldtrig) iio_trigger_put(oldtrig); if (indio_dev->trig) iio_trigger_get(indio_dev->trig); @@ -403,7 +395,7 @@ static void iio_trig_release(struct device *device) static struct device_type iio_trig_type = { .release = iio_trig_release, - .groups = iio_trig_attr_groups, + .groups = iio_trig_dev_groups, }; static void iio_trig_subirqmask(struct irq_data *d) @@ -506,6 +498,23 @@ static int devm_iio_trigger_match(struct device *dev, void *res, void *data) return *r == data; } +/** + * devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc() + * @dev: Device to allocate iio_trigger for + * @fmt: trigger name format. If it includes format + * specifiers, the additional arguments following + * format are formatted and inserted in the resulting + * string replacing their respective specifiers. + * + * Managed iio_trigger_alloc. iio_trigger allocated with this function is + * automatically freed on driver detach. + * + * If an iio_trigger allocated with this function needs to be freed separately, + * devm_iio_trigger_free() must be used. + * + * RETURNS: + * Pointer to allocated iio_trigger on success, NULL on failure. + */ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, const char *fmt, ...) { @@ -532,6 +541,13 @@ struct iio_trigger *devm_iio_trigger_alloc(struct device *dev, } EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc); +/** + * devm_iio_trigger_free - Resource-managed iio_trigger_free() + * @dev: Device this iio_dev belongs to + * @iio_trig: the iio_trigger associated with the device + * + * Free iio_trigger allocated with devm_iio_trigger_alloc(). + */ void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig) { int rc; diff --git a/drivers/iio/kfifo_buf.c b/drivers/iio/kfifo_buf.c index 95c6fc81c2c7..7134e8ada09a 100644 --- a/drivers/iio/kfifo_buf.c +++ b/drivers/iio/kfifo_buf.c @@ -42,7 +42,6 @@ static int iio_request_update_kfifo(struct iio_buffer *r) } else { kfifo_reset_out(&buf->kf); } - r->stufftoread = false; mutex_unlock(&buf->user_lock); return ret; @@ -108,7 +107,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r, ret = kfifo_in(&kf->kf, data, 1); if (ret != 1) return -EBUSY; - r->stufftoread = true; + wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM); return 0; @@ -127,13 +126,6 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, ret = -EINVAL; else ret = kfifo_to_user(&kf->kf, buf, n, &copied); - - if (kfifo_is_empty(&kf->kf)) - r->stufftoread = false; - /* verify it is still empty to avoid race */ - if (!kfifo_is_empty(&kf->kf)) - r->stufftoread = true; - mutex_unlock(&kf->user_lock); if (ret < 0) return ret; @@ -141,6 +133,18 @@ static int iio_read_first_n_kfifo(struct iio_buffer *r, return copied; } +static bool iio_kfifo_buf_data_available(struct iio_buffer *r) +{ + struct iio_kfifo *kf = iio_to_kfifo(r); + bool empty; + + mutex_lock(&kf->user_lock); + empty = kfifo_is_empty(&kf->kf); + mutex_unlock(&kf->user_lock); + + return !empty; +} + static void iio_kfifo_buffer_release(struct iio_buffer *buffer) { struct iio_kfifo *kf = iio_to_kfifo(buffer); @@ -153,6 +157,7 @@ static void iio_kfifo_buffer_release(struct iio_buffer *buffer) static const struct iio_buffer_access_funcs kfifo_access_funcs = { .store_to = &iio_store_to_kfifo, .read_first_n = &iio_read_first_n_kfifo, + .data_available = iio_kfifo_buf_data_available, .request_update = &iio_request_update_kfifo, .get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo, .set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo, diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig index a022f27c6690..d12b2a0dbfbc 100644 --- a/drivers/iio/light/Kconfig +++ b/drivers/iio/light/Kconfig @@ -27,6 +27,17 @@ config APDS9300 To compile this driver as a module, choose M here: the module will be called apds9300. +config CM32181 + depends on I2C + tristate "CM32181 driver" + help + Say Y here if you use cm32181. + This option enables ambient light sensor using + Capella cm32181 device driver. + + To compile this driver as a module, choose M here: + the module will be called cm32181. + config CM36651 depends on I2C tristate "CM36651 driver" diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile index daa327f39e04..60e35ac07ff0 100644 --- a/drivers/iio/light/Makefile +++ b/drivers/iio/light/Makefile @@ -5,6 +5,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_ADJD_S311) += adjd_s311.o obj-$(CONFIG_APDS9300) += apds9300.o +obj-$(CONFIG_CM32181) += cm32181.o obj-$(CONFIG_CM36651) += cm36651.o obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 83d15c5baf64..f3068477b466 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -155,7 +155,12 @@ done: BIT(IIO_CHAN_INFO_INT_TIME), \ .channel2 = (IIO_MOD_LIGHT_##_color), \ .scan_index = (_scan_idx), \ - .scan_type = IIO_ST('u', 10, 16, 0), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 10, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ } static const struct iio_chan_spec adjd_s311_channels[] = { diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c index 51097bbd59c9..9ddde0ca9c34 100644 --- a/drivers/iio/light/apds9300.c +++ b/drivers/iio/light/apds9300.c @@ -344,10 +344,10 @@ static const struct iio_info apds9300_info_no_irq = { static const struct iio_info apds9300_info = { .driver_module = THIS_MODULE, .read_raw = apds9300_read_raw, - .read_event_value_new = apds9300_read_thresh, - .write_event_value_new = apds9300_write_thresh, - .read_event_config_new = apds9300_read_interrupt_config, - .write_event_config_new = apds9300_write_interrupt_config, + .read_event_value = apds9300_read_thresh, + .write_event_value = apds9300_write_thresh, + .read_event_config = apds9300_read_interrupt_config, + .write_event_config = apds9300_write_interrupt_config, }; static const struct iio_event_spec apds9300_event_spec[] = { diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c new file mode 100644 index 000000000000..f17b4e6183c6 --- /dev/null +++ b/drivers/iio/light/cm32181.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2013 Capella Microsystems Inc. + * Author: Kevin Tsai + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2, as published + * by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Registers Address */ +#define CM32181_REG_ADDR_CMD 0x00 +#define CM32181_REG_ADDR_ALS 0x04 +#define CM32181_REG_ADDR_STATUS 0x06 +#define CM32181_REG_ADDR_ID 0x07 + +/* Number of Configurable Registers */ +#define CM32181_CONF_REG_NUM 0x01 + +/* CMD register */ +#define CM32181_CMD_ALS_ENABLE 0x00 +#define CM32181_CMD_ALS_DISABLE 0x01 +#define CM32181_CMD_ALS_INT_EN 0x02 + +#define CM32181_CMD_ALS_IT_SHIFT 6 +#define CM32181_CMD_ALS_IT_MASK (0x0F << CM32181_CMD_ALS_IT_SHIFT) +#define CM32181_CMD_ALS_IT_DEFAULT (0x00 << CM32181_CMD_ALS_IT_SHIFT) + +#define CM32181_CMD_ALS_SM_SHIFT 11 +#define CM32181_CMD_ALS_SM_MASK (0x03 << CM32181_CMD_ALS_SM_SHIFT) +#define CM32181_CMD_ALS_SM_DEFAULT (0x01 << CM32181_CMD_ALS_SM_SHIFT) + +#define CM32181_MLUX_PER_BIT 5 /* ALS_SM=01 IT=800ms */ +#define CM32181_MLUX_PER_BIT_BASE_IT 800000 /* Based on IT=800ms */ +#define CM32181_CALIBSCALE_DEFAULT 1000 +#define CM32181_CALIBSCALE_RESOLUTION 1000 +#define MLUX_PER_LUX 1000 + +static const u8 cm32181_reg[CM32181_CONF_REG_NUM] = { + CM32181_REG_ADDR_CMD, +}; + +static const int als_it_bits[] = {12, 8, 0, 1, 2, 3}; +static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000, + 800000}; + +struct cm32181_chip { + struct i2c_client *client; + struct mutex lock; + u16 conf_regs[CM32181_CONF_REG_NUM]; + int calibscale; +}; + +/** + * cm32181_reg_init() - Initialize CM32181 registers + * @cm32181: pointer of struct cm32181. + * + * Initialize CM32181 ambient light sensor register to default values. + * + * Return: 0 for success; otherwise for error code. + */ +static int cm32181_reg_init(struct cm32181_chip *cm32181) +{ + struct i2c_client *client = cm32181->client; + int i; + s32 ret; + + ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID); + if (ret < 0) + return ret; + + /* check device ID */ + if ((ret & 0xFF) != 0x81) + return -ENODEV; + + /* Default Values */ + cm32181->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_ALS_ENABLE | + CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT; + cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT; + + /* Initialize registers*/ + for (i = 0; i < CM32181_CONF_REG_NUM; i++) { + ret = i2c_smbus_write_word_data(client, cm32181_reg[i], + cm32181->conf_regs[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +/** + * cm32181_read_als_it() - Get sensor integration time (ms) + * @cm32181: pointer of struct cm32181 + * @val: pointer of int to load the als_it value. + * + * Report the current integartion time by millisecond. + * + * Return: IIO_VAL_INT for success, otherwise -EINVAL. + */ +static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val) +{ + u16 als_it; + int i; + + als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD]; + als_it &= CM32181_CMD_ALS_IT_MASK; + als_it >>= CM32181_CMD_ALS_IT_SHIFT; + for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) { + if (als_it == als_it_bits[i]) { + *val = als_it_value[i]; + return IIO_VAL_INT; + } + } + + return -EINVAL; +} + +/** + * cm32181_write_als_it() - Write sensor integration time + * @cm32181: pointer of struct cm32181. + * @val: integration time by millisecond. + * + * Convert integration time (ms) to sensor value. + * + * Return: i2c_smbus_write_word_data command return value. + */ +static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val) +{ + struct i2c_client *client = cm32181->client; + u16 als_it; + int ret, i, n; + + n = ARRAY_SIZE(als_it_value); + for (i = 0; i < n; i++) + if (val <= als_it_value[i]) + break; + if (i >= n) + i = n - 1; + + als_it = als_it_bits[i]; + als_it <<= CM32181_CMD_ALS_IT_SHIFT; + + mutex_lock(&cm32181->lock); + cm32181->conf_regs[CM32181_REG_ADDR_CMD] &= + ~CM32181_CMD_ALS_IT_MASK; + cm32181->conf_regs[CM32181_REG_ADDR_CMD] |= + als_it; + ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD, + cm32181->conf_regs[CM32181_REG_ADDR_CMD]); + mutex_unlock(&cm32181->lock); + + return ret; +} + +/** + * cm32181_get_lux() - report current lux value + * @cm32181: pointer of struct cm32181. + * + * Convert sensor raw data to lux. It depends on integration + * time and claibscale variable. + * + * Return: Positive value is lux, otherwise is error code. + */ +static int cm32181_get_lux(struct cm32181_chip *cm32181) +{ + struct i2c_client *client = cm32181->client; + int ret; + int als_it; + unsigned long lux; + + ret = cm32181_read_als_it(cm32181, &als_it); + if (ret < 0) + return -EINVAL; + + lux = CM32181_MLUX_PER_BIT; + lux *= CM32181_MLUX_PER_BIT_BASE_IT; + lux /= als_it; + + ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS); + if (ret < 0) + return ret; + + lux *= ret; + lux *= cm32181->calibscale; + lux /= CM32181_CALIBSCALE_RESOLUTION; + lux /= MLUX_PER_LUX; + + if (lux > 0xFFFF) + lux = 0xFFFF; + + return lux; +} + +static int cm32181_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct cm32181_chip *cm32181 = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + ret = cm32181_get_lux(cm32181); + if (ret < 0) + return ret; + *val = ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBSCALE: + *val = cm32181->calibscale; + return IIO_VAL_INT; + case IIO_CHAN_INFO_INT_TIME: + ret = cm32181_read_als_it(cm32181, val); + return ret; + } + + return -EINVAL; +} + +static int cm32181_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct cm32181_chip *cm32181 = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_CALIBSCALE: + cm32181->calibscale = val; + return val; + case IIO_CHAN_INFO_INT_TIME: + ret = cm32181_write_als_it(cm32181, val); + return ret; + } + + return -EINVAL; +} + +/** + * cm32181_get_it_available() - Get available ALS IT value + * @dev: pointer of struct device. + * @attr: pointer of struct device_attribute. + * @buf: pointer of return string buffer. + * + * Display the available integration time values by millisecond. + * + * Return: string length. + */ +static ssize_t cm32181_get_it_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, n, len; + + n = ARRAY_SIZE(als_it_value); + for (i = 0, len = 0; i < n; i++) + len += sprintf(buf + len, "%d ", als_it_value[i]); + return len + sprintf(buf + len, "\n"); +} + +static const struct iio_chan_spec cm32181_channels[] = { + { + .type = IIO_LIGHT, + .info_mask_separate = + BIT(IIO_CHAN_INFO_PROCESSED) | + BIT(IIO_CHAN_INFO_CALIBSCALE) | + BIT(IIO_CHAN_INFO_INT_TIME), + } +}; + +static IIO_DEVICE_ATTR(in_illuminance_integration_time_available, + S_IRUGO, cm32181_get_it_available, NULL, 0); + +static struct attribute *cm32181_attributes[] = { + &iio_dev_attr_in_illuminance_integration_time_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group cm32181_attribute_group = { + .attrs = cm32181_attributes +}; + +static const struct iio_info cm32181_info = { + .driver_module = THIS_MODULE, + .read_raw = &cm32181_read_raw, + .write_raw = &cm32181_write_raw, + .attrs = &cm32181_attribute_group, +}; + +static int cm32181_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cm32181_chip *cm32181; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm32181)); + if (!indio_dev) { + dev_err(&client->dev, "devm_iio_device_alloc failed\n"); + return -ENOMEM; + } + + cm32181 = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + cm32181->client = client; + + mutex_init(&cm32181->lock); + indio_dev->dev.parent = &client->dev; + indio_dev->channels = cm32181_channels; + indio_dev->num_channels = ARRAY_SIZE(cm32181_channels); + indio_dev->info = &cm32181_info; + indio_dev->name = id->name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = cm32181_reg_init(cm32181); + if (ret) { + dev_err(&client->dev, + "%s: register init failed\n", + __func__); + return ret; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&client->dev, + "%s: regist device failed\n", + __func__); + return ret; + } + + return 0; +} + +static int cm32181_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + return 0; +} + +static const struct i2c_device_id cm32181_id[] = { + { "cm32181", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, cm32181_id); + +static const struct of_device_id cm32181_of_match[] = { + { .compatible = "capella,cm32181" }, + { } +}; + +static struct i2c_driver cm32181_driver = { + .driver = { + .name = "cm32181", + .of_match_table = of_match_ptr(cm32181_of_match), + .owner = THIS_MODULE, + }, + .id_table = cm32181_id, + .probe = cm32181_probe, + .remove = cm32181_remove, +}; + +module_i2c_driver(cm32181_driver); + +MODULE_AUTHOR("Kevin Tsai "); +MODULE_DESCRIPTION("CM32181 ambient light sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index 0922e39b0ea9..0a142af83e25 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -488,7 +488,11 @@ static int cm36651_write_raw(struct iio_dev *indio_dev, } static int cm36651_read_prox_thresh(struct iio_dev *indio_dev, - u64 event_code, int *val) + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) { struct cm36651_data *cm36651 = iio_priv(indio_dev); @@ -498,7 +502,11 @@ static int cm36651_read_prox_thresh(struct iio_dev *indio_dev, } static int cm36651_write_prox_thresh(struct iio_dev *indio_dev, - u64 event_code, int val) + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) { struct cm36651_data *cm36651 = iio_priv(indio_dev); struct i2c_client *client = cm36651->client; @@ -520,7 +528,10 @@ static int cm36651_write_prox_thresh(struct iio_dev *indio_dev, } static int cm36651_write_prox_event_config(struct iio_dev *indio_dev, - u64 event_code, int state) + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + int state) { struct cm36651_data *cm36651 = iio_priv(indio_dev); int cmd, ret = -EINVAL; @@ -536,7 +547,9 @@ static int cm36651_write_prox_event_config(struct iio_dev *indio_dev, } static int cm36651_read_prox_event_config(struct iio_dev *indio_dev, - u64 event_code) + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) { struct cm36651_data *cm36651 = iio_priv(indio_dev); int event_en; @@ -559,12 +572,22 @@ static int cm36651_read_prox_event_config(struct iio_dev *indio_dev, .channel2 = IIO_MOD_LIGHT_##_color, \ } \ +static const struct iio_event_spec cm36651_event_spec[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + } +}; + static const struct iio_chan_spec cm36651_channels[] = { { .type = IIO_PROXIMITY, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_INT_TIME), - .event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER) + .event_spec = cm36651_event_spec, + .num_event_specs = ARRAY_SIZE(cm36651_event_spec), }, CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED), CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN), @@ -693,7 +716,7 @@ static const struct of_device_id cm36651_of_match[] = { static struct i2c_driver cm36651_driver = { .driver = { .name = "cm36651", - .of_match_table = of_match_ptr(cm36651_of_match), + .of_match_table = cm36651_of_match, .owner = THIS_MODULE, }, .probe = cm36651_probe, diff --git a/drivers/iio/light/gp2ap020a00f.c b/drivers/iio/light/gp2ap020a00f.c index dc79835be308..5ea4a03c7e71 100644 --- a/drivers/iio/light/gp2ap020a00f.c +++ b/drivers/iio/light/gp2ap020a00f.c @@ -1388,10 +1388,10 @@ static const struct iio_chan_spec gp2ap020a00f_channels[] = { static const struct iio_info gp2ap020a00f_info = { .read_raw = &gp2ap020a00f_read_raw, - .read_event_value_new = &gp2ap020a00f_read_event_val, - .read_event_config_new = &gp2ap020a00f_read_event_config, - .write_event_value_new = &gp2ap020a00f_write_event_val, - .write_event_config_new = &gp2ap020a00f_write_event_config, + .read_event_value = &gp2ap020a00f_read_event_val, + .read_event_config = &gp2ap020a00f_read_event_config, + .write_event_value = &gp2ap020a00f_write_event_val, + .write_event_config = &gp2ap020a00f_write_event_config, .driver_module = THIS_MODULE, }; diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 8e8b9d722853..621541fb10a9 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -229,6 +229,17 @@ static int als_parse_report(struct platform_device *pdev, dev_dbg(&pdev->dev, "als %x:%x\n", st->als_illum.index, st->als_illum.report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_LIGHT, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } return ret; } diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index 45df2204614a..887fecf1f9bb 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -67,7 +67,12 @@ struct tcs3472_data { .channel2 = IIO_MOD_LIGHT_##_color, \ .address = _addr, \ .scan_index = _si, \ - .scan_type = IIO_ST('u', 16, 16, 0), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ } static const int tcs3472_agains[] = { 1, 4, 16, 60 }; diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c index 5e5d9dea22c5..3d8110157f2d 100644 --- a/drivers/iio/light/tsl2563.c +++ b/drivers/iio/light/tsl2563.c @@ -702,10 +702,10 @@ static const struct iio_info tsl2563_info = { .driver_module = THIS_MODULE, .read_raw = &tsl2563_read_raw, .write_raw = &tsl2563_write_raw, - .read_event_value_new = &tsl2563_read_thresh, - .write_event_value_new = &tsl2563_write_thresh, - .read_event_config_new = &tsl2563_read_interrupt_config, - .write_event_config_new = &tsl2563_write_interrupt_config, + .read_event_value = &tsl2563_read_thresh, + .write_event_value = &tsl2563_write_thresh, + .read_event_config = &tsl2563_read_interrupt_config, + .write_event_config = &tsl2563_write_interrupt_config, }; static int tsl2563_probe(struct i2c_client *client, @@ -714,6 +714,7 @@ static int tsl2563_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct tsl2563_chip *chip; struct tsl2563_platform_data *pdata = client->dev.platform_data; + struct device_node *np = client->dev.of_node; int err = 0; u8 id = 0; @@ -750,6 +751,9 @@ static int tsl2563_probe(struct i2c_client *client, if (pdata) chip->cover_comp_gain = pdata->cover_comp_gain; + else if (np) + of_property_read_u32(np, "amstaos,cover-comp-gain", + &chip->cover_comp_gain); else chip->cover_comp_gain = 1; diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index ecb3341ef9c0..d948c4778ba6 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -56,7 +56,7 @@ static int vcnl4000_measure(struct vcnl4000_data *data, u8 req_mask, u8 rdy_mask, u8 data_reg, int *val) { int tries = 20; - u16 buf; + __be16 buf; int ret; ret = i2c_smbus_write_byte_data(data->client, VCNL4000_COMMAND, @@ -179,13 +179,7 @@ static int vcnl4000_probe(struct i2c_client *client, indio_dev->name = VCNL4000_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - return iio_device_register(indio_dev); -} - -static int vcnl4000_remove(struct i2c_client *client) -{ - iio_device_unregister(i2c_get_clientdata(client)); - return 0; + return devm_iio_device_register(&client->dev, indio_dev); } static struct i2c_driver vcnl4000_driver = { @@ -194,7 +188,6 @@ static struct i2c_driver vcnl4000_driver = { .owner = THIS_MODULE, }, .probe = vcnl4000_probe, - .remove = vcnl4000_remove, .id_table = vcnl4000_id, }; diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index b26e1028a0a0..6d162b7e7af5 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -263,6 +263,18 @@ static int magn_3d_parse_report(struct platform_device *pdev, st->magn[1].index, st->magn[1].report_id, st->magn[2].index, st->magn[2].report_id); + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ORIENTATION, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } + return ret; } diff --git a/drivers/iio/magnetometer/mag3110.c b/drivers/iio/magnetometer/mag3110.c index becf54496967..4b65b6d3bdb1 100644 --- a/drivers/iio/magnetometer/mag3110.c +++ b/drivers/iio/magnetometer/mag3110.c @@ -266,7 +266,11 @@ static const struct iio_chan_spec mag3110_channels[] = { .type = IIO_TEMP, .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), .scan_index = 3, - .scan_type = IIO_ST('s', 8, 8, 0), + .scan_type = { + .sign = 's', + .realbits = 8, + .storagebits = 8, + }, }, IIO_CHAN_SOFT_TIMESTAMP(4), }; diff --git a/drivers/iio/orientation/Kconfig b/drivers/iio/orientation/Kconfig new file mode 100644 index 000000000000..58c62c837e12 --- /dev/null +++ b/drivers/iio/orientation/Kconfig @@ -0,0 +1,19 @@ +# +# Inclinometer sensors +# +# When adding new entries keep the list in alphabetical order + +menu "Inclinometer sensors" + +config HID_SENSOR_INCLINOMETER_3D + depends on HID_SENSOR_HUB + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + select HID_SENSOR_IIO_COMMON + select HID_SENSOR_IIO_TRIGGER + tristate "HID Inclinometer 3D" + help + Say yes here to build support for the HID SENSOR + Inclinometer 3D. + +endmenu diff --git a/drivers/iio/orientation/Makefile b/drivers/iio/orientation/Makefile new file mode 100644 index 000000000000..2c97572ee919 --- /dev/null +++ b/drivers/iio/orientation/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for industrial I/O Inclinometer sensor drivers +# + +# When adding new entries keep the list in alphabetical order +obj-$(CONFIG_HID_SENSOR_INCLINOMETER_3D) += hid-sensor-incl-3d.o diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c b/drivers/iio/orientation/hid-sensor-incl-3d.c new file mode 100644 index 000000000000..070feab08faa --- /dev/null +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c @@ -0,0 +1,428 @@ +/* + * HID Sensors Driver + * Copyright (c) 2013, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/hid-sensors/hid-sensor-trigger.h" + +enum incl_3d_channel { + CHANNEL_SCAN_INDEX_X, + CHANNEL_SCAN_INDEX_Y, + CHANNEL_SCAN_INDEX_Z, + INCLI_3D_CHANNEL_MAX, +}; + +struct incl_3d_state { + struct hid_sensor_hub_callbacks callbacks; + struct hid_sensor_common common_attributes; + struct hid_sensor_hub_attribute_info incl[INCLI_3D_CHANNEL_MAX]; + u32 incl_val[INCLI_3D_CHANNEL_MAX]; +}; + +static const u32 incl_3d_addresses[INCLI_3D_CHANNEL_MAX] = { + HID_USAGE_SENSOR_ORIENT_TILT_X, + HID_USAGE_SENSOR_ORIENT_TILT_Y, + HID_USAGE_SENSOR_ORIENT_TILT_Z +}; + +/* Channel definitions */ +static const struct iio_chan_spec incl_3d_channels[] = { + { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_X, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Y, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_Y, + }, { + .type = IIO_INCLI, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_HYSTERESIS), + .scan_index = CHANNEL_SCAN_INDEX_Z, + } +}; + +/* Adjust channel real bits based on report descriptor */ +static void incl_3d_adjust_channel_bit_mask(struct iio_chan_spec *chan, + int size) +{ + chan->scan_type.sign = 's'; + /* Real storage bits will change based on the report desc. */ + chan->scan_type.realbits = size * 8; + /* Maximum size of a sample to capture is u32 */ + chan->scan_type.storagebits = sizeof(u32) * 8; +} + +/* Channel read_raw handler */ +static int incl_3d_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct incl_3d_state *incl_state = iio_priv(indio_dev); + int report_id = -1; + u32 address; + int ret_type; + + *val = 0; + *val2 = 0; + switch (mask) { + case IIO_CHAN_INFO_RAW: + report_id = + incl_state->incl[chan->scan_index].report_id; + address = incl_3d_addresses[chan->scan_index]; + if (report_id >= 0) + *val = sensor_hub_input_attr_get_raw_value( + incl_state->common_attributes.hsdev, + HID_USAGE_SENSOR_INCLINOMETER_3D, address, + report_id); + else { + return -EINVAL; + } + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SCALE: + *val = incl_state->incl[CHANNEL_SCAN_INDEX_X].units; + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_OFFSET: + *val = hid_sensor_convert_exponent( + incl_state->incl[CHANNEL_SCAN_INDEX_X].unit_expo); + ret_type = IIO_VAL_INT; + break; + case IIO_CHAN_INFO_SAMP_FREQ: + ret_type = hid_sensor_read_samp_freq_value( + &incl_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret_type = hid_sensor_read_raw_hyst_value( + &incl_state->common_attributes, val, val2); + break; + default: + ret_type = -EINVAL; + break; + } + + return ret_type; +} + +/* Channel write_raw handler */ +static int incl_3d_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct incl_3d_state *incl_state = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + ret = hid_sensor_write_samp_freq_value( + &incl_state->common_attributes, val, val2); + break; + case IIO_CHAN_INFO_HYSTERESIS: + ret = hid_sensor_write_raw_hyst_value( + &incl_state->common_attributes, val, val2); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct iio_info incl_3d_info = { + .driver_module = THIS_MODULE, + .read_raw = &incl_3d_read_raw, + .write_raw = &incl_3d_write_raw, +}; + +/* Function to push data to buffer */ +static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) +{ + dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); + iio_push_to_buffers(indio_dev, (u8 *)data); +} + +/* Callback handler to send event after all samples are received and captured */ +static int incl_3d_proc_event(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct incl_3d_state *incl_state = iio_priv(indio_dev); + + dev_dbg(&indio_dev->dev, "incl_3d_proc_event [%d]\n", + incl_state->common_attributes.data_ready); + if (incl_state->common_attributes.data_ready) + hid_sensor_push_data(indio_dev, + (u8 *)incl_state->incl_val, + sizeof(incl_state->incl_val)); + + return 0; +} + +/* Capture samples in local storage */ +static int incl_3d_capture_sample(struct hid_sensor_hub_device *hsdev, + unsigned usage_id, + size_t raw_len, char *raw_data, + void *priv) +{ + struct iio_dev *indio_dev = platform_get_drvdata(priv); + struct incl_3d_state *incl_state = iio_priv(indio_dev); + int ret = 0; + + switch (usage_id) { + case HID_USAGE_SENSOR_ORIENT_TILT_X: + incl_state->incl_val[CHANNEL_SCAN_INDEX_X] = *(u32 *)raw_data; + break; + case HID_USAGE_SENSOR_ORIENT_TILT_Y: + incl_state->incl_val[CHANNEL_SCAN_INDEX_Y] = *(u32 *)raw_data; + break; + case HID_USAGE_SENSOR_ORIENT_TILT_Z: + incl_state->incl_val[CHANNEL_SCAN_INDEX_Z] = *(u32 *)raw_data; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* Parse report which is specific to an usage id*/ +static int incl_3d_parse_report(struct platform_device *pdev, + struct hid_sensor_hub_device *hsdev, + struct iio_chan_spec *channels, + unsigned usage_id, + struct incl_3d_state *st) +{ + int ret; + + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ORIENT_TILT_X, + &st->incl[CHANNEL_SCAN_INDEX_X]); + if (ret) + return ret; + incl_3d_adjust_channel_bit_mask(&channels[CHANNEL_SCAN_INDEX_X], + st->incl[CHANNEL_SCAN_INDEX_X].size); + + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ORIENT_TILT_Y, + &st->incl[CHANNEL_SCAN_INDEX_Y]); + if (ret) + return ret; + incl_3d_adjust_channel_bit_mask(&channels[CHANNEL_SCAN_INDEX_Y], + st->incl[CHANNEL_SCAN_INDEX_Y].size); + + ret = sensor_hub_input_get_attribute_info(hsdev, + HID_INPUT_REPORT, + usage_id, + HID_USAGE_SENSOR_ORIENT_TILT_Z, + &st->incl[CHANNEL_SCAN_INDEX_Z]); + if (ret) + return ret; + incl_3d_adjust_channel_bit_mask(&channels[CHANNEL_SCAN_INDEX_Z], + st->incl[CHANNEL_SCAN_INDEX_Z].size); + + dev_dbg(&pdev->dev, "incl_3d %x:%x, %x:%x, %x:%x\n", + st->incl[0].index, + st->incl[0].report_id, + st->incl[1].index, st->incl[1].report_id, + st->incl[2].index, st->incl[2].report_id); + + /* Set Sensitivity field ids, when there is no individual modifier */ + if (st->common_attributes.sensitivity.index < 0) { + sensor_hub_input_get_attribute_info(hsdev, + HID_FEATURE_REPORT, usage_id, + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | + HID_USAGE_SENSOR_DATA_ORIENTATION, + &st->common_attributes.sensitivity); + dev_dbg(&pdev->dev, "Sensitivity index:report %d:%d\n", + st->common_attributes.sensitivity.index, + st->common_attributes.sensitivity.report_id); + } + return ret; +} + +/* Function to initialize the processing for usage id */ +static int hid_incl_3d_probe(struct platform_device *pdev) +{ + int ret; + static char *name = "incli_3d"; + struct iio_dev *indio_dev; + struct incl_3d_state *incl_state; + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_chan_spec *channels; + + indio_dev = devm_iio_device_alloc(&pdev->dev, + sizeof(struct incl_3d_state)); + if (indio_dev == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, indio_dev); + + incl_state = iio_priv(indio_dev); + incl_state->common_attributes.hsdev = hsdev; + incl_state->common_attributes.pdev = pdev; + + ret = hid_sensor_parse_common_attributes(hsdev, + HID_USAGE_SENSOR_INCLINOMETER_3D, + &incl_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "failed to setup common attributes\n"); + return ret; + } + + channels = kmemdup(incl_3d_channels, sizeof(incl_3d_channels), + GFP_KERNEL); + if (!channels) { + dev_err(&pdev->dev, "failed to duplicate channels\n"); + return -ENOMEM; + } + + ret = incl_3d_parse_report(pdev, hsdev, channels, + HID_USAGE_SENSOR_INCLINOMETER_3D, incl_state); + if (ret) { + dev_err(&pdev->dev, "failed to setup attributes\n"); + goto error_free_dev_mem; + } + + indio_dev->channels = channels; + indio_dev->num_channels = ARRAY_SIZE(incl_3d_channels); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &incl_3d_info; + indio_dev->name = name; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + NULL, NULL); + if (ret) { + dev_err(&pdev->dev, "failed to initialize trigger buffer\n"); + goto error_free_dev_mem; + } + incl_state->common_attributes.data_ready = false; + ret = hid_sensor_setup_trigger(indio_dev, name, + &incl_state->common_attributes); + if (ret) { + dev_err(&pdev->dev, "trigger setup failed\n"); + goto error_unreg_buffer_funcs; + } + + ret = iio_device_register(indio_dev); + if (ret) { + dev_err(&pdev->dev, "device register failed\n"); + goto error_remove_trigger; + } + + incl_state->callbacks.send_event = incl_3d_proc_event; + incl_state->callbacks.capture_sample = incl_3d_capture_sample; + incl_state->callbacks.pdev = pdev; + ret = sensor_hub_register_callback(hsdev, + HID_USAGE_SENSOR_INCLINOMETER_3D, + &incl_state->callbacks); + if (ret) { + dev_err(&pdev->dev, "callback reg failed\n"); + goto error_iio_unreg; + } + + return 0; + +error_iio_unreg: + iio_device_unregister(indio_dev); +error_remove_trigger: + hid_sensor_remove_trigger(&incl_state->common_attributes); +error_unreg_buffer_funcs: + iio_triggered_buffer_cleanup(indio_dev); +error_free_dev_mem: + kfree(indio_dev->channels); + return ret; +} + +/* Function to deinitialize the processing for usage id */ +static int hid_incl_3d_remove(struct platform_device *pdev) +{ + struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data; + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct incl_3d_state *incl_state = iio_priv(indio_dev); + + sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_INCLINOMETER_3D); + iio_device_unregister(indio_dev); + hid_sensor_remove_trigger(&incl_state->common_attributes); + iio_triggered_buffer_cleanup(indio_dev); + kfree(indio_dev->channels); + + return 0; +} + +static struct platform_device_id hid_incl_3d_ids[] = { + { + /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ + .name = "HID-SENSOR-200086", + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, hid_incl_3d_ids); + +static struct platform_driver hid_incl_3d_platform_driver = { + .id_table = hid_incl_3d_ids, + .driver = { + .name = KBUILD_MODNAME, + .owner = THIS_MODULE, + }, + .probe = hid_incl_3d_probe, + .remove = hid_incl_3d_remove, +}; +module_platform_driver(hid_incl_3d_platform_driver); + +MODULE_DESCRIPTION("HID Sensor Inclinometer 3D"); +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 4f2e0f9bad8c..a8b9cae5c173 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -5,6 +5,18 @@ menu "Pressure sensors" +config MPL3115 + tristate "Freescale MPL3115A2 pressure sensor driver" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for the Freescale MPL3115A2 + pressure sensor / altimeter. + + To compile this driver as a module, choose M here: the module + will be called mpl3115. + config IIO_ST_PRESS tristate "STMicroelectronics pressure sensor Driver" depends on (I2C || SPI_MASTER) && SYSFS diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index be71464c2752..42bb9fcf5436 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -3,6 +3,7 @@ # # When adding new entries keep the list in alphabetical order +obj-$(CONFIG_MPL3115) += mpl3115.o obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o st_pressure-y := st_pressure_core.o st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o diff --git a/drivers/iio/pressure/mpl3115.c b/drivers/iio/pressure/mpl3115.c new file mode 100644 index 000000000000..ac8c8ab723e5 --- /dev/null +++ b/drivers/iio/pressure/mpl3115.c @@ -0,0 +1,329 @@ +/* + * mpl3115.c - Support for Freescale MPL3115A2 pressure/temperature sensor + * + * Copyright (c) 2013 Peter Meerwald + * + * This file is subject to the terms and conditions of version 2 of + * the GNU General Public License. See the file COPYING in the main + * directory of this archive for more details. + * + * (7-bit I2C slave address 0x60) + * + * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode, + * interrupts, user offset correction, raw mode + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MPL3115_STATUS 0x00 +#define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */ +#define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */ +#define MPL3115_WHO_AM_I 0x0c +#define MPL3115_CTRL_REG1 0x26 + +#define MPL3115_DEVICE_ID 0xc4 + +#define MPL3115_STATUS_PRESS_RDY BIT(2) +#define MPL3115_STATUS_TEMP_RDY BIT(1) + +#define MPL3115_CTRL_RESET BIT(2) /* software reset */ +#define MPL3115_CTRL_OST BIT(1) /* initiate measurement */ +#define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */ +#define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */ + +struct mpl3115_data { + struct i2c_client *client; + struct mutex lock; + u8 ctrl_reg1; +}; + +static int mpl3115_request(struct mpl3115_data *data) +{ + int ret, tries = 15; + + /* trigger measurement */ + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1 | MPL3115_CTRL_OST); + if (ret < 0) + return ret; + + while (tries-- > 0) { + ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG1); + if (ret < 0) + return ret; + /* wait for data ready, i.e. OST cleared */ + if (!(ret & MPL3115_CTRL_OST)) + break; + msleep(20); + } + + if (tries < 0) { + dev_err(&data->client->dev, "data not ready\n"); + return -EIO; + } + + return 0; +} + +static int mpl3115_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct mpl3115_data *data = iio_priv(indio_dev); + s32 tmp = 0; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + + switch (chan->type) { + case IIO_PRESSURE: /* in 0.25 pascal / LSB */ + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_PRESS, 3, (u8 *) &tmp); + mutex_unlock(&data->lock); + if (ret < 0) + return ret; + *val = sign_extend32(be32_to_cpu(tmp) >> 12, 23); + return IIO_VAL_INT; + case IIO_TEMP: /* in 0.0625 celsius / LSB */ + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_TEMP, 2, (u8 *) &tmp); + mutex_unlock(&data->lock); + if (ret < 0) + return ret; + *val = sign_extend32(be32_to_cpu(tmp) >> 20, 15); + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_PRESSURE: + *val = 0; + *val2 = 250; /* want kilopascal */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_TEMP: + *val = 0; + *val2 = 62500; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + } + return -EINVAL; +} + +static irqreturn_t mpl3115_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct mpl3115_data *data = iio_priv(indio_dev); + u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */ + int ret, pos = 0; + + mutex_lock(&data->lock); + ret = mpl3115_request(data); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + + memset(buffer, 0, sizeof(buffer)); + if (test_bit(0, indio_dev->active_scan_mask)) { + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_PRESS, 3, &buffer[pos]); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + pos += 4; + } + + if (test_bit(1, indio_dev->active_scan_mask)) { + ret = i2c_smbus_read_i2c_block_data(data->client, + MPL3115_OUT_TEMP, 2, &buffer[pos]); + if (ret < 0) { + mutex_unlock(&data->lock); + goto done; + } + } + mutex_unlock(&data->lock); + + iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_get_time_ns()); + +done: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +static const struct iio_chan_spec mpl3115_channels[] = { + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 20, + .storagebits = 32, + .shift = 12, + .endianness = IIO_BE, + } + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + BIT(IIO_CHAN_INFO_SCALE), + .scan_index = 1, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .shift = 4, + .endianness = IIO_BE, + } + }, + IIO_CHAN_SOFT_TIMESTAMP(2), +}; + +static const struct iio_info mpl3115_info = { + .read_raw = &mpl3115_read_raw, + .driver_module = THIS_MODULE, +}; + +static int mpl3115_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct mpl3115_data *data; + struct iio_dev *indio_dev; + int ret; + + ret = i2c_smbus_read_byte_data(client, MPL3115_WHO_AM_I); + if (ret < 0) + return ret; + if (ret != MPL3115_DEVICE_ID) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->client = client; + mutex_init(&data->lock); + + i2c_set_clientdata(client, indio_dev); + indio_dev->info = &mpl3115_info; + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = mpl3115_channels; + indio_dev->num_channels = ARRAY_SIZE(mpl3115_channels); + + /* software reset, I2C transfer is aborted (fails) */ + i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, + MPL3115_CTRL_RESET); + msleep(50); + + data->ctrl_reg1 = MPL3115_CTRL_OS_258MS; + ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, + data->ctrl_reg1); + if (ret < 0) + return ret; + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + mpl3115_trigger_handler, NULL); + if (ret < 0) + return ret; + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto buffer_cleanup; + return 0; + +buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + return ret; +} + +static int mpl3115_standby(struct mpl3115_data *data) +{ + return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE); +} + +static int mpl3115_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + mpl3115_standby(iio_priv(indio_dev)); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int mpl3115_suspend(struct device *dev) +{ + return mpl3115_standby(iio_priv(i2c_get_clientdata( + to_i2c_client(dev)))); +} + +static int mpl3115_resume(struct device *dev) +{ + struct mpl3115_data *data = iio_priv(i2c_get_clientdata( + to_i2c_client(dev))); + + return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, + data->ctrl_reg1); +} + +static SIMPLE_DEV_PM_OPS(mpl3115_pm_ops, mpl3115_suspend, mpl3115_resume); +#define MPL3115_PM_OPS (&mpl3115_pm_ops) +#else +#define MPL3115_PM_OPS NULL +#endif + +static const struct i2c_device_id mpl3115_id[] = { + { "mpl3115", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mpl3115_id); + +static struct i2c_driver mpl3115_driver = { + .driver = { + .name = "mpl3115", + .pm = MPL3115_PM_OPS, + }, + .probe = mpl3115_probe, + .remove = mpl3115_remove, + .id_table = mpl3115_id, +}; +module_i2c_driver(mpl3115_driver); + +MODULE_AUTHOR("Peter Meerwald "); +MODULE_DESCRIPTION("Freescale MPL3115 pressure/temperature driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 3bfdaa8d80a9..4bb6b11166b3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -54,6 +54,8 @@ source "drivers/staging/rtl8188eu/Kconfig" source "drivers/staging/rts5139/Kconfig" +source "drivers/staging/rts5208/Kconfig" + source "drivers/staging/frontier/Kconfig" source "drivers/staging/phison/Kconfig" @@ -138,12 +140,8 @@ source "drivers/staging/netlogic/Kconfig" source "drivers/staging/mt29f_spinand/Kconfig" -source "drivers/staging/dwc2/Kconfig" - source "drivers/staging/lustre/Kconfig" -source "drivers/staging/btmtk_usb/Kconfig" - source "drivers/staging/xillybus/Kconfig" source "drivers/staging/dgnc/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index b0d3303b4680..9f07e5e16094 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_R8188EU) += rtl8188eu/ obj-$(CONFIG_RTS5139) += rts5139/ +obj-$(CONFIG_RTS5208) += rts5208/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ obj-$(CONFIG_LINE6_USB) += line6/ @@ -60,9 +61,7 @@ obj-$(CONFIG_DGRP) += dgrp/ obj-$(CONFIG_SB105X) += sb105x/ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ obj-$(CONFIG_GOLDFISH) += goldfish/ -obj-$(CONFIG_USB_DWC2) += dwc2/ obj-$(CONFIG_LUSTRE_FS) += lustre/ -obj-$(CONFIG_USB_BTMTK) += btmtk_usb/ obj-$(CONFIG_XILLYBUS) += xillybus/ obj-$(CONFIG_DGNC) += dgnc/ obj-$(CONFIG_DGAP) += dgap/ diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 1e9ab6dfc90d..b91c758883bf 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -100,6 +100,8 @@ config SW_SYNC_USER *WARNING* improper use of this can result in deadlocking kernel drivers from userspace. +source "drivers/staging/android/ion/Kconfig" + endif # if ANDROID endmenu diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index c136299e05af..0a01e1914905 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,5 +1,7 @@ ccflags-y += -I$(src) # needed for trace events +obj-y += ion/ + obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o diff --git a/drivers/staging/android/alarm-dev.c b/drivers/staging/android/alarm-dev.c index 647694f43dcf..2fc7cdd4c4e3 100644 --- a/drivers/staging/android/alarm-dev.c +++ b/drivers/staging/android/alarm-dev.c @@ -68,11 +68,10 @@ static struct devalarm alarms[ANDROID_ALARM_TYPE_COUNT]; */ static int is_wakeup(enum android_alarm_type type) { - return (type == ANDROID_ALARM_RTC_WAKEUP || - type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP); + return type == ANDROID_ALARM_RTC_WAKEUP || + type == ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP; } - static void devalarm_start(struct devalarm *alrm, ktime_t exp) { if (is_wakeup(alrm->type)) @@ -111,7 +110,6 @@ static void alarm_clear(enum android_alarm_type alarm_type) } alarm_enabled &= ~alarm_type_mask; spin_unlock_irqrestore(&alarm_slock, flags); - } static void alarm_set(enum android_alarm_type alarm_type, @@ -280,6 +278,7 @@ static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return 0; } + #ifdef CONFIG_COMPAT static long alarm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) @@ -371,7 +370,6 @@ static void devalarm_triggered(struct devalarm *alarm) spin_unlock_irqrestore(&alarm_slock, flags); } - static enum hrtimer_restart devalarm_hrthandler(struct hrtimer *hrt) { struct devalarm *devalrm = container_of(hrt, struct devalarm, u.hrt); diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig new file mode 100644 index 000000000000..0f8fec1f84e5 --- /dev/null +++ b/drivers/staging/android/ion/Kconfig @@ -0,0 +1,35 @@ +menuconfig ION + bool "Ion Memory Manager" + depends on HAVE_MEMBLOCK + select GENERIC_ALLOCATOR + select DMA_SHARED_BUFFER + ---help--- + Chose this option to enable the ION Memory Manager, + used by Android to efficiently allocate buffers + from userspace that can be shared between drivers. + If you're not using Android its probably safe to + say N here. + +config ION_TEST + tristate "Ion Test Device" + depends on ION + help + Choose this option to create a device that can be used to test the + kernel and device side ION functions. + +config ION_DUMMY + bool "Dummy Ion driver" + depends on ION + help + Provides a dummy ION driver that registers the + /dev/ion device and some basic heaps. This can + be used for testing the ION infrastructure if + one doesn't have access to hardware drivers that + use ION. + +config ION_TEGRA + tristate "Ion for Tegra" + depends on ARCH_TEGRA && ION + help + Choose this option if you wish to use ion on an nVidia Tegra. + diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile new file mode 100644 index 000000000000..b56fd2bf2b4f --- /dev/null +++ b/drivers/staging/android/ion/Makefile @@ -0,0 +1,10 @@ +obj-$(CONFIG_ION) += ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \ + ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o +obj-$(CONFIG_ION_TEST) += ion_test.o +ifdef CONFIG_COMPAT +obj-$(CONFIG_ION) += compat_ion.o +endif + +obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o +obj-$(CONFIG_ION_TEGRA) += tegra/ + diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c new file mode 100644 index 000000000000..af6cd370b30f --- /dev/null +++ b/drivers/staging/android/ion/compat_ion.c @@ -0,0 +1,177 @@ +/* + * drivers/staging/android/ion/compat_ion.c + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include + +#include "ion.h" +#include "compat_ion.h" + +/* See drivers/staging/android/uapi/ion.h for the definition of these structs */ +struct compat_ion_allocation_data { + compat_size_t len; + compat_size_t align; + compat_uint_t heap_id_mask; + compat_uint_t flags; + compat_int_t handle; +}; + +struct compat_ion_custom_data { + compat_uint_t cmd; + compat_ulong_t arg; +}; + +#define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct compat_ion_allocation_data) +#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) +#define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \ + struct compat_ion_custom_data) + +static int compat_get_ion_allocation_data( + struct compat_ion_allocation_data __user *data32, + struct ion_allocation_data __user *data) +{ + compat_size_t s; + compat_uint_t u; + compat_int_t i; + int err; + + err = get_user(s, &data32->len); + err |= put_user(s, &data->len); + err |= get_user(s, &data32->align); + err |= put_user(s, &data->align); + err |= get_user(u, &data32->heap_id_mask); + err |= put_user(u, &data->heap_id_mask); + err |= get_user(u, &data32->flags); + err |= put_user(u, &data->flags); + err |= get_user(i, &data32->handle); + err |= put_user(i, &data->handle); + + return err; +} + +static int compat_put_ion_allocation_data( + struct compat_ion_allocation_data __user *data32, + struct ion_allocation_data __user *data) +{ + compat_size_t s; + compat_uint_t u; + compat_int_t i; + int err; + + err = get_user(s, &data->len); + err |= put_user(s, &data32->len); + err |= get_user(s, &data->align); + err |= put_user(s, &data32->align); + err |= get_user(u, &data->heap_id_mask); + err |= put_user(u, &data32->heap_id_mask); + err |= get_user(u, &data->flags); + err |= put_user(u, &data32->flags); + err |= get_user(i, &data->handle); + err |= put_user(i, &data32->handle); + + return err; +} + +static int compat_get_ion_custom_data( + struct compat_ion_custom_data __user *data32, + struct ion_custom_data __user *data) +{ + compat_uint_t cmd; + compat_ulong_t arg; + int err; + + err = get_user(cmd, &data32->cmd); + err |= put_user(cmd, &data->cmd); + err |= get_user(arg, &data32->arg); + err |= put_user(arg, &data->arg); + + return err; +}; + +long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + long ret; + + if (!filp->f_op || !filp->f_op->unlocked_ioctl) + return -ENOTTY; + + switch (cmd) { + case COMPAT_ION_IOC_ALLOC: + { + struct compat_ion_allocation_data __user *data32; + struct ion_allocation_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_allocation_data(data32, data); + if (err) + return err; + ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC, + (unsigned long)data); + err = compat_put_ion_allocation_data(data32, data); + return ret ? ret : err; + } + case COMPAT_ION_IOC_FREE: + { + struct compat_ion_allocation_data __user *data32; + struct ion_allocation_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_allocation_data(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE, + (unsigned long)data); + } + case COMPAT_ION_IOC_CUSTOM: { + struct compat_ion_custom_data __user *data32; + struct ion_custom_data __user *data; + int err; + + data32 = compat_ptr(arg); + data = compat_alloc_user_space(sizeof(*data)); + if (data == NULL) + return -EFAULT; + + err = compat_get_ion_custom_data(data32, data); + if (err) + return err; + + return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM, + (unsigned long)data); + } + case ION_IOC_SHARE: + case ION_IOC_MAP: + case ION_IOC_IMPORT: + case ION_IOC_SYNC: + return filp->f_op->unlocked_ioctl(filp, cmd, + (unsigned long)compat_ptr(arg)); + default: + return -ENOIOCTLCMD; + } +} diff --git a/drivers/staging/android/ion/compat_ion.h b/drivers/staging/android/ion/compat_ion.h new file mode 100644 index 000000000000..c2ad5893dfda --- /dev/null +++ b/drivers/staging/android/ion/compat_ion.h @@ -0,0 +1,30 @@ +/* + + * drivers/staging/android/ion/compat_ion.h + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_COMPAT_ION_H +#define _LINUX_COMPAT_ION_H + +#if IS_ENABLED(CONFIG_COMPAT) + +long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); + +#else + +#define compat_ion_ioctl NULL + +#endif /* CONFIG_COMPAT */ +#endif /* _LINUX_COMPAT_ION_H */ diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c new file mode 100644 index 000000000000..574066ff73f8 --- /dev/null +++ b/drivers/staging/android/ion/ion.c @@ -0,0 +1,1549 @@ +/* + + * drivers/staging/android/ion/ion.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ion.h" +#include "ion_priv.h" +#include "compat_ion.h" + +/** + * struct ion_device - the metadata of the ion device node + * @dev: the actual misc device + * @buffers: an rb tree of all the existing buffers + * @buffer_lock: lock protecting the tree of buffers + * @lock: rwsem protecting the tree of heaps and clients + * @heaps: list of all the heaps in the system + * @user_clients: list of all the clients created from userspace + */ +struct ion_device { + struct miscdevice dev; + struct rb_root buffers; + struct mutex buffer_lock; + struct rw_semaphore lock; + struct plist_head heaps; + long (*custom_ioctl) (struct ion_client *client, unsigned int cmd, + unsigned long arg); + struct rb_root clients; + struct dentry *debug_root; +}; + +/** + * struct ion_client - a process/hw block local address space + * @node: node in the tree of all clients + * @dev: backpointer to ion device + * @handles: an rb tree of all the handles in this client + * @idr: an idr space for allocating handle ids + * @lock: lock protecting the tree of handles + * @name: used for debugging + * @task: used for debugging + * + * A client represents a list of buffers this client may access. + * The mutex stored here is used to protect both handles tree + * as well as the handles themselves, and should be held while modifying either. + */ +struct ion_client { + struct rb_node node; + struct ion_device *dev; + struct rb_root handles; + struct idr idr; + struct mutex lock; + const char *name; + struct task_struct *task; + pid_t pid; + struct dentry *debug_root; +}; + +/** + * ion_handle - a client local reference to a buffer + * @ref: reference count + * @client: back pointer to the client the buffer resides in + * @buffer: pointer to the buffer + * @node: node in the client's handle rbtree + * @kmap_cnt: count of times this client has mapped to kernel + * @id: client-unique id allocated by client->idr + * + * Modifications to node, map_cnt or mapping should be protected by the + * lock in the client. Other fields are never changed after initialization. + */ +struct ion_handle { + struct kref ref; + struct ion_client *client; + struct ion_buffer *buffer; + struct rb_node node; + unsigned int kmap_cnt; + int id; +}; + +bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer) +{ + return (buffer->flags & ION_FLAG_CACHED) && + !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC); +} + +bool ion_buffer_cached(struct ion_buffer *buffer) +{ + return !!(buffer->flags & ION_FLAG_CACHED); +} + +static inline struct page *ion_buffer_page(struct page *page) +{ + return (struct page *)((unsigned long)page & ~(1UL)); +} + +static inline bool ion_buffer_page_is_dirty(struct page *page) +{ + return !!((unsigned long)page & 1UL); +} + +static inline void ion_buffer_page_dirty(struct page **page) +{ + *page = (struct page *)((unsigned long)(*page) | 1UL); +} + +static inline void ion_buffer_page_clean(struct page **page) +{ + *page = (struct page *)((unsigned long)(*page) & ~(1UL)); +} + +/* this function should only be called while dev->lock is held */ +static void ion_buffer_add(struct ion_device *dev, + struct ion_buffer *buffer) +{ + struct rb_node **p = &dev->buffers.rb_node; + struct rb_node *parent = NULL; + struct ion_buffer *entry; + + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_buffer, node); + + if (buffer < entry) { + p = &(*p)->rb_left; + } else if (buffer > entry) { + p = &(*p)->rb_right; + } else { + pr_err("%s: buffer already found.", __func__); + BUG(); + } + } + + rb_link_node(&buffer->node, parent, p); + rb_insert_color(&buffer->node, &dev->buffers); +} + +/* this function should only be called while dev->lock is held */ +static struct ion_buffer *ion_buffer_create(struct ion_heap *heap, + struct ion_device *dev, + unsigned long len, + unsigned long align, + unsigned long flags) +{ + struct ion_buffer *buffer; + struct sg_table *table; + struct scatterlist *sg; + int i, ret; + + buffer = kzalloc(sizeof(struct ion_buffer), GFP_KERNEL); + if (!buffer) + return ERR_PTR(-ENOMEM); + + buffer->heap = heap; + buffer->flags = flags; + kref_init(&buffer->ref); + + ret = heap->ops->allocate(heap, buffer, len, align, flags); + + if (ret) { + if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE)) + goto err2; + + ion_heap_freelist_drain(heap, 0); + ret = heap->ops->allocate(heap, buffer, len, align, + flags); + if (ret) + goto err2; + } + + buffer->dev = dev; + buffer->size = len; + + table = heap->ops->map_dma(heap, buffer); + if (WARN_ONCE(table == NULL, + "heap->ops->map_dma should return ERR_PTR on error")) + table = ERR_PTR(-EINVAL); + if (IS_ERR(table)) { + heap->ops->free(buffer); + kfree(buffer); + return ERR_PTR(PTR_ERR(table)); + } + buffer->sg_table = table; + if (ion_buffer_fault_user_mappings(buffer)) { + int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + struct scatterlist *sg; + int i, j, k = 0; + + buffer->pages = vmalloc(sizeof(struct page *) * num_pages); + if (!buffer->pages) { + ret = -ENOMEM; + goto err1; + } + + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page = sg_page(sg); + + for (j = 0; j < sg->length / PAGE_SIZE; j++) + buffer->pages[k++] = page++; + } + + if (ret) + goto err; + } + + buffer->dev = dev; + buffer->size = len; + INIT_LIST_HEAD(&buffer->vmas); + mutex_init(&buffer->lock); + /* this will set up dma addresses for the sglist -- it is not + technically correct as per the dma api -- a specific + device isn't really taking ownership here. However, in practice on + our systems the only dma_address space is physical addresses. + Additionally, we can't afford the overhead of invalidating every + allocation via dma_map_sg. The implicit contract here is that + memory comming from the heaps is ready for dma, ie if it has a + cached mapping that mapping has been invalidated */ + for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) + sg_dma_address(sg) = sg_phys(sg); + mutex_lock(&dev->buffer_lock); + ion_buffer_add(dev, buffer); + mutex_unlock(&dev->buffer_lock); + return buffer; + +err: + heap->ops->unmap_dma(heap, buffer); + heap->ops->free(buffer); +err1: + if (buffer->pages) + vfree(buffer->pages); +err2: + kfree(buffer); + return ERR_PTR(ret); +} + +void ion_buffer_destroy(struct ion_buffer *buffer) +{ + if (WARN_ON(buffer->kmap_cnt > 0)) + buffer->heap->ops->unmap_kernel(buffer->heap, buffer); + buffer->heap->ops->unmap_dma(buffer->heap, buffer); + buffer->heap->ops->free(buffer); + if (buffer->pages) + vfree(buffer->pages); + kfree(buffer); +} + +static void _ion_buffer_destroy(struct kref *kref) +{ + struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref); + struct ion_heap *heap = buffer->heap; + struct ion_device *dev = buffer->dev; + + mutex_lock(&dev->buffer_lock); + rb_erase(&buffer->node, &dev->buffers); + mutex_unlock(&dev->buffer_lock); + + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + ion_heap_freelist_add(heap, buffer); + else + ion_buffer_destroy(buffer); +} + +static void ion_buffer_get(struct ion_buffer *buffer) +{ + kref_get(&buffer->ref); +} + +static int ion_buffer_put(struct ion_buffer *buffer) +{ + return kref_put(&buffer->ref, _ion_buffer_destroy); +} + +static void ion_buffer_add_to_handle(struct ion_buffer *buffer) +{ + mutex_lock(&buffer->lock); + buffer->handle_count++; + mutex_unlock(&buffer->lock); +} + +static void ion_buffer_remove_from_handle(struct ion_buffer *buffer) +{ + /* + * when a buffer is removed from a handle, if it is not in + * any other handles, copy the taskcomm and the pid of the + * process it's being removed from into the buffer. At this + * point there will be no way to track what processes this buffer is + * being used by, it only exists as a dma_buf file descriptor. + * The taskcomm and pid can provide a debug hint as to where this fd + * is in the system + */ + mutex_lock(&buffer->lock); + buffer->handle_count--; + BUG_ON(buffer->handle_count < 0); + if (!buffer->handle_count) { + struct task_struct *task; + + task = current->group_leader; + get_task_comm(buffer->task_comm, task); + buffer->pid = task_pid_nr(task); + } + mutex_unlock(&buffer->lock); +} + +static struct ion_handle *ion_handle_create(struct ion_client *client, + struct ion_buffer *buffer) +{ + struct ion_handle *handle; + + handle = kzalloc(sizeof(struct ion_handle), GFP_KERNEL); + if (!handle) + return ERR_PTR(-ENOMEM); + kref_init(&handle->ref); + RB_CLEAR_NODE(&handle->node); + handle->client = client; + ion_buffer_get(buffer); + ion_buffer_add_to_handle(buffer); + handle->buffer = buffer; + + return handle; +} + +static void ion_handle_kmap_put(struct ion_handle *); + +static void ion_handle_destroy(struct kref *kref) +{ + struct ion_handle *handle = container_of(kref, struct ion_handle, ref); + struct ion_client *client = handle->client; + struct ion_buffer *buffer = handle->buffer; + + mutex_lock(&buffer->lock); + while (handle->kmap_cnt) + ion_handle_kmap_put(handle); + mutex_unlock(&buffer->lock); + + idr_remove(&client->idr, handle->id); + if (!RB_EMPTY_NODE(&handle->node)) + rb_erase(&handle->node, &client->handles); + + ion_buffer_remove_from_handle(buffer); + ion_buffer_put(buffer); + + kfree(handle); +} + +struct ion_buffer *ion_handle_buffer(struct ion_handle *handle) +{ + return handle->buffer; +} + +static void ion_handle_get(struct ion_handle *handle) +{ + kref_get(&handle->ref); +} + +static int ion_handle_put(struct ion_handle *handle) +{ + struct ion_client *client = handle->client; + int ret; + + mutex_lock(&client->lock); + ret = kref_put(&handle->ref, ion_handle_destroy); + mutex_unlock(&client->lock); + + return ret; +} + +static struct ion_handle *ion_handle_lookup(struct ion_client *client, + struct ion_buffer *buffer) +{ + struct rb_node *n = client->handles.rb_node; + + while (n) { + struct ion_handle *entry = rb_entry(n, struct ion_handle, node); + if (buffer < entry->buffer) + n = n->rb_left; + else if (buffer > entry->buffer) + n = n->rb_right; + else + return entry; + } + return ERR_PTR(-EINVAL); +} + +static struct ion_handle *ion_handle_get_by_id(struct ion_client *client, + int id) +{ + struct ion_handle *handle; + + mutex_lock(&client->lock); + handle = idr_find(&client->idr, id); + if (handle) + ion_handle_get(handle); + mutex_unlock(&client->lock); + + return handle ? handle : ERR_PTR(-EINVAL); +} + +static bool ion_handle_validate(struct ion_client *client, + struct ion_handle *handle) +{ + WARN_ON(!mutex_is_locked(&client->lock)); + return (idr_find(&client->idr, handle->id) == handle); +} + +static int ion_handle_add(struct ion_client *client, struct ion_handle *handle) +{ + int id; + struct rb_node **p = &client->handles.rb_node; + struct rb_node *parent = NULL; + struct ion_handle *entry; + + id = idr_alloc(&client->idr, handle, 1, 0, GFP_KERNEL); + if (id < 0) + return id; + + handle->id = id; + + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_handle, node); + + if (handle->buffer < entry->buffer) + p = &(*p)->rb_left; + else if (handle->buffer > entry->buffer) + p = &(*p)->rb_right; + else + WARN(1, "%s: buffer already found.", __func__); + } + + rb_link_node(&handle->node, parent, p); + rb_insert_color(&handle->node, &client->handles); + + return 0; +} + +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags) +{ + struct ion_handle *handle; + struct ion_device *dev = client->dev; + struct ion_buffer *buffer = NULL; + struct ion_heap *heap; + int ret; + + pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__, + len, align, heap_id_mask, flags); + /* + * traverse the list of heaps available in this system in priority + * order. If the heap type is supported by the client, and matches the + * request of the caller allocate from it. Repeat until allocate has + * succeeded or all heaps have been tried + */ + len = PAGE_ALIGN(len); + + if (!len) + return ERR_PTR(-EINVAL); + + down_read(&dev->lock); + plist_for_each_entry(heap, &dev->heaps, node) { + /* if the caller didn't specify this heap id */ + if (!((1 << heap->id) & heap_id_mask)) + continue; + buffer = ion_buffer_create(heap, dev, len, align, flags); + if (!IS_ERR(buffer)) + break; + } + up_read(&dev->lock); + + if (buffer == NULL) + return ERR_PTR(-ENODEV); + + if (IS_ERR(buffer)) + return ERR_PTR(PTR_ERR(buffer)); + + handle = ion_handle_create(client, buffer); + + /* + * ion_buffer_create will create a buffer with a ref_cnt of 1, + * and ion_handle_create will take a second reference, drop one here + */ + ion_buffer_put(buffer); + + if (IS_ERR(handle)) + return handle; + + mutex_lock(&client->lock); + ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); + if (ret) { + ion_handle_put(handle); + handle = ERR_PTR(ret); + } + + return handle; +} +EXPORT_SYMBOL(ion_alloc); + +void ion_free(struct ion_client *client, struct ion_handle *handle) +{ + bool valid_handle; + + BUG_ON(client != handle->client); + + mutex_lock(&client->lock); + valid_handle = ion_handle_validate(client, handle); + + if (!valid_handle) { + WARN(1, "%s: invalid handle passed to free.\n", __func__); + mutex_unlock(&client->lock); + return; + } + mutex_unlock(&client->lock); + ion_handle_put(handle); +} +EXPORT_SYMBOL(ion_free); + +int ion_phys(struct ion_client *client, struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len) +{ + struct ion_buffer *buffer; + int ret; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + mutex_unlock(&client->lock); + return -EINVAL; + } + + buffer = handle->buffer; + + if (!buffer->heap->ops->phys) { + pr_err("%s: ion_phys is not implemented by this heap.\n", + __func__); + mutex_unlock(&client->lock); + return -ENODEV; + } + mutex_unlock(&client->lock); + ret = buffer->heap->ops->phys(buffer->heap, buffer, addr, len); + return ret; +} +EXPORT_SYMBOL(ion_phys); + +static void *ion_buffer_kmap_get(struct ion_buffer *buffer) +{ + void *vaddr; + + if (buffer->kmap_cnt) { + buffer->kmap_cnt++; + return buffer->vaddr; + } + vaddr = buffer->heap->ops->map_kernel(buffer->heap, buffer); + if (WARN_ONCE(vaddr == NULL, + "heap->ops->map_kernel should return ERR_PTR on error")) + return ERR_PTR(-EINVAL); + if (IS_ERR(vaddr)) + return vaddr; + buffer->vaddr = vaddr; + buffer->kmap_cnt++; + return vaddr; +} + +static void *ion_handle_kmap_get(struct ion_handle *handle) +{ + struct ion_buffer *buffer = handle->buffer; + void *vaddr; + + if (handle->kmap_cnt) { + handle->kmap_cnt++; + return buffer->vaddr; + } + vaddr = ion_buffer_kmap_get(buffer); + if (IS_ERR(vaddr)) + return vaddr; + handle->kmap_cnt++; + return vaddr; +} + +static void ion_buffer_kmap_put(struct ion_buffer *buffer) +{ + buffer->kmap_cnt--; + if (!buffer->kmap_cnt) { + buffer->heap->ops->unmap_kernel(buffer->heap, buffer); + buffer->vaddr = NULL; + } +} + +static void ion_handle_kmap_put(struct ion_handle *handle) +{ + struct ion_buffer *buffer = handle->buffer; + + handle->kmap_cnt--; + if (!handle->kmap_cnt) + ion_buffer_kmap_put(buffer); +} + +void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle) +{ + struct ion_buffer *buffer; + void *vaddr; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + pr_err("%s: invalid handle passed to map_kernel.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + + buffer = handle->buffer; + + if (!handle->buffer->heap->ops->map_kernel) { + pr_err("%s: map_kernel is not implemented by this heap.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-ENODEV); + } + + mutex_lock(&buffer->lock); + vaddr = ion_handle_kmap_get(handle); + mutex_unlock(&buffer->lock); + mutex_unlock(&client->lock); + return vaddr; +} +EXPORT_SYMBOL(ion_map_kernel); + +void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle) +{ + struct ion_buffer *buffer; + + mutex_lock(&client->lock); + buffer = handle->buffer; + mutex_lock(&buffer->lock); + ion_handle_kmap_put(handle); + mutex_unlock(&buffer->lock); + mutex_unlock(&client->lock); +} +EXPORT_SYMBOL(ion_unmap_kernel); + +static int ion_debug_client_show(struct seq_file *s, void *unused) +{ + struct ion_client *client = s->private; + struct rb_node *n; + size_t sizes[ION_NUM_HEAP_IDS] = {0}; + const char *names[ION_NUM_HEAP_IDS] = {NULL}; + int i; + + mutex_lock(&client->lock); + for (n = rb_first(&client->handles); n; n = rb_next(n)) { + struct ion_handle *handle = rb_entry(n, struct ion_handle, + node); + unsigned int id = handle->buffer->heap->id; + + if (!names[id]) + names[id] = handle->buffer->heap->name; + sizes[id] += handle->buffer->size; + } + mutex_unlock(&client->lock); + + seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes"); + for (i = 0; i < ION_NUM_HEAP_IDS; i++) { + if (!names[i]) + continue; + seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]); + } + return 0; +} + +static int ion_debug_client_open(struct inode *inode, struct file *file) +{ + return single_open(file, ion_debug_client_show, inode->i_private); +} + +static const struct file_operations debug_client_fops = { + .open = ion_debug_client_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +struct ion_client *ion_client_create(struct ion_device *dev, + const char *name) +{ + struct ion_client *client; + struct task_struct *task; + struct rb_node **p; + struct rb_node *parent = NULL; + struct ion_client *entry; + char debug_name[64]; + pid_t pid; + + get_task_struct(current->group_leader); + task_lock(current->group_leader); + pid = task_pid_nr(current->group_leader); + /* don't bother to store task struct for kernel threads, + they can't be killed anyway */ + if (current->group_leader->flags & PF_KTHREAD) { + put_task_struct(current->group_leader); + task = NULL; + } else { + task = current->group_leader; + } + task_unlock(current->group_leader); + + client = kzalloc(sizeof(struct ion_client), GFP_KERNEL); + if (!client) { + if (task) + put_task_struct(current->group_leader); + return ERR_PTR(-ENOMEM); + } + + client->dev = dev; + client->handles = RB_ROOT; + idr_init(&client->idr); + mutex_init(&client->lock); + client->name = name; + client->task = task; + client->pid = pid; + + down_write(&dev->lock); + p = &dev->clients.rb_node; + while (*p) { + parent = *p; + entry = rb_entry(parent, struct ion_client, node); + + if (client < entry) + p = &(*p)->rb_left; + else if (client > entry) + p = &(*p)->rb_right; + } + rb_link_node(&client->node, parent, p); + rb_insert_color(&client->node, &dev->clients); + + snprintf(debug_name, 64, "%u", client->pid); + client->debug_root = debugfs_create_file(debug_name, 0664, + dev->debug_root, client, + &debug_client_fops); + up_write(&dev->lock); + + return client; +} +EXPORT_SYMBOL(ion_client_create); + +void ion_client_destroy(struct ion_client *client) +{ + struct ion_device *dev = client->dev; + struct rb_node *n; + + pr_debug("%s: %d\n", __func__, __LINE__); + while ((n = rb_first(&client->handles))) { + struct ion_handle *handle = rb_entry(n, struct ion_handle, + node); + ion_handle_destroy(&handle->ref); + } + + idr_destroy(&client->idr); + + down_write(&dev->lock); + if (client->task) + put_task_struct(client->task); + rb_erase(&client->node, &dev->clients); + debugfs_remove_recursive(client->debug_root); + up_write(&dev->lock); + + kfree(client); +} +EXPORT_SYMBOL(ion_client_destroy); + +struct sg_table *ion_sg_table(struct ion_client *client, + struct ion_handle *handle) +{ + struct ion_buffer *buffer; + struct sg_table *table; + + mutex_lock(&client->lock); + if (!ion_handle_validate(client, handle)) { + pr_err("%s: invalid handle passed to map_dma.\n", + __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + buffer = handle->buffer; + table = buffer->sg_table; + mutex_unlock(&client->lock); + return table; +} +EXPORT_SYMBOL(ion_sg_table); + +static void ion_buffer_sync_for_device(struct ion_buffer *buffer, + struct device *dev, + enum dma_data_direction direction); + +static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct dma_buf *dmabuf = attachment->dmabuf; + struct ion_buffer *buffer = dmabuf->priv; + + ion_buffer_sync_for_device(buffer, attachment->dev, direction); + return buffer->sg_table; +} + +static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ +} + +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + /* + * This is not correct - sg_dma_address needs a dma_addr_t that is valid + * for the the targeted device, but this works on the currently targeted + * hardware. + */ + sg_dma_address(&sg) = page_to_phys(page); + dma_sync_sg_for_device(dev, &sg, 1, dir); +} + +struct ion_vma_list { + struct list_head list; + struct vm_area_struct *vma; +}; + +static void ion_buffer_sync_for_device(struct ion_buffer *buffer, + struct device *dev, + enum dma_data_direction dir) +{ + struct ion_vma_list *vma_list; + int pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + int i; + + pr_debug("%s: syncing for device %s\n", __func__, + dev ? dev_name(dev) : "null"); + + if (!ion_buffer_fault_user_mappings(buffer)) + return; + + mutex_lock(&buffer->lock); + for (i = 0; i < pages; i++) { + struct page *page = buffer->pages[i]; + + if (ion_buffer_page_is_dirty(page)) + ion_pages_sync_for_device(dev, ion_buffer_page(page), + PAGE_SIZE, dir); + + ion_buffer_page_clean(buffer->pages + i); + } + list_for_each_entry(vma_list, &buffer->vmas, list) { + struct vm_area_struct *vma = vma_list->vma; + + zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, + NULL); + } + mutex_unlock(&buffer->lock); +} + +static int ion_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct ion_buffer *buffer = vma->vm_private_data; + unsigned long pfn; + int ret; + + mutex_lock(&buffer->lock); + ion_buffer_page_dirty(buffer->pages + vmf->pgoff); + BUG_ON(!buffer->pages || !buffer->pages[vmf->pgoff]); + + pfn = page_to_pfn(ion_buffer_page(buffer->pages[vmf->pgoff])); + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); + mutex_unlock(&buffer->lock); + if (ret) + return VM_FAULT_ERROR; + + return VM_FAULT_NOPAGE; +} + +static void ion_vm_open(struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = vma->vm_private_data; + struct ion_vma_list *vma_list; + + vma_list = kmalloc(sizeof(struct ion_vma_list), GFP_KERNEL); + if (!vma_list) + return; + vma_list->vma = vma; + mutex_lock(&buffer->lock); + list_add(&vma_list->list, &buffer->vmas); + mutex_unlock(&buffer->lock); + pr_debug("%s: adding %p\n", __func__, vma); +} + +static void ion_vm_close(struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = vma->vm_private_data; + struct ion_vma_list *vma_list, *tmp; + + pr_debug("%s\n", __func__); + mutex_lock(&buffer->lock); + list_for_each_entry_safe(vma_list, tmp, &buffer->vmas, list) { + if (vma_list->vma != vma) + continue; + list_del(&vma_list->list); + kfree(vma_list); + pr_debug("%s: deleting %p\n", __func__, vma); + break; + } + mutex_unlock(&buffer->lock); +} + +static struct vm_operations_struct ion_vma_ops = { + .open = ion_vm_open, + .close = ion_vm_close, + .fault = ion_vm_fault, +}; + +static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct ion_buffer *buffer = dmabuf->priv; + int ret = 0; + + if (!buffer->heap->ops->map_user) { + pr_err("%s: this heap does not define a method for mapping " + "to userspace\n", __func__); + return -EINVAL; + } + + if (ion_buffer_fault_user_mappings(buffer)) { + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | + VM_DONTDUMP; + vma->vm_private_data = buffer; + vma->vm_ops = &ion_vma_ops; + ion_vm_open(vma); + return 0; + } + + if (!(buffer->flags & ION_FLAG_CACHED)) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + mutex_lock(&buffer->lock); + /* now map it to userspace */ + ret = buffer->heap->ops->map_user(buffer->heap, buffer, vma); + mutex_unlock(&buffer->lock); + + if (ret) + pr_err("%s: failure mapping buffer to userspace\n", + __func__); + + return ret; +} + +static void ion_dma_buf_release(struct dma_buf *dmabuf) +{ + struct ion_buffer *buffer = dmabuf->priv; + ion_buffer_put(buffer); +} + +static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) +{ + struct ion_buffer *buffer = dmabuf->priv; + return buffer->vaddr + offset * PAGE_SIZE; +} + +static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, + void *ptr) +{ + return; +} + +static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, + size_t len, + enum dma_data_direction direction) +{ + struct ion_buffer *buffer = dmabuf->priv; + void *vaddr; + + if (!buffer->heap->ops->map_kernel) { + pr_err("%s: map kernel is not implemented by this heap.\n", + __func__); + return -ENODEV; + } + + mutex_lock(&buffer->lock); + vaddr = ion_buffer_kmap_get(buffer); + mutex_unlock(&buffer->lock); + if (IS_ERR(vaddr)) + return PTR_ERR(vaddr); + return 0; +} + +static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, + size_t len, + enum dma_data_direction direction) +{ + struct ion_buffer *buffer = dmabuf->priv; + + mutex_lock(&buffer->lock); + ion_buffer_kmap_put(buffer); + mutex_unlock(&buffer->lock); +} + +static struct dma_buf_ops dma_buf_ops = { + .map_dma_buf = ion_map_dma_buf, + .unmap_dma_buf = ion_unmap_dma_buf, + .mmap = ion_mmap, + .release = ion_dma_buf_release, + .begin_cpu_access = ion_dma_buf_begin_cpu_access, + .end_cpu_access = ion_dma_buf_end_cpu_access, + .kmap_atomic = ion_dma_buf_kmap, + .kunmap_atomic = ion_dma_buf_kunmap, + .kmap = ion_dma_buf_kmap, + .kunmap = ion_dma_buf_kunmap, +}; + +struct dma_buf *ion_share_dma_buf(struct ion_client *client, + struct ion_handle *handle) +{ + struct ion_buffer *buffer; + struct dma_buf *dmabuf; + bool valid_handle; + + mutex_lock(&client->lock); + valid_handle = ion_handle_validate(client, handle); + if (!valid_handle) { + WARN(1, "%s: invalid handle passed to share.\n", __func__); + mutex_unlock(&client->lock); + return ERR_PTR(-EINVAL); + } + buffer = handle->buffer; + ion_buffer_get(buffer); + mutex_unlock(&client->lock); + + dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR); + if (IS_ERR(dmabuf)) { + ion_buffer_put(buffer); + return dmabuf; + } + + return dmabuf; +} +EXPORT_SYMBOL(ion_share_dma_buf); + +int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle) +{ + struct dma_buf *dmabuf; + int fd; + + dmabuf = ion_share_dma_buf(client, handle); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + fd = dma_buf_fd(dmabuf, O_CLOEXEC); + if (fd < 0) + dma_buf_put(dmabuf); + + return fd; +} +EXPORT_SYMBOL(ion_share_dma_buf_fd); + +struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + struct ion_handle *handle; + int ret; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return ERR_PTR(PTR_ERR(dmabuf)); + /* if this memory came from ion */ + + if (dmabuf->ops != &dma_buf_ops) { + pr_err("%s: can not import dmabuf from another exporter\n", + __func__); + dma_buf_put(dmabuf); + return ERR_PTR(-EINVAL); + } + buffer = dmabuf->priv; + + mutex_lock(&client->lock); + /* if a handle exists for this buffer just take a reference to it */ + handle = ion_handle_lookup(client, buffer); + if (!IS_ERR(handle)) { + ion_handle_get(handle); + mutex_unlock(&client->lock); + goto end; + } + mutex_unlock(&client->lock); + + handle = ion_handle_create(client, buffer); + if (IS_ERR(handle)) + goto end; + + mutex_lock(&client->lock); + ret = ion_handle_add(client, handle); + mutex_unlock(&client->lock); + if (ret) { + ion_handle_put(handle); + handle = ERR_PTR(ret); + } + +end: + dma_buf_put(dmabuf); + return handle; +} +EXPORT_SYMBOL(ion_import_dma_buf); + +static int ion_sync_for_device(struct ion_client *client, int fd) +{ + struct dma_buf *dmabuf; + struct ion_buffer *buffer; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) + return PTR_ERR(dmabuf); + + /* if this memory came from ion */ + if (dmabuf->ops != &dma_buf_ops) { + pr_err("%s: can not sync dmabuf from another exporter\n", + __func__); + dma_buf_put(dmabuf); + return -EINVAL; + } + buffer = dmabuf->priv; + + dma_sync_sg_for_device(NULL, buffer->sg_table->sgl, + buffer->sg_table->nents, DMA_BIDIRECTIONAL); + dma_buf_put(dmabuf); + return 0; +} + +/* fix up the cases where the ioctl direction bits are incorrect */ +static unsigned int ion_ioctl_dir(unsigned int cmd) +{ + switch (cmd) { + case ION_IOC_SYNC: + case ION_IOC_FREE: + case ION_IOC_CUSTOM: + return _IOC_WRITE; + default: + return _IOC_DIR(cmd); + } +} + +static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct ion_client *client = filp->private_data; + struct ion_device *dev = client->dev; + struct ion_handle *cleanup_handle = NULL; + int ret = 0; + unsigned int dir; + + union { + struct ion_fd_data fd; + struct ion_allocation_data allocation; + struct ion_handle_data handle; + struct ion_custom_data custom; + } data; + + dir = ion_ioctl_dir(cmd); + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (dir & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + switch (cmd) { + case ION_IOC_ALLOC: + { + struct ion_handle *handle; + + handle = ion_alloc(client, data.allocation.len, + data.allocation.align, + data.allocation.heap_id_mask, + data.allocation.flags); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + data.allocation.handle = handle->id; + + cleanup_handle = handle; + break; + } + case ION_IOC_FREE: + { + struct ion_handle *handle; + + handle = ion_handle_get_by_id(client, data.handle.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); + ion_free(client, handle); + ion_handle_put(handle); + break; + } + case ION_IOC_SHARE: + case ION_IOC_MAP: + { + struct ion_handle *handle; + + handle = ion_handle_get_by_id(client, data.handle.handle); + if (IS_ERR(handle)) + return PTR_ERR(handle); + data.fd.fd = ion_share_dma_buf_fd(client, handle); + ion_handle_put(handle); + if (data.fd.fd < 0) + ret = data.fd.fd; + break; + } + case ION_IOC_IMPORT: + { + struct ion_handle *handle; + handle = ion_import_dma_buf(client, data.fd.fd); + if (IS_ERR(handle)) + ret = PTR_ERR(handle); + else + data.handle.handle = handle->id; + break; + } + case ION_IOC_SYNC: + { + ret = ion_sync_for_device(client, data.fd.fd); + break; + } + case ION_IOC_CUSTOM: + { + if (!dev->custom_ioctl) + return -ENOTTY; + ret = dev->custom_ioctl(client, data.custom.cmd, + data.custom.arg); + break; + } + default: + return -ENOTTY; + } + + if (dir & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) { + if (cleanup_handle) + ion_free(client, cleanup_handle); + return -EFAULT; + } + } + return ret; +} + +static int ion_release(struct inode *inode, struct file *file) +{ + struct ion_client *client = file->private_data; + + pr_debug("%s: %d\n", __func__, __LINE__); + ion_client_destroy(client); + return 0; +} + +static int ion_open(struct inode *inode, struct file *file) +{ + struct miscdevice *miscdev = file->private_data; + struct ion_device *dev = container_of(miscdev, struct ion_device, dev); + struct ion_client *client; + + pr_debug("%s: %d\n", __func__, __LINE__); + client = ion_client_create(dev, "user"); + if (IS_ERR(client)) + return PTR_ERR(client); + file->private_data = client; + + return 0; +} + +static const struct file_operations ion_fops = { + .owner = THIS_MODULE, + .open = ion_open, + .release = ion_release, + .unlocked_ioctl = ion_ioctl, + .compat_ioctl = compat_ion_ioctl, +}; + +static size_t ion_debug_heap_total(struct ion_client *client, + unsigned int id) +{ + size_t size = 0; + struct rb_node *n; + + mutex_lock(&client->lock); + for (n = rb_first(&client->handles); n; n = rb_next(n)) { + struct ion_handle *handle = rb_entry(n, + struct ion_handle, + node); + if (handle->buffer->heap->id == id) + size += handle->buffer->size; + } + mutex_unlock(&client->lock); + return size; +} + +static int ion_debug_heap_show(struct seq_file *s, void *unused) +{ + struct ion_heap *heap = s->private; + struct ion_device *dev = heap->dev; + struct rb_node *n; + size_t total_size = 0; + size_t total_orphaned_size = 0; + + seq_printf(s, "%16.s %16.s %16.s\n", "client", "pid", "size"); + seq_printf(s, "----------------------------------------------------\n"); + + for (n = rb_first(&dev->clients); n; n = rb_next(n)) { + struct ion_client *client = rb_entry(n, struct ion_client, + node); + size_t size = ion_debug_heap_total(client, heap->id); + if (!size) + continue; + if (client->task) { + char task_comm[TASK_COMM_LEN]; + + get_task_comm(task_comm, client->task); + seq_printf(s, "%16.s %16u %16zu\n", task_comm, + client->pid, size); + } else { + seq_printf(s, "%16.s %16u %16zu\n", client->name, + client->pid, size); + } + } + seq_printf(s, "----------------------------------------------------\n"); + seq_printf(s, "orphaned allocations (info is from last known client):" + "\n"); + mutex_lock(&dev->buffer_lock); + for (n = rb_first(&dev->buffers); n; n = rb_next(n)) { + struct ion_buffer *buffer = rb_entry(n, struct ion_buffer, + node); + if (buffer->heap->id != heap->id) + continue; + total_size += buffer->size; + if (!buffer->handle_count) { + seq_printf(s, "%16.s %16u %16zu %d %d\n", + buffer->task_comm, buffer->pid, + buffer->size, buffer->kmap_cnt, + atomic_read(&buffer->ref.refcount)); + total_orphaned_size += buffer->size; + } + } + mutex_unlock(&dev->buffer_lock); + seq_printf(s, "----------------------------------------------------\n"); + seq_printf(s, "%16.s %16zu\n", "total orphaned", + total_orphaned_size); + seq_printf(s, "%16.s %16zu\n", "total ", total_size); + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + seq_printf(s, "%16.s %16zu\n", "deferred free", + heap->free_list_size); + seq_printf(s, "----------------------------------------------------\n"); + + if (heap->debug_show) + heap->debug_show(heap, s, unused); + + return 0; +} + +static int ion_debug_heap_open(struct inode *inode, struct file *file) +{ + return single_open(file, ion_debug_heap_show, inode->i_private); +} + +static const struct file_operations debug_heap_fops = { + .open = ion_debug_heap_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +#ifdef DEBUG_HEAP_SHRINKER +static int debug_shrink_set(void *data, u64 val) +{ + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + if (!val) + return 0; + + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + sc.nr_to_scan = objs; + + heap->shrinker.shrink(&heap->shrinker, &sc); + return 0; +} + +static int debug_shrink_get(void *data, u64 *val) +{ + struct ion_heap *heap = data; + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + objs = heap->shrinker.shrink(&heap->shrinker, &sc); + *val = objs; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, + debug_shrink_set, "%llu\n"); +#endif + +void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) +{ + if (!heap->ops->allocate || !heap->ops->free || !heap->ops->map_dma || + !heap->ops->unmap_dma) + pr_err("%s: can not add heap with invalid ops struct.\n", + __func__); + + if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) + ion_heap_init_deferred_free(heap); + + heap->dev = dev; + down_write(&dev->lock); + /* use negative heap->id to reverse the priority -- when traversing + the list later attempt higher id numbers first */ + plist_node_init(&heap->node, -heap->id); + plist_add(&heap->node, &dev->heaps); + debugfs_create_file(heap->name, 0664, dev->debug_root, heap, + &debug_heap_fops); +#ifdef DEBUG_HEAP_SHRINKER + if (heap->shrinker.shrink) { + char debug_name[64]; + + snprintf(debug_name, 64, "%s_shrink", heap->name); + debugfs_create_file(debug_name, 0644, dev->debug_root, heap, + &debug_shrink_fops); + } +#endif + up_write(&dev->lock); +} + +struct ion_device *ion_device_create(long (*custom_ioctl) + (struct ion_client *client, + unsigned int cmd, + unsigned long arg)) +{ + struct ion_device *idev; + int ret; + + idev = kzalloc(sizeof(struct ion_device), GFP_KERNEL); + if (!idev) + return ERR_PTR(-ENOMEM); + + idev->dev.minor = MISC_DYNAMIC_MINOR; + idev->dev.name = "ion"; + idev->dev.fops = &ion_fops; + idev->dev.parent = NULL; + ret = misc_register(&idev->dev); + if (ret) { + pr_err("ion: failed to register misc device.\n"); + return ERR_PTR(ret); + } + + idev->debug_root = debugfs_create_dir("ion", NULL); + if (!idev->debug_root) + pr_err("ion: failed to create debug files.\n"); + + idev->custom_ioctl = custom_ioctl; + idev->buffers = RB_ROOT; + mutex_init(&idev->buffer_lock); + init_rwsem(&idev->lock); + plist_head_init(&idev->heaps); + idev->clients = RB_ROOT; + return idev; +} + +void ion_device_destroy(struct ion_device *dev) +{ + misc_deregister(&dev->dev); + /* XXX need to free the heaps and clients ? */ + kfree(dev); +} + +void __init ion_reserve(struct ion_platform_data *data) +{ + int i; + + for (i = 0; i < data->nr; i++) { + if (data->heaps[i].size == 0) + continue; + + if (data->heaps[i].base == 0) { + phys_addr_t paddr; + paddr = memblock_alloc_base(data->heaps[i].size, + data->heaps[i].align, + MEMBLOCK_ALLOC_ANYWHERE); + if (!paddr) { + pr_err("%s: error allocating memblock for " + "heap %d\n", + __func__, i); + continue; + } + data->heaps[i].base = paddr; + } else { + int ret = memblock_reserve(data->heaps[i].base, + data->heaps[i].size); + if (ret) + pr_err("memblock reserve of %zx@%lx failed\n", + data->heaps[i].size, + data->heaps[i].base); + } + pr_info("%s: %s reserved base %lx size %zu\n", __func__, + data->heaps[i].name, + data->heaps[i].base, + data->heaps[i].size); + } +} diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h new file mode 100644 index 000000000000..dcd2a0cdb192 --- /dev/null +++ b/drivers/staging/android/ion/ion.h @@ -0,0 +1,204 @@ +/* + * drivers/staging/android/ion/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_ION_H +#define _LINUX_ION_H + +#include + +#include "../uapi/ion.h" + +struct ion_handle; +struct ion_device; +struct ion_heap; +struct ion_mapper; +struct ion_client; +struct ion_buffer; + +/* This should be removed some day when phys_addr_t's are fully + plumbed in the kernel, and all instances of ion_phys_addr_t should + be converted to phys_addr_t. For the time being many kernel interfaces + do not accept phys_addr_t's that would have to */ +#define ion_phys_addr_t unsigned long + +/** + * struct ion_platform_heap - defines a heap in the given platform + * @type: type of the heap from ion_heap_type enum + * @id: unique identifier for heap. When allocating higher numbers + * will be allocated from first. At allocation these are passed + * as a bit mask and therefore can not exceed ION_NUM_HEAP_IDS. + * @name: used for debug purposes + * @base: base address of heap in physical memory if applicable + * @size: size of the heap in bytes if applicable + * @align: required alignment in physical memory if applicable + * @priv: private info passed from the board file + * + * Provided by the board file. + */ +struct ion_platform_heap { + enum ion_heap_type type; + unsigned int id; + const char *name; + ion_phys_addr_t base; + size_t size; + ion_phys_addr_t align; + void *priv; +}; + +/** + * struct ion_platform_data - array of platform heaps passed from board file + * @nr: number of structures in the array + * @heaps: array of platform_heap structions + * + * Provided by the board file in the form of platform data to a platform device. + */ +struct ion_platform_data { + int nr; + struct ion_platform_heap *heaps; +}; + +/** + * ion_reserve() - reserve memory for ion heaps if applicable + * @data: platform data specifying starting physical address and + * size + * + * Calls memblock reserve to set aside memory for heaps that are + * located at specific memory addresses or of specfic sizes not + * managed by the kernel + */ +void ion_reserve(struct ion_platform_data *data); + +/** + * ion_client_create() - allocate a client and returns it + * @dev: the global ion device + * @heap_type_mask: mask of heaps this client can allocate from + * @name: used for debugging + */ +struct ion_client *ion_client_create(struct ion_device *dev, + const char *name); + +/** + * ion_client_destroy() - free's a client and all it's handles + * @client: the client + * + * Free the provided client and all it's resources including + * any handles it is holding. + */ +void ion_client_destroy(struct ion_client *client); + +/** + * ion_alloc - allocate ion memory + * @client: the client + * @len: size of the allocation + * @align: requested allocation alignment, lots of hardware blocks + * have alignment requirements of some kind + * @heap_id_mask: mask of heaps to allocate from, if multiple bits are set + * heaps will be tried in order from highest to lowest + * id + * @flags: heap flags, the low 16 bits are consumed by ion, the + * high 16 bits are passed on to the respective heap and + * can be heap custom + * + * Allocate memory in one of the heaps provided in heap mask and return + * an opaque handle to it. + */ +struct ion_handle *ion_alloc(struct ion_client *client, size_t len, + size_t align, unsigned int heap_id_mask, + unsigned int flags); + +/** + * ion_free - free a handle + * @client: the client + * @handle: the handle to free + * + * Free the provided handle. + */ +void ion_free(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_phys - returns the physical address and len of a handle + * @client: the client + * @handle: the handle + * @addr: a pointer to put the address in + * @len: a pointer to put the length in + * + * This function queries the heap for a particular handle to get the + * handle's physical address. It't output is only correct if + * a heap returns physically contiguous memory -- in other cases + * this api should not be implemented -- ion_sg_table should be used + * instead. Returns -EINVAL if the handle is invalid. This has + * no implications on the reference counting of the handle -- + * the returned value may not be valid if the caller is not + * holding a reference. + */ +int ion_phys(struct ion_client *client, struct ion_handle *handle, + ion_phys_addr_t *addr, size_t *len); + +/** + * ion_map_dma - return an sg_table describing a handle + * @client: the client + * @handle: the handle + * + * This function returns the sg_table describing + * a particular ion handle. + */ +struct sg_table *ion_sg_table(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_map_kernel - create mapping for the given handle + * @client: the client + * @handle: handle to map + * + * Map the given handle into the kernel and return a kernel address that + * can be used to access this address. + */ +void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_unmap_kernel() - destroy a kernel mapping for a handle + * @client: the client + * @handle: handle to unmap + */ +void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_share_dma_buf() - share buffer as dma-buf + * @client: the client + * @handle: the handle + */ +struct dma_buf *ion_share_dma_buf(struct ion_client *client, + struct ion_handle *handle); + +/** + * ion_share_dma_buf_fd() - given an ion client, create a dma-buf fd + * @client: the client + * @handle: the handle + */ +int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle); + +/** + * ion_import_dma_buf() - given an dma-buf fd from the ion exporter get handle + * @client: the client + * @fd: the dma-buf fd + * + * Given an dma-buf fd that was allocated through ion via ion_share_dma_buf, + * import that fd and return a handle representing it. If a dma-buf from + * another exporter is passed in this function will return ERR_PTR(-EINVAL) + */ +struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd); + +#endif /* _LINUX_ION_H */ diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c new file mode 100644 index 000000000000..3cb05b9b0e93 --- /dev/null +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -0,0 +1,194 @@ +/* + * drivers/staging/android/ion/ion_carveout_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ion.h" +#include "ion_priv.h" + +struct ion_carveout_heap { + struct ion_heap heap; + struct gen_pool *pool; + ion_phys_addr_t base; +}; + +ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, + unsigned long size, + unsigned long align) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + unsigned long offset = gen_pool_alloc(carveout_heap->pool, size); + + if (!offset) + return ION_CARVEOUT_ALLOCATE_FAIL; + + return offset; +} + +void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, + unsigned long size) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + + if (addr == ION_CARVEOUT_ALLOCATE_FAIL) + return; + gen_pool_free(carveout_heap->pool, addr, size); +} + +static int ion_carveout_heap_phys(struct ion_heap *heap, + struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); + + *addr = paddr; + *len = buffer->size; + return 0; +} + +static int ion_carveout_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct sg_table *table; + ion_phys_addr_t paddr; + int ret; + + if (align > PAGE_SIZE) + return -EINVAL; + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto err_free; + + paddr = ion_carveout_allocate(heap, size, align); + if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) { + ret = -ENOMEM; + goto err_free_table; + } + + sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), size, 0); + buffer->priv_virt = table; + + return 0; + +err_free_table: + sg_free_table(table); +err_free: + kfree(table); + return ret; +} + +static void ion_carveout_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + ion_phys_addr_t paddr = PFN_PHYS(page_to_pfn(page)); + + ion_heap_buffer_zero(buffer); + + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + + ion_carveout_free(heap, paddr, buffer->size); + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops carveout_heap_ops = { + .allocate = ion_carveout_heap_allocate, + .free = ion_carveout_heap_free, + .phys = ion_carveout_heap_phys, + .map_dma = ion_carveout_heap_map_dma, + .unmap_dma = ion_carveout_heap_unmap_dma, + .map_user = ion_heap_map_user, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, +}; + +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_carveout_heap *carveout_heap; + int ret; + + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); + + carveout_heap = kzalloc(sizeof(struct ion_carveout_heap), GFP_KERNEL); + if (!carveout_heap) + return ERR_PTR(-ENOMEM); + + carveout_heap->pool = gen_pool_create(12, -1); + if (!carveout_heap->pool) { + kfree(carveout_heap); + return ERR_PTR(-ENOMEM); + } + carveout_heap->base = heap_data->base; + gen_pool_add(carveout_heap->pool, carveout_heap->base, heap_data->size, + -1); + carveout_heap->heap.ops = &carveout_heap_ops; + carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT; + carveout_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + + return &carveout_heap->heap; +} + +void ion_carveout_heap_destroy(struct ion_heap *heap) +{ + struct ion_carveout_heap *carveout_heap = + container_of(heap, struct ion_carveout_heap, heap); + + gen_pool_destroy(carveout_heap->pool); + kfree(carveout_heap); + carveout_heap = NULL; +} diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c new file mode 100644 index 000000000000..d40f5f831808 --- /dev/null +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -0,0 +1,195 @@ +/* + * drivers/staging/android/ion/ion_chunk_heap.c + * + * Copyright (C) 2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "ion.h" +#include "ion_priv.h" + +struct ion_chunk_heap { + struct ion_heap heap; + struct gen_pool *pool; + ion_phys_addr_t base; + unsigned long chunk_size; + unsigned long size; + unsigned long allocated; +}; + +static int ion_chunk_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + struct sg_table *table; + struct scatterlist *sg; + int ret, i; + unsigned long num_chunks; + unsigned long allocated_size; + + if (align > chunk_heap->chunk_size) + return -EINVAL; + + allocated_size = ALIGN(size, chunk_heap->chunk_size); + num_chunks = allocated_size / chunk_heap->chunk_size; + + if (allocated_size > chunk_heap->size - chunk_heap->allocated) + return -ENOMEM; + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + return -ENOMEM; + ret = sg_alloc_table(table, num_chunks, GFP_KERNEL); + if (ret) { + kfree(table); + return ret; + } + + sg = table->sgl; + for (i = 0; i < num_chunks; i++) { + unsigned long paddr = gen_pool_alloc(chunk_heap->pool, + chunk_heap->chunk_size); + if (!paddr) + goto err; + sg_set_page(sg, pfn_to_page(PFN_DOWN(paddr)), + chunk_heap->chunk_size, 0); + sg = sg_next(sg); + } + + buffer->priv_virt = table; + chunk_heap->allocated += allocated_size; + return 0; +err: + sg = table->sgl; + for (i -= 1; i >= 0; i--) { + gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), + sg->length); + sg = sg_next(sg); + } + sg_free_table(table); + kfree(table); + return -ENOMEM; +} + +static void ion_chunk_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + struct sg_table *table = buffer->priv_virt; + struct scatterlist *sg; + int i; + unsigned long allocated_size; + + allocated_size = ALIGN(buffer->size, chunk_heap->chunk_size); + + ion_heap_buffer_zero(buffer); + + if (ion_buffer_cached(buffer)) + dma_sync_sg_for_device(NULL, table->sgl, table->nents, + DMA_BIDIRECTIONAL); + + for_each_sg(table->sgl, sg, table->nents, i) { + gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)), + sg->length); + } + chunk_heap->allocated -= allocated_size; + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_chunk_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops chunk_heap_ops = { + .allocate = ion_chunk_heap_allocate, + .free = ion_chunk_heap_free, + .map_dma = ion_chunk_heap_map_dma, + .unmap_dma = ion_chunk_heap_unmap_dma, + .map_user = ion_heap_map_user, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, +}; + +struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_chunk_heap *chunk_heap; + int ret; + struct page *page; + size_t size; + + page = pfn_to_page(PFN_DOWN(heap_data->base)); + size = heap_data->size; + + ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL); + + ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL)); + if (ret) + return ERR_PTR(ret); + + chunk_heap = kzalloc(sizeof(struct ion_chunk_heap), GFP_KERNEL); + if (!chunk_heap) + return ERR_PTR(-ENOMEM); + + chunk_heap->chunk_size = (unsigned long)heap_data->priv; + chunk_heap->pool = gen_pool_create(get_order(chunk_heap->chunk_size) + + PAGE_SHIFT, -1); + if (!chunk_heap->pool) { + ret = -ENOMEM; + goto error_gen_pool_create; + } + chunk_heap->base = heap_data->base; + chunk_heap->size = heap_data->size; + chunk_heap->allocated = 0; + + gen_pool_add(chunk_heap->pool, chunk_heap->base, heap_data->size, -1); + chunk_heap->heap.ops = &chunk_heap_ops; + chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK; + chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + pr_info("%s: base %lu size %zu align %ld\n", __func__, chunk_heap->base, + heap_data->size, heap_data->align); + + return &chunk_heap->heap; + +error_gen_pool_create: + kfree(chunk_heap); + return ERR_PTR(ret); +} + +void ion_chunk_heap_destroy(struct ion_heap *heap) +{ + struct ion_chunk_heap *chunk_heap = + container_of(heap, struct ion_chunk_heap, heap); + + gen_pool_destroy(chunk_heap->pool); + kfree(chunk_heap); + chunk_heap = NULL; +} diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c new file mode 100644 index 000000000000..f0f98897e4b9 --- /dev/null +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -0,0 +1,218 @@ +/* + * drivers/staging/android/ion/ion_cma_heap.c + * + * Copyright (C) Linaro 2012 + * Author: for ST-Ericsson. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include + +#include "ion.h" +#include "ion_priv.h" + +#define ION_CMA_ALLOCATE_FAILED -1 + +struct ion_cma_heap { + struct ion_heap heap; + struct device *dev; +}; + +#define to_cma_heap(x) container_of(x, struct ion_cma_heap, heap) + +struct ion_cma_buffer_info { + void *cpu_addr; + dma_addr_t handle; + struct sg_table *table; +}; + +/* + * Create scatter-list for the already allocated DMA buffer. + * This function could be replaced by dma_common_get_sgtable + * as soon as it will avalaible. + */ +static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt, + void *cpu_addr, dma_addr_t handle, size_t size) +{ + struct page *page = virt_to_page(cpu_addr); + int ret; + + ret = sg_alloc_table(sgt, 1, GFP_KERNEL); + if (unlikely(ret)) + return ret; + + sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0); + return 0; +} + +/* ION CMA heap operations functions */ +static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, + unsigned long len, unsigned long align, + unsigned long flags) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info; + + dev_dbg(dev, "Request buffer allocation len %ld\n", len); + + if (buffer->flags & ION_FLAG_CACHED) + return -EINVAL; + + if (align > PAGE_SIZE) + return -EINVAL; + + info = kzalloc(sizeof(struct ion_cma_buffer_info), GFP_KERNEL); + if (!info) { + dev_err(dev, "Can't allocate buffer info\n"); + return ION_CMA_ALLOCATE_FAILED; + } + + info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle), + GFP_HIGHUSER | __GFP_ZERO); + + if (!info->cpu_addr) { + dev_err(dev, "Fail to allocate buffer\n"); + goto err; + } + + info->table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!info->table) { + dev_err(dev, "Fail to allocate sg table\n"); + goto free_mem; + } + + if (ion_cma_get_sgtable + (dev, info->table, info->cpu_addr, info->handle, len)) + goto free_table; + /* keep this for memory release */ + buffer->priv_virt = info; + dev_dbg(dev, "Allocate buffer %p\n", buffer); + return 0; + +free_table: + kfree(info->table); +free_mem: + dma_free_coherent(dev, len, info->cpu_addr, info->handle); +err: + kfree(info); + return ION_CMA_ALLOCATE_FAILED; +} + +static void ion_cma_free(struct ion_buffer *buffer) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + dev_dbg(dev, "Release buffer %p\n", buffer); + /* release memory */ + dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle); + /* release sg table */ + sg_free_table(info->table); + kfree(info->table); + kfree(info); +} + +/* return physical address in addr */ +static int ion_cma_phys(struct ion_heap *heap, struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + dev_dbg(dev, "Return buffer %p physical address 0x%pa\n", buffer, + &info->handle); + + *addr = info->handle; + *len = buffer->size; + + return 0; +} + +static struct sg_table *ion_cma_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct ion_cma_buffer_info *info = buffer->priv_virt; + + return info->table; +} + +static void ion_cma_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static int ion_cma_mmap(struct ion_heap *mapper, struct ion_buffer *buffer, + struct vm_area_struct *vma) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap); + struct device *dev = cma_heap->dev; + struct ion_cma_buffer_info *info = buffer->priv_virt; + + return dma_mmap_coherent(dev, vma, info->cpu_addr, info->handle, + buffer->size); +} + +static void *ion_cma_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct ion_cma_buffer_info *info = buffer->priv_virt; + /* kernel memory mapping has been done at allocation time */ + return info->cpu_addr; +} + +static void ion_cma_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ +} + +static struct ion_heap_ops ion_cma_ops = { + .allocate = ion_cma_allocate, + .free = ion_cma_free, + .map_dma = ion_cma_heap_map_dma, + .unmap_dma = ion_cma_heap_unmap_dma, + .phys = ion_cma_phys, + .map_user = ion_cma_mmap, + .map_kernel = ion_cma_map_kernel, + .unmap_kernel = ion_cma_unmap_kernel, +}; + +struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) +{ + struct ion_cma_heap *cma_heap; + + cma_heap = kzalloc(sizeof(struct ion_cma_heap), GFP_KERNEL); + + if (!cma_heap) + return ERR_PTR(-ENOMEM); + + cma_heap->heap.ops = &ion_cma_ops; + /* get device from private heaps data, later it will be + * used to make the link with reserved CMA memory */ + cma_heap->dev = data->priv; + cma_heap->heap.type = ION_HEAP_TYPE_DMA; + return &cma_heap->heap; +} + +void ion_cma_heap_destroy(struct ion_heap *heap) +{ + struct ion_cma_heap *cma_heap = to_cma_heap(heap); + + kfree(cma_heap); +} diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c new file mode 100644 index 000000000000..55b2002753f2 --- /dev/null +++ b/drivers/staging/android/ion/ion_dummy_driver.c @@ -0,0 +1,158 @@ +/* + * drivers/gpu/ion/ion_dummy_driver.c + * + * Copyright (C) 2013 Linaro, Inc + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include "ion.h" +#include "ion_priv.h" + +struct ion_device *idev; +struct ion_heap **heaps; + +void *carveout_ptr; +void *chunk_ptr; + +struct ion_platform_heap dummy_heaps[] = { + { + .id = ION_HEAP_TYPE_SYSTEM, + .type = ION_HEAP_TYPE_SYSTEM, + .name = "system", + }, + { + .id = ION_HEAP_TYPE_SYSTEM_CONTIG, + .type = ION_HEAP_TYPE_SYSTEM_CONTIG, + .name = "system contig", + }, + { + .id = ION_HEAP_TYPE_CARVEOUT, + .type = ION_HEAP_TYPE_CARVEOUT, + .name = "carveout", + .size = SZ_4M, + }, + { + .id = ION_HEAP_TYPE_CHUNK, + .type = ION_HEAP_TYPE_CHUNK, + .name = "chunk", + .size = SZ_4M, + .align = SZ_16K, + .priv = (void *)(SZ_16K), + }, +}; + +struct ion_platform_data dummy_ion_pdata = { + .nr = 4, + .heaps = dummy_heaps, +}; + +static int __init ion_dummy_init(void) +{ + int i, err; + + idev = ion_device_create(NULL); + heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, + GFP_KERNEL); + if (!heaps) + return PTR_ERR(heaps); + + + /* Allocate a dummy carveout heap */ + carveout_ptr = alloc_pages_exact( + dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size, + GFP_KERNEL); + if (carveout_ptr) + dummy_heaps[ION_HEAP_TYPE_CARVEOUT].base = + virt_to_phys(carveout_ptr); + else + pr_err("ion_dummy: Could not allocate carveout\n"); + + /* Allocate a dummy chunk heap */ + chunk_ptr = alloc_pages_exact( + dummy_heaps[ION_HEAP_TYPE_CHUNK].size, + GFP_KERNEL); + if (chunk_ptr) + dummy_heaps[ION_HEAP_TYPE_CHUNK].base = virt_to_phys(chunk_ptr); + else + pr_err("ion_dummy: Could not allocate chunk\n"); + + for (i = 0; i < dummy_ion_pdata.nr; i++) { + struct ion_platform_heap *heap_data = &dummy_ion_pdata.heaps[i]; + + if (heap_data->type == ION_HEAP_TYPE_CARVEOUT && + !heap_data->base) + continue; + + if (heap_data->type == ION_HEAP_TYPE_CHUNK && !heap_data->base) + continue; + + heaps[i] = ion_heap_create(heap_data); + if (IS_ERR_OR_NULL(heaps[i])) { + err = PTR_ERR(heaps[i]); + goto err; + } + ion_device_add_heap(idev, heaps[i]); + } + return 0; +err: + for (i = 0; i < dummy_ion_pdata.nr; i++) { + if (heaps[i]) + ion_heap_destroy(heaps[i]); + } + kfree(heaps); + + if (carveout_ptr) { + free_pages_exact(carveout_ptr, + dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); + carveout_ptr = NULL; + } + if (chunk_ptr) { + free_pages_exact(chunk_ptr, + dummy_heaps[ION_HEAP_TYPE_CHUNK].size); + chunk_ptr = NULL; + } + return err; +} + +static void __exit ion_dummy_exit(void) +{ + int i; + + ion_device_destroy(idev); + + for (i = 0; i < dummy_ion_pdata.nr; i++) + ion_heap_destroy(heaps[i]); + kfree(heaps); + + if (carveout_ptr) { + free_pages_exact(carveout_ptr, + dummy_heaps[ION_HEAP_TYPE_CARVEOUT].size); + carveout_ptr = NULL; + } + if (chunk_ptr) { + free_pages_exact(chunk_ptr, + dummy_heaps[ION_HEAP_TYPE_CHUNK].size); + chunk_ptr = NULL; + } + + return; +} + +module_init(ion_dummy_init); +module_exit(ion_dummy_exit); + diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c new file mode 100644 index 000000000000..296c74f98dc0 --- /dev/null +++ b/drivers/staging/android/ion/ion_heap.c @@ -0,0 +1,318 @@ +/* + * drivers/staging/android/ion/ion_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ion.h" +#include "ion_priv.h" + +void *ion_heap_map_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + struct scatterlist *sg; + int i, j; + void *vaddr; + pgprot_t pgprot; + struct sg_table *table = buffer->sg_table; + int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; + struct page **pages = vmalloc(sizeof(struct page *) * npages); + struct page **tmp = pages; + + if (!pages) + return NULL; + + if (buffer->flags & ION_FLAG_CACHED) + pgprot = PAGE_KERNEL; + else + pgprot = pgprot_writecombine(PAGE_KERNEL); + + for_each_sg(table->sgl, sg, table->nents, i) { + int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; + struct page *page = sg_page(sg); + BUG_ON(i >= npages); + for (j = 0; j < npages_this_entry; j++) + *(tmp++) = page++; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + vfree(pages); + + if (vaddr == NULL) + return ERR_PTR(-ENOMEM); + + return vaddr; +} + +void ion_heap_unmap_kernel(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + vunmap(buffer->vaddr); +} + +int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, + struct vm_area_struct *vma) +{ + struct sg_table *table = buffer->sg_table; + unsigned long addr = vma->vm_start; + unsigned long offset = vma->vm_pgoff * PAGE_SIZE; + struct scatterlist *sg; + int i; + int ret; + + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page = sg_page(sg); + unsigned long remainder = vma->vm_end - addr; + unsigned long len = sg->length; + + if (offset >= sg->length) { + offset -= sg->length; + continue; + } else if (offset) { + page += offset / PAGE_SIZE; + len = sg->length - offset; + offset = 0; + } + len = min(len, remainder); + ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, + vma->vm_page_prot); + if (ret) + return ret; + addr += len; + if (addr >= vma->vm_end) + return 0; + } + return 0; +} + +static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) +{ + void *addr = vm_map_ram(pages, num, -1, pgprot); + if (!addr) + return -ENOMEM; + memset(addr, 0, PAGE_SIZE * num); + vm_unmap_ram(addr, num); + + return 0; +} + +static int ion_heap_sglist_zero(struct scatterlist *sgl, unsigned int nents, + pgprot_t pgprot) +{ + int p = 0; + int ret = 0; + struct sg_page_iter piter; + struct page *pages[32]; + + for_each_sg_page(sgl, &piter, nents, 0) { + pages[p++] = sg_page_iter_page(&piter); + if (p == ARRAY_SIZE(pages)) { + ret = ion_heap_clear_pages(pages, p, pgprot); + if (ret) + return ret; + p = 0; + } + } + if (p) + ret = ion_heap_clear_pages(pages, p, pgprot); + + return ret; +} + +int ion_heap_buffer_zero(struct ion_buffer *buffer) +{ + struct sg_table *table = buffer->sg_table; + pgprot_t pgprot; + + if (buffer->flags & ION_FLAG_CACHED) + pgprot = PAGE_KERNEL; + else + pgprot = pgprot_writecombine(PAGE_KERNEL); + + return ion_heap_sglist_zero(table->sgl, table->nents, pgprot); +} + +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot) +{ + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, page, size, 0); + return ion_heap_sglist_zero(&sg, 1, pgprot); +} + +void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer) +{ + spin_lock(&heap->free_lock); + list_add(&buffer->list, &heap->free_list); + heap->free_list_size += buffer->size; + spin_unlock(&heap->free_lock); + wake_up(&heap->waitqueue); +} + +size_t ion_heap_freelist_size(struct ion_heap *heap) +{ + size_t size; + + spin_lock(&heap->free_lock); + size = heap->free_list_size; + spin_unlock(&heap->free_lock); + + return size; +} + +size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size) +{ + struct ion_buffer *buffer; + size_t total_drained = 0; + + if (ion_heap_freelist_size(heap) == 0) + return 0; + + spin_lock(&heap->free_lock); + if (size == 0) + size = heap->free_list_size; + + while (!list_empty(&heap->free_list)) { + if (total_drained >= size) + break; + buffer = list_first_entry(&heap->free_list, struct ion_buffer, + list); + list_del(&buffer->list); + heap->free_list_size -= buffer->size; + total_drained += buffer->size; + spin_unlock(&heap->free_lock); + ion_buffer_destroy(buffer); + spin_lock(&heap->free_lock); + } + spin_unlock(&heap->free_lock); + + return total_drained; +} + +static int ion_heap_deferred_free(void *data) +{ + struct ion_heap *heap = data; + + while (true) { + struct ion_buffer *buffer; + + wait_event_freezable(heap->waitqueue, + ion_heap_freelist_size(heap) > 0); + + spin_lock(&heap->free_lock); + if (list_empty(&heap->free_list)) { + spin_unlock(&heap->free_lock); + continue; + } + buffer = list_first_entry(&heap->free_list, struct ion_buffer, + list); + list_del(&buffer->list); + heap->free_list_size -= buffer->size; + spin_unlock(&heap->free_lock); + ion_buffer_destroy(buffer); + } + + return 0; +} + +int ion_heap_init_deferred_free(struct ion_heap *heap) +{ + struct sched_param param = { .sched_priority = 0 }; + + INIT_LIST_HEAD(&heap->free_list); + heap->free_list_size = 0; + spin_lock_init(&heap->free_lock); + init_waitqueue_head(&heap->waitqueue); + heap->task = kthread_run(ion_heap_deferred_free, heap, + "%s", heap->name); + sched_setscheduler(heap->task, SCHED_IDLE, ¶m); + if (IS_ERR(heap->task)) { + pr_err("%s: creating thread for deferred free failed\n", + __func__); + return PTR_RET(heap->task); + } + return 0; +} + +struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data) +{ + struct ion_heap *heap = NULL; + + switch (heap_data->type) { + case ION_HEAP_TYPE_SYSTEM_CONTIG: + heap = ion_system_contig_heap_create(heap_data); + break; + case ION_HEAP_TYPE_SYSTEM: + heap = ion_system_heap_create(heap_data); + break; + case ION_HEAP_TYPE_CARVEOUT: + heap = ion_carveout_heap_create(heap_data); + break; + case ION_HEAP_TYPE_CHUNK: + heap = ion_chunk_heap_create(heap_data); + break; + case ION_HEAP_TYPE_DMA: + heap = ion_cma_heap_create(heap_data); + break; + default: + pr_err("%s: Invalid heap type %d\n", __func__, + heap_data->type); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR_OR_NULL(heap)) { + pr_err("%s: error creating heap %s type %d base %lu size %zu\n", + __func__, heap_data->name, heap_data->type, + heap_data->base, heap_data->size); + return ERR_PTR(-EINVAL); + } + + heap->name = heap_data->name; + heap->id = heap_data->id; + return heap; +} + +void ion_heap_destroy(struct ion_heap *heap) +{ + if (!heap) + return; + + switch (heap->type) { + case ION_HEAP_TYPE_SYSTEM_CONTIG: + ion_system_contig_heap_destroy(heap); + break; + case ION_HEAP_TYPE_SYSTEM: + ion_system_heap_destroy(heap); + break; + case ION_HEAP_TYPE_CARVEOUT: + ion_carveout_heap_destroy(heap); + break; + case ION_HEAP_TYPE_CHUNK: + ion_chunk_heap_destroy(heap); + break; + case ION_HEAP_TYPE_DMA: + ion_cma_heap_destroy(heap); + break; + default: + pr_err("%s: Invalid heap type %d\n", __func__, + heap->type); + } +} diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c new file mode 100644 index 000000000000..fa693c23681a --- /dev/null +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -0,0 +1,195 @@ +/* + * drivers/staging/android/ion/ion_mem_pool.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ion_priv.h" + +struct ion_page_pool_item { + struct page *page; + struct list_head list; +}; + +static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) +{ + struct page *page = alloc_pages(pool->gfp_mask, pool->order); + + if (!page) + return NULL; + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order, + DMA_BIDIRECTIONAL); + return page; +} + +static void ion_page_pool_free_pages(struct ion_page_pool *pool, + struct page *page) +{ + __free_pages(page, pool->order); +} + +static int ion_page_pool_add(struct ion_page_pool *pool, struct page *page) +{ + struct ion_page_pool_item *item; + + item = kmalloc(sizeof(struct ion_page_pool_item), GFP_KERNEL); + if (!item) + return -ENOMEM; + + mutex_lock(&pool->mutex); + item->page = page; + if (PageHighMem(page)) { + list_add_tail(&item->list, &pool->high_items); + pool->high_count++; + } else { + list_add_tail(&item->list, &pool->low_items); + pool->low_count++; + } + mutex_unlock(&pool->mutex); + return 0; +} + +static struct page *ion_page_pool_remove(struct ion_page_pool *pool, bool high) +{ + struct ion_page_pool_item *item; + struct page *page; + + if (high) { + BUG_ON(!pool->high_count); + item = list_first_entry(&pool->high_items, + struct ion_page_pool_item, list); + pool->high_count--; + } else { + BUG_ON(!pool->low_count); + item = list_first_entry(&pool->low_items, + struct ion_page_pool_item, list); + pool->low_count--; + } + + list_del(&item->list); + page = item->page; + kfree(item); + return page; +} + +void *ion_page_pool_alloc(struct ion_page_pool *pool) +{ + struct page *page = NULL; + + BUG_ON(!pool); + + mutex_lock(&pool->mutex); + if (pool->high_count) + page = ion_page_pool_remove(pool, true); + else if (pool->low_count) + page = ion_page_pool_remove(pool, false); + mutex_unlock(&pool->mutex); + + if (!page) + page = ion_page_pool_alloc_pages(pool); + + return page; +} + +void ion_page_pool_free(struct ion_page_pool *pool, struct page *page) +{ + int ret; + + ret = ion_page_pool_add(pool, page); + if (ret) + ion_page_pool_free_pages(pool, page); +} + +static int ion_page_pool_total(struct ion_page_pool *pool, bool high) +{ + int total = 0; + + total += high ? (pool->high_count + pool->low_count) * + (1 << pool->order) : + pool->low_count * (1 << pool->order); + return total; +} + +int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, + int nr_to_scan) +{ + int nr_freed = 0; + int i; + bool high; + + high = !!(gfp_mask & __GFP_HIGHMEM); + + if (nr_to_scan == 0) + return ion_page_pool_total(pool, high); + + for (i = 0; i < nr_to_scan; i++) { + struct page *page; + + mutex_lock(&pool->mutex); + if (pool->low_count) { + page = ion_page_pool_remove(pool, false); + } else if (high && pool->high_count) { + page = ion_page_pool_remove(pool, true); + } else { + mutex_unlock(&pool->mutex); + break; + } + mutex_unlock(&pool->mutex); + ion_page_pool_free_pages(pool, page); + nr_freed += (1 << pool->order); + } + + return nr_freed; +} + +struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) +{ + struct ion_page_pool *pool = kmalloc(sizeof(struct ion_page_pool), + GFP_KERNEL); + if (!pool) + return NULL; + pool->high_count = 0; + pool->low_count = 0; + INIT_LIST_HEAD(&pool->low_items); + INIT_LIST_HEAD(&pool->high_items); + pool->gfp_mask = gfp_mask; + pool->order = order; + mutex_init(&pool->mutex); + plist_node_init(&pool->list, order); + + return pool; +} + +void ion_page_pool_destroy(struct ion_page_pool *pool) +{ + kfree(pool); +} + +static int __init ion_page_pool_init(void) +{ + return 0; +} + +static void __exit ion_page_pool_exit(void) +{ +} + +module_init(ion_page_pool_init); +module_exit(ion_page_pool_exit); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h new file mode 100644 index 000000000000..d98673981cc4 --- /dev/null +++ b/drivers/staging/android/ion/ion_priv.h @@ -0,0 +1,360 @@ +/* + * drivers/staging/android/ion/ion_priv.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _ION_PRIV_H +#define _ION_PRIV_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ion.h" + +struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); + +/** + * struct ion_buffer - metadata for a particular buffer + * @ref: refernce count + * @node: node in the ion_device buffers tree + * @dev: back pointer to the ion_device + * @heap: back pointer to the heap the buffer came from + * @flags: buffer specific flags + * @size: size of the buffer + * @priv_virt: private data to the buffer representable as + * a void * + * @priv_phys: private data to the buffer representable as + * an ion_phys_addr_t (and someday a phys_addr_t) + * @lock: protects the buffers cnt fields + * @kmap_cnt: number of times the buffer is mapped to the kernel + * @vaddr: the kenrel mapping if kmap_cnt is not zero + * @dmap_cnt: number of times the buffer is mapped for dma + * @sg_table: the sg table for the buffer if dmap_cnt is not zero + * @pages: flat array of pages in the buffer -- used by fault + * handler and only valid for buffers that are faulted in + * @vmas: list of vma's mapping this buffer + * @handle_count: count of handles referencing this buffer + * @task_comm: taskcomm of last client to reference this buffer in a + * handle, used for debugging + * @pid: pid of last client to reference this buffer in a + * handle, used for debugging +*/ +struct ion_buffer { + struct kref ref; + union { + struct rb_node node; + struct list_head list; + }; + struct ion_device *dev; + struct ion_heap *heap; + unsigned long flags; + size_t size; + union { + void *priv_virt; + ion_phys_addr_t priv_phys; + }; + struct mutex lock; + int kmap_cnt; + void *vaddr; + int dmap_cnt; + struct sg_table *sg_table; + struct page **pages; + struct list_head vmas; + /* used to track orphaned buffers */ + int handle_count; + char task_comm[TASK_COMM_LEN]; + pid_t pid; +}; +void ion_buffer_destroy(struct ion_buffer *buffer); + +/** + * struct ion_heap_ops - ops to operate on a given heap + * @allocate: allocate memory + * @free: free memory + * @phys get physical address of a buffer (only define on + * physically contiguous heaps) + * @map_dma map the memory for dma to a scatterlist + * @unmap_dma unmap the memory for dma + * @map_kernel map memory to the kernel + * @unmap_kernel unmap memory to the kernel + * @map_user map memory to userspace + * + * allocate, phys, and map_user return 0 on success, -errno on error. + * map_dma and map_kernel return pointer on success, ERR_PTR on error. + */ +struct ion_heap_ops { + int (*allocate) (struct ion_heap *heap, + struct ion_buffer *buffer, unsigned long len, + unsigned long align, unsigned long flags); + void (*free) (struct ion_buffer *buffer); + int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len); + struct sg_table *(*map_dma) (struct ion_heap *heap, + struct ion_buffer *buffer); + void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer); + void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); + void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); + int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer, + struct vm_area_struct *vma); +}; + +/** + * heap flags - flags between the heaps and core ion code + */ +#define ION_HEAP_FLAG_DEFER_FREE (1 << 0) + +/** + * struct ion_heap - represents a heap in the system + * @node: rb node to put the heap on the device's tree of heaps + * @dev: back pointer to the ion_device + * @type: type of heap + * @ops: ops struct as above + * @flags: flags + * @id: id of heap, also indicates priority of this heap when + * allocating. These are specified by platform data and + * MUST be unique + * @name: used for debugging + * @shrinker: a shrinker for the heap, if the heap caches system + * memory, it must define a shrinker to return it on low + * memory conditions, this includes system memory cached + * in the deferred free lists for heaps that support it + * @free_list: free list head if deferred free is used + * @free_list_size size of the deferred free list in bytes + * @lock: protects the free list + * @waitqueue: queue to wait on from deferred free thread + * @task: task struct of deferred free thread + * @debug_show: called when heap debug file is read to add any + * heap specific debug info to output + * + * Represents a pool of memory from which buffers can be made. In some + * systems the only heap is regular system memory allocated via vmalloc. + * On others, some blocks might require large physically contiguous buffers + * that are allocated from a specially reserved heap. + */ +struct ion_heap { + struct plist_node node; + struct ion_device *dev; + enum ion_heap_type type; + struct ion_heap_ops *ops; + unsigned long flags; + unsigned int id; + const char *name; + struct shrinker shrinker; + struct list_head free_list; + size_t free_list_size; + spinlock_t free_lock; + wait_queue_head_t waitqueue; + struct task_struct *task; + int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *); +}; + +/** + * ion_buffer_cached - this ion buffer is cached + * @buffer: buffer + * + * indicates whether this ion buffer is cached + */ +bool ion_buffer_cached(struct ion_buffer *buffer); + +/** + * ion_buffer_fault_user_mappings - fault in user mappings of this buffer + * @buffer: buffer + * + * indicates whether userspace mappings of this buffer will be faulted + * in, this can affect how buffers are allocated from the heap. + */ +bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer); + +/** + * ion_device_create - allocates and returns an ion device + * @custom_ioctl: arch specific ioctl function if applicable + * + * returns a valid device or -PTR_ERR + */ +struct ion_device *ion_device_create(long (*custom_ioctl) + (struct ion_client *client, + unsigned int cmd, + unsigned long arg)); + +/** + * ion_device_destroy - free and device and it's resource + * @dev: the device + */ +void ion_device_destroy(struct ion_device *dev); + +/** + * ion_device_add_heap - adds a heap to the ion device + * @dev: the device + * @heap: the heap to add + */ +void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); + +/** + * some helpers for common operations on buffers using the sg_table + * and vaddr fields + */ +void *ion_heap_map_kernel(struct ion_heap *, struct ion_buffer *); +void ion_heap_unmap_kernel(struct ion_heap *, struct ion_buffer *); +int ion_heap_map_user(struct ion_heap *, struct ion_buffer *, + struct vm_area_struct *); +int ion_heap_buffer_zero(struct ion_buffer *buffer); +int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot); + +/** + * ion_heap_init_deferred_free -- initialize deferred free functionality + * @heap: the heap + * + * If a heap sets the ION_HEAP_FLAG_DEFER_FREE flag this function will + * be called to setup deferred frees. Calls to free the buffer will + * return immediately and the actual free will occur some time later + */ +int ion_heap_init_deferred_free(struct ion_heap *heap); + +/** + * ion_heap_freelist_add - add a buffer to the deferred free list + * @heap: the heap + * @buffer: the buffer + * + * Adds an item to the deferred freelist. + */ +void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer); + +/** + * ion_heap_freelist_drain - drain the deferred free list + * @heap: the heap + * @size: ammount of memory to drain in bytes + * + * Drains the indicated amount of memory from the deferred freelist immediately. + * Returns the total amount freed. The total freed may be higher depending + * on the size of the items in the list, or lower if there is insufficient + * total memory on the freelist. + */ +size_t ion_heap_freelist_drain(struct ion_heap *heap, size_t size); + +/** + * ion_heap_freelist_size - returns the size of the freelist in bytes + * @heap: the heap + */ +size_t ion_heap_freelist_size(struct ion_heap *heap); + + +/** + * functions for creating and destroying the built in ion heaps. + * architectures can add their own custom architecture specific + * heaps as appropriate. + */ + +struct ion_heap *ion_heap_create(struct ion_platform_heap *); +void ion_heap_destroy(struct ion_heap *); +struct ion_heap *ion_system_heap_create(struct ion_platform_heap *); +void ion_system_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *); +void ion_system_contig_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *); +void ion_carveout_heap_destroy(struct ion_heap *); + +struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *); +void ion_chunk_heap_destroy(struct ion_heap *); +struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *); +void ion_cma_heap_destroy(struct ion_heap *); + +/** + * kernel api to allocate/free from carveout -- used when carveout is + * used to back an architecture specific custom heap + */ +ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap, unsigned long size, + unsigned long align); +void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, + unsigned long size); +/** + * The carveout heap returns physical addresses, since 0 may be a valid + * physical address, this is used to indicate allocation failed + */ +#define ION_CARVEOUT_ALLOCATE_FAIL -1 + +/** + * functions for creating and destroying a heap pool -- allows you + * to keep a pool of pre allocated memory to use from your heap. Keeping + * a pool of memory that is ready for dma, ie any cached mapping have been + * invalidated from the cache, provides a significant peformance benefit on + * many systems */ + +/** + * struct ion_page_pool - pagepool struct + * @high_count: number of highmem items in the pool + * @low_count: number of lowmem items in the pool + * @high_items: list of highmem items + * @low_items: list of lowmem items + * @shrinker: a shrinker for the items + * @mutex: lock protecting this struct and especially the count + * item list + * @alloc: function to be used to allocate pageory when the pool + * is empty + * @free: function to be used to free pageory back to the system + * when the shrinker fires + * @gfp_mask: gfp_mask to use from alloc + * @order: order of pages in the pool + * @list: plist node for list of pools + * + * Allows you to keep a pool of pre allocated pages to use from your heap. + * Keeping a pool of pages that is ready for dma, ie any cached mapping have + * been invalidated from the cache, provides a significant peformance benefit + * on many systems + */ +struct ion_page_pool { + int high_count; + int low_count; + struct list_head high_items; + struct list_head low_items; + struct mutex mutex; + gfp_t gfp_mask; + unsigned int order; + struct plist_node list; +}; + +struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order); +void ion_page_pool_destroy(struct ion_page_pool *); +void *ion_page_pool_alloc(struct ion_page_pool *); +void ion_page_pool_free(struct ion_page_pool *, struct page *); + +/** ion_page_pool_shrink - shrinks the size of the memory cached in the pool + * @pool: the pool + * @gfp_mask: the memory type to reclaim + * @nr_to_scan: number of items to shrink in pages + * + * returns the number of items freed in pages + */ +int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, + int nr_to_scan); + +/** + * ion_pages_sync_for_device - cache flush pages for use with the specified + * device + * @dev: the device the pages will be used with + * @page: the first page to be flushed + * @size: size in bytes of region to be flushed + * @dir: direction of dma transfer + */ +void ion_pages_sync_for_device(struct device *dev, struct page *page, + size_t size, enum dma_data_direction dir); + +#endif /* _ION_PRIV_H */ diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c new file mode 100644 index 000000000000..7f0729130d65 --- /dev/null +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -0,0 +1,488 @@ +/* + * drivers/staging/android/ion/ion_system_heap.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ion.h" +#include "ion_priv.h" + +static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | + __GFP_NORETRY) & ~__GFP_WAIT; +static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN); +static const unsigned int orders[] = {8, 4, 0}; +static const int num_orders = ARRAY_SIZE(orders); +static int order_to_index(unsigned int order) +{ + int i; + for (i = 0; i < num_orders; i++) + if (order == orders[i]) + return i; + BUG(); + return -1; +} + +static unsigned int order_to_size(int order) +{ + return PAGE_SIZE << order; +} + +struct ion_system_heap { + struct ion_heap heap; + struct ion_page_pool **pools; +}; + +struct page_info { + struct page *page; + unsigned int order; + struct list_head list; +}; + +static struct page *alloc_buffer_page(struct ion_system_heap *heap, + struct ion_buffer *buffer, + unsigned long order) +{ + bool cached = ion_buffer_cached(buffer); + struct ion_page_pool *pool = heap->pools[order_to_index(order)]; + struct page *page; + + if (!cached) { + page = ion_page_pool_alloc(pool); + } else { + gfp_t gfp_flags = low_order_gfp_flags; + + if (order > 4) + gfp_flags = high_order_gfp_flags; + page = alloc_pages(gfp_flags, order); + if (!page) + return NULL; + ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order, + DMA_BIDIRECTIONAL); + } + if (!page) + return NULL; + + return page; +} + +static void free_buffer_page(struct ion_system_heap *heap, + struct ion_buffer *buffer, struct page *page, + unsigned int order) +{ + bool cached = ion_buffer_cached(buffer); + + if (!cached) { + struct ion_page_pool *pool = heap->pools[order_to_index(order)]; + ion_page_pool_free(pool, page); + } else { + __free_pages(page, order); + } +} + + +static struct page_info *alloc_largest_available(struct ion_system_heap *heap, + struct ion_buffer *buffer, + unsigned long size, + unsigned int max_order) +{ + struct page *page; + struct page_info *info; + int i; + + info = kmalloc(sizeof(struct page_info), GFP_KERNEL); + if (!info) + return NULL; + + for (i = 0; i < num_orders; i++) { + if (size < order_to_size(orders[i])) + continue; + if (max_order < orders[i]) + continue; + + page = alloc_buffer_page(heap, buffer, orders[i]); + if (!page) + continue; + + info->page = page; + info->order = orders[i]; + return info; + } + kfree(info); + + return NULL; +} + +static int ion_system_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long size, unsigned long align, + unsigned long flags) +{ + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + struct sg_table *table; + struct scatterlist *sg; + int ret; + struct list_head pages; + struct page_info *info, *tmp_info; + int i = 0; + long size_remaining = PAGE_ALIGN(size); + unsigned int max_order = orders[0]; + + if (align > PAGE_SIZE) + return -EINVAL; + + INIT_LIST_HEAD(&pages); + while (size_remaining > 0) { + info = alloc_largest_available(sys_heap, buffer, size_remaining, + max_order); + if (!info) + goto err; + list_add_tail(&info->list, &pages); + size_remaining -= (1 << info->order) * PAGE_SIZE; + max_order = info->order; + i++; + } + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + goto err; + + ret = sg_alloc_table(table, i, GFP_KERNEL); + if (ret) + goto err1; + + sg = table->sgl; + list_for_each_entry_safe(info, tmp_info, &pages, list) { + struct page *page = info->page; + sg_set_page(sg, page, (1 << info->order) * PAGE_SIZE, 0); + sg = sg_next(sg); + list_del(&info->list); + kfree(info); + } + + buffer->priv_virt = table; + return 0; +err1: + kfree(table); +err: + list_for_each_entry_safe(info, tmp_info, &pages, list) { + free_buffer_page(sys_heap, buffer, info->page, info->order); + kfree(info); + } + return -ENOMEM; +} + +static void ion_system_heap_free(struct ion_buffer *buffer) +{ + struct ion_heap *heap = buffer->heap; + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + struct sg_table *table = buffer->sg_table; + bool cached = ion_buffer_cached(buffer); + struct scatterlist *sg; + LIST_HEAD(pages); + int i; + + /* uncached pages come from the page pools, zero them before returning + for security purposes (other allocations are zerod at alloc time */ + if (!cached) + ion_heap_buffer_zero(buffer); + + for_each_sg(table->sgl, sg, table->nents, i) + free_buffer_page(sys_heap, buffer, sg_page(sg), + get_order(sg->length)); + sg_free_table(table); + kfree(table); +} + +static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_system_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return; +} + +static struct ion_heap_ops system_heap_ops = { + .allocate = ion_system_heap_allocate, + .free = ion_system_heap_free, + .map_dma = ion_system_heap_map_dma, + .unmap_dma = ion_system_heap_unmap_dma, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, + .map_user = ion_heap_map_user, +}; + +static unsigned long ion_system_heap_shrink_count(struct shrinker *shrinker, + struct shrink_control *sc) +{ + struct ion_heap *heap = container_of(shrinker, struct ion_heap, + shrinker); + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int nr_total = 0; + int i; + + /* total number of items is whatever the page pools are holding + plus whatever's in the freelist */ + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + nr_total += ion_page_pool_shrink(pool, sc->gfp_mask, 0); + } + nr_total += ion_heap_freelist_size(heap) / PAGE_SIZE; + return nr_total; + +} + +static unsigned long ion_system_heap_shrink_scan(struct shrinker *shrinker, + struct shrink_control *sc) +{ + + struct ion_heap *heap = container_of(shrinker, struct ion_heap, + shrinker); + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int nr_freed = 0; + int i; + + if (sc->nr_to_scan == 0) + goto end; + + /* shrink the free list first, no point in zeroing the memory if + we're just going to reclaim it */ + nr_freed += ion_heap_freelist_drain(heap, sc->nr_to_scan * PAGE_SIZE) / + PAGE_SIZE; + + if (nr_freed >= sc->nr_to_scan) + goto end; + + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + + nr_freed += ion_page_pool_shrink(pool, sc->gfp_mask, + sc->nr_to_scan); + if (nr_freed >= sc->nr_to_scan) + break; + } + +end: + return nr_freed; + +} + +static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s, + void *unused) +{ + + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int i; + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool = sys_heap->pools[i]; + seq_printf(s, "%d order %u highmem pages in pool = %lu total\n", + pool->high_count, pool->order, + (1 << pool->order) * PAGE_SIZE * pool->high_count); + seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n", + pool->low_count, pool->order, + (1 << pool->order) * PAGE_SIZE * pool->low_count); + } + return 0; +} + +struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) +{ + struct ion_system_heap *heap; + int i; + + heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL); + if (!heap) + return ERR_PTR(-ENOMEM); + heap->heap.ops = &system_heap_ops; + heap->heap.type = ION_HEAP_TYPE_SYSTEM; + heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE; + heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders, + GFP_KERNEL); + if (!heap->pools) + goto err_alloc_pools; + for (i = 0; i < num_orders; i++) { + struct ion_page_pool *pool; + gfp_t gfp_flags = low_order_gfp_flags; + + if (orders[i] > 4) + gfp_flags = high_order_gfp_flags; + pool = ion_page_pool_create(gfp_flags, orders[i]); + if (!pool) + goto err_create_pool; + heap->pools[i] = pool; + } + + heap->heap.shrinker.scan_objects = ion_system_heap_shrink_scan; + heap->heap.shrinker.count_objects = ion_system_heap_shrink_count; + heap->heap.shrinker.seeks = DEFAULT_SEEKS; + heap->heap.shrinker.batch = 0; + register_shrinker(&heap->heap.shrinker); + heap->heap.debug_show = ion_system_heap_debug_show; + return &heap->heap; +err_create_pool: + for (i = 0; i < num_orders; i++) + if (heap->pools[i]) + ion_page_pool_destroy(heap->pools[i]); + kfree(heap->pools); +err_alloc_pools: + kfree(heap); + return ERR_PTR(-ENOMEM); +} + +void ion_system_heap_destroy(struct ion_heap *heap) +{ + struct ion_system_heap *sys_heap = container_of(heap, + struct ion_system_heap, + heap); + int i; + + for (i = 0; i < num_orders; i++) + ion_page_pool_destroy(sys_heap->pools[i]); + kfree(sys_heap->pools); + kfree(sys_heap); +} + +static int ion_system_contig_heap_allocate(struct ion_heap *heap, + struct ion_buffer *buffer, + unsigned long len, + unsigned long align, + unsigned long flags) +{ + int order = get_order(len); + struct page *page; + struct sg_table *table; + unsigned long i; + int ret; + + if (align > (PAGE_SIZE << order)) + return -EINVAL; + + page = alloc_pages(low_order_gfp_flags, order); + if (!page) + return -ENOMEM; + + split_page(page, order); + + len = PAGE_ALIGN(len); + for (i = len >> PAGE_SHIFT; i < (1 << order); i++) + __free_page(page + i); + + table = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) { + ret = -ENOMEM; + goto out; + } + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto out; + + sg_set_page(table->sgl, page, len, 0); + + buffer->priv_virt = table; + + ion_pages_sync_for_device(NULL, page, len, DMA_BIDIRECTIONAL); + + return 0; + +out: + for (i = 0; i < len >> PAGE_SHIFT; i++) + __free_page(page + i); + kfree(table); + return ret; +} + +static void ion_system_contig_heap_free(struct ion_buffer *buffer) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + unsigned long pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < pages; i++) + __free_page(page + i); + sg_free_table(table); + kfree(table); +} + +static int ion_system_contig_heap_phys(struct ion_heap *heap, + struct ion_buffer *buffer, + ion_phys_addr_t *addr, size_t *len) +{ + struct sg_table *table = buffer->priv_virt; + struct page *page = sg_page(table->sgl); + *addr = page_to_phys(page); + *len = buffer->size; + return 0; +} + +static struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ + return buffer->priv_virt; +} + +static void ion_system_contig_heap_unmap_dma(struct ion_heap *heap, + struct ion_buffer *buffer) +{ +} + +static struct ion_heap_ops kmalloc_ops = { + .allocate = ion_system_contig_heap_allocate, + .free = ion_system_contig_heap_free, + .phys = ion_system_contig_heap_phys, + .map_dma = ion_system_contig_heap_map_dma, + .unmap_dma = ion_system_contig_heap_unmap_dma, + .map_kernel = ion_heap_map_kernel, + .unmap_kernel = ion_heap_unmap_kernel, + .map_user = ion_heap_map_user, +}; + +struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) +{ + struct ion_heap *heap; + + heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL); + if (!heap) + return ERR_PTR(-ENOMEM); + heap->ops = &kmalloc_ops; + heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; + return heap; +} + +void ion_system_contig_heap_destroy(struct ion_heap *heap) +{ + kfree(heap); +} + diff --git a/drivers/staging/android/ion/ion_test.c b/drivers/staging/android/ion/ion_test.c new file mode 100644 index 000000000000..654acb5c8eba --- /dev/null +++ b/drivers/staging/android/ion/ion_test.c @@ -0,0 +1,282 @@ +/* + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#define pr_fmt(fmt) "ion-test: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ion.h" +#include "../uapi/ion_test.h" + +#define u64_to_uptr(x) ((void __user *)(unsigned long)(x)) + +struct ion_test_device { + struct miscdevice misc; +}; + +struct ion_test_data { + struct dma_buf *dma_buf; + struct device *dev; +}; + +static int ion_handle_test_dma(struct device *dev, struct dma_buf *dma_buf, + void __user *ptr, size_t offset, size_t size, bool write) +{ + int ret = 0; + struct dma_buf_attachment *attach; + struct sg_table *table; + pgprot_t pgprot = pgprot_writecombine(PAGE_KERNEL); + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + struct sg_page_iter sg_iter; + unsigned long offset_page; + + attach = dma_buf_attach(dma_buf, dev); + if (IS_ERR(attach)) + return PTR_ERR(attach); + + table = dma_buf_map_attachment(attach, dir); + if (IS_ERR(table)) + return PTR_ERR(table); + + offset_page = offset >> PAGE_SHIFT; + offset %= PAGE_SIZE; + + for_each_sg_page(table->sgl, &sg_iter, table->nents, offset_page) { + struct page *page = sg_page_iter_page(&sg_iter); + void *vaddr = vmap(&page, 1, VM_MAP, pgprot); + size_t to_copy = PAGE_SIZE - offset; + + to_copy = min(to_copy, size); + if (!vaddr) { + ret = -ENOMEM; + goto err; + } + + if (write) + ret = copy_from_user(vaddr + offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + offset, to_copy); + + vunmap(vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + size -= to_copy; + if (!size) + break; + ptr += to_copy; + offset = 0; + } + +err: + dma_buf_unmap_attachment(attach, table, dir); + dma_buf_detach(dma_buf, attach); + return ret; +} + +static int ion_handle_test_kernel(struct dma_buf *dma_buf, void __user *ptr, + size_t offset, size_t size, bool write) +{ + int ret; + unsigned long page_offset = offset >> PAGE_SHIFT; + size_t copy_offset = offset % PAGE_SIZE; + size_t copy_size = size; + enum dma_data_direction dir = write ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + + if (offset > dma_buf->size || size > dma_buf->size - offset) + return -EINVAL; + + ret = dma_buf_begin_cpu_access(dma_buf, offset, size, dir); + if (ret) + return ret; + + while (copy_size > 0) { + size_t to_copy; + void *vaddr = dma_buf_kmap(dma_buf, page_offset); + + if (!vaddr) + goto err; + + to_copy = min_t(size_t, PAGE_SIZE - copy_offset, copy_size); + + if (write) + ret = copy_from_user(vaddr + copy_offset, ptr, to_copy); + else + ret = copy_to_user(ptr, vaddr + copy_offset, to_copy); + + dma_buf_kunmap(dma_buf, page_offset, vaddr); + if (ret) { + ret = -EFAULT; + goto err; + } + + copy_size -= to_copy; + ptr += to_copy; + page_offset++; + copy_offset = 0; + } +err: + dma_buf_end_cpu_access(dma_buf, offset, size, dir); + return ret; +} + +static long ion_test_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + struct ion_test_data *test_data = filp->private_data; + int ret = 0; + + union { + struct ion_test_rw_data test_rw; + } data; + + if (_IOC_SIZE(cmd) > sizeof(data)) + return -EINVAL; + + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(&data, (void __user *)arg, _IOC_SIZE(cmd))) + return -EFAULT; + + switch (cmd) { + case ION_IOC_TEST_SET_FD: + { + struct dma_buf *dma_buf = NULL; + int fd = arg; + + if (fd >= 0) { + dma_buf = dma_buf_get((int)arg); + if (IS_ERR(dma_buf)) + return PTR_ERR(dma_buf); + } + if (test_data->dma_buf) + dma_buf_put(test_data->dma_buf); + test_data->dma_buf = dma_buf; + break; + } + case ION_IOC_TEST_DMA_MAPPING: + { + ret = ion_handle_test_dma(test_data->dev, test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + case ION_IOC_TEST_KERNEL_MAPPING: + { + ret = ion_handle_test_kernel(test_data->dma_buf, + u64_to_uptr(data.test_rw.ptr), + data.test_rw.offset, data.test_rw.size, + data.test_rw.write); + break; + } + default: + return -ENOTTY; + } + + if (_IOC_DIR(cmd) & _IOC_READ) { + if (copy_to_user((void __user *)arg, &data, sizeof(data))) + return -EFAULT; + } + return ret; +} + +static int ion_test_open(struct inode *inode, struct file *file) +{ + struct ion_test_data *data; + struct miscdevice *miscdev = file->private_data; + + data = kzalloc(sizeof(struct ion_test_data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = miscdev->parent; + + file->private_data = data; + + return 0; +} + +static int ion_test_release(struct inode *inode, struct file *file) +{ + struct ion_test_data *data = file->private_data; + + kfree(data); + + return 0; +} + +static const struct file_operations ion_test_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ion_test_ioctl, + .compat_ioctl = ion_test_ioctl, + .open = ion_test_open, + .release = ion_test_release, +}; + +static int __init ion_test_probe(struct platform_device *pdev) +{ + int ret; + struct ion_test_device *testdev; + + testdev = devm_kzalloc(&pdev->dev, sizeof(struct ion_test_device), + GFP_KERNEL); + if (!testdev) + return -ENOMEM; + + testdev->misc.minor = MISC_DYNAMIC_MINOR; + testdev->misc.name = "ion-test"; + testdev->misc.fops = &ion_test_fops; + testdev->misc.parent = &pdev->dev; + ret = misc_register(&testdev->misc); + if (ret) { + pr_err("failed to register misc device.\n"); + return ret; + } + + platform_set_drvdata(pdev, testdev); + + return 0; +} + +static struct platform_driver ion_test_platform_driver = { + .driver = { + .name = "ion-test", + }, +}; + +static int __init ion_test_init(void) +{ + platform_device_register_simple("ion-test", -1, NULL, 0); + return platform_driver_probe(&ion_test_platform_driver, ion_test_probe); +} + +static void __exit ion_test_exit(void) +{ + platform_driver_unregister(&ion_test_platform_driver); +} + +module_init(ion_test_init); +module_exit(ion_test_exit); diff --git a/drivers/staging/android/ion/tegra/Makefile b/drivers/staging/android/ion/tegra/Makefile new file mode 100644 index 000000000000..11cd003fb08f --- /dev/null +++ b/drivers/staging/android/ion/tegra/Makefile @@ -0,0 +1 @@ +obj-y += tegra_ion.o diff --git a/drivers/staging/android/ion/tegra/tegra_ion.c b/drivers/staging/android/ion/tegra/tegra_ion.c new file mode 100644 index 000000000000..3474c65f87fa --- /dev/null +++ b/drivers/staging/android/ion/tegra/tegra_ion.c @@ -0,0 +1,84 @@ +/* + * drivers/gpu/tegra/tegra_ion.c + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include "../ion.h" +#include "../ion_priv.h" + +static struct ion_device *idev; +static int num_heaps; +static struct ion_heap **heaps; + +static int tegra_ion_probe(struct platform_device *pdev) +{ + struct ion_platform_data *pdata = pdev->dev.platform_data; + int err; + int i; + + num_heaps = pdata->nr; + + heaps = kzalloc(sizeof(struct ion_heap *) * pdata->nr, GFP_KERNEL); + + idev = ion_device_create(NULL); + if (IS_ERR_OR_NULL(idev)) { + kfree(heaps); + return PTR_ERR(idev); + } + + /* create the heaps as specified in the board file */ + for (i = 0; i < num_heaps; i++) { + struct ion_platform_heap *heap_data = &pdata->heaps[i]; + + heaps[i] = ion_heap_create(heap_data); + if (IS_ERR_OR_NULL(heaps[i])) { + err = PTR_ERR(heaps[i]); + goto err; + } + ion_device_add_heap(idev, heaps[i]); + } + platform_set_drvdata(pdev, idev); + return 0; +err: + for (i = 0; i < num_heaps; i++) { + if (heaps[i]) + ion_heap_destroy(heaps[i]); + } + kfree(heaps); + return err; +} + +static int tegra_ion_remove(struct platform_device *pdev) +{ + struct ion_device *idev = platform_get_drvdata(pdev); + int i; + + ion_device_destroy(idev); + for (i = 0; i < num_heaps; i++) + ion_heap_destroy(heaps[i]); + kfree(heaps); + return 0; +} + +static struct platform_driver ion_driver = { + .probe = tegra_ion_probe, + .remove = tegra_ion_remove, + .driver = { .name = "ion-tegra" } +}; + +module_platform_driver(ion_driver); + diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 38ea986dc70f..62e2255b1c1e 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -28,7 +28,7 @@ struct sync_fence; /** * struct sync_timeline_ops - sync object implementation ops - * @driver_name: name of the implentation + * @driver_name: name of the implementation * @dup: duplicate a sync_pt * @has_signaled: returns: * 1 if pt has signaled @@ -37,12 +37,12 @@ struct sync_fence; * @compare: returns: * 1 if b will signal before a * 0 if a and b will signal at the same time - * -1 if a will signabl before b + * -1 if a will signal before b * @free_pt: called before sync_pt is freed * @release_obj: called before sync_timeline is freed * @print_obj: deprecated * @print_pt: deprecated - * @fill_driver_data: write implmentation specific driver data to data. + * @fill_driver_data: write implementation specific driver data to data. * should return an error if there is not enough room * as specified by size. This information is returned * to userspace by SYNC_IOC_FENCE_INFO. @@ -88,9 +88,9 @@ struct sync_timeline_ops { /** * struct sync_timeline - sync object * @kref: reference count on fence. - * @ops: ops that define the implementaiton of the sync_timeline + * @ops: ops that define the implementation of the sync_timeline * @name: name of the sync_timeline. Useful for debugging - * @destoryed: set when sync_timeline is destroyed + * @destroyed: set when sync_timeline is destroyed * @child_list_head: list of children sync_pts for this sync_timeline * @child_list_lock: lock protecting @child_list_head, destroyed, and * sync_pt.status @@ -119,12 +119,12 @@ struct sync_timeline { * @parent: sync_timeline to which this sync_pt belongs * @child_list: membership in sync_timeline.child_list_head * @active_list: membership in sync_timeline.active_list_head - * @signaled_list: membership in temorary signaled_list on stack + * @signaled_list: membership in temporary signaled_list on stack * @fence: sync_fence to which the sync_pt belongs * @pt_list: membership in sync_fence.pt_list_head * @status: 1: signaled, 0:active, <0: error * @timestamp: time which sync_pt status transitioned from active to - * singaled or error. + * signaled or error. */ struct sync_pt { struct sync_timeline *parent; @@ -145,9 +145,9 @@ struct sync_pt { /** * struct sync_fence - sync fence * @file: file representing this fence - * @kref: referenace count on fence. + * @kref: reference count on fence. * @name: name of sync_fence. Useful for debugging - * @pt_list_head: list of sync_pts in ths fence. immutable once fence + * @pt_list_head: list of sync_pts in the fence. immutable once fence * is created * @waiter_list_head: list of asynchronous waiters on this fence * @waiter_list_lock: lock protecting @waiter_list_head and @status @@ -201,23 +201,23 @@ static inline void sync_fence_waiter_init(struct sync_fence_waiter *waiter, /** * sync_timeline_create() - creates a sync object - * @ops: specifies the implemention ops for the object + * @ops: specifies the implementation ops for the object * @size: size to allocate for this obj * @name: sync_timeline name * - * Creates a new sync_timeline which will use the implemetation specified by - * @ops. @size bytes will be allocated allowing for implemntation specific - * data to be kept after the generic sync_timeline stuct. + * Creates a new sync_timeline which will use the implementation specified by + * @ops. @size bytes will be allocated allowing for implementation specific + * data to be kept after the generic sync_timeline struct. */ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, int size, const char *name); /** - * sync_timeline_destory() - destorys a sync object + * sync_timeline_destroy() - destroys a sync object * @obj: sync_timeline to destroy * - * A sync implemntation should call this when the @obj is going away - * (i.e. module unload.) @obj won't actually be freed until all its childern + * A sync implementation should call this when the @obj is going away + * (i.e. module unload.) @obj won't actually be freed until all its children * sync_pts are freed. */ void sync_timeline_destroy(struct sync_timeline *obj); @@ -226,7 +226,7 @@ void sync_timeline_destroy(struct sync_timeline *obj); * sync_timeline_signal() - signal a status change on a sync_timeline * @obj: sync_timeline to signal * - * A sync implemntation should call this any time one of it's sync_pts + * A sync implementation should call this any time one of it's sync_pts * has signaled or has an error condition. */ void sync_timeline_signal(struct sync_timeline *obj); @@ -236,8 +236,8 @@ void sync_timeline_signal(struct sync_timeline *obj); * @parent: sync_pt's parent sync_timeline * @size: size to allocate for this pt * - * Creates a new sync_pt as a chiled of @parent. @size bytes will be - * allocated allowing for implemntation specific data to be kept after + * Creates a new sync_pt as a child of @parent. @size bytes will be + * allocated allowing for implementation specific data to be kept after * the generic sync_timeline struct. */ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size); @@ -287,7 +287,7 @@ struct sync_fence *sync_fence_merge(const char *name, struct sync_fence *sync_fence_fdget(int fd); /** - * sync_fence_put() - puts a refernnce of a sync fence + * sync_fence_put() - puts a reference of a sync fence * @fence: fence to put * * Puts a reference on @fence. If this is the last reference, the fence and @@ -297,7 +297,7 @@ void sync_fence_put(struct sync_fence *fence); /** * sync_fence_install() - installs a fence into a file descriptor - * @fence: fence to instal + * @fence: fence to install * @fd: file descriptor in which to install the fence * * Installs @fence into @fd. @fd's should be acquired through get_unused_fd(). @@ -359,10 +359,10 @@ struct sync_merge_data { * struct sync_pt_info - detailed sync_pt information * @len: length of sync_pt_info including any driver_data * @obj_name: name of parent sync_timeline - * @driver_name: name of driver implmenting the parent + * @driver_name: name of driver implementing the parent * @status: status of the sync_pt 0:active 1:signaled <0:error * @timestamp_ns: timestamp of status change in nanoseconds - * @driver_data: any driver dependant data + * @driver_data: any driver dependent data */ struct sync_pt_info { __u32 len; @@ -377,7 +377,7 @@ struct sync_pt_info { /** * struct sync_fence_info_data - data returned from fence info ioctl * @len: ioctl caller writes the size of the buffer its passing in. - * ioctl returns length of sync_fence_data reutnred to userspace + * ioctl returns length of sync_fence_data returned to userspace * including pt_info. * @name: name of fence * @status: status of fence. 1: signaled 0:active <0:error @@ -418,7 +418,7 @@ struct sync_fence_info_data { * pt_info. * * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence. - * To itterate over the sync_pt_infos, use the sync_pt_info.len field. + * To iterate over the sync_pt_infos, use the sync_pt_info.len field. */ #define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\ struct sync_fence_info_data) diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h new file mode 100644 index 000000000000..f09e7c154d69 --- /dev/null +++ b/drivers/staging/android/uapi/ion.h @@ -0,0 +1,196 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_ION_H +#define _UAPI_LINUX_ION_H + +#include +#include + +typedef int ion_user_handle_t; + +/** + * enum ion_heap_types - list of all possible types of heaps + * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc + * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc + * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved + * carveout heap, allocations are physically + * contiguous + * @ION_HEAP_TYPE_DMA: memory allocated via DMA API + * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask + * is used to identify the heaps, so only 32 + * total heap types are supported + */ +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CHUNK, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always + are at the end of this enum */ + ION_NUM_HEAPS = 16, +}; + +#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) +#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) +#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) + +#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 + +/** + * allocation flags - the lower 16 bits are used by core ion, the upper 16 + * bits are reserved for use by the heaps themselves. + */ +#define ION_FLAG_CACHED 1 /* mappings of this buffer should be + cached, ion will do cache + maintenance when the buffer is + mapped for dma */ +#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created + at mmap time, if this is set + caches must be managed manually */ + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @align: required alignment of the allocation + * @heap_id_mask: mask of heap ids to allocate from + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to + * refer to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_id_mask; + unsigned int flags; + ion_user_handle_t handle; +}; + +/** + * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair + * @handle: a handle + * @fd: a file descriptor representing that handle + * + * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with + * the handle returned from ion alloc, and the kernel returns the file + * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace + * provides the file descriptor and the kernel returns the handle. + */ +struct ion_fd_data { + ion_user_handle_t handle; + int fd; +}; + +/** + * struct ion_handle_data - a handle passed to/from the kernel + * @handle: a handle + */ +struct ion_handle_data { + ion_user_handle_t handle; +}; + +/** + * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl + * @cmd: the custom ioctl function to call + * @arg: additional data to pass to the custom ioctl, typically a user + * pointer to a predefined structure + * + * This works just like the regular cmd and arg fields of an ioctl. + */ +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + */ +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct ion_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + */ +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + +/** + * DOC: ION_IOC_MAP - get a file descriptor to mmap + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be used as an argument to mmap. + */ +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + */ +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + +/** + * DOC: ION_IOC_IMPORT - imports a shared file descriptor + * + * Takes an ion_fd_data struct with the fd field populated with a valid file + * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle + * filed set to the corresponding opaque handle. + */ +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) + +/** + * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory + * + * Deprecated in favor of using the dma_buf api's correctly (syncing + * will happend automatically when the buffer is mapped to a device). + * If necessary should be used after touching a cached buffer from the cpu, + * this will make the buffer in memory coherent. + */ +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) + +/** + * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl + * + * Takes the argument of the architecture specific ioctl to call and + * passes appropriate userdata for that ioctl + */ +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#endif /* _UAPI_LINUX_ION_H */ diff --git a/drivers/staging/android/uapi/ion_test.h b/drivers/staging/android/uapi/ion_test.h new file mode 100644 index 000000000000..ffef06f63133 --- /dev/null +++ b/drivers/staging/android/uapi/ion_test.h @@ -0,0 +1,70 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _UAPI_LINUX_ION_TEST_H +#define _UAPI_LINUX_ION_TEST_H + +#include +#include + +/** + * struct ion_test_rw_data - metadata passed to the kernel to read handle + * @ptr: a pointer to an area at least as large as size + * @offset: offset into the ion buffer to start reading + * @size: size to read or write + * @write: 1 to write, 0 to read + */ +struct ion_test_rw_data { + __u64 ptr; + __u64 offset; + __u64 size; + int write; + int __padding; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_TEST_SET_DMA_BUF - attach a dma buf to the test driver + * + * Attaches a dma buf fd to the test driver. Passing a second fd or -1 will + * release the first fd. + */ +#define ION_IOC_TEST_SET_FD \ + _IO(ION_IOC_MAGIC, 0xf0) + +/** + * DOC: ION_IOC_TEST_DMA_MAPPING - read or write memory from a handle as DMA + * + * Reads or writes the memory from a handle using an uncached mapping. Can be + * used by unit tests to emulate a DMA engine as close as possible. Only + * expected to be used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_DMA_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf1, struct ion_test_rw_data) + +/** + * DOC: ION_IOC_TEST_KERNEL_MAPPING - read or write memory from a handle + * + * Reads or writes the memory from a handle using a kernel mapping. Can be + * used by unit tests to test heap map_kernel functions. Only expected to be + * used for debugging and testing, may not always be available. + */ +#define ION_IOC_TEST_KERNEL_MAPPING \ + _IOW(ION_IOC_MAGIC, 0xf2, struct ion_test_rw_data) + + +#endif /* _UAPI_LINUX_ION_H */ diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 9cd59871adb2..f0d6f0c38207 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -378,7 +378,7 @@ struct bcm_mini_adapter { UINT uiFlashLayoutMinorVersion; bool bAllDSDWriteAllow; bool bSigCorrupted; - /* this should be set who so ever want to change the Headers. after Wrtie it should be reset immediately. */ + /* this should be set who so ever want to change the Headers. after Write it should be reset immediately. */ bool bHeaderChangeAllowed; int SelectedChip; bool bEndPointHalted; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 87b74ca84c42..f1b6de0293c8 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -160,7 +160,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) struct bcm_ioctl_buffer IoBuffer; int bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", + cmd, arg); if (_IOC_TYPE(cmd) != BCM_IOCTL) return -EFAULT; @@ -266,7 +268,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_3) || (uiTempVar == EEPROM_REJECT_REG_4))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } @@ -274,9 +277,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)sWrmBuffer.Data, sizeof(ULONG)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } break; @@ -291,7 +296,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Device in Idle Mode, Blocking Rdms\n"); return -EACCES; } @@ -317,7 +323,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sRdmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM Done On invalid Address : %x Access Denied.\n", (int)sRdmBuffer.Register); kfree(temp_buff); @@ -325,7 +332,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); + bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, + (PUINT)temp_buff, IoBuffer.OutputLength); if (bytes > 0) { Status = STATUS_SUCCESS; @@ -349,7 +357,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Device in Idle Mode, Blocking Wrms\n"); return -EACCES; } @@ -367,7 +376,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sWrmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM Done On invalid Address : %x Access Denied.\n", + (int)sWrmBuffer.Register); return -EINVAL; } @@ -379,17 +390,21 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_4)) && (cmd == IOCTL_BCM_REGISTER_WRITE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); + (PUINT)sWrmBuffer.Data, + sWrmBuffer.Length); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, + DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } break; @@ -405,7 +420,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "GPIO Can't be set/clear in Low power Mode"); return -EACCES; } @@ -423,7 +440,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) value = (1< is not correspond to LED !!!", value); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", + value); Status = -EINVAL; break; } @@ -431,27 +451,42 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* Set - setting 1 */ if (uiOperation) { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); + Status = wrmaltWithLock(Adapter, + BCM_GPIO_OUTPUT_SET_REG, + (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Failed to set the %dth GPIO\n", + uiBit); break; } } else { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); + Status = wrmaltWithLock(Adapter, + BCM_GPIO_OUTPUT_CLR_REG, + (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Failed to clear the %dth GPIO\n", + uiBit); break; } } - bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, + (PUINT)ucResetValue, sizeof(UINT)); if (bytes < 0) { Status = bytes; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, @@ -467,9 +502,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)ucResetValue, sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Set the GPIO to output Mode\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "Failed to put GPIO in Output Mode\n"); break; } } @@ -477,13 +516,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case BCM_LED_THREAD_STATE_CHANGE_REQ: { struct bcm_user_thread_req threadReq = {0}; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "User made LED thread InActive"); if ((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus == TRUE) || (Adapter->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, + "GPIO Can't be set/clear in Low power Mode"); Status = -EACCES; break; } @@ -500,10 +542,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* if LED thread is running(Actively or Inactively) set it state to make inactive */ if (Adapter->LEDInfo.led_thread_running) { if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "Activating thread req"); Adapter->DriverState = LED_THREAD_ACTIVE; } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req....."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + OSAL_DBG, DBG_LVL_ALL, + "DeActivating Thread req....."); Adapter->DriverState = LED_THREAD_INACTIVE; } @@ -540,7 +586,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM Failed\n"); return Status; } else { Status = STATUS_SUCCESS; @@ -570,9 +617,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) return -EFAULT; if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", - pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); + pgpio_multi_info[WIMAX_IDX].uiGPIOMask, + Adapter->gpioBitMap); Status = -EINVAL; break; } @@ -590,7 +639,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)ucResetValue, sizeof(ULONG)); if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); return Status; } @@ -603,7 +653,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG)); if (Status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); return Status; } } @@ -613,7 +664,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed."); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "RDM to GPIO_PIN_STATE_REGISTER Failed."); return Status; } else { Status = STATUS_SUCCESS; @@ -1190,7 +1242,7 @@ cntrlEnd: break; case IOCTL_BCM_CAL_INIT: { - UINT uiSectorSize = 0 ; + UINT uiSectorSize = 0; if (Adapter->eNVMType == NVM_FLASH) { if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; @@ -1403,7 +1455,7 @@ cntrlEnd: case IOCTL_BCM_FLASH2X_SECTION_READ: { struct bcm_flash2x_readwrite sFlash2xRead = {0}; - PUCHAR pReadBuff = NULL ; + PUCHAR pReadBuff = NULL; UINT NOB = 0; UINT BuffSize = 0; UINT ReadBytes = 0; @@ -1438,7 +1490,7 @@ cntrlEnd: else BuffSize = NOB; - ReadOffset = sFlash2xRead.offset ; + ReadOffset = sFlash2xRead.offset; OutPutBuff = IoBuffer.OutputBuffer; pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); @@ -1483,7 +1535,7 @@ cntrlEnd: NOB = NOB - ReadBytes; if (NOB) { ReadOffset = ReadOffset + ReadBytes; - OutPutBuff = OutPutBuff + ReadBytes ; + OutPutBuff = OutPutBuff + ReadBytes; } } @@ -1538,7 +1590,7 @@ cntrlEnd: if (NOB > Adapter->uiSectorSize) BuffSize = Adapter->uiSectorSize; else - BuffSize = NOB ; + BuffSize = NOB; pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); @@ -1718,12 +1770,12 @@ cntrlEnd: BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exist in Flash ", sCopySectStrut.SrcSection); return -EINVAL; } if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exist in Flash ", sCopySectStrut.DstSection); return -EINVAL; } @@ -1828,7 +1880,7 @@ cntrlEnd: SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); if (SectOfset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section val <%d> does not exist in Flash 2.x", eFlash2xSectionVal); return -EINVAL; } @@ -1841,10 +1893,10 @@ cntrlEnd: case IOCTL_BCM_NVM_RAW_READ: { struct bcm_nvm_readwrite stNVMRead; - INT NOB ; - INT BuffSize ; + INT NOB; + INT BuffSize; INT ReadOffset = 0; - UINT ReadBytes = 0 ; + UINT ReadBytes = 0; PUCHAR pReadBuff; void __user *OutPutBuff; diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 9f7e30f637ea..ed285b2d892d 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -5,882 +5,865 @@ #define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00 #define MIPS_CLOCK_REG 0x0f000820 - //DDR INIT-133Mhz -#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0F000800,0x00007212}, - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00000F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a04C,0x0000000C}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020202}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x110a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101010},//ROB - 0x02101010,//0x02101018}, - {0x0F007040,0x45751200},//ROB - 0x45751200,//0x450f1200}, - {0x0F007044,0x110a0d00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x081b0306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010246c}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} - }; -//80Mhz -#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07f1ffff}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a000,0x00000016}, - {0x0F00a04C,0x0000000C}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01000000}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, - {0x0F007020,0x04020107}, - {0x0F007024,0x00000007}, - {0x0F007028,0x02020201}, - {0x0F00702c,0x0204040a}, - {0x0F007030,0x04000000}, - {0x0F007034,0x00000002}, - {0x0F007038,0x1F060200}, - {0x0F00703C,0x1C22221F}, - {0x0F007040,0x8A006600}, - {0x0F007044,0x221a0800}, - {0x0F007048,0x02690204}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x000A15D6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00004000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007094,0x00000104}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} - }; -//100Mhz -#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 //index for 0x0F007000 -static struct bcm_ddr_setting asT3_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0F000800,0x00007008}, - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13E3F}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - //0x0f000840,0x0FFF1800, - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a04C,0x0000000C}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001}, // POP - 0x00020000 Normal 0x01020000 - {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020201}, - {0x0F00702c,0x0204040A}, - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x20080200}, - {0x0F00703C,0x02030320}, - {0x0F007040,0x6E7F1200}, - {0x0F007044,0x01190A00}, - {0x0F007048,0x06120305},//0x02690204 // 0x06120305 - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001C}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} - }; +/* DDR INIT-133Mhz */ +#define T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 12 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3_DDRSetting133MHz[] = { /* DPLL Clock Setting */ + {0x0F000800, 0x00007212}, + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00000F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a04C, 0x0000000C}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, + {0x0F007020, 0x04030107}, + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020202}, + {0x0F00702c, 0x0206060a}, + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x110a0200}, + {0x0F00703C, 0x02101010}, + {0x0F007040, 0x45751200}, + {0x0F007044, 0x110a0d00}, + {0x0F007048, 0x081b0306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010246c}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00000104}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; +/* 80Mhz */ +#define T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 10 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3_DDRSetting80MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07f1ffff}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a000, 0x00000016}, + {0x0F00a04C, 0x0000000C}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01000000}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x02020201}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x04000000}, + {0x0F007034, 0x00000002}, + {0x0F007038, 0x1F060200}, + {0x0F00703C, 0x1C22221F}, + {0x0F007040, 0x8A006600}, + {0x0F007044, 0x221a0800}, + {0x0F007048, 0x02690204}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x000A15D6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00004000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007094, 0x00000104}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; +/* 100Mhz */ +#define T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 13 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3_DDRSetting100MHz[] = { /* DPLL Clock Setting */ + {0x0F000800, 0x00007008}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13E3F}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a04C, 0x0000000C}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020201}, + {0x0F00702c, 0x0204040A}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x20080200}, + {0x0F00703C, 0x02030320}, + {0x0F007040, 0x6E7F1200}, + {0x0F007044, 0x01190A00}, + {0x0F007048, 0x06120305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001C}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00000104}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; -//Net T3B DDR Settings -//DDR INIT-133Mhz +/* Net T3B DDR Settings + * DDR INIT-133Mhz + */ static struct bcm_ddr_setting asDPLL_266MHZ[] = { - {0x0F000800,0x00007212}, - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00000F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF1B00}, - {0x0f000870,0x00000002} - }; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000 -static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13652}, - {0x0f000840,0x0FFF0800}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, - // Changed source for X-bar and MIPS clock to APLL - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020202}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x130a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101012},//ROB - 0x02101010,//0x02101018}, - {0x0F007040,0x457D1200},//ROB - 0x45751200,//0x450f1200}, - {0x0F007044,0x11130d00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x040D0306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0000001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010246c}, - {0x0F007064,0x00000012}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000}, - }; - -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F13FFF}, - {0x0f000840,0x0FFF1F00}, - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, - - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00a000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01000000}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, - {0x0F007020,0x04020107}, - {0x0F007024,0x00000007}, - {0x0F007028,0x02020201}, - {0x0F00702c,0x0204040a}, - {0x0F007030,0x04000000}, - {0x0F007034,0x02000002}, - {0x0F007038,0x1F060202}, - {0x0F00703C,0x1C22221F}, - {0x0F007040,0x8A006600}, - {0x0F007044,0x221a0800}, - {0x0F007048,0x02690204}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x000A15D6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00004000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007094,0x00000104}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} - }; - -//100Mhz -#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = {// # DPLL Clock Setting - {0x0f000810,0x00000F95}, - {0x0f000820,0x07F1369B}, - {0x0f000840,0x0FFF0800}, - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000}, // POP - 0x00020000 Normal 0x01020000 - {0x0F007020,0x04020107},//Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020201}, - {0x0F00702c,0x0204040A}, - {0x0F007030,0x06000000}, - {0x0F007034,0x02000004}, - {0x0F007038,0x20080200}, - {0x0F00703C,0x02030320}, - {0x0F007040,0x6E7F1200}, - {0x0F007044,0x01190A00}, - {0x0F007048,0x06120305},//0x02690204 // 0x06120305 - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001C}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00000104}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} - }; - - -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x03F1365B}, - {0x0f000810,0x00002F95}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020200}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x200a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101020},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x45711200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x110D0D00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x04080306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010245F}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00040000}, - {0x0F007098,0x00000000}, - {0x0F0070c8,0x00000104}, - //# Enable 2 ports within X-bar - //# Enable start bit within memory controller - {0x0F007018,0x01010000} + {0x0F000800, 0x00007212}, + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00000F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF1B00}, + {0x0f000870, 0x00000002} }; -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00002F95}, - {0x0f000820,0x03F1369B}, - {0x0f000840,0x0fff0000}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020200}, - {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x03000305}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - {0x0F007094,0x00010000}, - {0x0F007098,0x00000000}, - {0x0F0070C8,0x00000104}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3B_DDRSetting133MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00000F95}, + {0x0f000810, 0x00000F95}, + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13652}, + {0x0f000840, 0x0FFF0800}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, + {0x0F007020, 0x04030107}, + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020202}, + {0x0F00702c, 0x0206060a}, + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x130a0200}, + {0x0F00703C, 0x02101012}, + {0x0F007040, 0x457D1200}, + {0x0F007044, 0x11130d00}, + {0x0F007048, 0x040D0306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0000001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010246c}, + {0x0F007064, 0x00000012}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00000104}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000}, + }; + +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3B_DDRSetting80MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F13FFF}, + {0x0f000840, 0x0FFF1F00}, + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, + + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00a000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01000000}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x02020201}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x04000000}, + {0x0F007034, 0x02000002}, + {0x0F007038, 0x1F060202}, + {0x0F00703C, 0x1C22221F}, + {0x0F007040, 0x8A006600}, + {0x0F007044, 0x221a0800}, + {0x0F007048, 0x02690204}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x000A15D6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00004000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007094, 0x00000104}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} }; -#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00002F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF1F00}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0F00a084,0x1Cffffff}, - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000000}, - {0x0f007008,0x01000001}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000000}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04020107}, - {0x0f007024,0x00000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0204040a}, - {0x0f007030,0x04000000}, - {0x0f007034,0x00000002}, - {0x0f007038,0x1d060200}, - {0x0f00703c,0x1c22221d}, - {0x0f007040,0x8A116600}, - {0x0f007044,0x222d0800}, - {0x0f007048,0x02690204}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0100001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x000A15D6}, - {0x0f007064,0x0000000A}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00004000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00010000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +/* 100Mhz */ +#define T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 9 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3B_DDRSetting100MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00000F95}, + {0x0f000820, 0x07F1369B}, + {0x0f000840, 0x0FFF0800}, + {0x0f000880, 0x000003DD}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020201}, + {0x0F00702c, 0x0204040A}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x02000004}, + {0x0F007038, 0x20080200}, + {0x0F00703C, 0x02030320}, + {0x0F007040, 0x6E7F1200}, + {0x0F007044, 0x01190A00}, + {0x0F007048, 0x06120305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001C}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00000104}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; + + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 9 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LP_DDRSetting133MHz[] = { /* DPLL Clock Setting */ + {0x0f000820, 0x03F1365B}, + {0x0f000810, 0x00002F95}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF0000}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, + {0x0F007020, 0x04030107}, + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020200}, + {0x0F00702c, 0x0206060a}, + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x200a0200}, + {0x0F00703C, 0x02101020}, + {0x0F007040, 0x45711200}, + {0x0F007044, 0x110D0D00}, + {0x0F007048, 0x04080306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010245F}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00040000}, + {0x0F007098, 0x00000000}, + {0x0F0070c8, 0x00000104}, + /* Enable 2 ports within X-bar */ + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 11 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LP_DDRSetting100MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00002F95}, + {0x0f000820, 0x03F1369B}, + {0x0f000840, 0x0fff0000}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF0000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020200}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x1F080200}, + {0x0F00703C, 0x0203031F}, + {0x0F007040, 0x6e001200}, + {0x0F007044, 0x011a0a00}, + {0x0F007048, 0x03000305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + {0x0F007094, 0x00010000}, + {0x0F007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} +}; + +#define T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 9 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LP_DDRSetting80MHz[] = { /* DPLL Clock Setting */ + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00002F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF1F00}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0F00a084, 0x1Cffffff}, + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000000}, + {0x0f007008, 0x01000001}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000000}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04020107}, + {0x0f007024, 0x00000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0204040a}, + {0x0f007030, 0x04000000}, + {0x0f007034, 0x00000002}, + {0x0f007038, 0x1d060200}, + {0x0f00703c, 0x1c22221d}, + {0x0f007040, 0x8A116600}, + {0x0f007044, 0x222d0800}, + {0x0f007048, 0x02690204}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0100001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x000A15D6}, + {0x0f007064, 0x0000000A}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00004000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00010000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; -///T3 LP-B (UMA-B) +/* T3 LP-B (UMA-B) */ -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[]= {// # DPLL Clock Setting - - {0x0f000820,0x03F137DB}, - {0x0f000810,0x01842795}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF0400}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//this is flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},//Now dump from her in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000001}, - {0x0f007008,0x01000101}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000100}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04030107}, - {0x0f007024,0x02000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0206060a}, - {0x0f007030,0x050d0d00}, - {0x0f007034,0x00000003}, - {0x0f007038,0x170a0200}, - {0x0f00703c,0x02101012}, - {0x0f007040,0x45161200}, - {0x0f007044,0x11250c00}, - {0x0f007048,0x04da0307}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0000001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x00142bb6}, - {0x0f007064,0x20430014}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00009000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00040000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ 7 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LPB_DDRSetting160MHz[] = { /* DPLL Clock Setting */ + {0x0f000820, 0x03F137DB}, + {0x0f000810, 0x01842795}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF0400}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021}, /* this is flash/eeprom clock divisor which set the flash clock to 20 MHz */ + {0x0F00a084, 0x1Cffffff}, /* Now dump from her in internal memory */ + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000001}, + {0x0f007008, 0x01000101}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000100}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04030107}, + {0x0f007024, 0x02000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0206060a}, + {0x0f007030, 0x050d0d00}, + {0x0f007034, 0x00000003}, + {0x0f007038, 0x170a0200}, + {0x0f00703c, 0x02101012}, + {0x0f007040, 0x45161200}, + {0x0f007044, 0x11250c00}, + {0x0f007048, 0x04da0307}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0000001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x00142bb6}, + {0x0f007064, 0x20430014}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00009000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00040000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x03F1365B}, - {0x0f000810,0x00002F95}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0f000860,0x00000000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},//dump from here in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020001},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04030107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x02000007}, - {0x0F007028,0x02020200}, - {0x0F00702c,0x0206060a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x05000000}, - {0x0F007034,0x00000003}, - {0x0F007038,0x190a0200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x02101017},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x45171200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x11290D00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x04080306}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x0010245F}, - {0x0F007064,0x00000010}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00007000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - //# Enable BW improvement within memory controller - {0x0F007094,0x00040000}, - {0x0F007098,0x00000000}, - {0x0F0070c8,0x00000104}, - //# Enable 2 ports within X-bar - //# Enable start bit within memory controller - {0x0F007018,0x01010000} +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 7 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LPB_DDRSetting133MHz[] = { /* DPLL Clock Setting */ + {0x0f000820, 0x03F1365B}, + {0x0f000810, 0x00002F95}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF0000}, + {0x0f000860, 0x00000000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */ + {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020001}, + {0x0F007020, 0x04030107}, + {0x0F007024, 0x02000007}, + {0x0F007028, 0x02020200}, + {0x0F00702c, 0x0206060a}, + {0x0F007030, 0x05000000}, + {0x0F007034, 0x00000003}, + {0x0F007038, 0x190a0200}, + {0x0F00703C, 0x02101017}, + {0x0F007040, 0x45171200}, + {0x0F007044, 0x11290D00}, + {0x0F007048, 0x04080306}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x0010245F}, + {0x0F007064, 0x00000010}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00007000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + /* Enable BW improvement within memory controller */ + {0x0F007094, 0x00040000}, + {0x0F007098, 0x00000000}, + {0x0F0070c8, 0x00000104}, + /* Enable 2 ports within X-bar */ + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} }; -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[]= {// # DPLL Clock Setting - {0x0f000810,0x00002F95}, - {0x0f000820,0x03F1369B}, - {0x0f000840,0x0fff0000}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - // Changed source for X-bar and MIPS clock to APLL - {0x0f000840,0x0FFF0000}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff}, //dump from here in internal memory - {0x0F00a080,0x1C000000}, - //Memcontroller Default values - {0x0F007000,0x00010001}, - {0x0F007004,0x01010100}, - {0x0F007008,0x01000001}, - {0x0F00700c,0x00000000}, - {0x0F007010,0x01000000}, - {0x0F007014,0x01000100}, - {0x0F007018,0x01000000}, - {0x0F00701c,0x01020000},// POP - 0x00020001 Normal 0x01020001 - {0x0F007020,0x04020107}, //Normal - 0x04030107 POP - 0x05030107 - {0x0F007024,0x00000007}, - {0x0F007028,0x01020200}, - {0x0F00702c,0x0204040a},//ROB- 0x0205050a,//0x0206060a - {0x0F007030,0x06000000}, - {0x0F007034,0x00000004}, - {0x0F007038,0x1F080200},//ROB - 0x110a0200,//0x180a0200,// 0x1f0a0200 - {0x0F00703C,0x0203031F},//ROB - 0x02101010,//0x02101018, - {0x0F007040,0x6e001200},//ROB - 0x45751200,//0x450f1200, - {0x0F007044,0x011a0a00},//ROB - 0x110a0d00//0x111f0d00 - {0x0F007048,0x03000305}, - {0x0F00704c,0x00000000}, - {0x0F007050,0x0100001c}, - {0x0F007054,0x00000000}, - {0x0F007058,0x00000000}, - {0x0F00705c,0x00000000}, - {0x0F007060,0x00082ED6}, - {0x0F007064,0x0000000A}, - {0x0F007068,0x00000000}, - {0x0F00706c,0x00000001}, - {0x0F007070,0x00005000}, - {0x0F007074,0x00000000}, - {0x0F007078,0x00000000}, - {0x0F00707C,0x00000000}, - {0x0F007080,0x00000000}, - {0x0F007084,0x00000000}, - {0x0F007088,0x01000001}, - {0x0F00708c,0x00000101}, - {0x0F007090,0x00000000}, - {0x0F007094,0x00010000}, - {0x0F007098,0x00000000}, - {0x0F0070C8,0x00000104}, - //# Enable 2 ports within X-bar - {0x0F00A000,0x00000016}, - //# Enable start bit within memory controller - {0x0F007018,0x01010000} +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ 8 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LPB_DDRSetting100MHz[] = { /* DPLL Clock Setting */ + {0x0f000810, 0x00002F95}, + {0x0f000820, 0x03F1369B}, + {0x0f000840, 0x0fff0000}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + /* Changed source for X-bar and MIPS clock to APLL */ + {0x0f000840, 0x0FFF0000}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */ + {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ + {0x0F00a080, 0x1C000000}, + /* Memcontroller Default values */ + {0x0F007000, 0x00010001}, + {0x0F007004, 0x01010100}, + {0x0F007008, 0x01000001}, + {0x0F00700c, 0x00000000}, + {0x0F007010, 0x01000000}, + {0x0F007014, 0x01000100}, + {0x0F007018, 0x01000000}, + {0x0F00701c, 0x01020000}, + {0x0F007020, 0x04020107}, + {0x0F007024, 0x00000007}, + {0x0F007028, 0x01020200}, + {0x0F00702c, 0x0204040a}, + {0x0F007030, 0x06000000}, + {0x0F007034, 0x00000004}, + {0x0F007038, 0x1F080200}, + {0x0F00703C, 0x0203031F}, + {0x0F007040, 0x6e001200}, + {0x0F007044, 0x011a0a00}, + {0x0F007048, 0x03000305}, + {0x0F00704c, 0x00000000}, + {0x0F007050, 0x0100001c}, + {0x0F007054, 0x00000000}, + {0x0F007058, 0x00000000}, + {0x0F00705c, 0x00000000}, + {0x0F007060, 0x00082ED6}, + {0x0F007064, 0x0000000A}, + {0x0F007068, 0x00000000}, + {0x0F00706c, 0x00000001}, + {0x0F007070, 0x00005000}, + {0x0F007074, 0x00000000}, + {0x0F007078, 0x00000000}, + {0x0F00707C, 0x00000000}, + {0x0F007080, 0x00000000}, + {0x0F007084, 0x00000000}, + {0x0F007088, 0x01000001}, + {0x0F00708c, 0x00000101}, + {0x0F007090, 0x00000000}, + {0x0F007094, 0x00010000}, + {0x0F007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + /* Enable 2 ports within X-bar */ + {0x0F00A000, 0x00000016}, + /* Enable start bit within memory controller */ + {0x0F007018, 0x01010000} }; -#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 //index for 0x0F007000 -static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[]= {// # DPLL Clock Setting - {0x0f000820,0x07F13FFF}, - {0x0f000810,0x00002F95}, - {0x0f000860,0x00000000}, - {0x0f000880,0x000003DD}, - {0x0f000840,0x0FFF1F00}, - {0x0F00a044,0x1fffffff}, - {0x0F00a040,0x1f000000}, - {0x0f003050,0x00000021},//flash/eeprom clock divisor which set the flash clock to 20 MHz - {0x0F00a084,0x1Cffffff},// dump from here in internal memory - {0x0F00a080,0x1C000000}, - {0x0F00A000,0x00000016}, - {0x0f007000,0x00010001}, - {0x0f007004,0x01000000}, - {0x0f007008,0x01000001}, - {0x0f00700c,0x00000000}, - {0x0f007010,0x01000000}, - {0x0f007014,0x01000100}, - {0x0f007018,0x01000000}, - {0x0f00701c,0x01020000}, - {0x0f007020,0x04020107}, - {0x0f007024,0x00000007}, - {0x0f007028,0x02020200}, - {0x0f00702c,0x0204040a}, - {0x0f007030,0x04000000}, - {0x0f007034,0x00000002}, - {0x0f007038,0x1d060200}, - {0x0f00703c,0x1c22221d}, - {0x0f007040,0x8A116600}, - {0x0f007044,0x222d0800}, - {0x0f007048,0x02690204}, - {0x0f00704c,0x00000000}, - {0x0f007050,0x0100001c}, - {0x0f007054,0x00000000}, - {0x0f007058,0x00000000}, - {0x0f00705c,0x00000000}, - {0x0f007060,0x000A15D6}, - {0x0f007064,0x0000000A}, - {0x0f007068,0x00000000}, - {0x0f00706c,0x00000001}, - {0x0f007070,0x00004000}, - {0x0f007074,0x00000000}, - {0x0f007078,0x00000000}, - {0x0f00707c,0x00000000}, - {0x0f007080,0x00000000}, - {0x0f007084,0x00000000}, - {0x0f007088,0x01000001}, - {0x0f00708c,0x00000101}, - {0x0f007090,0x00000000}, - {0x0f007094,0x00010000}, - {0x0f007098,0x00000000}, - {0x0F0070C8,0x00000104}, - {0x0F007018,0x01010000} +#define T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ 7 /* index for 0x0F007000 */ +static struct bcm_ddr_setting asT3LPB_DDRSetting80MHz[] = { /* DPLL Clock Setting */ + {0x0f000820, 0x07F13FFF}, + {0x0f000810, 0x00002F95}, + {0x0f000860, 0x00000000}, + {0x0f000880, 0x000003DD}, + {0x0f000840, 0x0FFF1F00}, + {0x0F00a044, 0x1fffffff}, + {0x0F00a040, 0x1f000000}, + {0x0f003050, 0x00000021}, /* flash/eeprom clock divisor which set the flash clock to 20 MHz */ + {0x0F00a084, 0x1Cffffff}, /* dump from here in internal memory */ + {0x0F00a080, 0x1C000000}, + {0x0F00A000, 0x00000016}, + {0x0f007000, 0x00010001}, + {0x0f007004, 0x01000000}, + {0x0f007008, 0x01000001}, + {0x0f00700c, 0x00000000}, + {0x0f007010, 0x01000000}, + {0x0f007014, 0x01000100}, + {0x0f007018, 0x01000000}, + {0x0f00701c, 0x01020000}, + {0x0f007020, 0x04020107}, + {0x0f007024, 0x00000007}, + {0x0f007028, 0x02020200}, + {0x0f00702c, 0x0204040a}, + {0x0f007030, 0x04000000}, + {0x0f007034, 0x00000002}, + {0x0f007038, 0x1d060200}, + {0x0f00703c, 0x1c22221d}, + {0x0f007040, 0x8A116600}, + {0x0f007044, 0x222d0800}, + {0x0f007048, 0x02690204}, + {0x0f00704c, 0x00000000}, + {0x0f007050, 0x0100001c}, + {0x0f007054, 0x00000000}, + {0x0f007058, 0x00000000}, + {0x0f00705c, 0x00000000}, + {0x0f007060, 0x000A15D6}, + {0x0f007064, 0x0000000A}, + {0x0f007068, 0x00000000}, + {0x0f00706c, 0x00000001}, + {0x0f007070, 0x00004000}, + {0x0f007074, 0x00000000}, + {0x0f007078, 0x00000000}, + {0x0f00707c, 0x00000000}, + {0x0f007080, 0x00000000}, + {0x0f007084, 0x00000000}, + {0x0f007088, 0x01000001}, + {0x0f00708c, 0x00000101}, + {0x0f007090, 0x00000000}, + {0x0f007094, 0x00010000}, + {0x0f007098, 0x00000000}, + {0x0F0070C8, 0x00000104}, + {0x0F007018, 0x01010000} }; int ddr_init(struct bcm_mini_adapter *Adapter) { - struct bcm_ddr_setting *psDDRSetting=NULL; - ULONG RegCount=0; + struct bcm_ddr_setting *psDDRSetting = NULL; + ULONG RegCount = 0; UINT value = 0; UINT uiResetValue = 0; UINT uiClockSetting = 0; int retval = STATUS_SUCCESS; - switch (Adapter->chip_id) - { + switch (Adapter->chip_id) { case 0xbece3200: - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting=asT3LP_DDRSetting80MHz; - RegCount=(sizeof(asT3LP_DDRSetting80MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting=asT3LP_DDRSetting100MHz; - RegCount=(sizeof(asT3LP_DDRSetting100MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting=asT3LP_DDRSetting133MHz; - RegCount=(sizeof(asT3LP_DDRSetting133MHz)/ - sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) - { - uiClockSetting = 0x03F13652; - } - else - { - uiClockSetting = 0x03F1365B; - } - break; - default: - return -EINVAL; - } + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3LP_DDRSetting80MHz; + RegCount = (sizeof(asT3LP_DDRSetting80MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + case DDR_100_MHZ: + psDDRSetting = asT3LP_DDRSetting100MHz; + RegCount = (sizeof(asT3LP_DDRSetting100MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + case DDR_133_MHZ: + psDDRSetting = asT3LP_DDRSetting133MHz; + RegCount = (sizeof(asT3LP_DDRSetting133MHz)/ + sizeof(struct bcm_ddr_setting)); + if (Adapter->bMipsConfig == MIPS_200_MHZ) + uiClockSetting = 0x03F13652; + else + uiClockSetting = 0x03F1365B; + break; + default: + return -EINVAL; + } break; case T3LPB: case BCS220_2: case BCS220_2BC: case BCS250_BC: - case BCS220_3 : + case BCS220_3: /* Set bit 2 and bit 6 to 1 for BBIC 2mA drive * (please check current value and additionally set these bits) */ - if( (Adapter->chip_id != BCS220_2) && - (Adapter->chip_id != BCS220_2BC) && - (Adapter->chip_id != BCS220_3) ) - { - retval= rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); - return retval; - } - uiResetValue |= 0x44; - retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { - BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); - return retval; - } + if ((Adapter->chip_id != BCS220_2) && + (Adapter->chip_id != BCS220_2BC) && + (Adapter->chip_id != BCS220_3)) { + retval = rdmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); + if (retval < 0) { + BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); + return retval; } - switch(Adapter->DDRSetting) - { + uiResetValue |= 0x44; + retval = wrmalt(Adapter,(UINT)0x0f000830, &uiResetValue, sizeof(uiResetValue)); + if (retval < 0) { + BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); + return retval; + } + } + switch (Adapter->DDRSetting) { - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=(sizeof(asT3B_DDRSetting80MHz)/ - sizeof(struct bcm_ddr_setting)); + case DDR_80_MHZ: + psDDRSetting = asT3LPB_DDRSetting80MHz; + RegCount = (sizeof(asT3B_DDRSetting80MHz)/ + sizeof(struct bcm_ddr_setting)); break; - case DDR_100_MHZ: - psDDRSetting=asT3LPB_DDRSetting100MHz; - RegCount=(sizeof(asT3B_DDRSetting100MHz)/ - sizeof(struct bcm_ddr_setting)); + case DDR_100_MHZ: + psDDRSetting = asT3LPB_DDRSetting100MHz; + RegCount = (sizeof(asT3B_DDRSetting100MHz)/ + sizeof(struct bcm_ddr_setting)); break; - case DDR_133_MHZ: - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(struct bcm_ddr_setting)); + case DDR_133_MHZ: + psDDRSetting = asT3LPB_DDRSetting133MHz; + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ + sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) - { - uiClockSetting = 0x03F13652; - } - else - { - uiClockSetting = 0x03F1365B; - } + if (Adapter->bMipsConfig == MIPS_200_MHZ) + uiClockSetting = 0x03F13652; + else + uiClockSetting = 0x03F1365B; break; - case DDR_160_MHZ: - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting); + case DDR_160_MHZ: + psDDRSetting = asT3LPB_DDRSetting160MHz; + RegCount = sizeof(asT3LPB_DDRSetting160MHz)/sizeof(struct bcm_ddr_setting); - if(Adapter->bMipsConfig == MIPS_200_MHZ) - { - uiClockSetting = 0x03F137D2; - } - else - { - uiClockSetting = 0x03F137DB; - } - } + if (Adapter->bMipsConfig == MIPS_200_MHZ) + uiClockSetting = 0x03F137D2; + else + uiClockSetting = 0x03F137DB; + } break; case 0xbece0110: @@ -888,68 +871,59 @@ int ddr_init(struct bcm_mini_adapter *Adapter) case 0xbece0121: case 0xbece0130: case 0xbece0300: - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting); - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = (sizeof(asT3_DDRSetting80MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = (sizeof(asT3_DDRSetting100MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = (sizeof(asT3_DDRSetting133MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - default: - return -EINVAL; - } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting); + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3_DDRSetting80MHz; + RegCount = (sizeof(asT3_DDRSetting80MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + case DDR_100_MHZ: + psDDRSetting = asT3_DDRSetting100MHz; + RegCount = (sizeof(asT3_DDRSetting100MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + case DDR_133_MHZ: + psDDRSetting = asT3_DDRSetting133MHz; + RegCount = (sizeof(asT3_DDRSetting133MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + default: + return -EINVAL; + } case 0xbece0310: { - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount=(sizeof(asT3B_DDRSetting80MHz)/ - sizeof(struct bcm_ddr_setting)); - break; - case DDR_100_MHZ: - psDDRSetting=asT3B_DDRSetting100MHz; - RegCount=(sizeof(asT3B_DDRSetting100MHz)/ - sizeof(struct bcm_ddr_setting)); + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3B_DDRSetting80MHz; + RegCount = (sizeof(asT3B_DDRSetting80MHz)/ + sizeof(struct bcm_ddr_setting)); break; - case DDR_133_MHZ: + case DDR_100_MHZ: + psDDRSetting = asT3B_DDRSetting100MHz; + RegCount = (sizeof(asT3B_DDRSetting100MHz)/ + sizeof(struct bcm_ddr_setting)); + break; + case DDR_133_MHZ: - if(Adapter->bDPLLConfig == PLL_266_MHZ)//266Mhz PLL selected. - { - memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, - sizeof(asDPLL_266MHZ)); - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(struct bcm_ddr_setting)); - } + if (Adapter->bDPLLConfig == PLL_266_MHZ) { /* 266Mhz PLL selected. */ + memcpy(asT3B_DDRSetting133MHz, asDPLL_266MHZ, + sizeof(asDPLL_266MHZ)); + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ + sizeof(struct bcm_ddr_setting)); + } else { + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount = (sizeof(asT3B_DDRSetting133MHz)/ + sizeof(struct bcm_ddr_setting)); + if (Adapter->bMipsConfig == MIPS_200_MHZ) + uiClockSetting = 0x07F13652; else - { - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount=(sizeof(asT3B_DDRSetting133MHz)/ - sizeof(struct bcm_ddr_setting)); - if(Adapter->bMipsConfig == MIPS_200_MHZ) - { - uiClockSetting = 0x07F13652; - } - else - { - uiClockSetting = 0x07F1365B; - } - } - break; - default: - return -EINVAL; + uiClockSetting = 0x07F1365B; + } + break; + default: + return -EINVAL; } break; @@ -958,20 +932,15 @@ int ddr_init(struct bcm_mini_adapter *Adapter) return -EINVAL; } - value=0; + value = 0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register Count is =%lu\n", RegCount); - while(RegCount && !retval) - { - if(uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) - { + while (RegCount && !retval) { + if (uiClockSetting && psDDRSetting->ulRegAddress == MIPS_CLOCK_REG) value = uiClockSetting; - } else - { value = psDDRSetting->ulRegValue; - } retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value)); - if(STATUS_SUCCESS != retval) { + if (STATUS_SUCCESS != retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); break; } @@ -980,36 +949,34 @@ int ddr_init(struct bcm_mini_adapter *Adapter) psDDRSetting++; } - if(Adapter->chip_id >= 0xbece3300 ) - { + if (Adapter->chip_id >= 0xbece3300) { mdelay(3); - if( (Adapter->chip_id != BCS220_2)&& - (Adapter->chip_id != BCS220_2BC)&& - (Adapter->chip_id != BCS220_3)) - { + if ((Adapter->chip_id != BCS220_2) && + (Adapter->chip_id != BCS220_2BC) && + (Adapter->chip_id != BCS220_3)) { /* drive MDDR to half in case of UMA-B: */ uiResetValue = 0x01010001; retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x00040020; retval = wrmalt(Adapter, (UINT)0x0F007094, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x01020101; retval = wrmalt(Adapter, (UINT)0x0F00701c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x01010000; retval = wrmalt(Adapter, (UINT)0x0F007018, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } @@ -1020,75 +987,72 @@ int ddr_init(struct bcm_mini_adapter *Adapter) * This is to be done only for Hybrid PMU mode. * with the current h/w there is no way to detect this. * and since we dont have internal PMU lets do it under UMA-B chip id. - * we will change this when we will have internal PMU. - */ - if(Adapter->PmuMode == HYBRID_MODE_7C) - { + * we will change this when we will have internal PMU. + */ + if (Adapter->PmuMode == HYBRID_MODE_7C) { retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x1322a8; retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x132296; retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } - } - else if(Adapter->PmuMode == HYBRID_MODE_6 ) - { + } else if (Adapter->PmuMode == HYBRID_MODE_6) { retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x6003229a; retval = wrmalt(Adapter, (UINT)0x0f000d14, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } retval = rdmalt(Adapter,(UINT)0x0f000c00, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } uiResetValue = 0x1322a8; retval = wrmalt(Adapter, (UINT)0x0f000d1c, &uiResetValue, sizeof(uiResetValue)); - if(retval < 0) { + if (retval < 0) { BCM_DEBUG_PRINT(Adapter, CMHOST, RDM, DBG_LVL_ALL, "%s:%d RDM failed\n", __func__, __LINE__); return retval; } @@ -1101,179 +1065,167 @@ int ddr_init(struct bcm_mini_adapter *Adapter) int download_ddr_settings(struct bcm_mini_adapter *Adapter) { - struct bcm_ddr_setting *psDDRSetting=NULL; - ULONG RegCount=0; + struct bcm_ddr_setting *psDDRSetting = NULL; + ULONG RegCount = 0; unsigned long ul_ddr_setting_load_addr = DDR_DUMP_INTERNAL_DEVICE_MEMORY; UINT value = 0; int retval = STATUS_SUCCESS; bool bOverrideSelfRefresh = false; - switch (Adapter->chip_id) - { + switch (Adapter->chip_id) { case 0xbece3200: - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3LP_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3LP_DDRSetting80MHz; + RegCount = ARRAY_SIZE(asT3LP_DDRSetting80MHz); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3LP_DDRSetting100MHz; + RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LP_DDRSetting133MHz; + RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); + RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; - case DDR_100_MHZ: - psDDRSetting = asT3LP_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting100MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LP_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LP_DDRSetting133MHz); - RegCount -= T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - psDDRSetting += T3LP_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; default: return -EINVAL; - } + } break; case T3LPB: case BCS220_2: case BCS220_2BC: case BCS250_BC: - case BCS220_3 : - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3LPB_DDRSetting80MHz; - RegCount=ARRAY_SIZE(asT3LPB_DDRSetting80MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + case BCS220_3: + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3LPB_DDRSetting80MHz; + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting80MHz); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3LPB_DDRSetting100MHz; + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LPB_DDRSetting133MHz; + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; break; - case DDR_100_MHZ: - psDDRSetting = asT3LPB_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting100MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting133MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - case DDR_160_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3LPB_DDRSetting160MHz; - RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); - RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; + case DDR_160_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3LPB_DDRSetting160MHz; + RegCount = ARRAY_SIZE(asT3LPB_DDRSetting160MHz); + RegCount -= T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; + psDDRSetting += T3LPB_SKIP_CLOCK_PROGRAM_DUMP_160MHZ; - break; - default: - return -EINVAL; - } + break; + default: + return -EINVAL; + } break; case 0xbece0300: - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3_DDRSetting80MHz; + RegCount = ARRAY_SIZE(asT3_DDRSetting80MHz); + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; break; - case DDR_100_MHZ: - psDDRSetting = asT3_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - psDDRSetting = asT3_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); - RegCount-=T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - break; - default: - return -EINVAL; - } + case DDR_100_MHZ: + psDDRSetting = asT3_DDRSetting100MHz; + RegCount = ARRAY_SIZE(asT3_DDRSetting100MHz); + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + psDDRSetting = asT3_DDRSetting133MHz; + RegCount = ARRAY_SIZE(asT3_DDRSetting133MHz); + RegCount -= T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + psDDRSetting += T3_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + break; + default: + return -EINVAL; + } break; case 0xbece0310: { - switch (Adapter->DDRSetting) - { - case DDR_80_MHZ: - psDDRSetting = asT3B_DDRSetting80MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; - break; - case DDR_100_MHZ: - psDDRSetting = asT3B_DDRSetting100MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; - break; - case DDR_133_MHZ: - bOverrideSelfRefresh = TRUE; - psDDRSetting = asT3B_DDRSetting133MHz; - RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); - RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ ; - psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; - break; - } - break; + switch (Adapter->DDRSetting) { + case DDR_80_MHZ: + psDDRSetting = asT3B_DDRSetting80MHz; + RegCount = ARRAY_SIZE(asT3B_DDRSetting80MHz); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_80MHZ; + break; + case DDR_100_MHZ: + psDDRSetting = asT3B_DDRSetting100MHz; + RegCount = ARRAY_SIZE(asT3B_DDRSetting100MHz); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_100MHZ; + break; + case DDR_133_MHZ: + bOverrideSelfRefresh = TRUE; + psDDRSetting = asT3B_DDRSetting133MHz; + RegCount = ARRAY_SIZE(asT3B_DDRSetting133MHz); + RegCount -= T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + psDDRSetting += T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ; + break; + } + break; } default: return -EINVAL; } - //total number of Register that has to be dumped - value =RegCount ; + /* total number of Register that has to be dumped */ + value = RegCount; retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); - if(retval) - { + if (retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); return retval; } ul_ddr_setting_load_addr += sizeof(ULONG); - /*signature */ - value =(0x1d1e0dd0); + /* signature */ + value = (0x1d1e0dd0); retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); - if(retval) - { + if (retval) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); return retval; } ul_ddr_setting_load_addr += sizeof(ULONG); - RegCount*=(sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); + RegCount *= (sizeof(struct bcm_ddr_setting)/sizeof(ULONG)); - while(RegCount && !retval) - { - value = psDDRSetting->ulRegAddress ; - retval = wrmalt( Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); + while (RegCount && !retval) { + value = psDDRSetting->ulRegAddress; + retval = wrmalt(Adapter, ul_ddr_setting_load_addr, &value, sizeof(value)); ul_ddr_setting_load_addr += sizeof(ULONG); - if(!retval) - { - if(bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) - { + if (!retval) { + if (bOverrideSelfRefresh && (psDDRSetting->ulRegAddress == 0x0F007018)) { value = (psDDRSetting->ulRegValue |(1<<8)); - if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr, - &value, sizeof(value))){ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); - break; - } + if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr, + &value, sizeof(value))) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); + break; } - else - { + } else { value = psDDRSetting->ulRegValue; - if(STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr , - &value, sizeof(value))){ + if (STATUS_SUCCESS != wrmalt(Adapter, ul_ddr_setting_load_addr , + &value, sizeof(value))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "%s:%d\n", __func__, __LINE__); break; } @@ -1283,7 +1235,5 @@ int download_ddr_settings(struct bcm_mini_adapter *Adapter) RegCount--; psDDRSetting++; } - return retval; + return retval; } - - diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 463bdee9dfca..005e4607b260 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -20,18 +20,10 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) MAX_TRANSFER_CTRL_BYTE_USB, &pos); set_fs(oldfs); if (len <= 0) { - if (len < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, MP_INIT, - DBG_LVL_ALL, "len < 0"); + if (len < 0) errno = len; - } else { + else errno = 0; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_INITEXIT, MP_INIT, - DBG_LVL_ALL, - "Got end of file!"); - } break; } /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, @@ -39,12 +31,8 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) * MAX_TRANSFER_CTRL_BYTE_USB); */ errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); - if (errno) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, - DBG_TYPE_PRINTK, 0, 0, - "WRM Failed! status: %d", errno); + if (errno) break; - } on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; } @@ -52,7 +40,8 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) return errno; } -int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc) +int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, + unsigned int on_chip_loc) { char *buff, *buff_readback; unsigned int reg = 0; @@ -80,32 +69,28 @@ int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_c while (1) { oldfs = get_fs(); set_fs(get_ds()); - len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); + len = vfs_read(flp, (void __force __user *)buff, + MAX_TRANSFER_CTRL_BYTE_USB, &pos); set_fs(oldfs); fw_down++; if (len <= 0) { - if (len < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); + if (len < 0) errno = len; - } else { + else errno = 0; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); - } break; } - bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len); + bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, + buff_readback, len); if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg); goto exit; } reg++; if ((len-sizeof(unsigned int)) < 4) { if (memcmp(buff_readback, buff, len)) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len); Status = -EIO; goto exit; } @@ -113,10 +98,8 @@ int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_c len -= 4; while (len) { - if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Val from Binary %x, Val From Read Back %x ", *(unsigned int *)&buff[len], *(unsigned int*)&buff_readback[len]); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); + if (*(unsigned int *)&buff_readback[len] != + *(unsigned int *)&buff[len]) { Status = -EIO; goto exit; } @@ -132,13 +115,15 @@ exit: return Status; } -static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo) +static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, + struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; B_UINT32 value = 0; if (Adapter->pstargetparams == NULL) { - Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); + Adapter->pstargetparams = + kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); if (Adapter->pstargetparams == NULL) return -ENOMEM; } @@ -146,7 +131,9 @@ static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params)) return -EIO; - retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); + retval = copy_from_user(Adapter->pstargetparams, + psFwInfo->pvMappedFirmwareAddress, + psFwInfo->u32FirmwareLength); if (retval) { kfree(Adapter->pstargetparams); Adapter->pstargetparams = NULL; @@ -160,52 +147,54 @@ static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm BcmInitNVM(Adapter); retval = InitLedSettings(Adapter); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n"); + if (retval) return retval; - } - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { + if (Adapter->LEDInfo.led_thread_running & + BCM_LED_THREAD_RUNNING_ACTIVELY) { Adapter->LEDInfo.bLedInitDone = false; Adapter->DriverState = DRIVER_INIT; wake_up(&Adapter->LEDInfo.notify_led_event); } - if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { + if (Adapter->LEDInfo.led_thread_running & + BCM_LED_THREAD_RUNNING_ACTIVELY) { Adapter->DriverState = FW_DOWNLOAD; wake_up(&Adapter->LEDInfo.notify_led_event); } /* Initialize the DDR Controller */ retval = ddr_init(Adapter); - if (retval) { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n"); + if (retval) return retval; - } value = 0; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, + &value, sizeof(value)); + wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, + &value, sizeof(value)); if (Adapter->eNVMType == NVM_FLASH) { retval = PropagateCalParamsFromFlashToMemory(Adapter); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval); + if (retval) return retval; - } } - retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR); + retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, + sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR); if (retval) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, + MP_INIT, DBG_LVL_ALL, + "configuration file not downloaded properly"); else Adapter->bCfgDownloaded = TRUE; return retval; } -int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo) +int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, + struct bcm_firmware_info *psFwInfo) { int retval = STATUS_SUCCESS; PUCHAR buff = NULL; @@ -215,9 +204,9 @@ int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_ * Application */ atomic_set(&Adapter->uiMBupdate, false); - if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { + if (!Adapter->bCfgDownloaded && + psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { /* Can't Download Firmware. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n"); return -EINVAL; } @@ -226,14 +215,13 @@ int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_ retval = bcm_download_config_file(Adapter, psFwInfo); } else { buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); - if (buff == NULL) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory"); + if (buff == NULL) return -ENOMEM; - } - retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); + retval = copy_from_user(buff, + psFwInfo->pvMappedFirmwareAddress, + psFwInfo->u32FirmwareLength); if (retval != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); retval = -EFAULT; goto error; } @@ -243,10 +231,8 @@ int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_ psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); - if (retval != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval); + if (retval != STATUS_SUCCESS) goto error; - } } error: @@ -254,7 +240,9 @@ error: return retval; } -static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) +static INT buffDnld(struct bcm_mini_adapter *Adapter, + PUCHAR mappedbuffer, UINT u32FirmwareLength, + ULONG u32StartingAddress) { unsigned int len = 0; int retval = STATUS_SUCCESS; @@ -264,10 +252,8 @@ static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); - if (retval) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval); + if (retval) break; - } u32StartingAddress += len; u32FirmwareLength -= len; mappedbuffer += len; @@ -275,17 +261,17 @@ static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT return retval; } -static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) +static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, + PUCHAR mappedbuffer, UINT u32FirmwareLength, + ULONG u32StartingAddress) { UINT len = u32FirmwareLength; INT retval = STATUS_SUCCESS; PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); int bytes; - if (NULL == readbackbuff) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); + if (NULL == readbackbuff) return -ENOMEM; - } while (u32FirmwareLength && !retval) { len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); @@ -293,7 +279,6 @@ static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, if (bytes < 0) { retval = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval); break; } @@ -312,21 +297,22 @@ static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, return retval; } -INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress) +INT buffDnldVerify(struct bcm_mini_adapter *Adapter, + unsigned char *mappedbuffer, + unsigned int u32FirmwareLength, + unsigned long u32StartingAddress) { INT status = STATUS_SUCCESS; - status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed"); + status = buffDnld(Adapter, mappedbuffer, + u32FirmwareLength, u32StartingAddress); + if (status != STATUS_SUCCESS) goto error; - } - status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); - if (status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed"); + status = buffRdbkVerify(Adapter, mappedbuffer, + u32FirmwareLength, u32StartingAddress); + if (status != STATUS_SUCCESS) goto error; - } error: return status; } diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c index 5959fbdcd1be..fecf81ffe066 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -1,32 +1,37 @@ #include "headers.h" /* -Function: InterfaceIdleModeWakeup +Function: InterfaceIdleModeWakeup -Description: This is the hardware specific Function for waking up HW device from Idle mode. - A software abort pattern is written to the device to wake it and necessary power state - transitions from host are performed here. +Description: This is the hardware specific Function for + waking up HW device from Idle mode. + A software abort pattern is written to the + device to wake it and necessary power state + transitions from host are performed here. -Input parameters: IN struct bcm_mini_adapter *Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter *Adapter + - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface was successful. - Other - If an error occurred. +Return: BCM_STATUS_SUCCESS - If Wakeup of the HW Interface + was successful. + Other - If an error occurred. */ - /* -Function: InterfaceIdleModeRespond +Function: InterfaceIdleModeRespond -Description: This is the hardware specific Function for responding to Idle mode request from target. - Necessary power state transitions from host for idle mode or other device specific - initializations are performed here. +Description: This is the hardware specific Function for + responding to Idle mode request from target. + Necessary power state transitions from host for + idle mode or other device specific initializations + are performed here. -Input parameters: IN struct bcm_mini_adapter * Adapter - Miniport Adapter Context +Input parameters: IN struct bcm_mini_adapter * Adapter + - Miniport Adapter Context - -Return: BCM_STATUS_SUCCESS - If Idle mode response related HW configuration was successful. - Other - If an error occurred. +Return: BCM_STATUS_SUCCESS - If Idle mode response related + HW configuration was successful. + Other - If an error occurred. */ /* @@ -36,59 +41,59 @@ this value will be at address bfc02fa4.just before value d0ea1dle. Set time value by writing at bfc02f98 7d0 checking the Ack timer expire on kannon by running command -d qcslog .. if it shows e means host has not send response to f/w with in 200 ms. Response should be +d qcslog .. if it shows e means host has not send response +to f/w with in 200 ms. Response should be send to f/w with in 200 ms after the Idle/Shutdown req issued */ -int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer) +int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, + unsigned int *puiBuffer) { int status = STATUS_SUCCESS; unsigned int uiRegRead = 0; int bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "SubType of Message :0x%X", ntohl(*puiBuffer)); - if (ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, " Got GO_TO_IDLE_MODE_PAYLOAD(210) Msg Subtype"); - if (ntohl(*(puiBuffer+1)) == 0 ) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got IDLE MODE WAKE UP Response From F/W"); + if (ntohl(*(puiBuffer+1)) == 0) { - status = wrmalt (Adapter, SW_ABORT_IDLEMODE_LOC, &uiRegRead, sizeof(uiRegRead)); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg"); + status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, + &uiRegRead, sizeof(uiRegRead)); + if (status) return status; - } - if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { - uiRegRead = 0x00000000 ; - status = wrmalt (Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegRead, sizeof(uiRegRead)); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg"); + if (Adapter->ulPowerSaveMode == + DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { + uiRegRead = 0x00000000; + status = wrmalt(Adapter, + DEBUG_INTERRUPT_GENERATOR_REGISTOR, + &uiRegRead, sizeof(uiRegRead)); + if (status) return status; - } } - /* Below Register should not br read in case of Manual and Protocol Idle mode */ - else if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { + /* Below Register should not br read in case of + * Manual and Protocol Idle mode */ + else if (Adapter->ulPowerSaveMode != + DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegRead, sizeof(uiRegRead)); + bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, + &uiRegRead, sizeof(uiRegRead)); if (bytes < 0) { status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg0"); return status; } /* clear on read Register */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegRead, sizeof(uiRegRead)); + bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, + &uiRegRead, sizeof(uiRegRead)); if (bytes < 0) { status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed while clearing H/W Abort Reg1"); return status; } } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device Up from Idle Mode"); - /* Set Idle Mode Flag to False and Clear IdleMode reg. */ + /* Set Idle Mode Flag to False and + * Clear IdleMode reg. */ Adapter->IdleMode = false; Adapter->bTriedToWakeUpFromlowPowerMode = false; @@ -96,124 +101,123 @@ int InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *pui } else { if (TRUE == Adapter->IdleMode) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Device is already in Idle mode...."); - return status ; - } + return status; uiRegRead = 0; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Got Req from F/W to go in IDLE mode \n"); if (Adapter->chip_id == BCS220_2 || Adapter->chip_id == BCS220_2BC || Adapter->chip_id == BCS250_BC || Adapter->chip_id == BCS220_3) { - bytes = rdmalt(Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead)); + bytes = rdmalt(Adapter, HPM_CONFIG_MSW, + &uiRegRead, sizeof(uiRegRead)); if (bytes < 0) { status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "rdm failed while Reading HPM_CONFIG_LDO145 Reg 0\n"); return status; } uiRegRead |= (1<<17); - status = wrmalt (Adapter, HPM_CONFIG_MSW, &uiRegRead, sizeof(uiRegRead)); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "wrm failed while clearing Idle Mode Reg\n"); + status = wrmalt(Adapter, HPM_CONFIG_MSW, + &uiRegRead, sizeof(uiRegRead)); + if (status) return status; - } - } SendIdleModeResponse(Adapter); } } else if (ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "OverRiding Service Flow Params"); OverrideServiceFlowParams(Adapter, puiBuffer); } return status; } -static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, unsigned int Pattern) +static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, + unsigned int Pattern) { - int status = STATUS_SUCCESS; + int status = STATUS_SUCCESS; unsigned int value; - unsigned int chip_id ; + unsigned int chip_id; unsigned long timeout = 0, itr = 0; - int lenwritten = 0; - unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - struct bcm_interface_adapter *psInterfaceAdapter = Adapter->pvInterfaceAdapter; + int lenwritten = 0; + unsigned char aucAbortPattern[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF}; + struct bcm_interface_adapter *psInterfaceAdapter = + Adapter->pvInterfaceAdapter; /* Abort Bus suspend if its already suspended */ - if ((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend)) { - status = usb_autopm_get_interface(psInterfaceAdapter->interface); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Bus got wakeup..Aborting Idle mode... status:%d \n", status); + if ((TRUE == psInterfaceAdapter->bSuspended) && + (TRUE == Adapter->bDoSuspend)) + status = usb_autopm_get_interface( + psInterfaceAdapter->interface); - } - - if ((Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) - || - (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { + if ((Adapter->ulPowerSaveMode == + DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) || + (Adapter->ulPowerSaveMode == + DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE)) { /* write the SW abort pattern. */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing pattern<%d> to SW_ABORT_IDLEMODE_LOC\n", Pattern); - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(Pattern)); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "WRM to Register SW_ABORT_IDLEMODE_LOC failed.."); - return status; - } + status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, + &Pattern, sizeof(Pattern)); + if (status) + return status; } - if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { + if (Adapter->ulPowerSaveMode == + DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { value = 0x80000000; - status = wrmalt(Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &value, sizeof(value)); + status = wrmalt(Adapter, + DEBUG_INTERRUPT_GENERATOR_REGISTOR, + &value, sizeof(value)); if (status) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Register failed"); return status; - } - } else if (Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { + } else if (Adapter->ulPowerSaveMode != + DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) { /* * Get a Interrupt Out URB and send 8 Bytes Down * To be Done in Thread Context. * Not using Asynchronous Mechanism. */ - status = usb_interrupt_msg (psInterfaceAdapter->udev, + status = usb_interrupt_msg(psInterfaceAdapter->udev, usb_sndintpipe(psInterfaceAdapter->udev, psInterfaceAdapter->sIntrOut.int_out_endpointAddr), aucAbortPattern, 8, &lenwritten, 5000); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Sending Abort pattern down fails with status:%d..\n", status); + if (status) return status; - } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "NOB Sent down :%d", lenwritten); - } + else + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + IDLE_MODE, DBG_LVL_ALL, + "NOB Sent down :%d", lenwritten); /* mdelay(25); */ - timeout = jiffies + msecs_to_jiffies(50) ; - while ( timeout > jiffies ) { - itr++ ; + timeout = jiffies + msecs_to_jiffies(50); + while (time_after(timeout, jiffies)) { + itr++; rdmalt(Adapter, CHIP_ID_REG, &chip_id, sizeof(UINT)); if (0xbece3200 == (chip_id&~(0xF0))) chip_id = chip_id&~(0xF0); if (chip_id == Adapter->chip_id) break; } - if (timeout < jiffies ) - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Not able to read chip-id even after 25 msec"); + if (time_before(timeout, jiffies)) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + IDLE_MODE, DBG_LVL_ALL, + "Not able to read chip-id even after 25 msec"); else - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Number of completed iteration to read chip-id :%lu", itr); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + IDLE_MODE, DBG_LVL_ALL, + "Number of completed iteration to" + "read chip-id :%lu", itr); - status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, &Pattern, sizeof(status)); - if (status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to Register SW_ABORT_IDLEMODE_LOC failed.."); + status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, + &Pattern, sizeof(status)); + if (status) return status; - } } return status; } @@ -221,9 +225,10 @@ int InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter) { ULONG Status = 0; if (Adapter->bTriedToWakeUpFromlowPowerMode) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Wake up already attempted.. ignoring\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + IDLE_MODE, DBG_LVL_ALL, + "Wake up already attempted.. ignoring\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL, "Writing Low Power Mode Abort pattern to the Device\n"); Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; InterfaceAbortIdlemode(Adapter, Adapter->usIdleModePattern); @@ -237,30 +242,33 @@ void InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter) INT Status = 0; int bytes; - if (Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { + if (Adapter->ulPowerSaveMode == + DEVICE_POWERSAVE_MODE_AS_MANUAL_CLOCK_GATING) { /* clear idlemode interrupt. */ uiRegVal = 0; - Status = wrmalt(Adapter, DEBUG_INTERRUPT_GENERATOR_REGISTOR, &uiRegVal, sizeof(uiRegVal)); - if (Status) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM to DEBUG_INTERRUPT_GENERATOR_REGISTOR Failed with err :%d", Status); + Status = wrmalt(Adapter, + DEBUG_INTERRUPT_GENERATOR_REGISTOR, + &uiRegVal, sizeof(uiRegVal)); + if (Status) return; - } } - else { + else { - /* clear Interrupt EP registers. */ - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG0, &uiRegVal, sizeof(uiRegVal)); +/* clear Interrupt EP registers. */ + bytes = rdmalt(Adapter, + DEVICE_INT_OUT_EP_REG0, + &uiRegVal, sizeof(uiRegVal)); if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG0 failed with Err :%d", Status); return; } - bytes = rdmalt(Adapter, DEVICE_INT_OUT_EP_REG1, &uiRegVal, sizeof(uiRegVal)); + bytes = rdmalt(Adapter, + DEVICE_INT_OUT_EP_REG1, + &uiRegVal, sizeof(uiRegVal)); if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM of DEVICE_INT_OUT_EP_REG1 failed with Err :%d", Status); return; } } diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 3acdb58a10f5..94f32728f7c8 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -69,7 +69,7 @@ static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter) static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter) { - unsigned long ulReg = 0; + u32 ulReg; int bytes; /* Program EP2 MAX_PKT_SIZE */ @@ -96,7 +96,7 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE); /* Program TX EP as interrupt(Alternate Setting) */ - bytes = rdmalt(Adapter, 0x0F0110F8, (u32 *)&ulReg, sizeof(u32)); + bytes = rdmalt(Adapter, 0x0F0110F8, &ulReg, sizeof(u32)); if (bytes < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP failed\n"); @@ -119,18 +119,18 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter * Update EEPROM Version. * Read 4 bytes from 508 and modify 511 and 510. */ - ReadBeceemEEPROM(Adapter, 0x1FC, (PUINT)&ulReg); + ReadBeceemEEPROM(Adapter, 0x1FC, &ulReg); ulReg &= 0x0101FFFF; BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE); /* Update length field if required. Also make the string NULL terminated. */ - ReadBeceemEEPROM(Adapter, 0xA8, (PUINT)&ulReg); + ReadBeceemEEPROM(Adapter, 0xA8, &ulReg); if ((ulReg&0x00FF0000)>>16 > 0x30) { ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE); } - ReadBeceemEEPROM(Adapter, 0x148, (PUINT)&ulReg); + ReadBeceemEEPROM(Adapter, 0x148, &ulReg); if ((ulReg&0x00FF0000)>>16 > 0x30) { ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE); diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index f2973f5e503a..11008173f915 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -1,11 +1,11 @@ #include "headers.h" -static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid) +static int SearchVcid(struct bcm_mini_adapter *Adapter, unsigned short usVcid) { - int iIndex=0; + int iIndex = 0; - for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) - if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) + for (iIndex = (NO_OF_QUEUES-1); iIndex >= 0; iIndex--) + if (Adapter->PackInfo[iIndex].usVCID_Value == usVcid) return iIndex; return NO_OF_QUEUES+1; @@ -18,15 +18,14 @@ GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) struct bcm_usb_rcb *pRcb = NULL; UINT index = 0; - if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && - (psIntfAdapter->psAdapter->StopAllXaction == false)) - { + if ((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && + (psIntfAdapter->psAdapter->StopAllXaction == false)) { index = atomic_read(&psIntfAdapter->uCurrRcb); pRcb = &psIntfAdapter->asUsbRcb[index]; pRcb->bUsed = TRUE; - pRcb->psIntfAdapter= psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d", - index, atomic_read(&psIntfAdapter->uNumRcbUsed)); + pRcb->psIntfAdapter = psIntfAdapter; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Got Rx desc %d used %d", + index, atomic_read(&psIntfAdapter->uNumRcbUsed)); index = (index + 1) % MAXIMUM_USB_RCB; atomic_set(&psIntfAdapter->uCurrRcb, index); atomic_inc(&psIntfAdapter->uNumRcbUsed); @@ -40,9 +39,8 @@ static void read_bulk_callback(struct urb *urb) struct sk_buff *skb = NULL; bool bHeaderSupressionEnabled = false; int QueueIndex = NO_OF_QUEUES + 1; - UINT uiIndex=0; + UINT uiIndex = 0; int process_done = 1; - //int idleflag = 0 ; struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; @@ -52,49 +50,40 @@ static void read_bulk_callback(struct urb *urb) pr_info(PFX "%s: rx urb status %d length %d\n", Adapter->dev->name, urb->status, urb->actual_length); - if((Adapter->device_removed == TRUE) || - (TRUE == Adapter->bEndPointHalted) || - (0 == urb->actual_length) - ) - { - pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - return; - } - - if(urb->status != STATUS_SUCCESS) - { - if(urb->status == -EPIPE) - { - Adapter->bEndPointHalted = TRUE ; - wake_up(&Adapter->tx_packet_wait_queue); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"Rx URB has got cancelled. status :%d", urb->status); - } + if ((Adapter->device_removed == TRUE) || + (TRUE == Adapter->bEndPointHalted) || + (0 == urb->actual_length)) { pRcb->bUsed = false; - atomic_dec(&psIntfAdapter->uNumRcbUsed); - urb->status = STATUS_SUCCESS ; - return ; - } - - if(Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"device is going in low power mode while PMU option selected..hence rx packet should not be process"); - return ; - } - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength); - if(!pLeader->PLength) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0"); atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid); - if(MAX_CNTL_PKT_SIZE < pLeader->PLength) - { + + if (urb->status != STATUS_SUCCESS) { + if (urb->status == -EPIPE) { + Adapter->bEndPointHalted = TRUE; + wake_up(&Adapter->tx_packet_wait_queue); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Rx URB has got cancelled. status :%d", urb->status); + } + pRcb->bUsed = false; + atomic_dec(&psIntfAdapter->uNumRcbUsed); + urb->status = STATUS_SUCCESS; + return; + } + + if (Adapter->bDoSuspend && (Adapter->bPreparingForLowPowerMode)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "device is going in low power mode while PMU option selected..hence rx packet should not be process"); + return; + } + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Read back done len %d\n", pLeader->PLength); + if (!pLeader->PLength) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Length 0"); + atomic_dec(&psIntfAdapter->uNumRcbUsed); + return; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status, pLeader->PLength, pLeader->Vcid); + if (MAX_CNTL_PKT_SIZE < pLeader->PLength) { if (netif_msg_rx_err(Adapter)) pr_info(PFX "%s: corrupted leader length...%d\n", Adapter->dev->name, pLeader->PLength); @@ -103,65 +92,58 @@ static void read_bulk_callback(struct urb *urb) return; } - QueueIndex = SearchVcid( Adapter,pLeader->Vcid); - if(QueueIndex < NO_OF_QUEUES) - { + QueueIndex = SearchVcid(Adapter, pLeader->Vcid); + if (QueueIndex < NO_OF_QUEUES) { bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; bHeaderSupressionEnabled = bHeaderSupressionEnabled & Adapter->bPHSEnabled; } - skb = dev_alloc_skb (pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER);//2 //2 for allignment - if(!skb) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet"); + skb = dev_alloc_skb(pLeader->PLength + SKB_RESERVE_PHS_BYTES + SKB_RESERVE_ETHERNET_HEADER); + if (!skb) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "NO SKBUFF!!! Dropping the Packet"); atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } - /* If it is a control Packet, then call handle_bcm_packet ()*/ - if((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || - (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt..."); + /* If it is a control Packet, then call handle_bcm_packet ()*/ + if ((ntohs(pLeader->Vcid) == VCID_CONTROL_PACKET) || + (!(pLeader->Status >= 0x20 && pLeader->Status <= 0x3F))) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_CTRL, DBG_LVL_ALL, "Received control pkt..."); *(PUSHORT)skb->data = pLeader->Status; - memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + - (sizeof(struct bcm_leader)), pLeader->PLength); + memcpy(skb->data+sizeof(USHORT), urb->transfer_buffer + + (sizeof(struct bcm_leader)), pLeader->PLength); skb->len = pLeader->PLength + sizeof(USHORT); spin_lock(&Adapter->control_queue_lock); - ENQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail,skb); + ENQUEUEPACKET(Adapter->RxControlHead, Adapter->RxControlTail, skb); spin_unlock(&Adapter->control_queue_lock); atomic_inc(&Adapter->cntrlpktCnt); wake_up(&Adapter->process_rx_cntrlpkt); - } - else - { + } else { /* - * Data Packet, Format a proper Ethernet Header - * and give it to the stack - */ - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt..."); + * Data Packet, Format a proper Ethernet Header + * and give it to the stack + */ + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt..."); skb_reserve(skb, 2 + SKB_RESERVE_PHS_BYTES); memcpy(skb->data+ETH_HLEN, (PUCHAR)urb->transfer_buffer + sizeof(struct bcm_leader), pLeader->PLength); skb->dev = Adapter->dev; /* currently skb->len has extra ETH_HLEN bytes in the beginning */ - skb_put (skb, pLeader->PLength + ETH_HLEN); - Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength; - Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength); + skb_put(skb, pLeader->PLength + ETH_HLEN); + Adapter->PackInfo[QueueIndex].uiTotalRxBytes += pLeader->PLength; + Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes += pLeader->PLength; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Received Data pkt of len :0x%X", pLeader->PLength); - if(netif_running(Adapter->dev)) - { + if (netif_running(Adapter->dev)) { /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ skb_pull(skb, ETH_HLEN); PHSReceive(Adapter, pLeader->Vcid, skb, &skb->len, - NULL,bHeaderSupressionEnabled); + NULL, bHeaderSupressionEnabled); - if(!Adapter->PackInfo[QueueIndex].bEthCSSupport) - { + if (!Adapter->PackInfo[QueueIndex].bEthCSSupport) { skb_push(skb, ETH_HLEN); memcpy(skb->data, skb->dev->dev_addr, 6); @@ -169,29 +151,26 @@ static void read_bulk_callback(struct urb *urb) (*(skb->data+11))++; *(skb->data+12) = 0x08; *(skb->data+13) = 0x00; - pLeader->PLength+=ETH_HLEN; + pLeader->PLength += ETH_HLEN; } skb->protocol = eth_type_trans(skb, Adapter->dev); process_done = netif_rx(skb); - } - else - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); + } else { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); dev_kfree_skb(skb); } ++Adapter->dev->stats.rx_packets; Adapter->dev->stats.rx_bytes += pLeader->PLength; - for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) - { - if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) - && (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) + for (uiIndex = 0; uiIndex < MIBS_MAX_HIST_ENTRIES; uiIndex++) { + if ((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) && + (pLeader->PLength > MIBS_PKTSIZEHIST_RANGE*(uiIndex))) Adapter->aRxPktSizeHist[uiIndex]++; } } - Adapter->PrevNumRecvDescs++; + Adapter->PrevNumRecvDescs++; pRcb->bUsed = false; atomic_dec(&psIntfAdapter->uNumRcbUsed); } @@ -201,23 +180,18 @@ static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_us struct urb *urb = pRcb->urb; int retval = 0; - usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe( - psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr), - urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback, - pRcb); - if(false == psIntfAdapter->psAdapter->device_removed && - false == psIntfAdapter->psAdapter->bEndPointHalted && - false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) - { + usb_fill_bulk_urb(urb, psIntfAdapter->udev, usb_rcvbulkpipe(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr), + urb->transfer_buffer, BCM_USB_MAX_READ_LENGTH, read_bulk_callback, pRcb); + if (false == psIntfAdapter->psAdapter->device_removed && + false == psIntfAdapter->psAdapter->bEndPointHalted && + false == psIntfAdapter->bSuspended && + false == psIntfAdapter->bPreparingForBusSuspend) { retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval); - //if this return value is because of pipe halt. need to clear this. - if(retval == -EPIPE) - { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + if (retval) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "failed submitting read urb, error %d", retval); + /* if this return value is because of pipe halt. need to clear this. */ + if (retval == -EPIPE) { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } @@ -240,25 +214,20 @@ Return: TRUE - If Rx was successful. Other - If an error occurred. */ -bool InterfaceRx (struct bcm_interface_adapter *psIntfAdapter) +bool InterfaceRx(struct bcm_interface_adapter *psIntfAdapter) { USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed); struct bcm_usb_rcb *pRcb = NULL; -// RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs - -// psIntfAdapter->psAdapter->PrevNumRecvDescs; - while(RxDescCount) - { + while (RxDescCount) { pRcb = GetBulkInRcb(psIntfAdapter); - if(pRcb == NULL) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer"); + if (pRcb == NULL) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Unable to get Rcb pointer"); return false; } - //atomic_inc(&psIntfAdapter->uNumRcbUsed); ReceiveRcb(psIntfAdapter, pRcb); RxDescCount--; - } + } return TRUE; } diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index b9c2784e9811..ea7707b8e60e 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -3,26 +3,22 @@ /*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { - struct bcm_usb_tcb *pTcb= (struct bcm_usb_tcb *)urb->context; + struct bcm_usb_tcb *pTcb = (struct bcm_usb_tcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; - struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; - bool bpowerDownMsg = false ; + struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter; + bool bpowerDownMsg = false; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - if (unlikely(netif_msg_tx_done(Adapter))) - pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); + if (unlikely(netif_msg_tx_done(Adapter))) + pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); - if(urb->status != STATUS_SUCCESS) - { - if(urb->status == -EPIPE) - { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + if (urb->status != STATUS_SUCCESS) { + if (urb->status == -EPIPE) { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Tx URB has got cancelled. status :%d", urb->status); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx URB has got cancelled. status :%d", urb->status); } } @@ -31,69 +27,59 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) - if(TRUE == psAdapter->bPreparingForLowPowerMode) - { + if (TRUE == psAdapter->bPreparingForLowPowerMode) { - if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && - (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) - - { - bpowerDownMsg = TRUE ; - //This covers the bus err while Idle Request msg sent down. - if(urb->status != STATUS_SUCCESS) - { - psAdapter->bPreparingForLowPowerMode = false ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Idle Mode Request msg failed to reach to Modem"); - //Signalling the cntrl pkt path in Ioctl + if (((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && + (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) { + bpowerDownMsg = TRUE; + /* This covers the bus err while Idle Request msg sent down. */ + if (urb->status != STATUS_SUCCESS) { + psAdapter->bPreparingForLowPowerMode = false; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Request msg failed to reach to Modem"); + /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } - if(psAdapter->bDoSuspend == false) - { + if (psAdapter->bDoSuspend == false) { psAdapter->IdleMode = TRUE; - //since going in Idle mode completed hence making this var false; - psAdapter->bPreparingForLowPowerMode = false ; + /* since going in Idle mode completed hence making this var false */ + psAdapter->bPreparingForLowPowerMode = false; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); - //Signalling the cntrl pkt path in Ioctl + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in Idle Mode State..."); + /* Signalling the cntrl pkt path in Ioctl*/ wake_up(&psAdapter->lowpower_mode_wait_queue); } - } - else if((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && + } else if ((pControlMsg->Leader.Status == LINK_UP_CONTROL_REQ) && (pControlMsg->szData[0] == LINK_UP_ACK) && (pControlMsg->szData[1] == LINK_SHUTDOWN_REQ_FROM_FIRMWARE) && - (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) - { - //This covers the bus err while shutdown Request msg sent down. - if(urb->status != STATUS_SUCCESS) - { - psAdapter->bPreparingForLowPowerMode = false ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Shutdown Request Msg failed to reach to Modem"); - //Signalling the cntrl pkt path in Ioctl + (pControlMsg->szData[2] == SHUTDOWN_ACK_FROM_DRIVER)) { + /* This covers the bus err while shutdown Request msg sent down. */ + if (urb->status != STATUS_SUCCESS) { + psAdapter->bPreparingForLowPowerMode = false; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Shutdown Request Msg failed to reach to Modem"); + /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); StartInterruptUrb(psIntfAdapter); goto err_exit; } - bpowerDownMsg = TRUE ; - if(psAdapter->bDoSuspend == false) - { + bpowerDownMsg = TRUE; + if (psAdapter->bDoSuspend == false) { psAdapter->bShutStatus = TRUE; - //since going in shutdown mode completed hence making this var false; - psAdapter->bPreparingForLowPowerMode = false ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Host Entered in shutdown Mode State..."); - //Signalling the cntrl pkt path in Ioctl + /* since going in shutdown mode completed hence making this var false */ + psAdapter->bPreparingForLowPowerMode = false; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Host Entered in shutdown Mode State..."); + /* Signalling the cntrl pkt path in Ioctl */ wake_up(&psAdapter->lowpower_mode_wait_queue); } } - if(psAdapter->bDoSuspend && bpowerDownMsg) - { - //issuing bus suspend request - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL,"Issuing the Bus suspend request to USB stack"); + if (psAdapter->bDoSuspend && bpowerDownMsg) { + /* issuing bus suspend request */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Issuing the Bus suspend request to USB stack"); psIntfAdapter->bPreparingForBusSuspend = TRUE; schedule_work(&psIntfAdapter->usbSuspendWork); @@ -101,9 +87,9 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) } -err_exit : +err_exit: usb_free_coherent(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); + urb->transfer_buffer, urb->transfer_dma); } @@ -112,14 +98,13 @@ static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAda struct bcm_usb_tcb *pTcb = NULL; UINT index = 0; - if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && - (psIntfAdapter->psAdapter->StopAllXaction ==false)) - { + if ((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && + (psIntfAdapter->psAdapter->StopAllXaction == false)) { index = atomic_read(&psIntfAdapter->uCurrTcb); pTcb = &psIntfAdapter->asUsbTcb[index]; pTcb->bUsed = TRUE; - pTcb->psIntfAdapter= psIntfAdapter; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d", + pTcb->psIntfAdapter = psIntfAdapter; + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Got Tx desc %d used %d", index, atomic_read(&psIntfAdapter->uNumTcbUsed)); index = (index + 1) % MAXIMUM_USB_TCB; atomic_set(&psIntfAdapter->uCurrTcb, index); @@ -135,44 +120,37 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u int retval = 0; urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, - GFP_ATOMIC, &urb->transfer_dma); - if (!urb->transfer_buffer) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); + GFP_ATOMIC, &urb->transfer_dma); + if (!urb->transfer_buffer) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); return -ENOMEM; } memcpy(urb->transfer_buffer, data, len); urb->transfer_buffer_length = len; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); - //For T3B,INT OUT end point will be used as bulk out end point - if((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) - { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending Bulk out packet\n"); + /* For T3B,INT OUT end point will be used as bulk out end point */ + if ((psIntfAdapter->psAdapter->chip_id == T3B) && (psIntfAdapter->bHighSpeedDevice == TRUE)) { usb_fill_int_urb(urb, psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_pipe, + psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb, psIntfAdapter->sBulkOut.int_out_interval); - } - else - { + } else { usb_fill_bulk_urb(urb, psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_pipe, urb->transfer_buffer, len, write_bulk_callback, pTcb); } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* For DMA transfer */ - if(false == psIntfAdapter->psAdapter->device_removed && + if (false == psIntfAdapter->psAdapter->device_removed && false == psIntfAdapter->psAdapter->bEndPointHalted && false == psIntfAdapter->bSuspended && - false == psIntfAdapter->bPreparingForBusSuspend) - { + false == psIntfAdapter->bPreparingForBusSuspend) { retval = usb_submit_urb(urb, GFP_ATOMIC); - if (retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); - if(retval == -EPIPE) - { - psIntfAdapter->psAdapter->bEndPointHalted = TRUE ; + if (retval) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "failed submitting write urb, error %d", retval); + if (retval == -EPIPE) { + psIntfAdapter->psAdapter->bEndPointHalted = TRUE; wake_up(&psIntfAdapter->psAdapter->tx_packet_wait_queue); } } @@ -182,13 +160,12 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_u int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) { - struct bcm_usb_tcb *pTcb= NULL; + struct bcm_usb_tcb *pTcb = NULL; struct bcm_interface_adapter *psIntfAdapter = arg; - pTcb= GetBulkOutTcb(psIntfAdapter); - if(pTcb == NULL) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet"); + pTcb = GetBulkOutTcb(psIntfAdapter); + if (pTcb == NULL) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "No URB to transmit packet, dropping packet"); return -EFAULT; } return TransmitTcb(psIntfAdapter, pTcb, data, len); diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 892ebc65cdd3..afc7bcc3e54b 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -1280,11 +1280,11 @@ static int phs_decompress(unsigned char *in_buf, if (bit == SUPPRESS) { *out_buf = *phsf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d phsf %d ouput %d", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d phsf %d output %d", phss, *phsf, *out_buf); } else { *out_buf = *in_buf; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d input %d ouput %d", + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, PHS_RECEIVE, DBG_LVL_ALL, "\nDECOMP:In phss %d input %d output %d", phss, *in_buf, *out_buf); in_buf++; size++; diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 1609a2bdc522..0727599bf5fa 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -24,7 +24,7 @@ static VOID PruneQueue(struct bcm_mini_adapter *Adapter, INT iIndex); * * Returns - TRUE(If address matches) else FAIL . *********************************************************************/ -bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSrcIP) +static bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSrcIP) { UCHAR ucLoopIndex = 0; @@ -58,7 +58,7 @@ bool MatchSrcIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulSr * * Returns - TRUE(If address matches) else FAIL . *********************************************************************/ -bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP) +static bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulDestIP) { UCHAR ucLoopIndex = 0; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -91,7 +91,7 @@ bool MatchDestIpAddress(struct bcm_classifier_rule *pstClassifierRule, ULONG ulD * * Returns - TRUE(If address matches) else FAIL. **************************************************************************/ -bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfService) +static bool MatchTos(struct bcm_classifier_rule *pstClassifierRule, UCHAR ucTypeOfService) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 9e5f955a1a08..fca164f51f4b 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -1354,67 +1354,6 @@ BeceemFlashBulkWriteStatus_EXIT: return Status; } -/* - * Procedure: PropagateCalParamsFromEEPROMToMemory - * - * Description: Dumps the calibration section of EEPROM to DDR. - * - * Arguments: - * Adapter - ptr to Adapter object instance - * Returns: - * OSAL_STATUS_CODE - * - */ - -int PropagateCalParamsFromEEPROMToMemory(struct bcm_mini_adapter *Adapter) -{ - PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); - unsigned int uiEepromSize = 0; - unsigned int uiIndex = 0; - unsigned int uiBytesToCopy = 0; - unsigned int uiCalStartAddr = EEPROM_CALPARAM_START; - unsigned int uiMemoryLoc = EEPROM_CAL_DATA_INTERNAL_LOC; - unsigned int value; - int Status = 0; - - if (!pBuff) - return -ENOMEM; - - if (0 != BeceemEEPROMBulkRead(Adapter, &uiEepromSize, EEPROM_SIZE_OFFSET, 4)) { - kfree(pBuff); - return -1; - } - - uiEepromSize >>= 16; - if (uiEepromSize > 1024 * 1024) { - kfree(pBuff); - return -1; - } - - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - - while (uiBytesToCopy) { - if (0 != BeceemEEPROMBulkRead(Adapter, (PUINT)pBuff, uiCalStartAddr, uiBytesToCopy)) { - Status = -1; - break; - } - wrm(Adapter, uiMemoryLoc, (PCHAR)(((PULONG)pBuff) + uiIndex), uiBytesToCopy); - uiMemoryLoc += uiBytesToCopy; - uiEepromSize -= uiBytesToCopy; - uiCalStartAddr += uiBytesToCopy; - uiIndex += uiBytesToCopy / 4; - uiBytesToCopy = MIN(BUFFER_4K, uiEepromSize); - - } - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - value = 0xbeadbead; - wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - kfree(pBuff); - - return Status; -} - /* * Procedure: PropagateCalParamsFromFlashToMemory * @@ -2873,7 +2812,7 @@ int BcmFlash2xBulkRead(struct bcm_mini_adapter *Adapter, SectionStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); if (SectionStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash 2.x Map ", eFlash2xSectionVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash 2.x Map ", eFlash2xSectionVal); return -EINVAL; } @@ -2936,7 +2875,7 @@ int BcmFlash2xBulkWrite(struct bcm_mini_adapter *Adapter, FlashSectValStartOffset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectVal); if (FlashSectValStartOffset == STATUS_FAILURE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exixt in Flash Map 2.x", eFlash2xSectVal); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "This Section<%d> does not exist in Flash Map 2.x", eFlash2xSectVal); return -EINVAL; } @@ -3911,7 +3850,7 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2 uiNumOfBytes = psFlash2xReadWrite->numOfBytes; if (IsSectionExistInFlash(Adapter, psFlash2xReadWrite->Section) != TRUE) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exixt in Flash", psFlash2xReadWrite->Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%x> does not exist in Flash", psFlash2xReadWrite->Section); return false; } uiSectStartOffset = BcmGetSectionValStartOffset(Adapter, psFlash2xReadWrite->Section); @@ -3944,6 +3883,15 @@ int validateFlash2xReadWrite(struct bcm_mini_adapter *Adapter, struct bcm_flash2 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "End offset :%x\n", uiSectEndOffset); + /* psFlash2xReadWrite->offset and uiNumOfBytes are user controlled and can lead to integer overflows */ + if (psFlash2xReadWrite->offset > uiSectEndOffset) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); + return false; + } + if (uiNumOfBytes > uiSectEndOffset) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Invalid Request...."); + return false; + } /* Checking the boundary condition */ if ((uiSectStartOffset + psFlash2xReadWrite->offset + uiNumOfBytes) <= uiSectEndOffset) return TRUE; @@ -4530,13 +4478,13 @@ int IsSectionWritable(struct bcm_mini_adapter *Adapter, enum bcm_flash2x_section int Status = false; if (IsSectionExistInFlash(Adapter, Section) == false) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exixt", Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section <%d> does not exist", Section); return false; } offset = BcmGetSectionValStartOffset(Adapter, Section); if (offset == INVALID_OFFSET) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exixt", Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Section<%d> does not exist", Section); return false; } diff --git a/drivers/staging/btmtk_usb/Kconfig b/drivers/staging/btmtk_usb/Kconfig deleted file mode 100644 index a425ebda6c7a..000000000000 --- a/drivers/staging/btmtk_usb/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config USB_BTMTK - tristate "Mediatek Bluetooth support" - depends on USB && BT && m - ---help--- - Say Y here if you wish to control a MTK USB Bluetooth. - - This option depends on 'USB' support being enabled - - To compile this driver as a module, choose M here: the - module will be called btmtk_usb. - diff --git a/drivers/staging/btmtk_usb/Makefile b/drivers/staging/btmtk_usb/Makefile deleted file mode 100644 index 4d6c9d764621..000000000000 --- a/drivers/staging/btmtk_usb/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_USB_BTMTK) += btmtk_usb.o diff --git a/drivers/staging/btmtk_usb/README b/drivers/staging/btmtk_usb/README deleted file mode 100644 index c046c8e96b2d..000000000000 --- a/drivers/staging/btmtk_usb/README +++ /dev/null @@ -1,14 +0,0 @@ --build driver modules - make - --install driver modules - make install - --remove driver modules - make clean - --dynamic debug message - turn on CONFIG_DYNAMIC_DEBUG compiler flag for current kernel - mount -t debugfs none /sys/kernel/debug/ - echo "module module_name +p" > /sys/kernel/debug/dynamic_debug/control(turn on debug messages, module name such as btmtk_usb) - echo "module module_name -p" > /sys/kernel/debug/dynamic_debug/control(turn off debug messages, module name such as btmtk_usb) diff --git a/drivers/staging/btmtk_usb/TODO b/drivers/staging/btmtk_usb/TODO deleted file mode 100644 index a71d1297942d..000000000000 --- a/drivers/staging/btmtk_usb/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO: - - checkpatch.pl clean - - determine if the driver should not be using a duplicate - version of the usb-bluetooth interface code, but should - be merged into the drivers/bluetooth/ directory and - infrastructure instead. - - review by the bluetooth developer community - -Please send any patches for this driver to Yu-Chen, Cho and -jay.hung@mediatek.com diff --git a/drivers/staging/btmtk_usb/btmtk_usb.c b/drivers/staging/btmtk_usb/btmtk_usb.c deleted file mode 100644 index 9a5ebd6cc512..000000000000 --- a/drivers/staging/btmtk_usb/btmtk_usb.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * MediaTek Bluetooth USB Driver - * - * Copyright (C) 2013, MediaTek co. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * or on the worldwide web at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "btmtk_usb.h" - -#define VERSION "1.0.4" -#define MT7650_FIRMWARE "mt7650.bin" -#define MT7662_FIRMWARE "mt7662.bin" - -static struct usb_driver btmtk_usb_driver; - - -static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *); -static int btmtk_usb_load_fw(struct btmtk_usb_data *); - -static void hex_dump(char *str, u8 *src_buf, u32 src_buf_len) -{ - unsigned char *pt; - int x; - - pt = src_buf; - - BT_DBG("%s: %p, len = %d\n", str, src_buf, src_buf_len); - - for (x = 0; x < src_buf_len; x++) { - if (x % 16 == 0) - BT_DBG("0x%04x : ", x); - BT_DBG("%02x ", ((unsigned char)pt[x])); - if (x % 16 == 15) - BT_DBG("\n"); - } - - BT_DBG("\n"); -} - -static int btmtk_usb_reset(struct usb_device *udev) -{ - int ret; - - BT_DBG("%s\n", __func__); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, - DEVICE_VENDOR_REQUEST_OUT, 0x01, 0x00, - NULL, 0x00, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d)\n", __func__, ret); - return ret; - } - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_io_read32(struct btmtk_usb_data *data, u32 reg, u32 *val) -{ - u8 request = data->r_request; - struct usb_device *udev = data->udev; - int ret; - __le32 val_le; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), request, - DEVICE_VENDOR_REQUEST_IN, 0x0, reg, data->io_buf, - 4, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - *val = 0xffffffff; - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, *val); - return ret; - } - - memmove(&val_le, data->io_buf, 4); - - *val = le32_to_cpu(val_le); - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_io_write32(struct btmtk_usb_data *data, u32 reg, u32 val) -{ - u16 value, index; - u8 request = data->w_request; - struct usb_device *udev = data->udev; - int ret; - - index = (u16)reg; - value = val & 0x0000ffff; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, - DEVICE_VENDOR_REQUEST_OUT, value, index, - NULL, 0, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, val); - return ret; - } - - index = (u16)(reg + 2); - value = (val & 0xffff0000) >> 16; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - request, DEVICE_VENDOR_REQUEST_OUT, - value, index, NULL, 0, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d), reg=%x, value=%x\n", - __func__, ret, reg, val); - return ret; - } - - if (ret > 0) - ret = 0; - - return ret; -} - -static int btmtk_usb_switch_iobase(struct btmtk_usb_data *data, int base) -{ - int ret = 0; - - switch (base) { - case SYSCTL: - data->w_request = 0x42; - data->r_request = 0x47; - break; - case WLAN: - data->w_request = 0x02; - data->r_request = 0x07; - break; - - default: - return -EINVAL; - } - - return ret; -} - -static void btmtk_usb_cap_init(struct btmtk_usb_data *data) -{ - const struct firmware *firmware; - struct usb_device *udev = data->udev; - int ret; - - btmtk_usb_io_read32(data, 0x00, &data->chip_id); - - BT_DBG("chip id = %x\n", data->chip_id); - - if (is_mt7630(data) || is_mt7650(data)) { - data->need_load_fw = 1; - data->need_load_rom_patch = 0; - ret = request_firmware(&firmware, MT7650_FIRMWARE, &udev->dev); - if (ret < 0) { - if (ret == -ENOENT) { - BT_ERR("Firmware file \"%s\" not found\n", - MT7650_FIRMWARE); - } else { - BT_ERR("Firmware file \"%s\" request failed (err=%d)\n", - MT7650_FIRMWARE, ret); - } - } else { - BT_DBG("Firmware file \"%s\" Found\n", - MT7650_FIRMWARE); - /* load firmware here */ - data->firmware = firmware; - btmtk_usb_load_fw(data); - } - release_firmware(firmware); - } else if (is_mt7632(data) || is_mt7662(data)) { - data->need_load_fw = 0; - data->need_load_rom_patch = 1; - data->rom_patch_offset = 0x90000; - ret = request_firmware(&firmware, MT7662_FIRMWARE, &udev->dev); - if (ret < 0) { - if (ret == -ENOENT) { - BT_ERR("Firmware file \"%s\" not found\n", - MT7662_FIRMWARE); - } else { - BT_ERR("Firmware file \"%s\" request failed (err=%d)\n", - MT7662_FIRMWARE, ret); - } - } else { - BT_DBG("Firmware file \"%s\" Found\n", MT7662_FIRMWARE); - /* load rom patch here */ - data->firmware = firmware; - data->rom_patch_len = firmware->size; - btmtk_usb_load_rom_patch(data); - } - release_firmware(firmware); - } else { - BT_ERR("unknow chip(%x)\n", data->chip_id); - } -} - -static u16 checksume16(u8 *pData, int len) -{ - int sum = 0; - - while (len > 1) { - sum += *((u16 *)pData); - - pData = pData + 2; - - if (sum & 0x80000000) - sum = (sum & 0xFFFF) + (sum >> 16); - - len -= 2; - } - - if (len) - sum += *((u8 *)pData); - - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - return ~sum; -} - -static int btmtk_usb_chk_crc(struct btmtk_usb_data *data, u32 checksum_len) -{ - int ret = 0; - struct usb_device *udev = data->udev; - - BT_DBG("%s\n", __func__); - - memmove(data->io_buf, &data->rom_patch_offset, 4); - memmove(&data->io_buf[4], &checksum_len, 4); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, - DEVICE_VENDOR_REQUEST_IN, 0x20, 0x00, data->io_buf, - 8, CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) - BT_ERR("%s error(%d)\n", __func__, ret); - - return ret; -} - -static u16 btmtk_usb_get_crc(struct btmtk_usb_data *data) -{ - int ret = 0; - struct usb_device *udev = data->udev; - u16 crc, count = 0; - __le16 crc_le; - - BT_DBG("%s\n", __func__); - - while (1) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0x01, DEVICE_VENDOR_REQUEST_IN, - 0x21, 0x00, data->io_buf, 2, - CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - crc = 0xFFFF; - BT_ERR("%s error(%d)\n", __func__, ret); - } - - memmove(&crc_le, data->io_buf, 2); - - crc = le16_to_cpu(crc_le); - - if (crc != 0xFFFF) - break; - - mdelay(100); - - if (count++ > 100) { - BT_ERR("Query CRC over %d times\n", count); - break; - } - } - - return crc; -} - -static int btmtk_usb_reset_wmt(struct btmtk_usb_data *data) -{ - int ret = 0; - - /* reset command */ - u8 cmd[8] = {0x6F, 0xFC, 0x05, 0x01, 0x07, 0x01, 0x00, 0x04}; - - memmove(data->io_buf, cmd, 8); - - BT_DBG("%s\n", __func__); - - ret = usb_control_msg(data->udev, usb_sndctrlpipe(data->udev, 0), 0x01, - DEVICE_CLASS_REQUEST_OUT, 0x12, 0x00, - data->io_buf, 8, CONTROL_TIMEOUT_JIFFIES); - - if (ret) - BT_ERR("%s:(%d)\n", __func__, ret); - - return ret; -} - -static void load_rom_patch_complete(struct urb *urb) -{ - - struct completion *sent_to_mcu_done = (struct completion *)urb->context; - - complete(sent_to_mcu_done); -} - -static int btmtk_usb_load_rom_patch(struct btmtk_usb_data *data) -{ - u32 loop = 0; - u32 value; - s32 sent_len; - int ret = 0, total_checksum = 0; - struct urb *urb; - u32 patch_len = 0; - u32 cur_len = 0; - dma_addr_t data_dma; - struct completion sent_to_mcu_done; - int first_block = 1; - unsigned char phase; - void *buf; - char *pos; - unsigned int pipe; - pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); - - if (!data->firmware) { - BT_ERR("%s:please assign a rom patch\n", __func__); - return -1; - } - -load_patch_protect: - btmtk_usb_switch_iobase(data, WLAN); - btmtk_usb_io_read32(data, SEMAPHORE_03, &value); - loop++; - - if (((value & 0x01) == 0x00) && (loop < 600)) { - mdelay(1); - goto load_patch_protect; - } - - btmtk_usb_io_write32(data, 0x1004, 0x2c); - - btmtk_usb_switch_iobase(data, SYSCTL); - - btmtk_usb_io_write32(data, 0x1c, 0x30); - - /* Enable USB_DMA_CFG */ - btmtk_usb_io_write32(data, 0x9018, 0x00c00020); - - btmtk_usb_switch_iobase(data, WLAN); - - /* check ROM patch if upgrade */ - btmtk_usb_io_read32(data, COM_REG0, &value); - - if ((value & 0x02) == 0x02) - goto error0; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - if (!urb) { - ret = -ENOMEM; - goto error0; - } - - buf = usb_alloc_coherent(data->udev, UPLOAD_PATCH_UNIT, - GFP_ATOMIC, &data_dma); - - if (!buf) { - ret = -ENOMEM; - goto error1; - } - - pos = buf; - BT_DBG("loading rom patch"); - - init_completion(&sent_to_mcu_done); - - cur_len = 0x00; - patch_len = data->rom_patch_len - PATCH_INFO_SIZE; - - /* loading rom patch */ - while (1) { - s32 sent_len_max = UPLOAD_PATCH_UNIT - PATCH_HEADER_SIZE; - sent_len = min_t(s32, (patch_len - cur_len), sent_len_max); - - BT_DBG("patch_len = %d\n", patch_len); - BT_DBG("cur_len = %d\n", cur_len); - BT_DBG("sent_len = %d\n", sent_len); - - if (sent_len <= 0) - break; - - if (first_block == 1) { - if (sent_len < sent_len_max) - phase = PATCH_PHASE3; - else - phase = PATCH_PHASE1; - first_block = 0; - } else if (sent_len == sent_len_max) { - phase = PATCH_PHASE2; - } else { - phase = PATCH_PHASE3; - } - - /* prepare HCI header */ - pos[0] = 0x6F; - pos[1] = 0xFC; - pos[2] = (sent_len + 5) & 0xFF; - pos[3] = ((sent_len + 5) >> 8) & 0xFF; - - /* prepare WMT header */ - pos[4] = 0x01; - pos[5] = 0x01; - pos[6] = (sent_len + 1) & 0xFF; - pos[7] = ((sent_len + 1) >> 8) & 0xFF; - - pos[8] = phase; - - memcpy(&pos[9], - data->firmware->data + PATCH_INFO_SIZE + cur_len, - sent_len); - - BT_DBG("sent_len + PATCH_HEADER_SIZE = %d, phase = %d\n", - sent_len + PATCH_HEADER_SIZE, phase); - - usb_fill_bulk_urb(urb, - data->udev, - pipe, - buf, - sent_len + PATCH_HEADER_SIZE, - load_rom_patch_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error2; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload rom_patch timeout\n"); - goto error2; - } - - BT_DBG("."); - - mdelay(200); - - cur_len += sent_len; - - } - - total_checksum = checksume16( - (u8 *)data->firmware->data + PATCH_INFO_SIZE, - patch_len); - - BT_DBG("Send checksum req..\n"); - - btmtk_usb_chk_crc(data, patch_len); - - mdelay(20); - - if (total_checksum != btmtk_usb_get_crc(data)) { - BT_ERR("checksum fail!, local(0x%x) <> fw(0x%x)\n", - total_checksum, btmtk_usb_get_crc(data)); - ret = -1; - goto error2; - } - - mdelay(20); - - ret = btmtk_usb_reset_wmt(data); - - mdelay(20); - -error2: - usb_free_coherent(data->udev, UPLOAD_PATCH_UNIT, buf, data_dma); -error1: - usb_free_urb(urb); -error0: - btmtk_usb_io_write32(data, SEMAPHORE_03, 0x1); - return ret; -} - - -static int load_fw_iv(struct btmtk_usb_data *data) -{ - int ret; - struct usb_device *udev = data->udev; - char *buf = kmalloc(64, GFP_ATOMIC); - - memmove(buf, data->firmware->data + 32, 64); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, - DEVICE_VENDOR_REQUEST_OUT, 0x12, 0x0, buf, 64, - CONTROL_TIMEOUT_JIFFIES); - - if (ret < 0) { - BT_ERR("%s error(%d) step4\n", __func__, ret); - kfree(buf); - return ret; - } - - if (ret > 0) - ret = 0; - - kfree(buf); - - return ret; -} - -static void load_fw_complete(struct urb *urb) -{ - - struct completion *sent_to_mcu_done = (struct completion *)urb->context; - - complete(sent_to_mcu_done); -} - -static int btmtk_usb_load_fw(struct btmtk_usb_data *data) -{ - struct usb_device *udev = data->udev; - struct urb *urb; - void *buf; - u32 cur_len = 0; - u32 packet_header = 0; - __le32 packet_header_le; - u32 value; - u32 ilm_len = 0, dlm_len = 0; - u16 fw_ver, build_ver; - u32 loop = 0; - dma_addr_t data_dma; - int ret = 0, sent_len; - struct completion sent_to_mcu_done; - unsigned int pipe; - pipe = usb_sndbulkpipe(data->udev, data->bulk_tx_ep->bEndpointAddress); - - if (!data->firmware) { - BT_ERR("%s:please assign a fw\n", __func__); - return -1; - } - - BT_DBG("bulk_tx_ep = %x\n", data->bulk_tx_ep->bEndpointAddress); - -loadfw_protect: - btmtk_usb_switch_iobase(data, WLAN); - btmtk_usb_io_read32(data, SEMAPHORE_00, &value); - loop++; - - if (((value & 0x1) == 0) && (loop < 10000)) - goto loadfw_protect; - - /* check MCU if ready */ - btmtk_usb_io_read32(data, COM_REG0, &value); - - if ((value & 0x01) == 0x01) - goto error0; - - /* Enable MPDMA TX and EP2 load FW mode */ - btmtk_usb_io_write32(data, 0x238, 0x1c000000); - - btmtk_usb_reset(udev); - mdelay(100); - - ilm_len = (*(data->firmware->data + 3) << 24) - | (*(data->firmware->data + 2) << 16) - | (*(data->firmware->data + 1) << 8) - | (*data->firmware->data); - - dlm_len = (*(data->firmware->data + 7) << 24) - | (*(data->firmware->data + 6) << 16) - | (*(data->firmware->data + 5) << 8) - | (*(data->firmware->data + 4)); - - fw_ver = (*(data->firmware->data + 11) << 8) | - (*(data->firmware->data + 10)); - - build_ver = (*(data->firmware->data + 9) << 8) | - (*(data->firmware->data + 8)); - - BT_DBG("fw version:%d.%d.%02d ", - (fw_ver & 0xf000) >> 8, - (fw_ver & 0x0f00) >> 8, - (fw_ver & 0x00ff)); - - BT_DBG("build:%x\n", build_ver); - - BT_DBG("build Time ="); - - for (loop = 0; loop < 16; loop++) - BT_DBG("%c", *(data->firmware->data + 16 + loop)); - - BT_DBG("\n"); - - BT_DBG("ILM length = %d(bytes)\n", ilm_len); - BT_DBG("DLM length = %d(bytes)\n", dlm_len); - - btmtk_usb_switch_iobase(data, SYSCTL); - - /* U2M_PDMA rx_ring_base_ptr */ - btmtk_usb_io_write32(data, 0x790, 0x400230); - - /* U2M_PDMA rx_ring_max_cnt */ - btmtk_usb_io_write32(data, 0x794, 0x1); - - /* U2M_PDMA cpu_idx */ - btmtk_usb_io_write32(data, 0x798, 0x1); - - /* U2M_PDMA enable */ - btmtk_usb_io_write32(data, 0x704, 0x44); - - urb = usb_alloc_urb(0, GFP_ATOMIC); - - if (!urb) { - ret = -ENOMEM; - goto error1; - } - - buf = usb_alloc_coherent(udev, 14592, GFP_ATOMIC, &data_dma); - - if (!buf) { - ret = -ENOMEM; - goto error2; - } - - BT_DBG("loading fw"); - - init_completion(&sent_to_mcu_done); - - btmtk_usb_switch_iobase(data, SYSCTL); - - cur_len = 0x40; - - /* Loading ILM */ - while (1) { - sent_len = min_t(s32, (ilm_len - cur_len), 14336); - - if (sent_len > 0) { - packet_header &= ~(0xffffffff); - packet_header |= (sent_len << 16); - packet_header_le = cpu_to_le32(packet_header); - - memmove(buf, &packet_header_le, 4); - memmove(buf + 4, data->firmware->data + 32 + cur_len, - sent_len); - - /* U2M_PDMA descriptor */ - btmtk_usb_io_write32(data, 0x230, cur_len); - - while ((sent_len % 4) != 0) - sent_len++; - - /* U2M_PDMA length */ - btmtk_usb_io_write32(data, 0x234, sent_len << 16); - - usb_fill_bulk_urb(urb, - udev, - pipe, - buf, - sent_len + 4, - load_fw_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error3; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload ilm fw timeout\n"); - goto error3; - } - - BT_DBG("."); - - mdelay(200); - - cur_len += sent_len; - } else { - break; - } - } - - init_completion(&sent_to_mcu_done); - cur_len = 0x00; - - /* Loading DLM */ - while (1) { - sent_len = min_t(s32, (dlm_len - cur_len), 14336); - - if (sent_len <= 0) - break; - - packet_header &= ~(0xffffffff); - packet_header |= (sent_len << 16); - packet_header_le = cpu_to_le32(packet_header); - - memmove(buf, &packet_header_le, 4); - memmove(buf + 4, - data->firmware->data + 32 + ilm_len + cur_len, - sent_len); - - /* U2M_PDMA descriptor */ - btmtk_usb_io_write32(data, 0x230, 0x80000 + cur_len); - - while ((sent_len % 4) != 0) { - BT_DBG("sent_len is not divided by 4\n"); - sent_len++; - } - - /* U2M_PDMA length */ - btmtk_usb_io_write32(data, 0x234, sent_len << 16); - - usb_fill_bulk_urb(urb, - udev, - pipe, - buf, - sent_len + 4, - load_fw_complete, - &sent_to_mcu_done); - - urb->transfer_dma = data_dma; - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - ret = usb_submit_urb(urb, GFP_ATOMIC); - - if (ret) - goto error3; - - if (!wait_for_completion_timeout(&sent_to_mcu_done, - msecs_to_jiffies(1000))) { - usb_kill_urb(urb); - BT_ERR("upload dlm fw timeout\n"); - goto error3; - } - - BT_DBG("."); - - mdelay(500); - - cur_len += sent_len; - - } - - /* upload 64bytes interrupt vector */ - ret = load_fw_iv(data); - mdelay(100); - - btmtk_usb_switch_iobase(data, WLAN); - - /* check MCU if ready */ - loop = 0; - - do { - btmtk_usb_io_read32(data, COM_REG0, &value); - - if (value == 0x01) - break; - - mdelay(10); - loop++; - } while (loop <= 100); - - if (loop > 1000) { - BT_ERR("wait for 100 times\n"); - ret = -ENODEV; - } - -error3: - usb_free_coherent(udev, 14592, buf, data_dma); -error2: - usb_free_urb(urb); -error1: - /* Disbale load fw mode */ - btmtk_usb_io_read32(data, 0x238, &value); - value = value & ~(0x10000000); - btmtk_usb_io_write32(data, 0x238, value); -error0: - btmtk_usb_io_write32(data, SEMAPHORE_00, 0x1); - return ret; -} - -static int inc_tx(struct btmtk_usb_data *data) -{ - unsigned long flags; - int rv; - - spin_lock_irqsave(&data->txlock, flags); - rv = test_bit(BTUSB_SUSPENDING, &data->flags); - if (!rv) - data->tx_in_flight++; - spin_unlock_irqrestore(&data->txlock, flags); - - return rv; -} - -static void btmtk_usb_intr_complete(struct urb *urb) -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - hdev->stat.byte_rx += urb->actual_length; - - hex_dump("hci event", urb->transfer_buffer, urb->actual_length); - - if (hci_recv_fragment(hdev, HCI_EVENT_PKT, - urb->transfer_buffer, - urb->actual_length) < 0) { - BT_ERR("%s corrupted event packet", hdev->name); - hdev->stat.err_rx++; - } - } - - if (!test_bit(BTUSB_INTR_RUNNING, &data->flags)) - return; - - usb_mark_last_busy(data->udev); - usb_anchor_urb(urb, &data->intr_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static int btmtk_usb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size; - - BT_DBG("%s\n", __func__); - - if (!data->intr_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, mem_flags); - if (!urb) - return -ENOMEM; - - size = le16_to_cpu(data->intr_ep->wMaxPacketSize); - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_intr_complete, hdev, - data->intr_ep->bInterval); - - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_anchor_urb(urb, &data->intr_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; - -} - -static void btmtk_usb_bulk_in_complete(struct urb *urb) -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s:%s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - hdev->stat.byte_rx += urb->actual_length; - - if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, - urb->transfer_buffer, - urb->actual_length) < 0) { - BT_ERR("%s corrupted ACL packet", hdev->name); - hdev->stat.err_rx++; - } - } - - if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) - return; - - usb_anchor_urb(urb, &data->bulk_anchor); - usb_mark_last_busy(data->udev); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static int btmtk_usb_submit_bulk_in_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size = HCI_MAX_FRAME_SIZE; - - BT_DBG("%s:%s\n", __func__, hdev->name); - - if (!data->bulk_rx_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, mem_flags); - if (!urb) - return -ENOMEM; - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress); - - usb_fill_bulk_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_bulk_in_complete, hdev); - - urb->transfer_flags |= URB_FREE_BUFFER; - - usb_mark_last_busy(data->udev); - usb_anchor_urb(urb, &data->bulk_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; -} - -static void btmtk_usb_isoc_in_complete(struct urb *urb) - -{ - struct hci_dev *hdev = urb->context; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int i, err; - - BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return; - - if (urb->status == 0) { - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int offset = urb->iso_frame_desc[i].offset; - unsigned int length; - length = urb->iso_frame_desc[i].actual_length; - - if (urb->iso_frame_desc[i].status) - continue; - - hdev->stat.byte_rx += length; - - if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, - urb->transfer_buffer + offset, - length) < 0) { - BT_ERR("%s corrupted SCO packet", hdev->name); - hdev->stat.err_rx++; - } - } - } - - if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags)) - return; - - usb_anchor_urb(urb, &data->isoc_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - /* -EPERM: urb is being killed; - * -ENODEV: device got disconnected */ - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p failed to resubmit (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } -} - -static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu) -{ - int i, offset = 0; - - BT_DBG("len %d mtu %d", len, mtu); - - for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu; - i++, offset += mtu, len -= mtu) { - urb->iso_frame_desc[i].offset = offset; - urb->iso_frame_desc[i].length = mtu; - } - - if (len && i < BTUSB_MAX_ISOC_FRAMES) { - urb->iso_frame_desc[i].offset = offset; - urb->iso_frame_desc[i].length = len; - i++; - } - - urb->number_of_packets = i; -} - -static int btmtk_usb_submit_isoc_in_urb(struct hci_dev *hdev, gfp_t mem_flags) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct urb *urb; - unsigned char *buf; - unsigned int pipe; - int err, size; - - BT_DBG("%s\n", __func__); - - if (!data->isoc_rx_ep) - return -ENODEV; - - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags); - if (!urb) - return -ENOMEM; - - size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * - BTUSB_MAX_ISOC_FRAMES; - - buf = kmalloc(size, mem_flags); - if (!buf) { - usb_free_urb(urb); - return -ENOMEM; - } - - pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, buf, size, - btmtk_usb_isoc_in_complete, hdev, - data->isoc_rx_ep->bInterval); - - urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; - - __fill_isoc_descriptor(urb, size, - le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); - - usb_anchor_urb(urb, &data->isoc_anchor); - - err = usb_submit_urb(urb, mem_flags); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - usb_unanchor_urb(urb); - } - - usb_free_urb(urb); - - return err; -} - -static int btmtk_usb_open(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s\n", __func__); - - err = usb_autopm_get_interface(data->intf); - if (err < 0) - return err; - - data->intf->needs_remote_wakeup = 1; - - if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)) - goto done; - - err = btmtk_usb_submit_intr_urb(hdev, GFP_KERNEL); - if (err < 0) - goto failed; - - err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL); - if (err < 0) { - usb_kill_anchored_urbs(&data->intr_anchor); - goto failed; - } - - set_bit(BTUSB_BULK_RUNNING, &data->flags); - btmtk_usb_submit_bulk_in_urb(hdev, GFP_KERNEL); - -done: - usb_autopm_put_interface(data->intf); - return 0; - -failed: - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - clear_bit(HCI_RUNNING, &hdev->flags); - usb_autopm_put_interface(data->intf); - return err; -} - -static void btmtk_usb_stop_traffic(struct btmtk_usb_data *data) -{ - BT_DBG("%s\n", __func__); - - usb_kill_anchored_urbs(&data->intr_anchor); - usb_kill_anchored_urbs(&data->bulk_anchor); - usb_kill_anchored_urbs(&data->isoc_anchor); -} - -static int btmtk_usb_close(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - int err; - - BT_DBG("%s\n", __func__); - - if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) - return 0; - - cancel_work_sync(&data->work); - cancel_work_sync(&data->waker); - - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - - btmtk_usb_stop_traffic(data); - - err = usb_autopm_get_interface(data->intf); - if (err < 0) - goto failed; - - data->intf->needs_remote_wakeup = 0; - usb_autopm_put_interface(data->intf); - -failed: - usb_scuttle_anchored_urbs(&data->deferred); - return 0; -} - -static int btmtk_usb_flush(struct hci_dev *hdev) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s\n", __func__); - - usb_kill_anchored_urbs(&data->tx_anchor); - - return 0; -} - -static void btmtk_usb_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct hci_dev *hdev = (struct hci_dev *)skb->dev; - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s: %s urb %p status %d count %d\n", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (!urb->status) - hdev->stat.byte_tx += urb->transfer_buffer_length; - else - hdev->stat.err_tx++; - -done: - spin_lock(&data->txlock); - data->tx_in_flight--; - spin_unlock(&data->txlock); - - kfree(urb->setup_packet); - - kfree_skb(skb); -} - -static void btmtk_usb_isoc_tx_complete(struct urb *urb) -{ - struct sk_buff *skb = urb->context; - struct hci_dev *hdev = (struct hci_dev *) skb->dev; - - BT_DBG("%s: %s urb %p status %d count %d", __func__, hdev->name, - urb, urb->status, urb->actual_length); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (!urb->status) - hdev->stat.byte_tx += urb->transfer_buffer_length; - else - hdev->stat.err_tx++; - -done: - kfree(urb->setup_packet); - - kfree_skb(skb); -} - -static int btmtk_usb_send_frame(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct usb_ctrlrequest *dr; - struct urb *urb; - unsigned int pipe; - int err; - - BT_DBG("%s\n", __func__); - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - return -EBUSY; - - switch (bt_cb(skb)->pkt_type) { - case HCI_COMMAND_PKT: - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - dr = kmalloc(sizeof(*dr), GFP_ATOMIC); - if (!dr) { - usb_free_urb(urb); - return -ENOMEM; - } - - dr->bRequestType = data->cmdreq_type; - dr->bRequest = 0; - dr->wIndex = 0; - dr->wValue = 0; - dr->wLength = __cpu_to_le16(skb->len); - - pipe = usb_sndctrlpipe(data->udev, 0x00); - - if (test_bit(HCI_RUNNING, &hdev->flags)) { - u16 op_code; - memcpy(&op_code, skb->data, 2); - BT_DBG("ogf = %x\n", (op_code & 0xfc00) >> 10); - BT_DBG("ocf = %x\n", op_code & 0x03ff); - hex_dump("hci command", skb->data, skb->len); - - } - - usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, - skb->data, skb->len, - btmtk_usb_tx_complete, skb); - - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - if (!data->bulk_tx_ep) - return -ENODEV; - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - pipe = usb_sndbulkpipe(data->udev, - data->bulk_tx_ep->bEndpointAddress); - - usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, - skb->len, btmtk_usb_tx_complete, skb); - - hdev->stat.acl_tx++; - BT_DBG("HCI_ACLDATA_PKT:\n"); - break; - - case HCI_SCODATA_PKT: - if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) - return -ENODEV; - - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); - if (!urb) - return -ENOMEM; - - pipe = usb_sndisocpipe(data->udev, - data->isoc_tx_ep->bEndpointAddress); - - usb_fill_int_urb(urb, data->udev, pipe, - skb->data, skb->len, btmtk_usb_isoc_tx_complete, - skb, data->isoc_tx_ep->bInterval); - - urb->transfer_flags = URB_ISO_ASAP; - - __fill_isoc_descriptor(urb, skb->len, - le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); - - hdev->stat.sco_tx++; - BT_DBG("HCI_SCODATA_PKT:\n"); - goto skip_waking; - - default: - return -EILSEQ; - } - - err = inc_tx(data); - - if (err) { - usb_anchor_urb(urb, &data->deferred); - schedule_work(&data->waker); - err = 0; - goto done; - } - -skip_waking: - usb_anchor_urb(urb, &data->tx_anchor); - - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - if (err != -EPERM && err != -ENODEV) - BT_ERR("%s urb %p submission failed (%d)", - hdev->name, urb, -err); - kfree(urb->setup_packet); - usb_unanchor_urb(urb); - } else { - usb_mark_last_busy(data->udev); - } - -done: - usb_free_urb(urb); - return err; -} - -static void btmtk_usb_notify(struct hci_dev *hdev, unsigned int evt) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - - BT_DBG("%s evt %d", hdev->name, evt); - - if (hdev->conn_hash.sco_num != data->sco_num) { - data->sco_num = hdev->conn_hash.sco_num; - schedule_work(&data->work); - } -} - -static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting) -{ - struct btmtk_usb_data *data = hci_get_drvdata(hdev); - struct usb_interface *intf = data->isoc; - struct usb_endpoint_descriptor *ep_desc; - int i, err; - - if (!data->isoc) - return -ENODEV; - - err = usb_set_interface(data->udev, 1, altsetting); - if (err < 0) { - BT_ERR("%s setting interface failed (%d)", hdev->name, -err); - return err; - } - - data->isoc_altsetting = altsetting; - - data->isoc_tx_ep = NULL; - data->isoc_rx_ep = NULL; - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { - ep_desc = &intf->cur_altsetting->endpoint[i].desc; - - if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) { - data->isoc_tx_ep = ep_desc; - continue; - } - - if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) { - data->isoc_rx_ep = ep_desc; - continue; - } - } - - if (!data->isoc_tx_ep || !data->isoc_rx_ep) { - BT_ERR("%s invalid SCO descriptors", hdev->name); - return -ENODEV; - } - - return 0; -} - -static void btmtk_usb_work(struct work_struct *work) -{ - struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, - work); - struct hci_dev *hdev = data->hdev; - int new_alts; - int err; - - BT_DBG("%s\n", __func__); - - if (hdev->conn_hash.sco_num > 0) { - if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { - err = usb_autopm_get_interface(data->isoc ? - data->isoc : data->intf); - if (err < 0) { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - return; - } - - set_bit(BTUSB_DID_ISO_RESUME, &data->flags); - } - - if (hdev->voice_setting & 0x0020) { - static const int alts[3] = { 2, 4, 5 }; - new_alts = alts[hdev->conn_hash.sco_num - 1]; - } else { - new_alts = hdev->conn_hash.sco_num; - } - - if (data->isoc_altsetting != new_alts) { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - - if (__set_isoc_interface(hdev, new_alts) < 0) - return; - } - - if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL) < 0) - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - else - btmtk_usb_submit_isoc_in_urb(hdev, GFP_KERNEL); - } - } else { - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->isoc_anchor); - - __set_isoc_interface(hdev, 0); - - if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) - usb_autopm_put_interface(data->isoc ? - data->isoc : data->intf); - } -} - -static void btmtk_usb_waker(struct work_struct *work) -{ - struct btmtk_usb_data *data = container_of(work, struct btmtk_usb_data, - waker); - int err; - - err = usb_autopm_get_interface(data->intf); - - if (err < 0) - return; - - usb_autopm_put_interface(data->intf); -} - -static int btmtk_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct btmtk_usb_data *data; - struct usb_endpoint_descriptor *ep_desc; - int i, err; - struct hci_dev *hdev; - - /* interface numbers are hardcoded in the spec */ - if (intf->cur_altsetting->desc.bInterfaceNumber != 0) - return -ENODEV; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - - if (!data) - return -ENOMEM; - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { - ep_desc = &intf->cur_altsetting->endpoint[i].desc; - - if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) { - data->intr_ep = ep_desc; - continue; - } - - if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) { - data->bulk_tx_ep = ep_desc; - continue; - } - - if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) { - data->bulk_rx_ep = ep_desc; - continue; - } - } - - if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { - kfree(data); - return -ENODEV; - } - - data->cmdreq_type = USB_TYPE_CLASS; - - data->udev = interface_to_usbdev(intf); - data->intf = intf; - - spin_lock_init(&data->lock); - INIT_WORK(&data->work, btmtk_usb_work); - INIT_WORK(&data->waker, btmtk_usb_waker); - spin_lock_init(&data->txlock); - - init_usb_anchor(&data->tx_anchor); - init_usb_anchor(&data->intr_anchor); - init_usb_anchor(&data->bulk_anchor); - init_usb_anchor(&data->isoc_anchor); - init_usb_anchor(&data->deferred); - - hdev = hci_alloc_dev(); - if (!hdev) { - kfree(data); - return -ENOMEM; - } - - hdev->bus = HCI_USB; - - hci_set_drvdata(hdev, data); - - data->hdev = hdev; - - SET_HCIDEV_DEV(hdev, &intf->dev); - - hdev->open = btmtk_usb_open; - hdev->close = btmtk_usb_close; - hdev->flush = btmtk_usb_flush; - hdev->send = btmtk_usb_send_frame; - hdev->notify = btmtk_usb_notify; - - /* Interface numbers are hardcoded in the specification */ - data->isoc = usb_ifnum_to_if(data->udev, 1); - - if (data->isoc) { - err = usb_driver_claim_interface(&btmtk_usb_driver, - data->isoc, data); - if (err < 0) { - hci_free_dev(hdev); - kfree(data); - return err; - } - } - - data->io_buf = kmalloc(256, GFP_KERNEL); - if (!data->io_buf) { - hci_free_dev(hdev); - kfree(data); - return -ENOMEM; - } - - btmtk_usb_switch_iobase(data, WLAN); - - btmtk_usb_cap_init(data); - - err = hci_register_dev(hdev); - if (err < 0) { - hci_free_dev(hdev); - kfree(data); - return err; - } - - usb_set_intfdata(intf, data); - - return 0; -} - -static void btmtk_usb_disconnect(struct usb_interface *intf) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - struct hci_dev *hdev; - - BT_DBG("%s\n", __func__); - - if (!data) - return; - - hdev = data->hdev; - usb_set_intfdata(data->intf, NULL); - - if (data->isoc) - usb_set_intfdata(data->isoc, NULL); - - hci_unregister_dev(hdev); - - if (intf == data->isoc) - usb_driver_release_interface(&btmtk_usb_driver, data->intf); - else if (data->isoc) - usb_driver_release_interface(&btmtk_usb_driver, data->isoc); - - hci_free_dev(hdev); - - kfree(data->io_buf); - - kfree(data); -} - -#ifdef CONFIG_PM -static int btmtk_usb_suspend(struct usb_interface *intf, pm_message_t message) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - - BT_DBG("%s\n", __func__); - - if (data->suspend_count++) - return 0; - - spin_lock_irq(&data->txlock); - if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) { - set_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - } else { - spin_unlock_irq(&data->txlock); - data->suspend_count--; - return -EBUSY; - } - - cancel_work_sync(&data->work); - - btmtk_usb_stop_traffic(data); - usb_kill_anchored_urbs(&data->tx_anchor); - - return 0; -} - -static void play_deferred(struct btmtk_usb_data *data) -{ - struct urb *urb; - int err; - - while ((urb = usb_get_from_anchor(&data->deferred))) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) - break; - - data->tx_in_flight++; - } - - usb_scuttle_anchored_urbs(&data->deferred); -} - -static int btmtk_usb_resume(struct usb_interface *intf) -{ - struct btmtk_usb_data *data = usb_get_intfdata(intf); - struct hci_dev *hdev = data->hdev; - int err = 0; - - BT_DBG("%s\n", __func__); - - if (--data->suspend_count) - return 0; - - if (!test_bit(HCI_RUNNING, &hdev->flags)) - goto done; - - if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) { - err = btmtk_usb_submit_intr_urb(hdev, GFP_NOIO); - if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - goto failed; - } - } - - if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { - err = btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO); - if (err < 0) { - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - goto failed; - } - - btmtk_usb_submit_bulk_in_urb(hdev, GFP_NOIO); - } - - if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - if (btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO) < 0) - clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - else - btmtk_usb_submit_isoc_in_urb(hdev, GFP_NOIO); - } - - spin_lock_irq(&data->txlock); - play_deferred(data); - clear_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - schedule_work(&data->work); - - return 0; - -failed: - usb_scuttle_anchored_urbs(&data->deferred); -done: - spin_lock_irq(&data->txlock); - clear_bit(BTUSB_SUSPENDING, &data->flags); - spin_unlock_irq(&data->txlock); - - return err; -} -#endif - -static struct usb_device_id btmtk_usb_table[] = { - /* Mediatek MT7650 */ - { USB_DEVICE(0x0e8d, 0x7650) }, - { USB_DEVICE(0x0e8d, 0x7630) }, - { USB_DEVICE(0x0e8d, 0x763e) }, - /* Mediatek MT662 */ - { USB_DEVICE(0x0e8d, 0x7662) }, - { USB_DEVICE(0x0e8d, 0x7632) }, - { } /* Terminating entry */ -}; - -static struct usb_driver btmtk_usb_driver = { - .name = "btmtk_usb", - .probe = btmtk_usb_probe, - .disconnect = btmtk_usb_disconnect, -#ifdef CONFIG_PM - .suspend = btmtk_usb_suspend, - .resume = btmtk_usb_resume, -#endif - .id_table = btmtk_usb_table, - .supports_autosuspend = 1, - .disable_hub_initiated_lpm = 1, -}; - -module_usb_driver(btmtk_usb_driver); - -MODULE_DESCRIPTION("Mediatek Bluetooth USB driver ver " VERSION); -MODULE_VERSION(VERSION); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE(MT7650_FIRMWARE); -MODULE_FIRMWARE(MT7662_FIRMWARE); diff --git a/drivers/staging/btmtk_usb/btmtk_usb.h b/drivers/staging/btmtk_usb/btmtk_usb.h deleted file mode 100644 index 12f0d3b27bfe..000000000000 --- a/drivers/staging/btmtk_usb/btmtk_usb.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * MediaTek Bluetooth USB Driver - * - * Copyright (C) 2013, MediaTek co. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * or on the worldwide web at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. - * - */ - -#ifndef __BTMTK_USB_H__ -#define __BTMTK_USB_H_ - -/* Memory map for MTK BT */ - -/* SYS Control */ -#define SYSCTL 0x400000 - -/* WLAN */ -#define WLAN 0x410000 - -/* MCUCTL */ -#define INT_LEVEL 0x0718 -#define COM_REG0 0x0730 -#define SEMAPHORE_00 0x07B0 -#define SEMAPHORE_01 0x07B4 -#define SEMAPHORE_02 0x07B8 -#define SEMAPHORE_03 0x07BC - -/* Chip definition */ - -#define CONTROL_TIMEOUT_JIFFIES ((300 * HZ) / 100) -#define DEVICE_VENDOR_REQUEST_OUT 0x40 -#define DEVICE_VENDOR_REQUEST_IN 0xc0 -#define DEVICE_CLASS_REQUEST_OUT 0x20 - -#define BTUSB_MAX_ISOC_FRAMES 10 -#define BTUSB_INTR_RUNNING 0 -#define BTUSB_BULK_RUNNING 1 -#define BTUSB_ISOC_RUNNING 2 -#define BTUSB_SUSPENDING 3 -#define BTUSB_DID_ISO_RESUME 4 - -/* ROM Patch */ -#define PATCH_HCI_HEADER_SIZE 4 -#define PATCH_WMT_HEADER_SIZE 5 -#define PATCH_HEADER_SIZE (PATCH_HCI_HEADER_SIZE + PATCH_WMT_HEADER_SIZE) -#define UPLOAD_PATCH_UNIT 2048 -#define PATCH_INFO_SIZE 30 -#define PATCH_PHASE1 1 -#define PATCH_PHASE2 2 -#define PATCH_PHASE3 3 - -struct btmtk_usb_data { - struct hci_dev *hdev; - struct usb_device *udev; - struct usb_interface *intf; - struct usb_interface *isoc; - - spinlock_t lock; - - unsigned long flags; - struct work_struct work; - struct work_struct waker; - - struct usb_anchor tx_anchor; - struct usb_anchor intr_anchor; - struct usb_anchor bulk_anchor; - struct usb_anchor isoc_anchor; - struct usb_anchor deferred; - int tx_in_flight; - spinlock_t txlock; - - struct usb_endpoint_descriptor *intr_ep; - struct usb_endpoint_descriptor *bulk_tx_ep; - struct usb_endpoint_descriptor *bulk_rx_ep; - struct usb_endpoint_descriptor *isoc_tx_ep; - struct usb_endpoint_descriptor *isoc_rx_ep; - - __u8 cmdreq_type; - - unsigned int sco_num; - int isoc_altsetting; - int suspend_count; - - /* request for different io operation */ - u8 w_request; - u8 r_request; - - /* io buffer for usb control transfer */ - char *io_buf; - - struct semaphore fw_upload_sem; - - /* unsigned char *fw_image; */ - /* unsigned char *rom_patch; */ - const struct firmware *firmware; - u32 chip_id; - u8 need_load_fw; - u8 need_load_rom_patch; - u32 rom_patch_offset; - u32 rom_patch_len; -}; - -static inline int is_mt7630(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76300000); -} - -static inline int is_mt7650(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76500000); -} - -static inline int is_mt7632(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76320000); -} - -static inline int is_mt7662(struct btmtk_usb_data *data) -{ - return ((data->chip_id & 0xffff0000) == 0x76620000); -} - -#endif diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 62efd74b8c04..bf532b1bd345 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -19,7 +19,6 @@ */ #include #include -#include #include #include #include @@ -630,7 +629,7 @@ int ClearArea(DEVICE_EXTENSION *pdx, int nArea) } spin_unlock_irq(&pdx->stagedLock); - if (pPages) { /* if we decided to release the memory */ + if (pPages) { /* if we decided to release the memory */ /* Now we must undo the pinning down of the pages. We will assume the worst and mark */ /* all the pages as dirty. Don't be tempted to move this up above as you must not be */ /* holding a spin lock to do this stuff as it is not atomic. */ diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 97c55f9e5151..efc310ca789e 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -89,7 +89,6 @@ synchronous non-Urb based transfers. #include #include #include -#include #include #include #include diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index bfa27e7fc016..89e25b4203ad 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -884,6 +884,12 @@ config COMEDI_GSC_HPDI To compile this driver as a module, choose M here: the module will be called gsc_hpdi. +config COMEDI_MF6X4 + tristate "Humusoft MF634 and MF624 DAQ Card support" + ---help--- + This driver supports both Humusoft MF634 and MF624 Data acquisition + cards. The legacy Humusoft MF614 card is not supported. + config COMEDI_ICP_MULTI tristate "Inova ICP_MULTI support" ---help--- diff --git a/drivers/staging/comedi/Makefile b/drivers/staging/comedi/Makefile index e6dfc98f8c8e..fae2d9090006 100644 --- a/drivers/staging/comedi/Makefile +++ b/drivers/staging/comedi/Makefile @@ -1,3 +1,5 @@ +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG + comedi-y := comedi_fops.o range.o drivers.o \ comedi_buf.o comedi-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_pci.o diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 4e26bd7fc84f..924fce977985 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -16,6 +16,7 @@ */ #include +#include #include "comedidev.h" #include "comedi_internal.h" @@ -26,31 +27,21 @@ #define COMEDI_PAGE_PROTECTION PAGE_KERNEL #endif -static void __comedi_buf_free(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned n_pages) +static void comedi_buf_map_kref_release(struct kref *kref) { - struct comedi_async *async = s->async; + struct comedi_buf_map *bm = + container_of(kref, struct comedi_buf_map, refcount); struct comedi_buf_page *buf; - unsigned i; + unsigned int i; - if (async->prealloc_buf) { - vunmap(async->prealloc_buf); - async->prealloc_buf = NULL; - async->prealloc_bufsz = 0; - } - - if (!async->buf_page_list) - return; - - for (i = 0; i < n_pages; ++i) { - buf = &async->buf_page_list[i]; - if (buf->virt_addr) { + if (bm->page_list) { + for (i = 0; i < bm->n_pages; i++) { + buf = &bm->page_list[i]; clear_bit(PG_reserved, &(virt_to_page(buf->virt_addr)->flags)); - if (s->async_dma_dir != DMA_NONE) { + if (bm->dma_dir != DMA_NONE) { #ifdef CONFIG_HAS_DMA - dma_free_coherent(dev->hw_dev, + dma_free_coherent(bm->dma_hw_dev, PAGE_SIZE, buf->virt_addr, buf->dma_addr); @@ -59,10 +50,26 @@ static void __comedi_buf_free(struct comedi_device *dev, free_page((unsigned long)buf->virt_addr); } } + vfree(bm->page_list); } - vfree(async->buf_page_list); - async->buf_page_list = NULL; - async->n_buf_pages = 0; + if (bm->dma_dir != DMA_NONE) + put_device(bm->dma_hw_dev); + kfree(bm); +} + +static void __comedi_buf_free(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct comedi_async *async = s->async; + + if (async->prealloc_buf) { + vunmap(async->prealloc_buf); + async->prealloc_buf = NULL; + async->prealloc_bufsz = 0; + } + + comedi_buf_map_put(async->buf_map); + async->buf_map = NULL; } static void __comedi_buf_alloc(struct comedi_device *dev, @@ -71,6 +78,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, { struct comedi_async *async = s->async; struct page **pages = NULL; + struct comedi_buf_map *bm; struct comedi_buf_page *buf; unsigned i; @@ -80,18 +88,29 @@ static void __comedi_buf_alloc(struct comedi_device *dev, return; } - async->buf_page_list = vzalloc(sizeof(*buf) * n_pages); - if (async->buf_page_list) + bm = kzalloc(sizeof(*async->buf_map), GFP_KERNEL); + if (!bm) + return; + + async->buf_map = bm; + kref_init(&bm->refcount); + bm->dma_dir = s->async_dma_dir; + if (bm->dma_dir != DMA_NONE) + /* Need ref to hardware device to free buffer later. */ + bm->dma_hw_dev = get_device(dev->hw_dev); + + bm->page_list = vzalloc(sizeof(*buf) * n_pages); + if (bm->page_list) pages = vmalloc(sizeof(struct page *) * n_pages); if (!pages) return; for (i = 0; i < n_pages; i++) { - buf = &async->buf_page_list[i]; - if (s->async_dma_dir != DMA_NONE) + buf = &bm->page_list[i]; + if (bm->dma_dir != DMA_NONE) #ifdef CONFIG_HAS_DMA - buf->virt_addr = dma_alloc_coherent(dev->hw_dev, + buf->virt_addr = dma_alloc_coherent(bm->dma_hw_dev, PAGE_SIZE, &buf->dma_addr, GFP_KERNEL | @@ -108,6 +127,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, pages[i] = virt_to_page(buf->virt_addr); } + bm->n_pages = i; /* vmap the prealloc_buf if all the pages were allocated */ if (i == n_pages) @@ -117,6 +137,26 @@ static void __comedi_buf_alloc(struct comedi_device *dev, vfree(pages); } +void comedi_buf_map_get(struct comedi_buf_map *bm) +{ + if (bm) + kref_get(&bm->refcount); +} + +int comedi_buf_map_put(struct comedi_buf_map *bm) +{ + if (bm) + return kref_put(&bm->refcount, comedi_buf_map_kref_release); + return 1; +} + +bool comedi_buf_is_mmapped(struct comedi_async *async) +{ + struct comedi_buf_map *bm = async->buf_map; + + return bm && (atomic_read(&bm->refcount.refcount) > 1); +} + int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { @@ -130,7 +170,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, return 0; /* deallocate old buffer */ - __comedi_buf_free(dev, s, async->n_buf_pages); + __comedi_buf_free(dev, s); /* allocate new buffer */ if (new_size) { @@ -140,10 +180,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, if (!async->prealloc_buf) { /* allocation failed */ - __comedi_buf_free(dev, s, n_pages); + __comedi_buf_free(dev, s); return -ENOMEM; } - async->n_buf_pages = n_pages; } async->prealloc_bufsz = new_size; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f3d59e2a1152..c22c617b0da1 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -16,8 +16,6 @@ GNU General Public License for more details. */ -#undef DEBUG - #include "comedi_compat32.h" #include @@ -47,15 +45,6 @@ #define COMEDI_NUM_SUBDEVICE_MINORS \ (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS) -#ifdef CONFIG_COMEDI_DEBUG -int comedi_debug; -EXPORT_SYMBOL_GPL(comedi_debug); -module_param(comedi_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(comedi_debug, - "enable comedi core and driver debugging if non-zero (default 0)" - ); -#endif - static int comedi_num_legacy_minors; module_param(comedi_num_legacy_minors, int, S_IRUGO); MODULE_PARM_DESC(comedi_num_legacy_minors, @@ -89,11 +78,38 @@ static struct cdev comedi_cdev; static void comedi_device_init(struct comedi_device *dev) { + kref_init(&dev->refcount); spin_lock_init(&dev->spinlock); mutex_init(&dev->mutex); + init_rwsem(&dev->attach_lock); dev->minor = -1; } +static void comedi_dev_kref_release(struct kref *kref) +{ + struct comedi_device *dev = + container_of(kref, struct comedi_device, refcount); + + mutex_destroy(&dev->mutex); + put_device(dev->class_dev); + kfree(dev); +} + +int comedi_dev_put(struct comedi_device *dev) +{ + if (dev) + return kref_put(&dev->refcount, comedi_dev_kref_release); + return 1; +} +EXPORT_SYMBOL_GPL(comedi_dev_put); + +static struct comedi_device *comedi_dev_get(struct comedi_device *dev) +{ + if (dev) + kref_get(&dev->refcount); + return dev; +} + static void comedi_device_cleanup(struct comedi_device *dev) { struct module *driver_module = NULL; @@ -104,14 +120,9 @@ static void comedi_device_cleanup(struct comedi_device *dev) if (dev->attached) driver_module = dev->driver->module; comedi_device_detach(dev); - while (dev->use_count > 0) { - if (driver_module) - module_put(driver_module); - module_put(THIS_MODULE); - dev->use_count--; - } + if (driver_module && dev->use_count) + module_put(driver_module); mutex_unlock(&dev->mutex); - mutex_destroy(&dev->mutex); } static bool comedi_clear_board_dev(struct comedi_device *dev) @@ -142,17 +153,17 @@ static struct comedi_device *comedi_clear_board_minor(unsigned minor) static void comedi_free_board_dev(struct comedi_device *dev) { if (dev) { + comedi_device_cleanup(dev); if (dev->class_dev) { device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, dev->minor)); } - comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); } } static struct comedi_subdevice -*comedi_subdevice_from_minor(unsigned minor) +*comedi_subdevice_from_minor(const struct comedi_device *dev, unsigned minor) { struct comedi_subdevice *s; unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; @@ -160,37 +171,45 @@ static struct comedi_subdevice BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS); mutex_lock(&comedi_subdevice_minor_table_lock); s = comedi_subdevice_minor_table[i]; + if (s && s->device != dev) + s = NULL; mutex_unlock(&comedi_subdevice_minor_table_lock); return s; } -static struct comedi_device *comedi_dev_from_board_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor) { struct comedi_device *dev; BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); mutex_lock(&comedi_board_minor_table_lock); - dev = comedi_board_minor_table[minor]; + dev = comedi_dev_get(comedi_board_minor_table[minor]); mutex_unlock(&comedi_board_minor_table_lock); return dev; } -static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor) +static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor) { + struct comedi_device *dev; struct comedi_subdevice *s; + unsigned int i = minor - COMEDI_NUM_BOARD_MINORS; - s = comedi_subdevice_from_minor(minor); - return s ? s->device : NULL; + BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS); + mutex_lock(&comedi_subdevice_minor_table_lock); + s = comedi_subdevice_minor_table[i]; + dev = comedi_dev_get(s ? s->device : NULL); + mutex_unlock(&comedi_subdevice_minor_table_lock); + return dev; } -struct comedi_device *comedi_dev_from_minor(unsigned minor) +struct comedi_device *comedi_dev_get_from_minor(unsigned minor) { if (minor < COMEDI_NUM_BOARD_MINORS) - return comedi_dev_from_board_minor(minor); + return comedi_dev_get_from_board_minor(minor); else - return comedi_dev_from_subdevice_minor(minor); + return comedi_dev_get_from_subdevice_minor(minor); } -EXPORT_SYMBOL_GPL(comedi_dev_from_minor); +EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor); static struct comedi_subdevice * comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) @@ -198,10 +217,8 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_READ) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_READ)) return s; } return dev->read_subdev; @@ -213,10 +230,8 @@ comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) struct comedi_subdevice *s; if (minor >= COMEDI_NUM_BOARD_MINORS) { - s = comedi_subdevice_from_minor(minor); - if (!s || s->device != dev) - return NULL; - if (s->subdev_flags & SDF_CMD_WRITE) + s = comedi_subdevice_from_minor(dev, minor); + if (s == NULL || (s->subdev_flags & SDF_CMD_WRITE)) return s; } return dev->write_subdev; @@ -232,11 +247,13 @@ static int resize_async_buffer(struct comedi_device *dev, return -EPERM; if (s->busy) { - DPRINTK("subdevice is busy, cannot resize buffer\n"); + dev_dbg(dev->class_dev, + "subdevice is busy, cannot resize buffer\n"); return -EBUSY; } - if (async->mmap_count) { - DPRINTK("subdevice is mmapped, cannot resize buffer\n"); + if (comedi_buf_is_mmapped(async)) { + dev_dbg(dev->class_dev, + "subdevice is mmapped, cannot resize buffer\n"); return -EBUSY; } @@ -254,8 +271,8 @@ static int resize_async_buffer(struct comedi_device *dev, return retval; } - DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", - dev->minor, s->index, async->prealloc_bufsz); + dev_dbg(dev->class_dev, "subd %d buffer resized to %i bytes\n", + s->index, async->prealloc_bufsz); return 0; } @@ -269,7 +286,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -279,6 +296,7 @@ static ssize_t max_read_buffer_kb_show(struct device *csdev, size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -299,7 +317,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -311,6 +329,7 @@ static ssize_t max_read_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(max_read_buffer_kb); @@ -323,7 +342,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -333,6 +352,7 @@ static ssize_t read_buffer_kb_show(struct device *csdev, size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -353,7 +373,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -365,6 +385,7 @@ static ssize_t read_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(read_buffer_kb); @@ -378,7 +399,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -388,6 +409,7 @@ static ssize_t max_write_buffer_kb_show(struct device *csdev, size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -408,7 +430,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -420,6 +442,7 @@ static ssize_t max_write_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(max_write_buffer_kb); @@ -432,7 +455,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev, struct comedi_subdevice *s; unsigned int size = 0; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -442,6 +465,7 @@ static ssize_t write_buffer_kb_show(struct device *csdev, size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return snprintf(buf, PAGE_SIZE, "%i\n", size); } @@ -462,7 +486,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev, return -EINVAL; size *= 1024; - dev = comedi_dev_from_minor(minor); + dev = comedi_dev_get_from_minor(minor); if (!dev) return -ENODEV; @@ -474,6 +498,7 @@ static ssize_t write_buffer_kb_store(struct device *csdev, err = -EINVAL; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return err ? err : count; } static DEVICE_ATTR_RW(write_buffer_kb); @@ -562,12 +587,13 @@ static void do_become_nonbusy(struct comedi_device *dev, async->inttrig = NULL; kfree(async->cmd.chanlist); async->cmd.chanlist = NULL; + s->busy = NULL; + wake_up_interruptible_all(&s->async->wait_head); } else { dev_err(dev->class_dev, "BUG: (?) do_become_nonbusy called with async=NULL\n"); + s->busy = NULL; } - - s->busy = NULL; } static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) @@ -582,6 +608,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } +void comedi_device_cancel_all(struct comedi_device *dev) +{ + struct comedi_subdevice *s; + int i; + + if (!dev->attached) + return; + + for (i = 0; i < dev->n_subdevices; i++) { + s = &dev->subdevices[i]; + if (s->async) + do_cancel(dev, s); + } +} + static int is_device_busy(struct comedi_device *dev) { struct comedi_subdevice *s; @@ -594,7 +635,7 @@ static int is_device_busy(struct comedi_device *dev) s = &dev->subdevices[i]; if (s->busy) return 1; - if (s->async && s->async->mmap_count) + if (s->async && comedi_buf_is_mmapped(s->async)) return 1; } @@ -684,7 +725,8 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, async = s->async; if (!async) { - DPRINTK("subdevice does not have async capability\n"); + dev_dbg(dev->class_dev, + "subdevice does not have async capability\n"); bc.size = 0; bc.maximum_size = 0; goto copyback; @@ -931,7 +973,8 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, async = s->async; if (!async) { - DPRINTK("subdevice does not have async capability\n"); + dev_dbg(dev->class_dev, + "subdevice does not have async capability\n"); bi.buf_write_ptr = 0; bi.buf_read_ptr = 0; bi.buf_write_count = 0; @@ -1083,19 +1126,20 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, break; } if (insn->subdev >= dev->n_subdevices) { - DPRINTK("%d not usable subdevice\n", + dev_dbg(dev->class_dev, + "%d not usable subdevice\n", insn->subdev); ret = -EINVAL; break; } s = &dev->subdevices[insn->subdev]; if (!s->async) { - DPRINTK("no async\n"); + dev_dbg(dev->class_dev, "no async\n"); ret = -EINVAL; break; } if (!s->async->inttrig) { - DPRINTK("no inttrig\n"); + dev_dbg(dev->class_dev, "no inttrig\n"); ret = -EAGAIN; break; } @@ -1104,7 +1148,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = 1; break; default: - DPRINTK("invalid insn\n"); + dev_dbg(dev->class_dev, "invalid insn\n"); ret = -EINVAL; break; } @@ -1113,21 +1157,23 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int maxdata; if (insn->subdev >= dev->n_subdevices) { - DPRINTK("subdevice %d out of range\n", insn->subdev); + dev_dbg(dev->class_dev, "subdevice %d out of range\n", + insn->subdev); ret = -EINVAL; goto out; } s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not usable subdevice\n", insn->subdev); + dev_dbg(dev->class_dev, "%d not usable subdevice\n", + insn->subdev); ret = -EIO; goto out; } /* are we locked? (ioctl lock) */ if (s->lock && s->lock != file) { - DPRINTK("device locked\n"); + dev_dbg(dev->class_dev, "device locked\n"); ret = -EACCES; goto out; } @@ -1135,7 +1181,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { ret = -EINVAL; - DPRINTK("bad chanspec\n"); + dev_dbg(dev->class_dev, "bad chanspec\n"); goto out; } @@ -1156,7 +1202,8 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, for (i = 0; i < insn->n; ++i) { if (data[i] > maxdata) { ret = -EINVAL; - DPRINTK("bad data value(s)\n"); + dev_dbg(dev->class_dev, + "bad data value(s)\n"); break; } } @@ -1238,35 +1285,35 @@ static int do_insnlist_ioctl(struct comedi_device *dev, data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL); if (!data) { - DPRINTK("kmalloc failed\n"); ret = -ENOMEM; goto error; } insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL); if (!insns) { - DPRINTK("kmalloc failed\n"); ret = -ENOMEM; goto error; } if (copy_from_user(insns, insnlist.insns, sizeof(*insns) * insnlist.n_insns)) { - DPRINTK("copy_from_user failed\n"); + dev_dbg(dev->class_dev, "copy_from_user failed\n"); ret = -EFAULT; goto error; } for (i = 0; i < insnlist.n_insns; i++) { if (insns[i].n > MAX_SAMPLES) { - DPRINTK("number of samples too large\n"); + dev_dbg(dev->class_dev, + "number of samples too large\n"); ret = -EINVAL; goto error; } if (insns[i].insn & INSN_MASK_WRITE) { if (copy_from_user(data, insns[i].data, insns[i].n * sizeof(unsigned int))) { - DPRINTK("copy_from_user failed\n"); + dev_dbg(dev->class_dev, + "copy_from_user failed\n"); ret = -EFAULT; goto error; } @@ -1277,7 +1324,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev, if (insns[i].insn & INSN_MASK_READ) { if (copy_to_user(insns[i].data, data, insns[i].n * sizeof(unsigned int))) { - DPRINTK("copy_to_user failed\n"); + dev_dbg(dev->class_dev, + "copy_to_user failed\n"); ret = -EFAULT; goto error; } @@ -1367,14 +1415,14 @@ static int do_cmd_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev); return -ENODEV; } @@ -1382,38 +1430,38 @@ static int do_cmd_ioctl(struct comedi_device *dev, async = s->async; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest || !s->async) { - DPRINTK("subdevice %i does not support commands\n", - cmd.subdev); + dev_dbg(dev->class_dev, + "subdevice %i does not support commands\n", cmd.subdev); return -EIO; } /* are we locked? (ioctl lock) */ if (s->lock && s->lock != file) { - DPRINTK("subdevice locked\n"); + dev_dbg(dev->class_dev, "subdevice locked\n"); return -EACCES; } /* are we busy? */ if (s->busy) { - DPRINTK("subdevice busy\n"); + dev_dbg(dev->class_dev, "subdevice busy\n"); return -EBUSY; } /* make sure channel/gain list isn't too long */ if (cmd.chanlist_len > s->len_chanlist) { - DPRINTK("channel/gain list too long %u > %d\n", + dev_dbg(dev->class_dev, "channel/gain list too long %u > %d\n", cmd.chanlist_len, s->len_chanlist); return -EINVAL; } /* make sure channel/gain list isn't too short */ if (cmd.chanlist_len < 1) { - DPRINTK("channel/gain list too short %u < 1\n", + dev_dbg(dev->class_dev, "channel/gain list too short %u < 1\n", cmd.chanlist_len); return -EINVAL; } @@ -1425,7 +1473,9 @@ static int do_cmd_ioctl(struct comedi_device *dev, async->cmd.chanlist_len * sizeof(int)); if (IS_ERR(async->cmd.chanlist)) { ret = PTR_ERR(async->cmd.chanlist); - DPRINTK("memdup_user failed with code %d\n", ret); + async->cmd.chanlist = NULL; + dev_dbg(dev->class_dev, "memdup_user failed with code %d\n", + ret); goto cleanup; } @@ -1434,20 +1484,20 @@ static int do_cmd_ioctl(struct comedi_device *dev, async->cmd.chanlist_len, async->cmd.chanlist); if (ret < 0) { - DPRINTK("bad chanlist\n"); + dev_dbg(dev->class_dev, "bad chanlist\n"); goto cleanup; } ret = s->do_cmdtest(dev, s, &async->cmd); if (async->cmd.flags & TRIG_BOGUS || ret) { - DPRINTK("test returned %d\n", ret); + dev_dbg(dev->class_dev, "test returned %d\n", ret); cmd = async->cmd; /* restore chanlist pointer before copying back */ cmd.chanlist = (unsigned int __force *)user_chanlist; cmd.data = NULL; if (copy_to_user(arg, &cmd, sizeof(cmd))) { - DPRINTK("fault writing cmd\n"); + dev_dbg(dev->class_dev, "fault writing cmd\n"); ret = -EFAULT; goto cleanup; } @@ -1457,7 +1507,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (!async->prealloc_bufsz) { ret = -ENOMEM; - DPRINTK("no buffer (?)\n"); + dev_dbg(dev->class_dev, "no buffer (?)\n"); goto cleanup; } @@ -1469,8 +1519,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (async->cmd.flags & TRIG_WAKE_EOS) async->cb_mask |= COMEDI_CB_EOS; - comedi_set_subdevice_runflags(s, SRF_USER | SRF_ERROR | SRF_RUNNING, - SRF_USER | SRF_RUNNING); + comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING); /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with * comedi_read() or comedi_write() */ @@ -1510,32 +1559,32 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, unsigned int __user *user_chanlist; if (copy_from_user(&cmd, arg, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ user_chanlist = (unsigned int __user *)cmd.chanlist; if (cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d no such subdevice\n", cmd.subdev); return -ENODEV; } s = &dev->subdevices[cmd.subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", cmd.subdev); + dev_dbg(dev->class_dev, "%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest) { - DPRINTK("subdevice %i does not support commands\n", - cmd.subdev); + dev_dbg(dev->class_dev, + "subdevice %i does not support commands\n", cmd.subdev); return -EIO; } /* make sure channel/gain list isn't too long */ if (cmd.chanlist_len > s->len_chanlist) { - DPRINTK("channel/gain list too long %d > %d\n", + dev_dbg(dev->class_dev, "channel/gain list too long %d > %d\n", cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; @@ -1547,14 +1596,16 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, cmd.chanlist_len * sizeof(int)); if (IS_ERR(chanlist)) { ret = PTR_ERR(chanlist); - DPRINTK("memdup_user exited with code %d", ret); + chanlist = NULL; + dev_dbg(dev->class_dev, + "memdup_user exited with code %d", ret); goto cleanup; } /* make sure each element in channel/gain list is valid */ ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist); if (ret < 0) { - DPRINTK("bad chanlist\n"); + dev_dbg(dev->class_dev, "bad chanlist\n"); goto cleanup; } @@ -1567,7 +1618,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, cmd.chanlist = (unsigned int __force *)user_chanlist; if (copy_to_user(arg, &cmd, sizeof(cmd))) { - DPRINTK("bad cmd address\n"); + dev_dbg(dev->class_dev, "bad cmd address\n"); ret = -EFAULT; goto cleanup; } @@ -1700,8 +1751,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, return -EBUSY; ret = do_cancel(dev, s); - if (comedi_get_subdevice_runflags(s) & SRF_USER) - wake_up_interruptible(&s->async->wait_head); return ret; } @@ -1748,12 +1797,9 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; int rc; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); /* Device config is special, because it must work on @@ -1782,7 +1828,7 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, } if (!dev->attached) { - DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); rc = -ENODEV; goto done; } @@ -1852,28 +1898,18 @@ done: static void comedi_vm_open(struct vm_area_struct *area) { - struct comedi_async *async; - struct comedi_device *dev; + struct comedi_buf_map *bm; - async = area->vm_private_data; - dev = async->subdevice->device; - - mutex_lock(&dev->mutex); - async->mmap_count++; - mutex_unlock(&dev->mutex); + bm = area->vm_private_data; + comedi_buf_map_get(bm); } static void comedi_vm_close(struct vm_area_struct *area) { - struct comedi_async *async; - struct comedi_device *dev; + struct comedi_buf_map *bm; - async = area->vm_private_data; - dev = async->subdevice->device; - - mutex_lock(&dev->mutex); - async->mmap_count--; - mutex_unlock(&dev->mutex); + bm = area->vm_private_data; + comedi_buf_map_put(bm); } static struct vm_operations_struct comedi_vm_ops = { @@ -1884,22 +1920,20 @@ static struct vm_operations_struct comedi_vm_ops = { static int comedi_mmap(struct file *file, struct vm_area_struct *vma) { const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; struct comedi_async *async; + struct comedi_buf_map *bm; unsigned long start = vma->vm_start; unsigned long size; int n_pages; int i; int retval; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); retval = -ENODEV; goto done; } @@ -1920,7 +1954,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } if (vma->vm_pgoff != 0) { - DPRINTK("comedi: mmap() offset must be 0.\n"); + dev_dbg(dev->class_dev, "mmap() offset must be 0.\n"); retval = -EINVAL; goto done; } @@ -1936,8 +1970,13 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } n_pages = size >> PAGE_SHIFT; + bm = async->buf_map; + if (!bm || n_pages > bm->n_pages) { + retval = -EINVAL; + goto done; + } for (i = 0; i < n_pages; ++i) { - struct comedi_buf_page *buf = &async->buf_page_list[i]; + struct comedi_buf_page *buf = &bm->page_list[i]; if (remap_pfn_range(vma, start, page_to_pfn(virt_to_page(buf->virt_addr)), @@ -1949,9 +1988,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } vma->vm_ops = &comedi_vm_ops; - vma->vm_private_data = async; + vma->vm_private_data = bm; - async->mmap_count++; + vma->vm_ops->open(vma); retval = 0; done: @@ -1963,16 +2002,13 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) { unsigned int mask = 0; const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); + dev_dbg(dev->class_dev, "no driver attached\n"); goto done; } @@ -2008,39 +2044,75 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; + bool on_wait_queue = false; + bool attach_locked; + unsigned int old_detach_count; - if (!dev) - return -ENODEV; + /* Protect against device detachment during operation. */ + down_read(&dev->attach_lock); + attach_locked = true; + old_detach_count = dev->detach_count; if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); - return -ENODEV; + dev_dbg(dev->class_dev, "no driver attached\n"); + retval = -ENODEV; + goto out; } s = comedi_write_subdevice(dev, minor); - if (!s || !s->async) - return -EIO; + if (!s || !s->async) { + retval = -EIO; + goto out; + } async = s->async; if (!s->busy || !nbytes) - return 0; - if (s->busy != file) - return -EACCES; + goto out; + if (s->busy != file) { + retval = -EACCES; + goto out; + } add_wait_queue(&async->wait_head, &wait); + on_wait_queue = true; while (nbytes > 0 && !retval) { set_current_state(TASK_INTERRUPTIBLE); if (!comedi_is_subdevice_running(s)) { if (count == 0) { - mutex_lock(&dev->mutex); + struct comedi_subdevice *new_s; + if (comedi_is_subdevice_in_error(s)) retval = -EPIPE; else retval = 0; - do_become_nonbusy(dev, s); + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. Need to + * remove task from the async wait queue before + * releasing dev->attach_lock, as it might not + * be valid afterwards. + */ + remove_wait_queue(&async->wait_head, &wait); + on_wait_queue = false; + up_read(&dev->attach_lock); + attach_locked = false; + mutex_lock(&dev->mutex); + /* + * Become non-busy unless things have changed + * behind our back. Checking dev->detach_count + * is unchanged ought to be sufficient (unless + * there have been 2**32 detaches in the + * meantime!), but check the subdevice pointer + * as well just in case. + */ + new_s = comedi_write_subdevice(dev, minor); + if (dev->attached && + old_detach_count == dev->detach_count && + s == new_s && new_s->async == async) + do_become_nonbusy(dev, s); mutex_unlock(&dev->mutex); } break; @@ -2090,8 +2162,12 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, buf += n; break; /* makes device work like a pipe */ } +out: + if (on_wait_queue) + remove_wait_queue(&async->wait_head, &wait); set_current_state(TASK_RUNNING); - remove_wait_queue(&async->wait_head, &wait); + if (attach_locked) + up_read(&dev->attach_lock); return count ? count : retval; } @@ -2104,25 +2180,35 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, int n, m, count = 0, retval = 0; DECLARE_WAITQUEUE(wait, current); const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; + unsigned int old_detach_count; + bool become_nonbusy = false; + bool attach_locked; - if (!dev) - return -ENODEV; + /* Protect against device detachment during operation. */ + down_read(&dev->attach_lock); + attach_locked = true; + old_detach_count = dev->detach_count; if (!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", dev->minor); - return -ENODEV; + dev_dbg(dev->class_dev, "no driver attached\n"); + retval = -ENODEV; + goto out; } s = comedi_read_subdevice(dev, minor); - if (!s || !s->async) - return -EIO; + if (!s || !s->async) { + retval = -EIO; + goto out; + } async = s->async; if (!s->busy || !nbytes) - return 0; - if (s->busy != file) - return -EACCES; + goto out; + if (s->busy != file) { + retval = -EACCES; + goto out; + } add_wait_queue(&async->wait_head, &wait); while (nbytes > 0 && !retval) { @@ -2140,13 +2226,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, if (n == 0) { if (!comedi_is_subdevice_running(s)) { - mutex_lock(&dev->mutex); - do_become_nonbusy(dev, s); if (comedi_is_subdevice_in_error(s)) retval = -EPIPE; else retval = 0; - mutex_unlock(&dev->mutex); + become_nonbusy = true; break; } if (file->f_flags & O_NONBLOCK) { @@ -2184,14 +2268,37 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, buf += n; break; /* makes device work like a pipe */ } - if (comedi_is_subdevice_idle(s)) { + remove_wait_queue(&async->wait_head, &wait); + set_current_state(TASK_RUNNING); + if (become_nonbusy || comedi_is_subdevice_idle(s)) { + struct comedi_subdevice *new_s; + + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. + */ + up_read(&dev->attach_lock); + attach_locked = false; mutex_lock(&dev->mutex); - if (async->buf_read_count - async->buf_write_count == 0) - do_become_nonbusy(dev, s); + /* + * Check device hasn't become detached behind our back. + * Checking dev->detach_count is unchanged ought to be + * sufficient (unless there have been 2**32 detaches in the + * meantime!), but check the subdevice pointer as well just in + * case. + */ + new_s = comedi_read_subdevice(dev, minor); + if (dev->attached && old_detach_count == dev->detach_count && + s == new_s && new_s->async == async) { + if (become_nonbusy || + async->buf_read_count - async->buf_write_count == 0) + do_become_nonbusy(dev, s); + } mutex_unlock(&dev->mutex); } - set_current_state(TASK_RUNNING); - remove_wait_queue(&async->wait_head, &wait); +out: + if (attach_locked) + up_read(&dev->attach_lock); return count ? count : retval; } @@ -2199,10 +2306,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, static int comedi_open(struct inode *inode, struct file *file) { const unsigned minor = iminor(inode); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = comedi_dev_get_from_minor(minor); + int rc; if (!dev) { - DPRINTK("invalid minor number\n"); + pr_debug("invalid minor number\n"); return -ENODEV; } @@ -2223,9 +2331,9 @@ static int comedi_open(struct inode *inode, struct file *file) if (dev->attached) goto ok; if (!capable(CAP_NET_ADMIN) && dev->in_request_module) { - DPRINTK("in request module\n"); - mutex_unlock(&dev->mutex); - return -ENODEV; + dev_dbg(dev->class_dev, "in request module\n"); + rc = -ENODEV; + goto out; } if (capable(CAP_NET_ADMIN) && dev->in_request_module) goto ok; @@ -2241,59 +2349,49 @@ static int comedi_open(struct inode *inode, struct file *file) dev->in_request_module = false; if (!dev->attached && !capable(CAP_NET_ADMIN)) { - DPRINTK("not attached and not CAP_NET_ADMIN\n"); - mutex_unlock(&dev->mutex); - return -ENODEV; + dev_dbg(dev->class_dev, "not attached and not CAP_NET_ADMIN\n"); + rc = -ENODEV; + goto out; } ok: - __module_get(THIS_MODULE); - - if (dev->attached) { + if (dev->attached && dev->use_count == 0) { if (!try_module_get(dev->driver->module)) { - module_put(THIS_MODULE); - mutex_unlock(&dev->mutex); - return -ENOSYS; + rc = -ENOSYS; + goto out; } - } - - if (dev->attached && dev->use_count == 0 && dev->open) { - int rc = dev->open(dev); - if (rc < 0) { - module_put(dev->driver->module); - module_put(THIS_MODULE); - mutex_unlock(&dev->mutex); - return rc; + if (dev->open) { + rc = dev->open(dev); + if (rc < 0) { + module_put(dev->driver->module); + goto out; + } } } dev->use_count++; + file->private_data = dev; + rc = 0; +out: mutex_unlock(&dev->mutex); - - return 0; + if (rc) + comedi_dev_put(dev); + return rc; } static int comedi_fasync(int fd, struct file *file, int on) { - const unsigned minor = iminor(file_inode(file)); - struct comedi_device *dev = comedi_dev_from_minor(minor); - - if (!dev) - return -ENODEV; + struct comedi_device *dev = file->private_data; return fasync_helper(fd, file, on, &dev->async_queue); } static int comedi_close(struct inode *inode, struct file *file) { - const unsigned minor = iminor(inode); - struct comedi_device *dev = comedi_dev_from_minor(minor); + struct comedi_device *dev = file->private_data; struct comedi_subdevice *s = NULL; int i; - if (!dev) - return -ENODEV; - mutex_lock(&dev->mutex); if (dev->subdevices) { @@ -2306,16 +2404,16 @@ static int comedi_close(struct inode *inode, struct file *file) s->lock = NULL; } } - if (dev->attached && dev->use_count == 1 && dev->close) - dev->close(dev); - - module_put(THIS_MODULE); - if (dev->attached) + if (dev->attached && dev->use_count == 1) { + if (dev->close) + dev->close(dev); module_put(dev->driver->module); + } dev->use_count--; mutex_unlock(&dev->mutex); + comedi_dev_put(dev); return 0; } @@ -2346,8 +2444,6 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) unsigned runflags = 0; unsigned runflags_mask = 0; - /* DPRINTK("comedi_event 0x%x\n",mask); */ - if (!comedi_is_subdevice_running(s)) return; @@ -2368,16 +2464,11 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) } if (async->cb_mask & s->async->events) { - if (comedi_get_subdevice_runflags(s) & SRF_USER) { - wake_up_interruptible(&async->wait_head); - if (s->subdev_flags & SDF_CMD_READ) - kill_fasync(&dev->async_queue, SIGIO, POLL_IN); - if (s->subdev_flags & SDF_CMD_WRITE) - kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); - } else { - if (async->cb_func) - async->cb_func(s->async->events, async->cb_arg); - } + wake_up_interruptible(&async->wait_head); + if (s->subdev_flags & SDF_CMD_READ) + kill_fasync(&dev->async_queue, SIGIO, POLL_IN); + if (s->subdev_flags & SDF_CMD_WRITE) + kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); } s->async->events = 0; } @@ -2408,7 +2499,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) if (i == COMEDI_NUM_BOARD_MINORS) { mutex_unlock(&dev->mutex); comedi_device_cleanup(dev); - kfree(dev); + comedi_dev_put(dev); pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return ERR_PTR(-EBUSY); } @@ -2416,7 +2507,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) csdev = device_create(comedi_class, hardware_device, MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i); if (!IS_ERR(csdev)) - dev->class_dev = csdev; + dev->class_dev = get_device(csdev); /* Note: dev->mutex needs to be unlocked by the caller. */ return dev; diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index fda1a7ba0e16..9a746570f161 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -16,7 +16,11 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size); void comedi_buf_reset(struct comedi_async *async); +bool comedi_buf_is_mmapped(struct comedi_async *async); +void comedi_buf_map_get(struct comedi_buf_map *bm); +int comedi_buf_map_put(struct comedi_buf_map *bm); unsigned int comedi_buf_write_n_allocated(struct comedi_async *async); +void comedi_device_cancel_all(struct comedi_device *dev); extern unsigned int comedi_default_buf_size_kb; extern unsigned int comedi_default_buf_maxsize_kb; diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 143be8076a2e..f82bd4256d51 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -20,14 +20,13 @@ #define _COMEDIDEV_H #include +#include +#include +#include +#include #include "comedi.h" -#define DPRINTK(format, args...) do { \ - if (comedi_debug) \ - pr_debug("comedi: " format, ## args); \ -} while (0) - #define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) #define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, \ COMEDI_MINORVERSION, COMEDI_MICROVERSION) @@ -100,18 +99,22 @@ struct comedi_buf_page { dma_addr_t dma_addr; }; +struct comedi_buf_map { + struct device *dma_hw_dev; + struct comedi_buf_page *page_list; + unsigned int n_pages; + enum dma_data_direction dma_dir; + struct kref refcount; +}; + struct comedi_async { struct comedi_subdevice *subdevice; void *prealloc_buf; /* pre-allocated buffer */ unsigned int prealloc_bufsz; /* buffer size, in bytes */ - /* virtual and dma address of each page */ - struct comedi_buf_page *buf_page_list; - unsigned n_buf_pages; /* num elements in buf_page_list */ + struct comedi_buf_map *buf_map; /* map of buffer pages */ unsigned int max_bufsize; /* maximum buffer size, bytes */ - /* current number of mmaps of prealloc_buf */ - unsigned int mmap_count; /* byte count for writer (write completed) */ unsigned int buf_write_count; @@ -141,10 +144,7 @@ struct comedi_async { wait_queue_head_t wait_head; - /* callback stuff */ unsigned int cb_mask; - int (*cb_func) (unsigned int flags, void *); - void *cb_arg; int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x); @@ -173,6 +173,7 @@ struct comedi_device { struct device *class_dev; int minor; + unsigned int detach_count; /* hw_dev is passed to dma_alloc_coherent when allocating async buffers * for subdevices that have async_dma_dir set to something other than * DMA_NONE */ @@ -185,6 +186,8 @@ struct comedi_device { bool ioenabled:1; spinlock_t spinlock; struct mutex mutex; + struct rw_semaphore attach_lock; + struct kref refcount; int n_subdevices; struct comedi_subdevice *subdevices; @@ -208,12 +211,6 @@ static inline const void *comedi_board(const struct comedi_device *dev) return dev->board_ptr; } -#ifdef CONFIG_COMEDI_DEBUG -extern int comedi_debug; -#else -static const int comedi_debug; -#endif - /* * function prototypes */ @@ -231,7 +228,8 @@ enum comedi_minor_bits { static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4; static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; -struct comedi_device *comedi_dev_from_minor(unsigned minor); +struct comedi_device *comedi_dev_get_from_minor(unsigned minor); +int comedi_dev_put(struct comedi_device *dev); void init_polling(void); void cleanup_polling(void); @@ -240,7 +238,6 @@ void stop_polling(struct comedi_device *); /* subdevice runflags */ enum subdevice_runflags { - SRF_USER = 0x00000001, SRF_RT = 0x00000002, /* indicates an COMEDI_CB_ERROR event has occurred since the last * command was started */ @@ -410,6 +407,7 @@ void comedi_driver_unregister(struct comedi_driver *); #define PCI_VENDOR_ID_IOTECH 0x1616 #define PCI_VENDOR_ID_CONTEC 0x1221 #define PCI_VENDOR_ID_RTD 0x1435 +#define PCI_VENDOR_ID_HUMUSOFT 0x186c struct pci_dev; struct pci_driver; diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 4964d2a2fc7d..246080316c90 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -95,7 +95,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) } EXPORT_SYMBOL_GPL(comedi_alloc_subdevices); -static void cleanup_device(struct comedi_device *dev) +static void comedi_device_detach_cleanup(struct comedi_device *dev) { int i; struct comedi_subdevice *s; @@ -133,10 +133,14 @@ static void cleanup_device(struct comedi_device *dev) void comedi_device_detach(struct comedi_device *dev) { + comedi_device_cancel_all(dev); + down_write(&dev->attach_lock); dev->attached = false; + dev->detach_count++; if (dev->driver) dev->driver->detach(dev); - cleanup_device(dev); + comedi_device_detach_cleanup(dev); + up_write(&dev->attach_lock); } static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s) @@ -355,8 +359,9 @@ static int comedi_device_postconfig(struct comedi_device *dev) ret = __comedi_device_postconfig(dev); if (ret < 0) return ret; - smp_wmb(); + down_write(&dev->attach_lock); dev->attached = true; + up_write(&dev->attach_lock); return 0; } @@ -598,8 +603,12 @@ int comedi_auto_config(struct device *hardware_device, } dev = comedi_alloc_board_minor(hardware_device); - if (IS_ERR(dev)) + if (IS_ERR(dev)) { + dev_warn(hardware_device, + "driver '%s' could not create device.\n", + driver->driver_name); return PTR_ERR(dev); + } /* Note: comedi_alloc_board_minor() locked dev->mutex. */ dev->driver = driver; @@ -611,8 +620,20 @@ int comedi_auto_config(struct device *hardware_device, comedi_device_detach(dev); mutex_unlock(&dev->mutex); - if (ret < 0) + if (ret < 0) { + dev_warn(hardware_device, + "driver '%s' failed to auto-configure device.\n", + driver->driver_name); comedi_release_hardware_device(hardware_device); + } else { + /* + * class_dev should be set properly here + * after a successful auto config + */ + dev_info(dev->class_dev, + "driver '%s' has successfully auto-configured '%s'.\n", + driver->driver_name, dev->board_name); + } return ret; } EXPORT_SYMBOL_GPL(comedi_auto_config); @@ -657,7 +678,7 @@ void comedi_driver_unregister(struct comedi_driver *driver) /* check for devices using this driver */ for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { - struct comedi_device *dev = comedi_dev_from_minor(i); + struct comedi_device *dev = comedi_dev_get_from_minor(i); if (!dev) continue; @@ -671,6 +692,7 @@ void comedi_driver_unregister(struct comedi_driver *driver) comedi_device_detach(dev); } mutex_unlock(&dev->mutex); + comedi_dev_put(dev); } } EXPORT_SYMBOL_GPL(comedi_driver_unregister); diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index b4009e863414..48817f087d97 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -94,7 +94,7 @@ I/O port base address can be found in the output of 'lspci -v'. struct subdev_8255_private { unsigned long iobase; - int (*io) (int, int, int, unsigned long); + int (*io)(int, int, int, unsigned long); }; static int subdev_8255_io(int dir, int port, int data, unsigned long iobase) @@ -262,7 +262,7 @@ static int subdev_8255_cancel(struct comedi_device *dev, } int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io) (int, int, int, unsigned long), + int (*io)(int, int, int, unsigned long), unsigned long iobase) { struct subdev_8255_private *spriv; @@ -289,7 +289,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, EXPORT_SYMBOL_GPL(subdev_8255_init); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io) (int, int, int, unsigned long), + int (*io)(int, int, int, unsigned long), unsigned long iobase) { int ret; diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index c55f234b29e6..8a57c3c1ade0 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -263,7 +263,7 @@ static int pci_8255_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &pci_8255_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(pci_8255_pci_table) = { +static const struct pci_device_id pci_8255_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x7224), BOARD_ADLINK_PCI7224 }, { PCI_VDEVICE(ADLINK, 0x7248), BOARD_ADLINK_PCI7248 }, { PCI_VDEVICE(ADLINK, 0x7296), BOARD_ADLINK_PCI7296 }, diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 94cbd2618fc8..2706f583d8f0 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -1,5 +1,6 @@ # Makefile for individual comedi drivers # +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG # Comedi "helper" modules @@ -110,6 +111,7 @@ obj-$(CONFIG_COMEDI_NI_PCIMIO) += ni_pcimio.o obj-$(CONFIG_COMEDI_RTD520) += rtd520.o obj-$(CONFIG_COMEDI_S626) += s626.o obj-$(CONFIG_COMEDI_SSV_DNP) += ssv_dnp.o +obj-$(CONFIG_COMEDI_MF6X4) += mf6x4.o # Comedi PCMCIA drivers obj-$(CONFIG_COMEDI_CB_DAS16_CS) += cb_das16_cs.o diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 3c9eec84f0eb..bd05857b82f2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -1414,7 +1414,7 @@ static void v_APCI3120_InterruptDma(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int next_dma_buf, samplesinbuf; unsigned long low_word, high_word, var; unsigned int ui_Tmp; @@ -1568,8 +1568,8 @@ static void v_APCI3120_InterruptDma(int irq, void *d) static int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; int n_chan, i; - struct comedi_subdevice *s = &dev->subdevices[0]; int err = 1; n_chan = devpriv->ui_AiNbrofChannels; @@ -1593,11 +1593,11 @@ static void v_APCI3120_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; unsigned short int_daq; unsigned int int_amcc, ui_Check, i; unsigned short us_TmpValue; unsigned char b_DummyRead; - struct comedi_subdevice *s = &dev->subdevices[0]; ui_Check = 1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index dc73d4d348ed..8c85a09d1c66 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -2590,8 +2590,8 @@ static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; unsigned int ui_StatusRegister = 0; - struct comedi_subdevice *s = &dev->subdevices[0]; /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ /* comedi_async *async = s->async; */ diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 8d229b2f0973..ccd49211ea17 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -58,7 +58,7 @@ static int apci035_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci035_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = { +static const struct pci_device_id apci035_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 34ab0679e992..0daa0ea63b5e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -325,8 +325,8 @@ static int apci1032_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (dev->irq) { dev->read_subdev = s; - s->type = COMEDI_SUBD_DI | SDF_CMD_READ; - s->subdev_flags = SDF_READABLE; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = 1; s->maxdata = 1; s->range_table = &range_digital; @@ -364,7 +364,7 @@ static int apci1032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1032_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = { +static const struct pci_device_id apci1032_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index ae9ded63dcec..74f7ace8adbc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -57,7 +57,7 @@ static int apci1500_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = { +static const struct pci_device_id apci1500_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 9d1b1425c60b..e9c5291c77cd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -206,7 +206,7 @@ static int apci1516_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1516_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { +static const struct pci_device_id apci1516_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x1000), BOARD_APCI1016 }, { PCI_VDEVICE(ADDIDATA, 0x1001), BOARD_APCI1516 }, { PCI_VDEVICE(ADDIDATA, 0x1002), BOARD_APCI2016 }, diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index c5717d63e16a..6248284caaf5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -55,7 +55,7 @@ static int apci1564_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1564_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = { +static const struct pci_device_id apci1564_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 5ee204bcbeef..28df4b50b87a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -168,7 +168,7 @@ static int apci16xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci16xx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { +static const struct pci_device_id apci16xx_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x1009), BOARD_APCI1648 }, { PCI_VDEVICE(ADDIDATA, 0x100a), BOARD_APCI1696 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index c77ee8732d38..c9b933cb5987 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -359,7 +359,7 @@ static int apci2032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2032_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { +static const struct pci_device_id apci2032_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 7fb32e778d8b..e1a916546d18 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -134,7 +134,7 @@ static int apci2200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2200_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = { +static const struct pci_device_id apci2200_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 67d09e8afb2e..1e6fa56c516e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -230,7 +230,7 @@ static int apci3120_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { +static const struct pci_device_id apci3120_pci_table[] = { { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 }, { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 1213d5aa6bea..9868a5369aff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -109,7 +109,7 @@ static int apci3200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3200_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { +static const struct pci_device_id apci3200_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x3000), BOARD_APCI3200 }, { PCI_VDEVICE(ADDIDATA, 0x3007), BOARD_APCI3300 }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 6138440b919e..4cb69ec54c9b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -428,7 +428,7 @@ static int apci3501_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3501_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { +static const struct pci_device_id apci3501_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 761cbf8f964b..ceadf8eff47f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -915,7 +915,7 @@ static int apci3xxx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { +static const struct pci_device_id apci3xxx_pci_table[] = { { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 }, { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 }, { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 }, diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index dd092c7954a9..5c1413abc52d 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -242,7 +242,7 @@ static int adl_pci6208_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci6208_pci_table) = { +static const struct pci_device_id adl_pci6208_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x6208), BOARD_PCI6208 }, { PCI_VDEVICE(ADLINK, 0x6216), BOARD_PCI6216 }, { 0 } diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 5617f5ca384a..6f622b4de698 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -259,7 +259,7 @@ static int adl_pci7x3x_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci7x3x_pci_table) = { +static const struct pci_device_id adl_pci7x3x_pci_table[] = { { PCI_VDEVICE(ADLINK, 0x7230), BOARD_PCI7230 }, { PCI_VDEVICE(ADLINK, 0x7233), BOARD_PCI7233 }, { PCI_VDEVICE(ADLINK, 0x7234), BOARD_PCI7234 }, diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index b3d009285ed4..300df55a2802 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -145,7 +145,7 @@ static int adl_pci8164_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = { +static const struct pci_device_id adl_pci8164_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index eab8da2c3d66..363f2e42a27f 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -125,8 +125,7 @@ TODO: PLX9052_INTCSR_LI2STAT) static const struct comedi_lrange pci9111_ai_range = { - 5, - { + 5, { BIP_RANGE(10), BIP_RANGE(5), BIP_RANGE(2.5), @@ -470,11 +469,6 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct pci9111_private_data *dev_private = dev->private; struct comedi_cmd *async_cmd = &s->async->cmd; - if (!dev->irq) { - comedi_error(dev, - "no irq assigned for PCI9111, cannot do hardware conversion"); - return -1; - } /* Set channel scan limit */ /* PCI9111 allows only scanning from channel 0 to channel n */ /* TODO: handle the case of an external multiplexer */ @@ -858,12 +852,11 @@ static int pci9111_auto_attach(struct comedi_device *dev, pci9111_reset(dev); - if (pcidev->irq > 0) { - ret = request_irq(dev->irq, pci9111_interrupt, + if (pcidev->irq) { + ret = request_irq(pcidev->irq, pci9111_interrupt, IRQF_SHARED, dev->board_name, dev); - if (ret) - return ret; - dev->irq = pcidev->irq; + if (ret == 0) + dev->irq = pcidev->irq; } ret = comedi_alloc_subdevices(dev, 4); @@ -871,18 +864,21 @@ static int pci9111_auto_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_COMMON; s->n_chan = 16; s->maxdata = 0xffff; - s->len_chanlist = 16; s->range_table = &pci9111_ai_range; - s->cancel = pci9111_ai_cancel; s->insn_read = pci9111_ai_insn_read; - s->do_cmdtest = pci9111_ai_do_cmd_test; - s->do_cmd = pci9111_ai_do_cmd; - s->munge = pci9111_ai_munge; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmdtest = pci9111_ai_do_cmd_test; + s->do_cmd = pci9111_ai_do_cmd; + s->cancel = pci9111_ai_cancel; + s->munge = pci9111_ai_munge; + } s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -938,7 +934,7 @@ static int pci9111_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = { +static const struct pci_device_id pci9111_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID) }, /* { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID) }, */ { 0 } diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 986489641ed7..4bdd9720e9eb 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -194,28 +194,30 @@ Configuration options: #define EXTTRG_AI 0 /* ext trg is used by AI */ -static const struct comedi_lrange range_pci9118dg_hr = { 8, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } +static const struct comedi_lrange range_pci9118dg_hr = { + 8, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; -static const struct comedi_lrange range_pci9118hg = { 8, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01) - } +static const struct comedi_lrange range_pci9118hg = { + 8, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.005), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01) + } }; #define PCI9118_BIPOLAR_RANGES 4 /* @@ -1126,7 +1128,7 @@ static irqreturn_t interrupt_pci9118(int irq, void *d) } } - (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat, + (devpriv->int_ai_func) (dev, dev->read_subdev, int_adstat, int_amcc, int_daq); } @@ -1965,7 +1967,6 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret, pages, i; - unsigned int irq; u16 u16w; dev->board_name = this_board->name; @@ -2036,12 +2037,18 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ + if (!disable_irq && pcidev->irq) { + ret = request_irq(pcidev->irq, interrupt_pci9118, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; if (devpriv->usemux) @@ -2050,11 +2057,17 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, s->n_chan = this_board->n_aichan; s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->n_aichanlist; s->range_table = this_board->rangelist_ai; - s->cancel = pci9118_ai_cancel; s->insn_read = pci9118_insn_read_ai; - s->munge = pci9118_ai_munge; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = this_board->n_aichanlist; + s->do_cmdtest = pci9118_ai_cmdtest; + s->do_cmd = pci9118_ai_cmd; + s->cancel = pci9118_ai_cancel; + s->munge = pci9118_ai_munge; + } s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -2100,27 +2113,7 @@ static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, break; } - if (disable_irq) - irq = 0; - else - irq = pcidev->irq; - if (irq > 0) { - if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - dev->board_name, dev)) { - dev_warn(dev->class_dev, - "unable to allocate IRQ %u, DISABLING IT\n", - irq); - } else { - dev->irq = irq; - /* Enable AI commands */ - s = &dev->subdevices[0]; - s->subdev_flags |= SDF_CMD_READ; - s->do_cmdtest = pci9118_ai_cmdtest; - s->do_cmd = pci9118_ai_cmd; - } - } - - pci9118_report_attach(dev, irq); + pci9118_report_attach(dev, dev->irq); return 0; } @@ -2217,7 +2210,7 @@ static int adl_pci9118_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = { +static const struct pci_device_id adl_pci9118_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 8150a67cd1fb..3190ef7d285e 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -97,21 +97,22 @@ If you do not specify any options, they will default to #define TIMEOUT 20 /* available ranges through the PGA gains */ -static const struct comedi_lrange range_adq12b_ai_bipolar = { 4, { - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - BIP_RANGE(0.5) - } +static const struct comedi_lrange range_adq12b_ai_bipolar = { + 4, { + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + BIP_RANGE(0.5) + } }; -static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, { - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1), - UNI_RANGE - (0.5) - } +static const struct comedi_lrange range_adq12b_ai_unipolar = { + 4, { + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5) + } }; struct adq12b_private { @@ -162,8 +163,6 @@ static int adq12b_ai_rinsn(struct comedi_device *dev, hi = inb(dev->iobase + ADQ12B_ADHIG); lo = inb(dev->iobase + ADQ12B_ADLOW); - /* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", - channel, range, status, hi, lo); */ data[n] = (hi << 8) | lo; } diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index c3fdcabe9aec..593676cf706a 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -115,65 +115,70 @@ Configuration options: /* D/A synchronized control (PCI1720_SYNCONT) */ #define Syncont_SC0 1 /* set synchronous output mode */ -static const struct comedi_lrange range_pci1710_3 = { 9, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - BIP_RANGE(10), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } +static const struct comedi_lrange range_pci1710_3 = { + 9, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + BIP_RANGE(10), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; static const char range_codes_pci1710_3[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 }; -static const struct comedi_lrange range_pci1710hg = { 12, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - BIP_RANGE(10), - BIP_RANGE(1), - BIP_RANGE(0.1), - BIP_RANGE(0.01), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01) - } +static const struct comedi_lrange range_pci1710hg = { + 12, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.005), + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.01), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01) + } }; static const char range_codes_pci1710hg[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13 }; -static const struct comedi_lrange range_pci17x1 = { 5, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625) - } +static const struct comedi_lrange range_pci17x1 = { + 5, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 }; -static const struct comedi_lrange range_pci1720 = { 4, { - UNI_RANGE(5), - UNI_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(10) - } +static const struct comedi_lrange range_pci1720 = { + 4, { + UNI_RANGE(5), + UNI_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(10) + } }; -static const struct comedi_lrange range_pci171x_da = { 2, { - UNI_RANGE(5), - UNI_RANGE(10), - } +static const struct comedi_lrange range_pci171x_da = { + 2, { + UNI_RANGE(5), + UNI_RANGE(10) + } }; enum pci1710_boardid { @@ -731,7 +736,7 @@ static void interrupt_pci1710_every_sample(void *d) { struct comedi_device *dev = d; struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int m; #ifdef PCI171x_PARANOIDCHECK const struct boardtype *this_board = comedi_board(dev); @@ -740,16 +745,15 @@ static void interrupt_pci1710_every_sample(void *d) m = inw(dev->iobase + PCI171x_STATUS); if (m & Status_FE) { - printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m); + dev_dbg(dev->class_dev, "A/D FIFO empty (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); return; } if (m & Status_FF) { - printk - ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, + "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -825,12 +829,12 @@ static int move_block_from_fifo(struct comedi_device *dev, sampl = inw(dev->iobase + PCI171x_AD_DATA); if (this_board->cardtype != TYPE_PCI1713) if ((sampl & 0xf000) != devpriv->act_chanlist[j]) { - printk - ("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n", - dev->minor, (sampl & 0xf000) >> 12, - (devpriv->act_chanlist[j] & 0xf000) >> 12, - i, j, devpriv->ai_act_scan, n, turn, - sampl); + dev_dbg(dev->class_dev, + "A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n", + (sampl & 0xf000) >> 12, + (devpriv->act_chanlist[j] & 0xf000) >> 12, + i, j, devpriv->ai_act_scan, n, turn, + sampl); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; @@ -860,22 +864,20 @@ static void interrupt_pci1710_half_fifo(void *d) struct comedi_device *dev = d; const struct boardtype *this_board = comedi_board(dev); struct pci1710_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int m, samplesinbuf; m = inw(dev->iobase + PCI171x_STATUS); if (!(m & Status_FH)) { - printk("comedi%d: A/D FIFO not half full! (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, "A/D FIFO not half full! (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); return; } if (m & Status_FF) { - printk - ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n", - dev->minor, m); + dev_dbg(dev->class_dev, + "A/D FIFO Full status (Fatal Error!) (%4x)\n", m); pci171x_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -1267,21 +1269,21 @@ static int pci1710_auto_attach(struct comedi_device *dev, if (this_board->n_aichan) { s = &dev->subdevices[subdev]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; if (this_board->n_aichand) s->subdev_flags |= SDF_DIFF; s->n_chan = this_board->n_aichan; s->maxdata = this_board->ai_maxdata; - s->len_chanlist = this_board->n_aichan; s->range_table = this_board->rangelist_ai; - s->cancel = pci171x_ai_cancel; s->insn_read = pci171x_insn_read_ai; if (dev->irq) { + dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; s->do_cmdtest = pci171x_ai_cmdtest; s->do_cmd = pci171x_ai_cmd; + s->cancel = pci171x_ai_cancel; } devpriv->i8254_osc_base = I8254_OSC_BASE_10MHZ; subdev++; @@ -1374,7 +1376,7 @@ static int adv_pci1710_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1710_pci_table) = { +static const struct pci_device_id adv_pci1710_pci_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index bd4f781b4b24..72394267ddfe 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -306,7 +306,7 @@ static int adv_pci1723_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1723_pci_table) = { +static const struct pci_device_id adv_pci1723_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1723) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index 009a3039fc4f..af670acb03d8 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -116,8 +116,8 @@ enum board_id_contents { BOARD_ID_MASK = 0xf }; -static const struct comedi_lrange ao_ranges_1724 = { 4, - { +static const struct comedi_lrange ao_ranges_1724 = { + 4, { BIP_RANGE(10), RANGE_mA(0, 20), RANGE_mA(4, 20), @@ -381,7 +381,7 @@ static int adv_pci1724_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci1724_pci_table) = { +static const struct pci_device_id adv_pci1724_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ADVANTECH, 0x1724) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 6bac665261f8..d4bd61d84daf 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1188,7 +1188,7 @@ static int adv_pci_dio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adv_pci_dio_driver, cardtype); } -static DEFINE_PCI_DEVICE_TABLE(adv_pci_dio_pci_table) = { +static const struct pci_device_id adv_pci_dio_pci_table[] = { { PCI_VDEVICE(ADVANTECH, 0x1730), TYPE_PCI1730 }, { PCI_VDEVICE(ADVANTECH, 0x1733), TYPE_PCI1733 }, { PCI_VDEVICE(ADVANTECH, 0x1734), TYPE_PCI1734 }, diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index abb28498b58c..68c3fb3226ca 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -181,13 +181,12 @@ static int aio_aio12_8_ao_write(struct comedi_device *dev, } static const struct comedi_lrange range_aio_aio12_8 = { - 4, - { - UNI_RANGE(5), - BIP_RANGE(5), - UNI_RANGE(10), - BIP_RANGE(10), - } + 4, { + UNI_RANGE(5), + BIP_RANGE(5), + UNI_RANGE(10), + BIP_RANGE(10) + } }; static int aio_aio12_8_attach(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h index b810d5f3d971..2ba736444610 100644 --- a/drivers/staging/comedi/drivers/amcc_s5933.h +++ b/drivers/staging/comedi/drivers/amcc_s5933.h @@ -145,12 +145,12 @@ #define AINT_READ_COMPL 0x00008000 #define AINT_WRITE_COMPL 0x00004000 -#define AINT_OMB_ENABLE 0x00001000 -#define AINT_OMB_SELECT 0x00000c00 +#define AINT_OMB_ENABLE 0x00001000 +#define AINT_OMB_SELECT 0x00000c00 #define AINT_OMB_BYTE 0x00000300 -#define AINT_IMB_ENABLE 0x00000010 -#define AINT_IMB_SELECT 0x0000000c +#define AINT_IMB_ENABLE 0x00000010 +#define AINT_IMB_SELECT 0x0000000c #define AINT_IMB_BYTE 0x00000003 /* these are bits from various different registers, needs cleanup XXX */ diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 2e4bf284d52c..9c9559ffc643 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -513,7 +513,7 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, int event = 0; spin_lock_irqsave(&subpriv->spinlock, flags); - subpriv->active = 1; + subpriv->active = true; /* Set up end of acquisition. */ switch (cmd->stop_src) { diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index a810a2416443..e0367380b37a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -439,7 +439,7 @@ static struct comedi_driver dio200_pci_comedi_driver = { .detach = dio200_pci_detach, }; -static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { +static const struct pci_device_id dio200_pci_table[] = { { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215), pci215_model diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 98075f999c9f..31734e1142fd 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -356,7 +356,7 @@ static int pc236_intr_cancel(struct comedi_device *dev, static irqreturn_t pc236_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[1]; + struct comedi_subdevice *s = dev->read_subdev; int handled; handled = pc236_intr_check(dev); @@ -567,7 +567,7 @@ static struct comedi_driver amplc_pc236_driver = { }; #if DO_PCI -static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { +static const struct pci_device_id pc236_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236) }, {0} }; diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 810e397d8fd7..ae4048a624fa 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -267,17 +267,16 @@ Caveats: /* The software selectable internal ranges for PCI224 (option[2] == 0). */ static const struct comedi_lrange range_pci224_internal = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; static const unsigned short hwrange_pci224_internal[8] = { @@ -293,11 +292,10 @@ static const unsigned short hwrange_pci224_internal[8] = { /* The software selectable external ranges for PCI224 (option[2] == 1). */ static const struct comedi_lrange range_pci224_external = { - 2, - { - RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */ - RANGE_ext(0, 1), /* unipolar [0,+Vref] */ - } + 2, { + RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */ + RANGE_ext(0, 1) /* unipolar [0,+Vref] */ + } }; static const unsigned short hwrange_pci224_external[2] = { @@ -308,19 +306,17 @@ static const unsigned short hwrange_pci224_external[2] = { /* The hardware selectable Vref*2 external range for PCI234 * (option[2] == 1, option[3+n] == 0). */ static const struct comedi_lrange range_pci234_ext2 = { - 1, - { - RANGE_ext(-2, 2), - } + 1, { + RANGE_ext(-2, 2) + } }; /* The hardware selectable Vref external range for PCI234 * (option[2] == 1, option[3+n] == 1). */ static const struct comedi_lrange range_pci234_ext = { - 1, - { - RANGE_ext(-1, 1), - } + 1, { + RANGE_ext(-1, 1) + } }; /* This serves for all the PCI234 ranges. */ @@ -909,16 +905,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } if (errors) { if (errors & dupchan_err) { - DPRINTK("comedi%d: " DRIVER_NAME - ": ao_cmdtest: " - "entries in chanlist must contain no " - "duplicate channels\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: entries in chanlist must contain no duplicate channels\n", + __func__); } if (errors & range_err) { - DPRINTK("comedi%d: " DRIVER_NAME - ": ao_cmdtest: " - "entries in chanlist must all have " - "the same range index\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: entries in chanlist must all have the same range index\n", + __func__); } err++; } @@ -1142,7 +1136,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct pci224_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->write_subdev; struct comedi_cmd *cmd; unsigned char intstat, valid_intstat; unsigned char curenab; @@ -1498,7 +1492,7 @@ static int amplc_pci224_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(amplc_pci224_pci_table) = { +static const struct pci_device_id amplc_pci224_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) }, { 0 } diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index a97bbd6ca3db..c08dfbbe4062 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -546,15 +546,16 @@ static const unsigned int pci230_timebase[8] = { }; /* PCI230 analogue input range table */ -static const struct comedi_lrange pci230_ai_range = { 7, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5) - } +static const struct comedi_lrange pci230_ai_range = { + 7, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5) + } }; /* PCI230 analogue gain bits for each input range. */ @@ -564,10 +565,11 @@ static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 }; static const unsigned char pci230_ai_bipolar[7] = { 1, 1, 1, 1, 0, 0, 0 }; /* PCI230 analogue output range table */ -static const struct comedi_lrange pci230_ao_range = { 2, { - UNI_RANGE(10), - BIP_RANGE(10) - } +static const struct comedi_lrange pci230_ao_range = { + 2, { + UNI_RANGE(10), + BIP_RANGE(10) + } }; /* PCI230 daccon bipolar flag for each analogue output range. */ @@ -818,9 +820,9 @@ static int pci230_ai_rinsn(struct comedi_device *dev, if (aref == AREF_DIFF) { /* Differential. */ if (chan >= s->n_chan / 2) { - DPRINTK("comedi%d: amplc_pci230: ai_rinsn: " - "differential channel number out of range " - "0 to %u\n", dev->minor, (s->n_chan / 2) - 1); + dev_dbg(dev->class_dev, + "%s: differential channel number out of range 0 to %u\n", + __func__, (s->n_chan / 2) - 1); return -EINVAL; } } @@ -1092,14 +1094,14 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if (errors != 0) { err++; if ((errors & seq_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: " - "channel numbers must increase\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel numbers must increase\n", + __func__); } if ((errors & range_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: " - "channels must have the same range\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channels must have the same range\n", + __func__); } } } @@ -1835,33 +1837,29 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if (errors != 0) { err++; if ((errors & seq_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel numbers must increase or " - "sequence must repeat exactly\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel numbers must increase or sequence must repeat exactly\n", + __func__); } if ((errors & rangepair_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "single-ended channel pairs must " - "have the same range\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: single-ended channel pairs must have the same range\n", + __func__); } if ((errors & polarity_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel sequence ranges must be all " - "bipolar or all unipolar\n", - dev->minor); + dev_dbg(dev->class_dev, + "%s: channel sequence ranges must be all bipolar or all unipolar\n", + __func__); } if ((errors & aref_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "channel sequence analogue references " - "must be all the same (single-ended " - "or differential)\n", dev->minor); + dev_dbg(dev->class_dev, + "%s: channel sequence analogue references must be all the same (single-ended or differential)\n", + __func__); } if ((errors & diffchan_err) != 0) { - DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: " - "differential channel number out of " - "range 0 to %u\n", dev->minor, - (s->n_chan / 2) - 1); + dev_dbg(dev->class_dev, + "%s: differential channel number out of range 0 to %u\n", + __func__, (s->n_chan / 2) - 1); } if ((errors & buggy_chan0_err) != 0) { dev_info(dev->class_dev, @@ -2637,7 +2635,7 @@ static int pci230_attach_common(struct comedi_device *dev, struct comedi_subdevice *s; unsigned long iobase1, iobase2; /* PCI230's I/O spaces 1 and 2 respectively. */ - int irq_hdl, rc; + int rc; comedi_set_hw_dev(dev, &pci_dev->dev); @@ -2709,16 +2707,12 @@ static int pci230_attach_common(struct comedi_device *dev, outw(devpriv->adcg, dev->iobase + PCI230_ADCG); outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON); - /* Register the interrupt handler. */ - irq_hdl = request_irq(pci_dev->irq, pci230_interrupt, - IRQF_SHARED, "amplc_pci230", dev); - if (irq_hdl < 0) { - dev_warn(dev->class_dev, - "unable to register irq %u, commands will not be available\n", - pci_dev->irq); - } else { - dev->irq = pci_dev->irq; - dev_dbg(dev->class_dev, "registered irq %u\n", pci_dev->irq); + + if (pci_dev->irq) { + rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (rc == 0) + dev->irq = pci_dev->irq; } rc = comedi_alloc_subdevices(dev, 3); @@ -2734,14 +2728,14 @@ static int pci230_attach_common(struct comedi_device *dev, s->range_table = &pci230_ai_range; s->insn_read = &pci230_ai_rinsn; s->len_chanlist = 256; /* but there are restrictions. */ - /* Only register commands if the interrupt handler is installed. */ - if (irq_hdl == 0) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; s->do_cmd = &pci230_ai_cmd; s->do_cmdtest = &pci230_ai_cmdtest; s->cancel = pci230_ai_cancel; } + s = &dev->subdevices[1]; /* analog output subdevice */ if (thisboard->ao_chans > 0) { @@ -2753,9 +2747,7 @@ static int pci230_attach_common(struct comedi_device *dev, s->insn_write = &pci230_ao_winsn; s->insn_read = &pci230_ao_rinsn; s->len_chanlist = thisboard->ao_chans; - /* Only register commands if the interrupt handler is - * installed. */ - if (irq_hdl == 0) { + if (dev->irq) { dev->write_subdev = s; s->subdev_flags |= SDF_CMD_WRITE; s->do_cmd = &pci230_ao_cmd; @@ -2765,6 +2757,7 @@ static int pci230_attach_common(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } + s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->have_dio) { @@ -2856,7 +2849,7 @@ static int amplc_pci230_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(amplc_pci230_pci_table) = { +static const struct pci_device_id amplc_pci230_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260) }, { 0 } diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index 4bd4ef8e88cd..be28e6cbea20 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -96,7 +96,7 @@ static struct comedi_driver amplc_pci263_driver = { .detach = comedi_pci_disable, }; -static DEFINE_PCI_DEVICE_TABLE(pci263_pci_table) = { +static const struct pci_device_id pci263_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) }, {0} }; diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 217aa19cdc32..5034f663eec9 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -94,8 +94,6 @@ static void C6X_pwmInit(unsigned long baseAddr) { int timeout = 0; -/* printk("Inside C6X_pwmInit\n"); */ - WriteByteToHwPort(baseAddr, 0x70); while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { @@ -132,8 +130,6 @@ static void C6X_pwmOutput(unsigned long baseAddr, unsigned channel, int value) int timeout = 0; unsigned tmp; - /* printk("Inside C6X_pwmOutput\n"); */ - pwm.cmd = value; if (pwm.cmd > 498) pwm.cmd = 498; @@ -200,8 +196,6 @@ static int C6X_encInput(unsigned long baseAddr, unsigned channel) int timeout = 0; int tmp; - /* printk("Inside C6X_encInput\n"); */ - enc.value = 0; if (channel == 0) ppcmd = 0x48; @@ -295,8 +289,6 @@ static void C6X_encResetAll(unsigned long baseAddr) { unsigned timeout = 0; -/* printk("Inside C6X_encResetAll\n"); */ - WriteByteToHwPort(baseAddr, 0x68); while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) { @@ -322,14 +314,6 @@ static void C6X_encResetAll(unsigned long baseAddr) } } -static int c6xdigio_pwmo_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - printk(KERN_DEBUG "c6xdigio_pwmo_insn_read %x\n", insn->n); - return insn->n; -} - static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -338,7 +322,6 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, int i; int chan = CR_CHAN(insn->chanspec); - /* printk("c6xdigio_pwmo_insn_write %x\n", insn->n); */ for (i = 0; i < insn->n; i++) { C6X_pwmOutput(dev->iobase, chan, data[i]); /* devpriv->ao_readback[chan] = data[i]; */ @@ -346,31 +329,10 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev, return i; } -/* static int c6xdigio_ei_init_insn_read(struct comedi_device *dev, */ -/* struct comedi_subdevice *s, */ -/* struct comedi_insn *insn, */ -/* unsigned int *data) */ -/* { */ -/* printk("c6xdigio_ei_init_insn_read %x\n", insn->n); */ -/* return insn->n; */ -/* } */ - -/* static int c6xdigio_ei_init_insn_write(struct comedi_device *dev, */ -/* struct comedi_subdevice *s, */ -/* struct comedi_insn *insn, */ -/* unsigned int *data) */ -/* { */ -/* int i; */ -/* int chan = CR_CHAN(insn->chanspec); */ - /* *//* C6X_encResetAll( dev->iobase ); */ - /* *//* return insn->n; */ -/* } */ - static int c6xdigio_ei_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - /* printk("c6xdigio_ei__insn_read %x\n", insn->n); */ int n; int chan = CR_CHAN(insn->chanspec); @@ -382,12 +344,8 @@ static int c6xdigio_ei_insn_read(struct comedi_device *dev, static void board_init(struct comedi_device *dev) { - - /* printk("Inside board_init\n"); */ - C6X_pwmInit(dev->iobase); C6X_encResetAll(dev->iobase); - } static const struct pnp_device_id c6xdigio_pnp_tbl[] = { @@ -426,7 +384,6 @@ static int c6xdigio_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE; s->n_chan = 2; /* s->trig[0] = c6xdigio_pwmo; */ - s->insn_read = c6xdigio_pwmo_insn_read; s->insn_write = c6xdigio_pwmo_insn_write; s->maxdata = 500; s->range_table = &range_bipolar10; /* A suitable lie */ @@ -441,17 +398,6 @@ static int c6xdigio_attach(struct comedi_device *dev, s->maxdata = 0xffffff; s->range_table = &range_unknown; - /* s = &dev->subdevices[2]; */ - /* pwm output subdevice */ - /* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */ - /* s->subdev_flags = SDF_WRITEABLE; */ - /* s->n_chan = 1; */ - /* s->trig[0] = c6xdigio_ei_init; */ - /* s->insn_read = c6xdigio_ei_init_insn_read; */ - /* s->insn_write = c6xdigio_ei_init_insn_write; */ - /* s->maxdata = 0xFFFF; // Really just a don't care */ - /* s->range_table = &range_unknown; // Not sure what to put here */ - /* I will call this init anyway but more than likely the DSP board */ /* will not be connected when device driver is loaded. */ board_init(dev); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e72a403db17c..9819be092f8d 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -181,43 +181,40 @@ static inline unsigned int DAC_DATA_REG(unsigned int channel) /* analog input ranges for most boards */ static const struct comedi_lrange cb_pcidas_ranges = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; /* pci-das1001 input ranges */ static const struct comedi_lrange cb_pcidas_alt_ranges = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(1), - BIP_RANGE(0.1), - BIP_RANGE(0.01), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01) - } + 8, { + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.01), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01) + } }; /* analog output ranges */ static const struct comedi_lrange cb_pcidas_ao_ranges = { - 4, - { - BIP_RANGE(5), - BIP_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(10), - } + 4, { + BIP_RANGE(5), + BIP_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(10) + } }; enum trimpot_model { @@ -1614,7 +1611,7 @@ static int cb_pcidas_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { +static const struct pci_device_id cb_pcidas_pci_table[] = { { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 }, { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 }, { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 }, diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index ff5206536be3..4fff1738e3f8 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -94,15 +94,6 @@ TODO: #include "plx9080.h" #include "comedi_fc.h" -#undef PCIDAS64_DEBUG /* disable debugging code */ -/* #define PCIDAS64_DEBUG enable debugging code */ - -#ifdef PCIDAS64_DEBUG -#define DEBUG_PRINT(format, args...) pr_debug(format, ## args) -#else -#define DEBUG_PRINT(format, args...) no_printk(format, ## args) -#endif - #define TIMER_BASE 25 /* 40MHz master clock */ /* 100kHz 'prescaled' clock for slow acquisition, * maybe I'll support this someday */ @@ -438,91 +429,85 @@ static inline uint8_t attenuate_bit(unsigned int channel) /* analog input ranges for 64xx boards */ static const struct comedi_lrange ai_ranges_64xx = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; /* analog input ranges for 60xx boards */ static const struct comedi_lrange ai_ranges_60xx = { - 4, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - } + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05) + } }; /* analog input ranges for 6030, etc boards */ static const struct comedi_lrange ai_ranges_6030 = { - 14, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - BIP_RANGE(0.5), - BIP_RANGE(0.2), - BIP_RANGE(0.1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1), - UNI_RANGE(0.5), - UNI_RANGE(0.2), - UNI_RANGE(0.1), - } + 14, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.2), + BIP_RANGE(0.1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5), + UNI_RANGE(0.2), + UNI_RANGE(0.1) + } }; /* analog input ranges for 6052, etc boards */ static const struct comedi_lrange ai_ranges_6052 = { - 15, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1), - BIP_RANGE(0.5), - BIP_RANGE(0.25), - BIP_RANGE(0.1), - BIP_RANGE(0.05), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1), - UNI_RANGE(0.5), - UNI_RANGE(0.2), - UNI_RANGE(0.1), - } + 15, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.25), + BIP_RANGE(0.1), + BIP_RANGE(0.05), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5), + UNI_RANGE(0.2), + UNI_RANGE(0.1) + } }; /* analog input ranges for 4020 board */ static const struct comedi_lrange ai_ranges_4020 = { - 2, - { - BIP_RANGE(5), - BIP_RANGE(1), - } + 2, { + BIP_RANGE(5), + BIP_RANGE(1) + } }; /* analog output ranges */ static const struct comedi_lrange ao_ranges_64xx = { - 4, - { - BIP_RANGE(5), - BIP_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(10), - } + 4, { + BIP_RANGE(5), + BIP_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(10) + } }; static const int ao_range_code_64xx[] = { @@ -537,11 +522,10 @@ static const int ao_range_code_60xx[] = { }; static const struct comedi_lrange ao_ranges_6030 = { - 2, - { - BIP_RANGE(10), - UNI_RANGE(10), - } + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } }; static const int ao_range_code_6030[] = { @@ -550,11 +534,10 @@ static const int ao_range_code_6030[] = { }; static const struct comedi_lrange ao_ranges_4020 = { - 2, - { - BIP_RANGE(5), - BIP_RANGE(10), - } + 2, { + BIP_RANGE(5), + BIP_RANGE(10) + } }; static const int ao_range_code_4020[] = { @@ -1252,8 +1235,6 @@ static void disable_ai_interrupts(struct comedi_device *dev) writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); } static void enable_ai_interrupts(struct comedi_device *dev, @@ -1277,7 +1258,6 @@ static void enable_ai_interrupts(struct comedi_device *dev, devpriv->intr_enable_bits |= bits; writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -1292,38 +1272,6 @@ static void init_plx9080(struct comedi_device *dev) devpriv->plx_control_bits = readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); - /* plx9080 dump */ - DEBUG_PRINT(" plx interrupt status 0x%x\n", - readl(plx_iobase + PLX_INTRCS_REG)); - DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits); - DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n", - readl(plx_iobase + PLX_MARB_REG)); - DEBUG_PRINT(" plx region0 reg 0x%x\n", - readl(plx_iobase + PLX_REGION0_REG)); - DEBUG_PRINT(" plx region1 reg 0x%x\n", - readl(plx_iobase + PLX_REGION1_REG)); - - DEBUG_PRINT(" plx revision 0x%x\n", - readl(plx_iobase + PLX_REVISION_REG)); - DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n", - readl(plx_iobase + PLX_DMA0_MODE_REG)); - DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n", - readl(plx_iobase + PLX_DMA1_MODE_REG)); - DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n", - readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n", - readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n", - readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG)); - DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n", - readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n", - readb(plx_iobase + PLX_DMA0_CS_REG)); - DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n", - readl(plx_iobase + PLX_DMA0_THRESHOLD_REG)); - DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG)); - #ifdef __BIG_ENDIAN bits = BIGEND_DMA0 | BIGEND_DMA1; #else @@ -1417,9 +1365,6 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, devpriv->ai_fifo_segment_length = num_increments * increment_size; - DEBUG_PRINT("set hardware fifo segment length to %i\n", - devpriv->ai_fifo_segment_length); - return devpriv->ai_fifo_segment_length; } @@ -1441,8 +1386,6 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; - DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); - return num_samples; } @@ -1538,8 +1481,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) if (devpriv->ai_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(thisboard)) { devpriv->ao_dma_desc = pci_alloc_consistent(pcidev, @@ -1548,9 +1489,6 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) &devpriv->ao_dma_desc_bus_addr); if (devpriv->ao_dma_desc == NULL) return -ENOMEM; - - DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n", - (unsigned long long)devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ for (i = 0; i < ai_dma_ring_count(thisboard); i++) { @@ -1650,8 +1588,6 @@ static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) uint8_t bit; unsigned int num_bits = 8; - DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); - for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { i2c_set_scl(dev, 0); if ((byte & bit)) @@ -1738,7 +1674,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; static const int timeout = 100; - DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec); channel = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); aref = CR_AREF(insn->chanspec); @@ -1766,7 +1701,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (insn->chanspec & CR_ALT_SOURCE) { unsigned int cal_en_bit; - DEBUG_PRINT("reading calibration source\n"); if (thisboard->layout == LAYOUT_60XX) cal_en_bit = CAL_EN_60XX_BIT; else @@ -1800,7 +1734,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; if (insn->chanspec & CR_ALT_SOURCE) { - DEBUG_PRINT("reading calibration source\n"); devpriv->i2c_cal_range_bits |= adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ @@ -1839,7 +1772,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* wait for data */ for (i = 0; i < timeout; i++) { bits = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); if (thisboard->layout == LAYOUT_4020) { if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) @@ -1850,7 +1782,6 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } udelay(1); } - DEBUG_PRINT(" looped %i times waiting for data\n", i); if (i == timeout) { comedi_error(dev, " analog input read insn timed out"); dev_info(dev->class_dev, "status 0x%x\n", bits); @@ -1884,7 +1815,6 @@ static int ai_config_calibration_source(struct comedi_device *dev, return -EINVAL; } - DEBUG_PRINT("setting calibration source to %i\n", source); devpriv->calibration_source = source; return 2; @@ -2368,7 +2298,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load lower 16 bits of convert interval */ writew(convert_counter & 0xffff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); - DEBUG_PRINT("convert counter 0x%x\n", convert_counter); /* load upper 8 bits of convert interval */ writew((convert_counter >> 16) & 0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); @@ -2378,7 +2307,6 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load upper 8 bits of scan delay */ writew((scan_counter >> 16) & 0xff, devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); - DEBUG_PRINT("scan counter 0x%x\n", scan_counter); } static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) @@ -2469,9 +2397,6 @@ static int setup_channel_queue(struct comedi_device *dev, writew(bits, devpriv->main_iobase + ADC_QUEUE_FIFO_REG); - DEBUG_PRINT( - "wrote 0x%x to external channel queue\n", - bits); } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ @@ -2593,7 +2518,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } writew(devpriv->adc_control1_bits, devpriv->main_iobase + ADC_CONTROL1_REG); - DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits); spin_unlock_irqrestore(&dev->spinlock, flags); /* clear adc buffer */ @@ -2645,17 +2569,14 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (use_hw_sample_counter(cmd)) bits |= ADC_SAMPLE_COUNTER_EN_BIT; writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG); - DEBUG_PRINT("control0 bits 0x%x\n", bits); devpriv->ai_cmd_running = 1; spin_unlock_irqrestore(&dev->spinlock, flags); /* start acquisition */ - if (cmd->start_src == TRIG_NOW) { + if (cmd->start_src == TRIG_NOW) writew(0, devpriv->main_iobase + ADC_START_REG); - DEBUG_PRINT("soft trig\n"); - } return 0; } @@ -2690,10 +2611,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) read_segment = adc_upper_read_ptr_code(prepost_bits); write_segment = adc_upper_write_ptr_code(prepost_bits); - DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n", - read_segment, write_segment, read_index, - write_index); - if (read_segment != write_segment) num_samples = devpriv->ai_fifo_segment_length - read_index; @@ -2715,8 +2632,6 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) break; } - DEBUG_PRINT(" read %i samples from fifo\n", num_samples); - for (i = 0; i < num_samples; i++) { cfc_write_to_buffer(s, readw(devpriv->main_iobase + @@ -2812,11 +2727,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) num_samples * sizeof(uint16_t)); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % ai_dma_ring_count(thisboard); - - DEBUG_PRINT("next buffer addr 0x%lx\n", - (unsigned long)devpriv-> - ai_buffer_bus_addr[devpriv->ai_dma_index]); - DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } /* XXX check for dma ring buffer overrun * (use end-of-chain bit to mark last unused buffer) */ @@ -2845,24 +2755,17 @@ static void handle_ai_interrupt(struct comedi_device *dev, if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA1_CS_REG); - DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); if (dma1_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 1); - - DEBUG_PRINT(" cleared dma ch1 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); - if (status & ADC_DONE_BIT) - DEBUG_PRINT("adc done interrupt\n"); - /* drain fifo with pio */ if ((status & ADC_DONE_BIT) || ((cmd->flags & TRIG_WAKE_EOS) && (status & ADC_INTR_PENDING_BIT) && (thisboard->layout != LAYOUT_4020))) { - DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->ai_cmd_running) { spin_unlock_irqrestore(&dev->spinlock, flags); @@ -2947,7 +2850,6 @@ static void restart_ao_dma(struct comedi_device *dev) dma_desc_bits = readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; - DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); dma_start_sync(dev, 0); @@ -2963,10 +2865,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, buffer_index = devpriv->ao_dma_index; prev_buffer_index = prev_ao_dma_index(dev); - DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, - (unsigned long long)devpriv->ao_buffer_bus_addr[ - buffer_index]); - num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); if (num_bytes > DMA_BUFFER_SIZE) num_bytes = DMA_BUFFER_SIZE; @@ -2977,8 +2875,6 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, if (num_bytes == 0) return 0; - DEBUG_PRINT("loading %i bytes\n", num_bytes); - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, devpriv-> ao_buffer[buffer_index], @@ -3052,14 +2948,12 @@ static void handle_ao_interrupt(struct comedi_device *dev, writeb(PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) { load_ao_dma(dev, cmd); /* try to recover from dma end-of-chain event */ if (ao_dma_needs_restart(dev, dma0_status)) restart_ao_dma(dev); } - DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } else { spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -3068,12 +2962,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, async->events |= COMEDI_CB_EOA; if (ao_stopped_by_error(dev, cmd)) async->events |= COMEDI_CB_ERROR; - DEBUG_PRINT("plx dma0 desc reg 0x%x\n", - readl(devpriv->plx9080_iobase + - PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT("plx dma0 address reg 0x%x\n", - readl(devpriv->plx9080_iobase + - PLX_DMA0_PCI_ADDRESS_REG)); } cfc_handle_events(dev, s); } @@ -3089,15 +2977,12 @@ static irqreturn_t handle_interrupt(int irq, void *d) plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); status = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status); - /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ - if (!dev->attached) { - DEBUG_PRINT("premature interrupt, ignoring\n"); + if (!dev->attached) return IRQ_HANDLED; - } + handle_ai_interrupt(dev, status, plx_status); handle_ao_interrupt(dev, status, plx_status); @@ -3105,11 +2990,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); - DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } - DEBUG_PRINT("exiting handler\n"); - return IRQ_HANDLED; } @@ -3130,7 +3012,6 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) abort_dma(dev, 1); - DEBUG_PRINT("ai canceled\n"); return 0; } @@ -3458,7 +3339,6 @@ static int dio_callback(int dir, int port, int data, unsigned long arg) void __iomem *iobase = (void __iomem *)arg; if (dir) { writeb(data, iobase + port); - DEBUG_PRINT("wrote 0x%x to port %i\n", data, port); return 0; } else { return readb(iobase + port); @@ -4046,11 +3926,6 @@ static int auto_attach(struct comedi_device *dev, return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); - DEBUG_PRINT(" diocounter remapped to 0x%p\n", - devpriv->dio_counter_iobase); - /* figure out what local addresses are */ local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; @@ -4065,9 +3940,6 @@ static int auto_attach(struct comedi_device *dev, devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & ~local_range) | local_decode; - DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); - retval = alloc_and_init_dma_members(dev); if (retval < 0) return retval; @@ -4161,7 +4033,7 @@ static int cb_pcidas64_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { +static const struct pci_device_id cb_pcidas64_pci_table[] = { { PCI_VDEVICE(CB, 0x001d), BOARD_PCIDAS6402_16 }, { PCI_VDEVICE(CB, 0x001e), BOARD_PCIDAS6402_12 }, { PCI_VDEVICE(CB, 0x0035), BOARD_PCIDAS64_M1_16 }, diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 94f115820279..8cca0518cfda 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -407,7 +407,7 @@ static int cb_pcidda_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { +static const struct pci_device_id cb_pcidda_pci_table[] = { { PCI_VDEVICE(CB, 0x0020), BOARD_DDA02_12 }, { PCI_VDEVICE(CB, 0x0021), BOARD_DDA04_12 }, { PCI_VDEVICE(CB, 0x0022), BOARD_DDA08_12 }, diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 30520d4c16a6..57295d189ff6 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -44,9 +44,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #include "plx9052.h" #include "8255.h" -/* #define CBPCIMDAS_DEBUG */ -#undef CBPCIMDAS_DEBUG - /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ @@ -145,10 +142,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, if (!busy) break; } - if (i == TIMEOUT) { - printk("timeout\n"); + if (i == TIMEOUT) return -ETIMEDOUT; - } + /* read data */ data[n] = inw(dev->iobase + 0); } @@ -222,15 +218,6 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, devpriv->BADR3 = pci_resource_start(pcidev, 3); iobase_8255 = pci_resource_start(pcidev, 4); -/* Dont support IRQ yet */ -/* get irq */ -/* if(request_irq(pcidev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev )) */ -/* { */ -/* printk(" unable to allocate irq %u\n", pcidev->irq); */ -/* return -EINVAL; */ -/* } */ -/* dev->irq = pcidev->irq; */ - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -288,7 +275,7 @@ static int cb_pcimdas_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { +static const struct pci_device_id cb_pcimdas_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index edf17b63096f..43a86630a66e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -206,7 +206,7 @@ static int cb_pcimdda_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { +static const struct pci_device_id cb_pcimdda_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 16c07802107f..d539eaf53b63 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -74,11 +74,10 @@ static const int nano_per_micro = 1000; /* fake analog input ranges */ static const struct comedi_lrange waveform_ai_ranges = { - 2, - { - BIP_RANGE(10), - BIP_RANGE(5), - } + 2, { + BIP_RANGE(10), + BIP_RANGE(5) + } }; static unsigned short fake_sawtooth(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 89836c0828d9..323a7f39cd97 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -111,7 +111,7 @@ static int contec_pci_dio_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(contec_pci_dio_pci_table) = { +static const struct pci_device_id contec_pci_dio_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index de920ccff400..ce153fcb8b2a 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -772,7 +772,7 @@ static int daqboard2000_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = { +static const struct pci_device_id daqboard2000_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_IOTECH, 0x0409) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 15dd33e3e1c7..e5c0ee9a09c2 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -120,46 +120,49 @@ /* gainlist same as _pgx_ below */ -static const struct comedi_lrange range_das08_pgl = { 9, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } +static const struct comedi_lrange range_das08_pgl = { + 9, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; -static const struct comedi_lrange range_das08_pgh = { 12, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(1), - BIP_RANGE(0.5), - BIP_RANGE(0.1), - BIP_RANGE(0.05), - BIP_RANGE(0.01), - BIP_RANGE(0.005), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01), - } +static const struct comedi_lrange range_das08_pgh = { + 12, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.1), + BIP_RANGE(0.05), + BIP_RANGE(0.01), + BIP_RANGE(0.005), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01) + } }; -static const struct comedi_lrange range_das08_pgm = { 9, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.01), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01) - } +static const struct comedi_lrange range_das08_pgm = { + 9, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.01), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01) + } }; /* cio-das08jr.pdf diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index 3a6d3725b25f..d94af09151b0 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -89,7 +89,7 @@ static int das08_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { +static const struct pci_device_id das08_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index fce9acfe8084..fee5facff8dd 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -110,18 +110,18 @@ irq can be omitted, although the cmd interface will not work without it. #define DAS16M1_82C55 0x400 #define DAS16M1_8254_THIRD 0x404 -static const struct comedi_lrange range_das16m1 = { 9, - { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - BIP_RANGE(10), - } +static const struct comedi_lrange range_das16m1 = { + 9, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + BIP_RANGE(10) + } }; struct das16m1_private_struct { @@ -269,11 +269,6 @@ static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_cmd *cmd = &async->cmd; unsigned int byte, i; - if (dev->irq == 0) { - comedi_error(dev, "irq required to execute comedi_cmd"); - return -1; - } - /* disable interrupts and internal pacer */ devpriv->control_state &= ~INTE & ~PACER_MASK; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); @@ -508,38 +503,26 @@ static irqreturn_t das16m1_interrupt(int irq, void *d) static int das16m1_irq_bits(unsigned int irq) { - int ret; - switch (irq) { case 10: - ret = 0x0; - break; + return 0x0; case 11: - ret = 0x1; - break; + return 0x1; case 12: - ret = 0x2; - break; + return 0x2; case 15: - ret = 0x3; - break; + return 0x3; case 2: - ret = 0x4; - break; + return 0x4; case 3: - ret = 0x5; - break; + return 0x5; case 5: - ret = 0x6; - break; + return 0x6; case 7: - ret = 0x7; - break; + return 0x7; default: - return -1; - break; + return 0x0; } - return ret << 4; } /* @@ -553,7 +536,6 @@ static int das16m1_attach(struct comedi_device *dev, struct das16m1_private_struct *devpriv; struct comedi_subdevice *s; int ret; - unsigned int irq; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) @@ -569,24 +551,12 @@ static int das16m1_attach(struct comedi_device *dev, return ret; devpriv->extra_iobase = dev->iobase + DAS16M1_82C55; - /* now for the irq */ - irq = it->options[1]; - /* make sure it is valid */ - if (das16m1_irq_bits(irq) >= 0) { - ret = request_irq(irq, das16m1_interrupt, 0, - dev->driver->driver_name, dev); - if (ret < 0) - return ret; - dev->irq = irq; - printk - ("irq %u\n", irq); - } else if (irq == 0) { - printk - (", no irq\n"); - } else { - comedi_error(dev, "invalid irq\n" - " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n"); - return -EINVAL; + /* only irqs 2, 3, 4, 5, 6, 7, 10, 11, 12, 14, and 15 are valid */ + if ((1 << it->options[1]) & 0xdcfc) { + ret = request_irq(it->options[1], das16m1_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } ret = comedi_alloc_subdevices(dev, 4); @@ -594,20 +564,22 @@ static int das16m1_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF; s->n_chan = 8; - s->subdev_flags = SDF_DIFF; - s->len_chanlist = 256; s->maxdata = (1 << 12) - 1; s->range_table = &range_das16m1; s->insn_read = das16m1_ai_rinsn; - s->do_cmdtest = das16m1_cmd_test; - s->do_cmd = das16m1_cmd_exec; - s->cancel = das16m1_cancel; - s->poll = das16m1_poll; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 256; + s->do_cmdtest = das16m1_cmd_test; + s->do_cmd = das16m1_cmd_exec; + s->cancel = das16m1_cancel; + s->poll = das16m1_poll; + } s = &dev->subdevices[1]; /* di */ @@ -640,10 +612,7 @@ static int das16m1_attach(struct comedi_device *dev, outb(0, dev->iobase + DAS16M1_DIO); /* set the interrupt level */ - if (dev->irq) - devpriv->control_state = das16m1_irq_bits(dev->irq); - else - devpriv->control_state = 0; + devpriv->control_state = das16m1_irq_bits(dev->irq) << 4; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); return 0; diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 1880038956d0..320d95a5f47b 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -178,31 +178,29 @@ enum { /* analog input ranges */ static const struct comedi_lrange range_ai_das1801 = { - 8, - { - RANGE(-5, 5), - RANGE(-1, 1), - RANGE(-0.1, 0.1), - RANGE(-0.02, 0.02), - RANGE(0, 5), - RANGE(0, 1), - RANGE(0, 0.1), - RANGE(0, 0.02), - } + 8, { + BIP_RANGE(5), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02), + UNI_RANGE(5), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.02) + } }; static const struct comedi_lrange range_ai_das1802 = { - 8, - { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25), - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 2.5), - RANGE(0, 1.25), - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; struct das1800_board { @@ -445,10 +443,9 @@ struct das1800_private { /* analog out range for 'ao' boards */ /* static const struct comedi_lrange range_ao_2 = { - 2, - { - RANGE(-10, 10), - RANGE(-5, 5), + 2, { + BIP_RANGE(10), + BIP_RANGE(5) } }; */ @@ -462,7 +459,7 @@ static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, return sample; } -static void munge_data(struct comedi_device *dev, uint16_t * array, +static void munge_data(struct comedi_device *dev, uint16_t *array, unsigned int num_elements) { unsigned int i; @@ -644,7 +641,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void das1800_ai_handler(struct comedi_device *dev) { struct das1800_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int status = inb(dev->iobase + DAS1800_STATUS); @@ -1150,12 +1147,6 @@ static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_async *async = s->async; const struct comedi_cmd *cmd = &async->cmd; - if (!dev->irq) { - comedi_error(dev, - "no irq assigned for das-1800, cannot do hardware conversions"); - return -1; - } - /* disable dma on TRIG_WAKE_EOS, or TRIG_RT * (because dma in handler is unsafe at hard real-time priority) */ if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) @@ -1522,43 +1513,34 @@ static int das1800_attach(struct comedi_device *dev, devpriv->iobase2 = iobase2; } - /* grab our IRQ */ - if (irq) { - if (request_irq(irq, das1800_interrupt, 0, - dev->driver->driver_name, dev)) { - dev_dbg(dev->class_dev, "unable to allocate irq %u\n", - irq); - return -EINVAL; - } - } - dev->irq = irq; + if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 || + irq == 15) { + ret = request_irq(irq, das1800_interrupt, 0, + dev->board_name, dev); + if (ret == 0) { + dev->irq = irq; - /* set bits that tell card which irq to use */ - switch (irq) { - case 0: - break; - case 3: - devpriv->irq_dma_bits |= 0x8; - break; - case 5: - devpriv->irq_dma_bits |= 0x10; - break; - case 7: - devpriv->irq_dma_bits |= 0x18; - break; - case 10: - devpriv->irq_dma_bits |= 0x28; - break; - case 11: - devpriv->irq_dma_bits |= 0x30; - break; - case 15: - devpriv->irq_dma_bits |= 0x38; - break; - default: - dev_err(dev->class_dev, "irq out of range\n"); - return -EINVAL; - break; + switch (irq) { + case 3: + devpriv->irq_dma_bits |= 0x8; + break; + case 5: + devpriv->irq_dma_bits |= 0x10; + break; + case 7: + devpriv->irq_dma_bits |= 0x18; + break; + case 10: + devpriv->irq_dma_bits |= 0x28; + break; + case 11: + devpriv->irq_dma_bits |= 0x30; + break; + case 15: + devpriv->irq_dma_bits |= 0x38; + break; + } + } } ret = das1800_init_dma(dev, dma0, dma1); @@ -1578,20 +1560,23 @@ static int das1800_attach(struct comedi_device *dev, /* analog input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; if (thisboard->common) s->subdev_flags |= SDF_COMMON; s->n_chan = thisboard->qram_len; - s->len_chanlist = thisboard->qram_len; s->maxdata = (1 << thisboard->resolution) - 1; s->range_table = thisboard->range_ai; - s->do_cmd = das1800_ai_do_cmd; - s->do_cmdtest = das1800_ai_do_cmdtest; s->insn_read = das1800_ai_rinsn; - s->poll = das1800_ai_poll; - s->cancel = das1800_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmd = das1800_ai_do_cmd; + s->do_cmdtest = das1800_ai_do_cmdtest; + s->poll = das1800_ai_poll; + s->cancel = das1800_cancel; + } /* analog out */ s = &dev->subdevices[1]; diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index fb25cb847032..43027ee500e3 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -152,21 +152,12 @@ static irqreturn_t intr_handler(int irq, void *d) dev_warn(dev->class_dev, "BUG: spurious interrupt\n"); return IRQ_HANDLED; } -#ifdef DEBUG - printk("das6402: interrupt! das6402_irqcount=%i\n", - devpriv->das6402_irqcount); - printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2)); -#endif das6402_ai_fifo_dregs(dev, s); if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) { outw_p(SCANL, dev->iobase + 2); /* clears the fifo */ outb(0x07, dev->iobase + 8); /* clears all flip-flops */ -#ifdef DEBUG - printk("das6402: Got %i samples\n\n", - devpriv->das6402_wordsread - diff); -#endif s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); } @@ -211,7 +202,7 @@ static int das6402_ai_cancel(struct comedi_device *dev, #ifdef unused static int das6402_ai_mode2(struct comedi_device *dev, - struct comedi_subdevice *s, comedi_trig * it) + struct comedi_subdevice *s, comedi_trig *it) { struct das6402_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index b04a5633f754..78a19629ff56 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -124,13 +124,12 @@ Configuration Options: /* board AI ranges in comedi structure */ static const struct comedi_lrange dmm32at_airanges = { - 4, - { - UNI_RANGE(10), - UNI_RANGE(5), - BIP_RANGE(10), - BIP_RANGE(5), - } + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + BIP_RANGE(10), + BIP_RANGE(5) + } }; /* register values for above ranges */ @@ -145,13 +144,12 @@ static const unsigned char dmm32at_rangebits[] = { * board. The application should only use the range set by the jumper */ static const struct comedi_lrange dmm32at_aoranges = { - 4, - { - UNI_RANGE(10), - UNI_RANGE(5), - BIP_RANGE(10), - BIP_RANGE(5), - } + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + BIP_RANGE(10), + BIP_RANGE(5) + } }; struct dmm32at_private { @@ -182,8 +180,6 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1); range = CR_RANGE(insn->chanspec); - /* printk("channel=0x%02x, range=%d\n",chan,range); */ - /* zero scan and fifo control and reset fifo */ outb(DMM32AT_FIFORESET, dev->iobase + DMM32AT_FIFOCNTRL); @@ -199,10 +195,8 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } /* convert n samples */ for (n = 0; n < insn->n; n++) { @@ -214,10 +208,8 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } /* read data */ lsb = inb(dev->iobase + DMM32AT_AILSB); @@ -453,10 +445,8 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if ((status & DMM32AT_STATUS) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } if (devpriv->ai_scans_left > 1) { /* start the clock and enable the interrupts */ @@ -467,8 +457,6 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) outb(0xff, dev->iobase + DMM32AT_CONV); } -/* printk("dmmat32 in command\n"); */ - /* for(i=0;ichanlist_len;i++) */ /* comedi_buf_put(s->async,i*100); */ @@ -556,7 +544,6 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, lo = data[i] & 0x00ff; /* high byte also contains channel number */ hi = (data[i] >> 8) + chan * (1 << 6); - /* printk("writing 0x%02x 0x%02x\n",hi,lo); */ /* write the low and high values to the board */ outb(lo, dev->iobase + DMM32AT_DACLSB); outb(hi, dev->iobase + DMM32AT_DACMSB); @@ -567,10 +554,9 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, if ((status & DMM32AT_DACBUSY) == 0) break; } - if (i == 40000) { - printk(KERN_WARNING "dmm32at: timeout\n"); + if (i == 40000) return -ETIMEDOUT; - } + /* dummy read to update trigger the output */ status = inb(dev->iobase + DMM32AT_DACMSB); @@ -682,9 +668,6 @@ static int dmm32at_attach(struct comedi_device *dev, int ret; struct comedi_subdevice *s; unsigned char aihi, ailo, fifostat, aistat, intstat, airback; - unsigned int irq; - - irq = it->options[1]; ret = comedi_request_region(dev, it->options[0], DMM32AT_MEMSIZE); if (ret) @@ -723,26 +706,17 @@ static int dmm32at_attach(struct comedi_device *dev, intstat = inb(dev->iobase + DMM32AT_INTCLOCK); airback = inb(dev->iobase + DMM32AT_AIRBACK); - printk(KERN_DEBUG "dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n", - ailo, aihi, fifostat); - printk(KERN_DEBUG - "dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n", - aistat, intstat, airback); - if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) || (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) { - printk(KERN_ERR "dmmat32: board detection failed\n"); + dev_err(dev->class_dev, "board detection failed\n"); return -EIO; } - /* board is there, register interrupt */ - if (irq) { - ret = request_irq(irq, dmm32at_isr, 0, dev->board_name, dev); - if (ret < 0) { - printk(KERN_ERR "dmm32at: irq conflict\n"); - return ret; - } - dev->irq = irq; + if (it->options[1]) { + ret = request_irq(it->options[1], dmm32at_isr, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); @@ -754,20 +728,22 @@ static int dmm32at_attach(struct comedi_device *dev, return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; /* we support single-ended (ground) and differential */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = 32; s->maxdata = 0xffff; s->range_table = &dmm32at_airanges; - s->len_chanlist = 32; /* This is the maximum chanlist length that - the board can handle */ s->insn_read = dmm32at_ai_rinsn; - s->do_cmd = dmm32at_ai_cmd; - s->do_cmdtest = dmm32at_ai_cmdtest; - s->cancel = dmm32at_ai_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 32; + s->do_cmd = dmm32at_ai_cmd; + s->do_cmdtest = dmm32at_ai_cmdtest; + s->cancel = dmm32at_ai_cancel; + } s = &dev->subdevices[1]; /* analog output subdevice */ @@ -799,11 +775,7 @@ static int dmm32at_attach(struct comedi_device *dev, s->insn_bits = dmm32at_dio_insn_bits; s->insn_config = dmm32at_dio_insn_config; - /* success */ - printk(KERN_INFO "comedi%d: dmm32at: attached\n", dev->minor); - - return 1; - + return 0; } static struct comedi_driver dmm32at_driver = { diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 811c8c59c017..d4d4e4b497dc 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -90,58 +90,42 @@ Configuration options: #if 0 /* ignore 'defined but not used' warning */ -static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, { - RANGE(-10, - 10), - RANGE(-5, - 5), - RANGE - (-2.5, - 2.5), - RANGE - (-1.25, - 1.25), - } +static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25) + } }; #endif -static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { 4, { - RANGE(-10, - 10), - RANGE(-1, - 1), - RANGE - (-0.1, - 0.1), - RANGE - (-0.02, - 0.02), - } +static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { + 4, { + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02) + } }; #if 0 /* ignore 'defined but not used' warning */ -static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { 4, { - RANGE(0, - 10), - RANGE(0, - 5), - RANGE(0, - 2.5), - RANGE(0, - 1.25), - } +static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; #endif -static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { 4, { - RANGE(0, - 10), - RANGE(0, - 1), - RANGE(0, - 0.1), - RANGE(0, - 0.02), - } +static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { + 4, { + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.02) + } }; struct dt2801_board { @@ -289,13 +273,6 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data) outb_p(data & 0xff, dev->iobase + DT2801_DATA); return 0; } -#if 0 - if (stat & DT_S_READY) { - printk - ("dt2801: ready flag set (bad!) in dt2801_writedata()\n"); - return -EIO; - } -#endif } while (--timeout > 0); return -ETIME; @@ -343,11 +320,11 @@ static int dt2801_writecmd(struct comedi_device *dev, int command) stat = inb_p(dev->iobase + DT2801_STATUS); if (stat & DT_S_COMPOSITE_ERROR) { - printk - ("dt2801: composite-error in dt2801_writecmd(), ignoring\n"); + dev_dbg(dev->class_dev, + "composite-error in %s, ignoring\n", __func__); } if (!(stat & DT_S_READY)) - printk("dt2801: !ready in dt2801_writecmd(), ignoring\n"); + dev_dbg(dev->class_dev, "!ready in %s, ignoring\n", __func__); outb_p(command, dev->iobase + DT2801_CMD); return 0; @@ -359,17 +336,12 @@ static int dt2801_reset(struct comedi_device *dev) unsigned int stat; int timeout; - DPRINTK("dt2801: resetting board...\n"); - DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase), - inb_p(dev->iobase + 1)); - /* pull random data from data port */ inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); inb_p(dev->iobase + DT2801_DATA); - DPRINTK("dt2801: stop\n"); /* dt2801_writecmd(dev,DT_C_STOP); */ outb_p(DT_C_STOP, dev->iobase + DT2801_CMD); @@ -382,12 +354,10 @@ static int dt2801_reset(struct comedi_device *dev) break; } while (timeout--); if (!timeout) - printk("dt2801: timeout 1 status=0x%02x\n", stat); + dev_dbg(dev->class_dev, "timeout 1 status=0x%02x\n", stat); - /* printk("dt2801: reading dummy\n"); */ /* dt2801_readdata(dev,&board_code); */ - DPRINTK("dt2801: reset\n"); outb_p(DT_C_RESET, dev->iobase + DT2801_CMD); /* dt2801_writecmd(dev,DT_C_RESET); */ @@ -399,13 +369,10 @@ static int dt2801_reset(struct comedi_device *dev) break; } while (timeout--); if (!timeout) - printk("dt2801: timeout 2 status=0x%02x\n", stat); + dev_dbg(dev->class_dev, "timeout 2 status=0x%02x\n", stat); - DPRINTK("dt2801: reading code\n"); dt2801_readdata(dev, &board_code); - DPRINTK("dt2801: ok. code=0x%02x\n", board_code); - return board_code; } @@ -465,12 +432,12 @@ static int dt2801_error(struct comedi_device *dev, int stat) { if (stat < 0) { if (stat == -ETIME) - printk("dt2801: timeout\n"); + dev_dbg(dev->class_dev, "timeout\n"); else - printk("dt2801: error %d\n", stat); + dev_dbg(dev->class_dev, "error %d\n", stat); return stat; } - printk("dt2801: error status 0x%02x, resetting...\n", stat); + dev_dbg(dev->class_dev, "error status 0x%02x, resetting...\n", stat); dt2801_reset(dev); dt2801_reset(dev); @@ -601,8 +568,8 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (boardtypes[type].boardcode == board_code) goto havetype; } - printk("dt2801: unrecognized board code=0x%02x, contact author\n", - board_code); + dev_dbg(dev->class_dev, + "unrecognized board code=0x%02x, contact author\n", board_code); type = 0; havetype: diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index 0ca02fa7ba1b..4271903facd7 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -42,60 +42,59 @@ Configuration options: */ #include -#include #include "../comedidev.h" static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, { - RANGE(0, 5), - RANGE(0, 2.5), - RANGE(0, 1.25), - RANGE(0, 0.625) + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + UNI_RANGE(0.625) } }; static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, { - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25), - RANGE(-0.625, 0.625), - RANGE(-0.3125, 0.3125) + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + BIP_RANGE(0.3125) } }; static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, { - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25), - RANGE(-0.625, 0.625) + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) } }; static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, { - RANGE(0, 5), - RANGE(0, 0.5), - RANGE(0, 0.05), - RANGE(0, 0.01) + UNI_RANGE(5), + UNI_RANGE(0.5), + UNI_RANGE(0.05), + UNI_RANGE(0.01) } }; static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, { - RANGE(-2.5, 2.5), - RANGE(-0.25, 0.25), - RANGE(-0.025, 0.025), - RANGE(-0.005, 0.005) + BIP_RANGE(2.5), + BIP_RANGE(0.25), + BIP_RANGE(0.025), + BIP_RANGE(0.005) } }; static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, { - RANGE(-5, 5), - RANGE(-0.5, 0.5), - RANGE(-0.05, 0.05), - RANGE(-0.01, 0.01) + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.01) } }; @@ -227,33 +226,6 @@ static const struct comedi_lrange *dac_range_types[] = { #define DT2811_TIMEOUT 5 -#if 0 -static irqreturn_t dt2811_interrupt(int irq, void *d) -{ - int lo, hi; - int data; - struct comedi_device *dev = d; - struct dt2811_private *devpriv = dev->private; - - if (!dev->attached) { - comedi_error(dev, "spurious interrupt"); - return IRQ_HANDLED; - } - - lo = inb(dev->iobase + DT2811_ADDATLO); - hi = inb(dev->iobase + DT2811_ADDATHI); - - data = lo + (hi << 8); - - if (!(--devpriv->ntrig)) { - /* how to turn off acquisition */ - s->async->events |= COMEDI_SB_EOA; - } - comedi_event(dev, s); - return IRQ_HANDLED; -} -#endif - static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -278,35 +250,6 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, return i; } -#if 0 -/* Wow. This is code from the Comedi stone age. But it hasn't been - * replaced, so I'll let it stay. */ -int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) -{ - struct comedi_device *dev = comedi_devices + minor; - - if (adtrig->n < 1) - return 0; - dev->curadchan = adtrig->chan; - switch (dev->i_admode) { - case COMEDI_MDEMAND: - dev->ntrig = adtrig->n - 1; - /* not necessary */ - /*printk("dt2811: AD soft trigger\n"); */ - /*outb(DT2811_CLRERROR|DT2811_INTENB, - dev->iobase+DT2811_ADCSR); */ - outb(dev->curadchan, dev->iobase + DT2811_ADGCR); - do_gettimeofday(&trigtime); - break; - case COMEDI_MCONTS: - dev->ntrig = adtrig->n; - break; - } - - return 0; -} -#endif - static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -386,10 +329,7 @@ static int dt2811_do_insn_bits(struct comedi_device *dev, */ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - /* int i, irq; */ - /* unsigned long irqs; */ - /* long flags; */ - + /* int i; */ const struct dt2811_board *board = comedi_board(dev); struct dt2811_private *devpriv; int ret; @@ -406,45 +346,6 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) i = inb(dev->iobase + DT2811_ADDATHI); #endif -#if 0 - irq = it->options[1]; - if (irq < 0) { - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - outb(DT2811_CLRERROR | DT2811_INTENB, - dev->iobase + DT2811_ADCSR); - outb(0, dev->iobase + DT2811_ADGCR); - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - - /*outb(DT2811_CLRERROR|DT2811_INTENB, - dev->iobase+DT2811_ADCSR);*/ - - if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) - printk(KERN_ERR "error probing irq (bad)\n"); - dev->irq = 0; - if (irq > 0) { - i = inb(dev->iobase + DT2811_ADDATLO); - i = inb(dev->iobase + DT2811_ADDATHI); - printk(KERN_INFO "(irq = %d)\n", irq); - ret = request_irq(irq, dt2811_interrupt, 0, - dev->board_name, dev); - if (ret < 0) - return -EIO; - dev->irq = irq; - } else if (irq == 0) { - printk(KERN_INFO "(no irq)\n"); - } else { - printk(KERN_ERR "( multiple irq's -- this is bad! )\n"); - } - } -#endif - ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 6514b9e00552..abad6e49c1c1 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -80,15 +80,12 @@ static int dt2814_ai_insn_read(struct comedi_device *dev, outb(chan, dev->iobase + DT2814_CSR); for (i = 0; i < DT2814_TIMEOUT; i++) { status = inb(dev->iobase + DT2814_CSR); - printk(KERN_INFO "dt2814: status: %02x\n", status); udelay(10); if (status & DT2814_FINISH) break; } - if (i >= DT2814_TIMEOUT) { - printk(KERN_INFO "dt2814: status: %02x\n", status); + if (i >= DT2814_TIMEOUT) return -ETIMEDOUT; - } hi = inb(dev->iobase + DT2814_DATA); lo = inb(dev->iobase + DT2814_DATA); @@ -200,7 +197,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) int lo, hi; struct comedi_device *dev = d; struct dt2814_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s = dev->read_subdev; int data; if (!dev->attached) { @@ -208,8 +205,6 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = &dev->subdevices[0]; - hi = inb(dev->iobase + DT2814_DATA); lo = inb(dev->iobase + DT2814_DATA); @@ -238,9 +233,9 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct dt2814_private *devpriv; - int i, irq; - int ret; struct comedi_subdevice *s; + int ret; + int i; ret = comedi_request_region(dev, it->options[0], DT2814_SIZE); if (ret) @@ -249,49 +244,17 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) outb(0, dev->iobase + DT2814_CSR); udelay(100); if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) { - printk(KERN_ERR "reset error (fatal)\n"); + dev_err(dev->class_dev, "reset error (fatal)\n"); return -EIO; } i = inb(dev->iobase + DT2814_DATA); i = inb(dev->iobase + DT2814_DATA); - irq = it->options[1]; -#if 0 - if (irq < 0) { - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - outb(0, dev->iobase + DT2814_CSR); - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) - printk(KERN_DEBUG "error probing irq (bad)\n"); - - - i = inb(dev->iobase + DT2814_DATA); - i = inb(dev->iobase + DT2814_DATA); - } -#endif - dev->irq = 0; - if (irq > 0) { - if (request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) { - printk(KERN_WARNING "(irq %d unavailable)\n", irq); - } else { - printk(KERN_INFO "( irq = %d )\n", irq); - dev->irq = irq; - } - } else if (irq == 0) { - printk(KERN_WARNING "(no irq)\n"); - } else { -#if 0 - printk(KERN_DEBUG "(probe returned multiple irqs--bad)\n"); -#else - printk(KERN_WARNING "(irq probe not implemented)\n"); -#endif + if (it->options[1]) { + ret = request_irq(it->options[1], dt2814_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } ret = comedi_alloc_subdevices(dev, 1); @@ -303,16 +266,19 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -ENOMEM; s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = 16; /* XXX */ - s->len_chanlist = 1; s->insn_read = dt2814_ai_insn_read; - s->do_cmd = dt2814_ai_cmd; - s->do_cmdtest = dt2814_ai_cmdtest; s->maxdata = 0xfff; s->range_table = &range_unknown; /* XXX */ + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 1; + s->do_cmd = dt2814_ai_cmd; + s->do_cmdtest = dt2814_ai_cmdtest; + } return 0; } diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 34040f0175e8..ee24717821e1 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -107,8 +107,9 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x00); if (status != 0) { - printk(KERN_WARNING "dt2815: failed to write low byte " - "on %d reason %x\n", chan, status); + dev_dbg(dev->class_dev, + "failed to write low byte on %d reason %x\n", + chan, status); return -EBUSY; } @@ -116,8 +117,9 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, status = dt2815_wait_for_status(dev, 0x10); if (status != 0x10) { - printk(KERN_WARNING "dt2815: failed to write high byte " - "on %d reason %x\n", chan, status); + dev_dbg(dev->class_dev, + "failed to write high byte on %d reason %x\n", + chan, status); return -EBUSY; } devpriv->ao_readback[chan] = data[i]; @@ -200,12 +202,13 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int program; program = (it->options[4] & 0x3) << 3 | 0x7; outb(program, dev->iobase + DT2815_DATA); - printk(KERN_INFO ", program: 0x%x (@t=%d)\n", - program, i); + dev_dbg(dev->class_dev, "program: 0x%x (@t=%d)\n", + program, i); break; } else if (status != 0x00) { - printk(KERN_WARNING "dt2815: unexpected status 0x%x " - "(@t=%d)\n", status, i); + dev_dbg(dev->class_dev, + "unexpected status 0x%x (@t=%d)\n", + status, i); if (status & 0x60) outb(0x00, dev->iobase + DT2815_STATUS); } diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index a01e6b553887..895f73a19023 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -63,8 +63,6 @@ Notes: #include "comedi_fc.h" -#define DEBUG - #define DT2821_TIMEOUT 100 /* 500 us */ #define DT2821_SIZE 0x10 @@ -156,55 +154,55 @@ Notes: static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25) + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25) } }; static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, { - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 2.5), - RANGE(0, 1.25) + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) } }; static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, { - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25), - RANGE(-0.625, 0.625) + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) } }; static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, { - RANGE(0, 5), - RANGE(0, 2.5), - RANGE(0, 1.25), - RANGE(0, 0.625), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + UNI_RANGE(0.625) } }; static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, { - RANGE(-10, 10), - RANGE(-1, 1), - RANGE(-0.1, 0.1), - RANGE(-0.02, 0.02) + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02) } }; static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, { - RANGE(0, 10), - RANGE(0, 1), - RANGE(0, 0.1), - RANGE(0, 0.02) + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.02) } }; @@ -308,15 +306,15 @@ static void dt282x_munge(struct comedi_device *dev, unsigned short *buf, static void dt282x_ao_dma_interrupt(struct comedi_device *dev) { struct dt282x_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->write_subdev; void *ptr; int size; int i; - struct comedi_subdevice *s = &dev->subdevices[1]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); if (!s->async->prealloc_buf) { - printk(KERN_ERR "async->data disappeared. dang!\n"); + dev_err(dev->class_dev, "no buffer in %s\n", __func__); return; } @@ -329,7 +327,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); dt282x_ao_cancel(dev, s); s->async->events |= COMEDI_CB_OVERFLOW; return; @@ -341,16 +339,16 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) static void dt282x_ai_dma_interrupt(struct comedi_device *dev) { struct dt282x_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; void *ptr; int size; int i; int ret; - struct comedi_subdevice *s = &dev->subdevices[0]; outw(devpriv->supcsr | DT2821_CLRDMADNE, dev->iobase + DT2821_SUPCSR); if (!s->async->prealloc_buf) { - printk(KERN_ERR "async->data disappeared. dang!\n"); + dev_err(dev->class_dev, "no buffer in %s\n", __func__); return; } @@ -371,7 +369,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) devpriv->nread -= size / 2; if (devpriv->nread < 0) { - printk(KERN_INFO "dt282x: off by one\n"); + dev_info(dev->class_dev, "nread off by one\n"); devpriv->nread = 0; } if (!devpriv->nread) { @@ -450,8 +448,8 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct dt282x_private *devpriv = dev->private; - struct comedi_subdevice *s; - struct comedi_subdevice *s_ao; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_subdevice *s_ao = dev->write_subdev; unsigned int supcsr, adcsr, dacsr; int handled = 0; @@ -460,8 +458,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) return IRQ_HANDLED; } - s = &dev->subdevices[0]; - s_ao = &dev->subdevices[1]; adcsr = inw(dev->iobase + DT2821_ADCSR); dacsr = inw(dev->iobase + DT2821_DACSR); supcsr = inw(dev->iobase + DT2821_SUPCSR); @@ -481,13 +477,6 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) handled = 1; } if (dacsr & DT2821_DAERR) { -#if 0 - static int warn = 5; - if (--warn <= 0) { - disable_irq(dev->irq); - printk(KERN_INFO "disabling irq\n"); - } -#endif comedi_error(dev, "D/A error"); dt282x_ao_cancel(dev, s_ao); s->async->events |= COMEDI_CB_ERROR; @@ -520,8 +509,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) } #endif comedi_event(dev, s); - /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", - adcsr, dacsr, supcsr); */ + return IRQ_RETVAL(handled); } @@ -894,7 +882,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 0, size); @@ -902,7 +890,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf, devpriv->dma_maxsize); if (size == 0) { - printk(KERN_ERR "dt282x: AO underrun\n"); + dev_err(dev->class_dev, "AO underrun\n"); return -EPIPE; } prep_ao_dma(dev, 1, size); @@ -1062,10 +1050,8 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->usedma = 0; - if (!dma1 && !dma2) { - printk(KERN_ERR " (no dma)"); + if (!dma1 && !dma2) return 0; - } if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7) return -EINVAL; @@ -1090,12 +1076,8 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) devpriv->dma_maxsize = PAGE_SIZE; devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA); - if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) { - printk(KERN_ERR " can't get DMA memory"); + if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) return -ENOMEM; - } - - printk(KERN_INFO " (dma=%d,%d)", dma1, dma2); devpriv->usedma = 1; @@ -1120,9 +1102,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dt282x_board *board = comedi_board(dev); struct dt282x_private *devpriv; - int i, irq; - int ret; struct comedi_subdevice *s; + int ret; + int i; ret = comedi_request_region(dev, it->options[0], DT2821_SIZE); if (ret) @@ -1130,14 +1112,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR); i = inw(dev->iobase + DT2821_ADCSR); -#ifdef DEBUG - printk(KERN_DEBUG " fingerprint=%x,%x,%x,%x,%x", - inw(dev->iobase + DT2821_ADCSR), - inw(dev->iobase + DT2821_CHANCSR), - inw(dev->iobase + DT2821_DACSR), - inw(dev->iobase + DT2821_SUPCSR), - inw(dev->iobase + DT2821_TMRCTR)); -#endif if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK) != DT2821_ADCSR_VAL) || @@ -1149,58 +1123,28 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) != DT2821_SUPCSR_VAL) || ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK) != DT2821_TMRCTR_VAL)) { - printk(KERN_ERR " board not found"); + dev_err(dev->class_dev, "board not found\n"); return -EIO; } /* should do board test */ - irq = it->options[opt_irq]; -#if 0 - if (irq < 0) { - unsigned long flags; - int irqs; - - save_flags(flags); - sti(); - irqs = probe_irq_on(); - - /* trigger interrupt */ - - udelay(100); - - irq = probe_irq_off(irqs); - restore_flags(flags); - if (0 /* error */) - printk(KERN_ERR " error probing irq (bad)"); - } -#endif - if (irq > 0) { - printk(KERN_INFO " ( irq = %d )", irq); - ret = request_irq(irq, dt282x_interrupt, 0, + if (it->options[opt_irq] > 0) { + ret = request_irq(it->options[opt_irq], dt282x_interrupt, 0, dev->board_name, dev); - if (ret < 0) { - printk(KERN_ERR " failed to get irq\n"); - return -EIO; - } - dev->irq = irq; - } else if (irq == 0) { - printk(KERN_INFO " (no irq)"); - } else { -#if 0 - printk(KERN_INFO " (probe returned multiple irqs--bad)"); -#else - printk(KERN_INFO " (irq probe not implemented)"); -#endif + if (ret == 0) + dev->irq = it->options[opt_irq]; } devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; - ret = dt282x_grab_dma(dev, it->options[opt_dma1], - it->options[opt_dma2]); - if (ret < 0) - return ret; + if (dev->irq) { + ret = dt282x_grab_dma(dev, it->options[opt_dma1], + it->options[opt_dma2]); + if (ret < 0) + return ret; + } ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -1208,22 +1152,25 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ | + s->subdev_flags = SDF_READABLE | ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON); s->n_chan = (it->options[opt_diff]) ? board->adchan_di : board->adchan_se; s->insn_read = dt282x_ai_insn_read; - s->do_cmdtest = dt282x_ai_cmdtest; - s->do_cmd = dt282x_ai_cmd; - s->cancel = dt282x_ai_cancel; s->maxdata = (1 << board->adbits) - 1; - s->len_chanlist = 16; s->range_table = opt_ai_range_lkup(board->ispgl, it->options[opt_ai_range]); devpriv->ad_2scomp = it->options[opt_ai_twos]; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 16; + s->do_cmdtest = dt282x_ai_cmdtest; + s->do_cmd = dt282x_ai_cmd; + s->cancel = dt282x_ai_cancel; + } s = &dev->subdevices[1]; @@ -1231,15 +1178,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (s->n_chan) { /* ao subsystem */ s->type = COMEDI_SUBD_AO; - dev->write_subdev = s; - s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE; + s->subdev_flags = SDF_WRITABLE; s->insn_read = dt282x_ao_insn_read; s->insn_write = dt282x_ao_insn_write; - s->do_cmdtest = dt282x_ao_cmdtest; - s->do_cmd = dt282x_ao_cmd; - s->cancel = dt282x_ao_cancel; s->maxdata = (1 << board->dabits) - 1; - s->len_chanlist = 2; s->range_table_list = devpriv->darangelist; devpriv->darangelist[0] = opt_ao_range_lkup(it->options[opt_ao0_range]); @@ -1247,6 +1189,14 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) opt_ao_range_lkup(it->options[opt_ao1_range]); devpriv->da0_2scomp = it->options[opt_ao0_twos]; devpriv->da1_2scomp = it->options[opt_ao1_twos]; + if (dev->irq) { + dev->write_subdev = s; + s->subdev_flags |= SDF_CMD_WRITE; + s->len_chanlist = 2; + s->do_cmdtest = dt282x_ao_cmdtest; + s->do_cmd = dt282x_ao_cmd; + s->cancel = dt282x_ao_cancel; + } } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1261,8 +1211,6 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->maxdata = 1; s->range_table = &range_digital; - printk(KERN_INFO "\n"); - return 0; } diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 292226eeff92..f52a4476cb73 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -48,8 +48,6 @@ AO commands are not supported. you the docs without one, also. */ -#define DEBUG 1 - #include #include #include @@ -253,24 +251,6 @@ struct dt3k_private { unsigned int ai_rear; }; -#ifdef DEBUG -static char *intr_flags[] = { - "AdFull", "AdSwError", "AdHwError", "DaEmpty", - "DaSwError", "DaHwError", "CtDone", "CmDone", -}; - -static void debug_intr_flags(unsigned int flags) -{ - int i; - printk(KERN_DEBUG "dt3k: intr_flags:"); - for (i = 0; i < 8; i++) { - if (flags & (1 << i)) - printk(KERN_CONT " %s", intr_flags[i]); - } - printk(KERN_CONT "\n"); -} -#endif - #define TIMEOUT 100 static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) @@ -372,17 +352,13 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct dt3k_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s = dev->read_subdev; unsigned int status; if (!dev->attached) return IRQ_NONE; - s = &dev->subdevices[0]; status = readw(devpriv->io_addr + DPR_Intr_Flag); -#ifdef DEBUG - debug_intr_flags(status); -#endif if (status & DT3000_ADFULL) { dt3k_ai_empty_fifo(dev, s); @@ -725,29 +701,33 @@ static int dt3000_auto_attach(struct comedi_device *dev, if (!devpriv->io_addr) return -ENOMEM; - ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret) - return ret; - dev->irq = pcidev->irq; + if (pcidev->irq) { + ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->n_chan = this_board->adchan; s->insn_read = dt3k_ai_insn; s->maxdata = (1 << this_board->adbits) - 1; - s->len_chanlist = 512; s->range_table = &range_dt3000_ai; /* XXX */ - s->do_cmd = dt3k_ai_cmd; - s->do_cmdtest = dt3k_ai_cmdtest; - s->cancel = dt3k_ai_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 512; + s->do_cmd = dt3k_ai_cmd; + s->do_cmdtest = dt3k_ai_cmdtest; + s->cancel = dt3k_ai_cancel; + } s = &dev->subdevices[1]; /* ao subsystem */ @@ -818,7 +798,7 @@ static int dt3000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &dt3000_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { +static const struct pci_device_id dt3000_pci_table[] = { { PCI_VDEVICE(DT, 0x0022), BOARD_DT3001 }, { PCI_VDEVICE(DT, 0x0023), BOARD_DT3002 }, { PCI_VDEVICE(DT, 0x0024), BOARD_DT3003 }, diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 73af600c1725..b3aeb6fb2ad0 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -41,7 +41,6 @@ for my needs. #include #include #include -#include #include #include diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index f2a9f1c2f3b6..f224825830ba 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -42,11 +42,12 @@ #define READ_TIMEOUT 50 -static const struct comedi_lrange range_pci1050_ai = { 3, { - BIP_RANGE(10), - BIP_RANGE(5), - UNI_RANGE(10) - } +static const struct comedi_lrange range_pci1050_ai = { + 3, { + BIP_RANGE(10), + BIP_RANGE(5), + UNI_RANGE(10) + } }; static const char range_codes_pci1050_ai[] = { 0x00, 0x10, 0x30 }; @@ -90,8 +91,7 @@ static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, goto conv_finish; } data[n] = 0; - printk(KERN_DEBUG "comedi: dyna_pci10xx: " - "timeout reading analog input\n"); + dev_dbg(dev->class_dev, "timeout reading analog input\n"); continue; conv_finish: /* mask the first 4 bits - EOC bits */ @@ -260,7 +260,7 @@ static int dyna_pci10xx_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { +static const struct pci_device_id dyna_pci10xx_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index e3ff4c438979..a99ddf00ddc4 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -16,8 +16,6 @@ Configuration options: [0] - I/O port base address */ -#define DEBUG 0 - #include #include "../comedidev.h" @@ -28,15 +26,16 @@ struct fl512_private { unsigned short ao_readback[2]; }; -static const struct comedi_lrange range_fl512 = { 4, { - BIP_RANGE(0.5), - BIP_RANGE(1), - BIP_RANGE(5), - BIP_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(5), - UNI_RANGE(10), - } +static const struct comedi_lrange range_fl512 = { + 4, { + BIP_RANGE(0.5), + BIP_RANGE(1), + BIP_RANGE(5), + BIP_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(5), + UNI_RANGE(10) + } }; /* diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 559bf5583530..de60a2871d70 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -60,15 +60,6 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static irqreturn_t handle_interrupt(int irq, void *d); static int dio_config_block_size(struct comedi_device *dev, unsigned int *data); -#undef HPDI_DEBUG /* disable debugging messages */ -/* #define HPDI_DEBUG enable debugging code */ - -#ifdef HPDI_DEBUG -#define DEBUG_PRINT(format, args...) pr_debug(format , ## args) -#else -#define DEBUG_PRINT(format, args...) no_printk(pr_fmt(format), ## args) -#endif - #define TIMER_BASE 50 /* 20MHz master clock */ #define DMA_BUFFER_SIZE 0x10000 #define NUM_DMA_BUFFERS 4 @@ -260,32 +251,6 @@ static void init_plx9080(struct comedi_device *dev) uint32_t bits; void __iomem *plx_iobase = devpriv->plx9080_iobase; - /* plx9080 dump */ - DEBUG_PRINT(" plx interrupt status 0x%x\n", - readl(plx_iobase + PLX_INTRCS_REG)); - DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", - readl(devpriv->plx9080_iobase + PLX_CONTROL_REG)); - - DEBUG_PRINT(" plx revision 0x%x\n", - readl(plx_iobase + PLX_REVISION_REG)); - DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n", - readl(plx_iobase + PLX_DMA0_MODE_REG)); - DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n", - readl(plx_iobase + PLX_DMA1_MODE_REG)); - DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n", - readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n", - readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG)); - DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n", - readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG)); - DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n", - readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG)); - DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n", - readb(plx_iobase + PLX_DMA0_CS_REG)); - DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n", - readl(plx_iobase + PLX_DMA0_THRESHOLD_REG)); - DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG)); #ifdef __BIG_ENDIAN bits = BIGEND_DMA0 | BIGEND_DMA1; #else @@ -395,10 +360,6 @@ static int setup_dma_descriptors(struct comedi_device *dev, if (transfer_size == 0) return -1; - DEBUG_PRINT(" transfer_size %i\n", transfer_size); - DEBUG_PRINT(" descriptors at 0x%lx\n", - (unsigned long)devpriv->dma_desc_phys_addr); - buffer_offset = 0; buffer_index = 0; for (i = 0; i < NUM_DMA_DESCRIPTORS && @@ -423,21 +384,11 @@ static int setup_dma_descriptors(struct comedi_device *dev, buffer_offset = 0; buffer_index++; } - - DEBUG_PRINT(" desc %i\n", i); - DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n", - devpriv->desc_dio_buffer[i], - (unsigned long)devpriv->dma_desc[i]. - pci_start_addr); - DEBUG_PRINT(" next 0x%lx\n", - (unsigned long)devpriv->dma_desc[i].next); } devpriv->num_dma_descriptors = i; /* fix last descriptor to point back to first */ devpriv->dma_desc[i - 1].next = cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits); - DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1, - (unsigned long)devpriv->dma_desc[i - 1].next); devpriv->block_size = transfer_size; @@ -489,9 +440,6 @@ static int hpdi_auto_attach(struct comedi_device *dev, return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase); - init_plx9080(dev); /* get irq */ @@ -510,9 +458,6 @@ static int hpdi_auto_attach(struct comedi_device *dev, devpriv->dio_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->dio_buffer_phys_addr[i]); - DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n", - devpriv->dio_buffer[i], - (unsigned long)devpriv->dio_buffer_phys_addr[i]); } /* allocate dma descriptors */ devpriv->dma_desc = pci_alloc_consistent(pcidev, @@ -687,8 +632,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG); - DEBUG_PRINT("hpdi: in di_cmd\n"); - abort_dma(dev, 0); devpriv->dma_desc_index = 0; @@ -725,7 +668,6 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(intr_bit(RX_FULL_INTR), devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); - DEBUG_PRINT("hpdi: starting rx\n"); hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG); return 0; @@ -778,11 +720,6 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) num_samples * sizeof(uint32_t)); devpriv->dma_desc_index++; devpriv->dma_desc_index %= devpriv->num_dma_descriptors; - - DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long) - devpriv->dma_desc[devpriv->dma_desc_index]. - next); - DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } /* XXX check for buffer overrun somehow */ } @@ -812,7 +749,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) async->events = 0; if (hpdi_intr_status) { - DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status); writel(hpdi_intr_status, devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); } @@ -823,10 +759,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); - DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) drain_dma_buffers(dev, 0); - DEBUG_PRINT(" cleared dma ch0 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -836,9 +770,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA1_CS_REG); - DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); - - DEBUG_PRINT(" cleared dma ch1 interrupt\n"); } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -846,15 +777,11 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); - DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } if (hpdi_board_status & RX_OVERRUN_BIT) { comedi_error(dev, "rx fifo overrun"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; - DEBUG_PRINT("dma0_status 0x%x\n", - (int)readb(devpriv->plx9080_iobase + - PLX_DMA0_CS_REG)); } if (hpdi_board_status & RX_UNDERRUN_BIT) { @@ -865,11 +792,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; - DEBUG_PRINT("board status 0x%x, ", hpdi_board_status); - DEBUG_PRINT("plx status 0x%x\n", plx_status); - if (async->events) - DEBUG_PRINT(" events 0x%x\n", async->events); - cfc_handle_events(dev, s); return IRQ_HANDLED; @@ -914,7 +836,7 @@ static int gsc_hpdi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(gsc_hpdi_pci_table) = { +static const struct pci_device_id gsc_hpdi_pci_table[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400, 0, 0, 0}, { 0 } diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 1e16641ec52d..80539b2bea1a 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -91,12 +91,13 @@ Configuration options: not applicable, uses PCI auto config #define Status_IRQ 0x00ff /* All interrupts */ /* Define analogue range */ -static const struct comedi_lrange range_analog = { 4, { - UNI_RANGE(5), - UNI_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(10) - } +static const struct comedi_lrange range_analog = { + 4, { + UNI_RANGE(5), + UNI_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(10) + } }; static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 }; @@ -597,7 +598,7 @@ static int icp_multi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &icp_multi_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(icp_multi_pci_table) = { +static const struct pci_device_id icp_multi_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_ICP, PCI_DEVICE_ID_ICP_MULTI) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index b52d58e5de27..6100c12c164f 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -807,7 +807,7 @@ static int jr3_pci_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { +static const struct pci_device_id jr3_pci_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL) }, { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW) }, { PCI_DEVICE(PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL) }, diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 15589f62a619..6b9846fd8c48 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -139,7 +139,7 @@ static int ke_counter_pci_probe(struct pci_dev *dev, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ke_counter_pci_table) = { +static const struct pci_device_id ke_counter_pci_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID) }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 3d12e9135926..e739bcd66a04 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -328,13 +328,12 @@ static const struct me4000_board me4000_boards[] = { }; static const struct comedi_lrange me4000_ai_range = { - 4, - { - UNI_RANGE(2.5), - UNI_RANGE(10), - BIP_RANGE(2.5), - BIP_RANGE(10), - } + 4, { + UNI_RANGE(2.5), + UNI_RANGE(10), + BIP_RANGE(2.5), + BIP_RANGE(10) + } }; #define FIRMWARE_NOT_AVAILABLE 1 @@ -1105,7 +1104,7 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) { unsigned int tmp; struct comedi_device *dev = dev_id; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i; int c = 0; unsigned int lval; @@ -1116,12 +1115,6 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) /* Reset all events */ s->async->events = 0; - /* Check if irq number is right */ - if (irq != dev->irq) { - dev_err(dev->class_dev, "Incorrect interrupt num: %d\n", irq); - return IRQ_HANDLED; - } - if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & ME4000_IRQ_STATUS_BIT_AI_HF) { /* Read status register to find out what happened */ @@ -1505,6 +1498,13 @@ static int me4000_auto_attach(struct comedi_device *dev, me4000_reset(dev); + if (pcidev->irq > 0) { + result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED, + dev->board_name, dev); + if (result == 0) + dev->irq = pcidev->irq; + } + result = comedi_alloc_subdevices(dev, 4); if (result) return result; @@ -1525,22 +1525,12 @@ static int me4000_auto_attach(struct comedi_device *dev, s->range_table = &me4000_ai_range; s->insn_read = me4000_ai_insn_read; - if (pcidev->irq > 0) { - if (request_irq(pcidev->irq, me4000_ai_isr, - IRQF_SHARED, dev->board_name, dev)) { - dev_warn(dev->class_dev, - "request_irq failed\n"); - } else { - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = me4000_ai_cancel; - s->do_cmdtest = me4000_ai_do_cmd_test; - s->do_cmd = me4000_ai_do_cmd; - - dev->irq = pcidev->irq; - } - } else { - dev_warn(dev->class_dev, "No interrupt available\n"); + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->cancel = me4000_ai_cancel; + s->do_cmdtest = me4000_ai_do_cmd_test; + s->do_cmd = me4000_ai_do_cmd; } } else { s->type = COMEDI_SUBD_UNUSED; @@ -1635,7 +1625,7 @@ static int me4000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = { +static const struct pci_device_id me4000_pci_table[] = { { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 }, { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 }, { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I }, diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 24ec9ef9b1a0..7f6687896401 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -576,7 +576,7 @@ static int me_daq_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me_daq_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(me_daq_pci_table) = { +static const struct pci_device_id me_daq_pci_table[] = { { PCI_VDEVICE(MEILHAUS, 0x2600), BOARD_ME2600 }, { PCI_VDEVICE(MEILHAUS, 0x2000), BOARD_ME2000 }, { 0 } diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c new file mode 100644 index 000000000000..81b78e053f4e --- /dev/null +++ b/drivers/staging/comedi/drivers/mf6x4.c @@ -0,0 +1,354 @@ +/* + * comedi/drivers/mf6x4.c + * Driver for Humusoft MF634 and MF624 Data acquisition cards + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2000 David A. Schleef + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +/* + * Driver: mf6x4 + * Description: Humusoft MF634 and MF624 Data acquisition card driver + * Devices: Humusoft MF634, Humusoft MF624 + * Author: Rostislav Lisovy + * Status: works + * Updated: + * Configuration Options: none + */ + +#include +#include +#include +#include "../comedidev.h" + +/* Registers present in BAR0 memory region */ +#define MF624_GPIOC_R 0x54 + +#define MF6X4_GPIOC_EOLC /* End Of Last Conversion */ (1 << 17) +#define MF6X4_GPIOC_LDAC /* Load DACs */ (1 << 23) +#define MF6X4_GPIOC_DACEN (1 << 26) + +/* BAR1 registers */ +#define MF6X4_DIN_R 0x10 +#define MF6X4_DIN_M 0xff +#define MF6X4_DOUT_R 0x10 +#define MF6X4_DOUT_M 0xff + +#define MF6X4_ADSTART_R 0x20 +#define MF6X4_ADDATA_R 0x00 +#define MF6X4_ADCTRL_R 0x00 +#define MF6X4_ADCTRL_M 0xff + +#define MF6X4_DA0_R 0x20 +#define MF6X4_DA1_R 0x22 +#define MF6X4_DA2_R 0x24 +#define MF6X4_DA3_R 0x26 +#define MF6X4_DA4_R 0x28 +#define MF6X4_DA5_R 0x2a +#define MF6X4_DA6_R 0x2c +#define MF6X4_DA7_R 0x2e +/* Map DAC cahnnel id to real HW-dependent offset value */ +#define MF6X4_DAC_R(x) (0x20 + ((x) * 2)) +#define MF6X4_DA_M 0x3fff + +/* BAR2 registers */ +#define MF634_GPIOC_R 0x68 + +enum mf6x4_boardid { + BOARD_MF634, + BOARD_MF624, +}; + +struct mf6x4_board { + const char *name; + unsigned int bar_nums[3]; /* We need to keep track of the + order of BARs used by the cards */ +}; + +static const struct mf6x4_board mf6x4_boards[] = { + [BOARD_MF634] = { + .name = "mf634", + .bar_nums = {0, 2, 3}, + }, + [BOARD_MF624] = { + .name = "mf624", + .bar_nums = {0, 2, 4}, + }, +}; + +struct mf6x4_private { + /* + * Documentation for both MF634 and MF624 describes registers + * present in BAR0, 1 and 2 regions. + * The real (i.e. in HW) BAR numbers are different for MF624 + * and MF634 yet we will call them 0, 1, 2 + */ + void __iomem *bar0_mem; + void __iomem *bar1_mem; + void __iomem *bar2_mem; + + /* + * This configuration register has the same function and fields + * for both cards however it lies in different BARs on different + * offsets -- this variable makes the access easier + */ + void __iomem *gpioc_R; + + /* DAC value cache -- used for insn_read function */ + int ao_readback[8]; +}; + +static int mf6x4_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct mf6x4_private *devpriv = dev->private; + + data[1] = ioread16(devpriv->bar1_mem + MF6X4_DIN_R) & MF6X4_DIN_M; + + return insn->n; +} + +static int mf6x4_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct mf6x4_private *devpriv = dev->private; + + if (comedi_dio_update_state(s, data)) + iowrite16(s->state & MF6X4_DOUT_M, + devpriv->bar1_mem + MF6X4_DOUT_R); + + data[1] = s->state; + + return insn->n; +} + +static int mf6x4_ai_wait_for_eoc(struct comedi_device *dev, + unsigned int timeout) +{ + struct mf6x4_private *devpriv = dev->private; + unsigned int eolc; + + while (timeout--) { + eolc = ioread32(devpriv->gpioc_R) & MF6X4_GPIOC_EOLC; + if (eolc) + return 0; + + udelay(1); + } + + return -ETIME; +} + +static int mf6x4_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct mf6x4_private *devpriv = dev->private; + int chan = CR_CHAN(insn->chanspec); + int ret; + int i; + int d; + + /* Set the ADC channel number in the scan list */ + iowrite16((1 << chan) & MF6X4_ADCTRL_M, + devpriv->bar1_mem + MF6X4_ADCTRL_R); + + for (i = 0; i < insn->n; i++) { + /* Trigger ADC conversion by reading ADSTART */ + ioread16(devpriv->bar1_mem + MF6X4_ADSTART_R); + + ret = mf6x4_ai_wait_for_eoc(dev, 100); + if (ret) + return ret; + + /* Read the actual value */ + d = ioread16(devpriv->bar1_mem + MF6X4_ADDATA_R); + d &= s->maxdata; + data[i] = d; + } + + iowrite16(0x0, devpriv->bar1_mem + MF6X4_ADCTRL_R); + + return insn->n; +} + +static int mf6x4_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct mf6x4_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + uint32_t gpioc; + int i; + + /* Enable instantaneous update of converters outputs + Enable DACs */ + gpioc = ioread32(devpriv->gpioc_R); + iowrite32((gpioc & ~MF6X4_GPIOC_LDAC) | MF6X4_GPIOC_DACEN, + devpriv->gpioc_R); + + for (i = 0; i < insn->n; i++) { + iowrite16(data[i] & MF6X4_DA_M, + devpriv->bar1_mem + MF6X4_DAC_R(chan)); + + devpriv->ao_readback[chan] = data[i]; + } + + return insn->n; +} + +static int mf6x4_ao_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct mf6x4_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + int i; + + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_readback[chan]; + + return insn->n; +} + +static int mf6x4_auto_attach(struct comedi_device *dev, unsigned long context) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct mf6x4_board *board = NULL; + struct mf6x4_private *devpriv; + struct comedi_subdevice *s; + int ret; + + if (context < ARRAY_SIZE(mf6x4_boards)) + board = &mf6x4_boards[context]; + else + return -ENODEV; + + dev->board_ptr = board; + dev->board_name = board->name; + + ret = comedi_pci_enable(dev); + if (ret) + return ret; + + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + + devpriv->bar0_mem = pci_ioremap_bar(pcidev, board->bar_nums[0]); + if (!devpriv->bar0_mem) + return -ENODEV; + + devpriv->bar1_mem = pci_ioremap_bar(pcidev, board->bar_nums[1]); + if (!devpriv->bar1_mem) + return -ENODEV; + + devpriv->bar2_mem = pci_ioremap_bar(pcidev, board->bar_nums[2]); + if (!devpriv->bar2_mem) + return -ENODEV; + + if (board == &mf6x4_boards[BOARD_MF634]) + devpriv->gpioc_R = devpriv->bar2_mem + MF634_GPIOC_R; + else + devpriv->gpioc_R = devpriv->bar0_mem + MF624_GPIOC_R; + + + ret = comedi_alloc_subdevices(dev, 4); + if (ret) + return ret; + + /* ADC */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->n_chan = 8; + s->maxdata = 0x3fff; /* 14 bits ADC */ + s->range_table = &range_bipolar10; + s->insn_read = mf6x4_ai_insn_read; + + /* DAC */ + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 0x3fff; /* 14 bits DAC */ + s->range_table = &range_bipolar10; + s->insn_write = mf6x4_ao_insn_write; + s->insn_read = mf6x4_ao_insn_read; + + /* DIN */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = mf6x4_di_insn_bits; + + /* DOUT */ + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = mf6x4_do_insn_bits; + + return 0; +} + +static void mf6x4_detach(struct comedi_device *dev) +{ + struct mf6x4_private *devpriv = dev->private; + + if (devpriv->bar0_mem) + iounmap(devpriv->bar0_mem); + if (devpriv->bar1_mem) + iounmap(devpriv->bar1_mem); + if (devpriv->bar2_mem) + iounmap(devpriv->bar2_mem); + + comedi_pci_disable(dev); +} + +static struct comedi_driver mf6x4_driver = { + .driver_name = "mf6x4", + .module = THIS_MODULE, + .auto_attach = mf6x4_auto_attach, + .detach = mf6x4_detach, +}; + +static int mf6x4_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + return comedi_pci_auto_config(dev, &mf6x4_driver, id->driver_data); +} + +static const struct pci_device_id mf6x4_pci_table[] = { + { PCI_VDEVICE(HUMUSOFT, 0x0634), BOARD_MF634 }, + { PCI_VDEVICE(HUMUSOFT, 0x0624), BOARD_MF624 }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, mf6x4_pci_table); + +static struct pci_driver mf6x4_pci_driver = { + .name = "mf6x4", + .id_table = mf6x4_pci_table, + .probe = mf6x4_pci_probe, + .remove = comedi_pci_auto_unconfig, +}; + +module_comedi_pci_driver(mf6x4_driver, mf6x4_pci_driver); + +MODULE_AUTHOR("Rostislav Lisovy "); +MODULE_DESCRIPTION("Comedi MF634 and MF624 DAQ cards driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 35cb4ace7970..9c9a0ee432cf 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -288,7 +288,6 @@ void mite_dma_arm(struct mite_channel *mite_chan) int chor; unsigned long flags; - MDPRINTK("mite_dma_arm ch%i\n", mite_chan->channel); /* * memory barrier is intended to insure any twiddling with the buffer * is done before writing to the mite to arm dma transfer @@ -329,8 +328,6 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, n_links = async->prealloc_bufsz >> PAGE_SHIFT; - MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links); - ring->descriptors = dma_alloc_coherent(ring->hw_dev, n_links * sizeof(struct mite_dma_descriptor), @@ -345,7 +342,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, for (i = 0; i < n_links; i++) { ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE); ring->descriptors[i].addr = - cpu_to_le32(async->buf_page_list[i].dma_addr); + cpu_to_le32(async->buf_map->page_list[i].dma_addr); ring->descriptors[i].next = cpu_to_le32(ring->descriptors_dma_addr + (i + 1) * @@ -368,8 +365,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, unsigned int chor, chcr, mcr, dcr, lkcr; struct mite_struct *mite = mite_chan->mite; - MDPRINTK("mite_prep_dma ch%i\n", mite_chan->channel); - /* reset DMA and FIFO */ chor = CHOR_DMARESET | CHOR_FRESET; writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); @@ -448,8 +443,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, /* starting address for link chaining */ writel(mite_chan->ring->descriptors_dma_addr, mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); - - MDPRINTK("exit mite_prep_dma\n"); } EXPORT_SYMBOL_GPL(mite_prep_dma); @@ -515,8 +508,6 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan) lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel)); tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel)); - MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel, - lkar, tcr); return tcr; } @@ -642,140 +633,6 @@ int mite_done(struct mite_channel *mite_chan) } EXPORT_SYMBOL_GPL(mite_done); -#ifdef DEBUG_MITE - -/* names of bits in mite registers */ - -static const char *const mite_CHOR_strings[] = { - "start", "cont", "stop", "abort", - "freset", "clrlc", "clrrb", "clrdone", - "clr_lpause", "set_lpause", "clr_send_tc", - "set_send_tc", "12", "13", "14", - "15", "16", "17", "18", - "19", "20", "21", "22", - "23", "24", "25", "26", - "27", "28", "29", "30", - "dmareset", -}; - -static const char *const mite_CHCR_strings[] = { - "continue", "ringbuff", "2", "3", - "4", "5", "6", "7", - "8", "9", "10", "11", - "12", "13", "bursten", "fifodis", - "clr_cont_rb_ie", "set_cont_rb_ie", "clr_lc_ie", "set_lc_ie", - "clr_drdy_ie", "set_drdy_ie", "clr_mrdy_ie", "set_mrdy_ie", - "clr_done_ie", "set_done_ie", "clr_sar_ie", "set_sar_ie", - "clr_linkp_ie", "set_linkp_ie", "clr_dma_ie", "set_dma_ie", -}; - -static const char *const mite_MCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "11", - "12", "13", "blocken", "berhand", - "reqsintlim/reqs0", "reqs1", "reqs2", "rd32", - "rd512", "rl1", "rl2", "rl8", - "24", "25", "26", "27", - "28", "29", "30", "stopen", -}; - -static const char *const mite_DCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "aseqxp1", "aseqxp2", - "aseqxp8", "13", "blocken", "berhand", - "reqsintlim", "reqs1", "reqs2", "rd32", - "rd512", "rl1", "rl2", "rl8", - "23", "24", "25", "27", - "28", "wsdevc", "wsdevs", "rwdevpack", -}; - -static const char *const mite_LKCR_strings[] = { - "amdevice", "1", "2", "3", - "4", "5", "portio", "portvxi", - "psizebyte", "psizehalf (byte & half = word)", "asequp", "aseqdown", - "12", "13", "14", "berhand", - "16", "17", "18", "rd32", - "rd512", "rl1", "rl2", "rl8", - "24", "25", "26", "27", - "28", "29", "30", "chngend", -}; - -static const char *const mite_CHSR_strings[] = { - "d.err0", "d.err1", "m.err0", "m.err1", - "l.err0", "l.err1", "drq0", "drq1", - "end", "xferr", "operr0", "operr1", - "stops", "habort", "sabort", "error", - "16", "conts_rb", "18", "linkc", - "20", "drdy", "22", "mrdy", - "24", "done", "26", "sars", - "28", "lpauses", "30", "int", -}; - -static void mite_decode(const char *const *bit_str, unsigned int bits) -{ - int i; - - for (i = 31; i >= 0; i--) { - if (bits & (1 << i)) - pr_debug(" %s\n", bit_str[i]); - } -} - -void mite_dump_regs(struct mite_channel *mite_chan) -{ - void __iomem *mite_io_addr = mite_chan->mite->mite_io_addr; - unsigned int offset; - unsigned int value; - int channel = mite_chan->channel; - - pr_debug("mite_dump_regs ch%i\n", channel); - pr_debug("mite address is =%p\n", mite_io_addr); - - offset = MITE_CHOR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHOR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHOR_strings, value); - offset = MITE_CHCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHCR_strings, value); - offset = MITE_TCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[TCR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_MCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[MCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_MCR_strings, value); - offset = MITE_MAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[MAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_DCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[DCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_DCR_strings, value); - offset = MITE_DAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[DAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_LKCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[LKCR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_LKCR_strings, value); - offset = MITE_LKAR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[LKAR] at 0x%08x =0x%08x\n", offset, value); - offset = MITE_CHSR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[CHSR] at 0x%08x =0x%08x\n", offset, value); - mite_decode(mite_CHSR_strings, value); - offset = MITE_FCR(channel); - value = readl(mite_io_addr + offset); - pr_debug("mite status[FCR] at 0x%08x =0x%08x\n", offset, value); -} -EXPORT_SYMBOL_GPL(mite_dump_regs); -#endif - static int __init mite_module_init(void) { return 0; diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 8423b8bf3384..bcf2f972376e 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -24,15 +24,8 @@ #include #include "../comedidev.h" -/* #define DEBUG_MITE */ #define PCIMIO_COMPAT -#ifdef DEBUG_MITE -#define MDPRINTK(format, args...) pr_debug(format , ## args) -#else -#define MDPRINTK(format, args...) do { } while (0) -#endif - #define MAX_MITE_DMA_CHANNELS 8 struct mite_dma_descriptor { @@ -129,11 +122,6 @@ void mite_prep_dma(struct mite_channel *mite_chan, int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *async); -#ifdef DEBUG_MITE -void mite_print_chsr(unsigned int chsr); -void mite_dump_regs(struct mite_channel *mite_chan); -#endif - static inline int CHAN_OFFSET(int channel) { return 0x500 + 0x100 * channel; diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index acbaeee6250c..fe4621ea65c3 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -159,11 +159,6 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, * We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc */ outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH); -/* printk("Channel %d:\n", insn->chanspec); */ - if (!insn->n) { - printk(KERN_INFO "MPC624: Warning, no data to acquire\n"); - return 0; - } for (n = 0; n < insn->n; n++) { /* Trigger the conversion */ @@ -182,11 +177,9 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, else break; } - if (i == TIMEOUT) { - printk(KERN_ERR "MPC624: timeout (%dms)\n", TIMEOUT); - data[n] = 0; + if (i == TIMEOUT) return -ETIMEDOUT; - } + /* Start reading data */ data_in = 0; data_out = devpriv->ulConvertionRate; @@ -245,11 +238,11 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, */ if (data_in & MPC624_EOC_BIT) - printk(KERN_INFO "MPC624:EOC bit is set (data_in=%lu)!", - data_in); + dev_dbg(dev->class_dev, + "EOC bit is set (data_in=%lu)!", data_in); if (data_in & MPC624_DMY_BIT) - printk(KERN_INFO "MPC624:DMY bit is set (data_in=%lu)!", - data_in); + dev_dbg(dev->class_dev, + "DMY bit is set (data_in=%lu)!", data_in); if (data_in & MPC624_SGN_BIT) { /* Volatge is positive */ /* * comedi operates on unsigned numbers, so mask off EOC diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 85aa9609d6a2..860fc81fb11c 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -455,7 +455,7 @@ static int ni6527_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = { +static const struct pci_device_id ni6527_pci_table[] = { { PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 }, { PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 }, { 0 } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 853f62b2b1a9..6e42001f686e 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -43,9 +43,6 @@ except maybe the 6514. */ -#define DEBUG 1 -#define DEBUG_FLAGS - #include #include #include @@ -430,7 +427,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct ni_65xx_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[2]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int status; status = readb(devpriv->mite->daq_io_addr + Change_Status); @@ -741,7 +738,7 @@ static int ni_65xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_65xx_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = { +static const struct pci_device_id ni_65xx_pci_table[] = { { PCI_VDEVICE(NI, 0x1710), BOARD_PXI6509 }, { PCI_VDEVICE(NI, 0x7085), BOARD_PCI6509 }, { PCI_VDEVICE(NI, 0x7086), BOARD_PXI6528 }, diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 8a991dcab24a..df42e3906171 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -55,112 +55,112 @@ for 4 */ #define MAX_DMA_CHANNEL 4 /* See Register-Level Programmer Manual page 3.1 */ -enum NI_660x_Register { - G0InterruptAcknowledge, - G0StatusRegister, - G1InterruptAcknowledge, - G1StatusRegister, - G01StatusRegister, - G0CommandRegister, - STCDIOParallelInput, - G1CommandRegister, - G0HWSaveRegister, - G1HWSaveRegister, - STCDIOOutput, - STCDIOControl, - G0SWSaveRegister, - G1SWSaveRegister, - G0ModeRegister, - G01JointStatus1Register, - G1ModeRegister, - STCDIOSerialInput, - G0LoadARegister, - G01JointStatus2Register, - G0LoadBRegister, - G1LoadARegister, - G1LoadBRegister, - G0InputSelectRegister, - G1InputSelectRegister, - G0AutoincrementRegister, - G1AutoincrementRegister, - G01JointResetRegister, - G0InterruptEnable, - G1InterruptEnable, - G0CountingModeRegister, - G1CountingModeRegister, - G0SecondGateRegister, - G1SecondGateRegister, - G0DMAConfigRegister, - G0DMAStatusRegister, - G1DMAConfigRegister, - G1DMAStatusRegister, - G2InterruptAcknowledge, - G2StatusRegister, - G3InterruptAcknowledge, - G3StatusRegister, - G23StatusRegister, - G2CommandRegister, - G3CommandRegister, - G2HWSaveRegister, - G3HWSaveRegister, - G2SWSaveRegister, - G3SWSaveRegister, - G2ModeRegister, - G23JointStatus1Register, - G3ModeRegister, - G2LoadARegister, - G23JointStatus2Register, - G2LoadBRegister, - G3LoadARegister, - G3LoadBRegister, - G2InputSelectRegister, - G3InputSelectRegister, - G2AutoincrementRegister, - G3AutoincrementRegister, - G23JointResetRegister, - G2InterruptEnable, - G3InterruptEnable, - G2CountingModeRegister, - G3CountingModeRegister, - G3SecondGateRegister, - G2SecondGateRegister, - G2DMAConfigRegister, - G2DMAStatusRegister, - G3DMAConfigRegister, - G3DMAStatusRegister, - DIO32Input, - DIO32Output, - ClockConfigRegister, - GlobalInterruptStatusRegister, - DMAConfigRegister, - GlobalInterruptConfigRegister, - IOConfigReg0_1, - IOConfigReg2_3, - IOConfigReg4_5, - IOConfigReg6_7, - IOConfigReg8_9, - IOConfigReg10_11, - IOConfigReg12_13, - IOConfigReg14_15, - IOConfigReg16_17, - IOConfigReg18_19, - IOConfigReg20_21, - IOConfigReg22_23, - IOConfigReg24_25, - IOConfigReg26_27, - IOConfigReg28_29, - IOConfigReg30_31, - IOConfigReg32_33, - IOConfigReg34_35, - IOConfigReg36_37, - IOConfigReg38_39, - NumRegisters, +enum ni_660x_register { + NI660X_G0_INT_ACK, + NI660X_G0_STATUS, + NI660X_G1_INT_ACK, + NI660X_G1_STATUS, + NI660X_G01_STATUS, + NI660X_G0_CMD, + NI660X_STC_DIO_PARALLEL_INPUT, + NI660X_G1_CMD, + NI660X_G0_HW_SAVE, + NI660X_G1_HW_SAVE, + NI660X_STC_DIO_OUTPUT, + NI660X_STC_DIO_CONTROL, + NI660X_G0_SW_SAVE, + NI660X_G1_SW_SAVE, + NI660X_G0_MODE, + NI660X_G01_STATUS1, + NI660X_G1_MODE, + NI660X_STC_DIO_SERIAL_INPUT, + NI660X_G0_LOADA, + NI660X_G01_STATUS2, + NI660X_G0_LOADB, + NI660X_G1_LOADA, + NI660X_G1_LOADB, + NI660X_G0_INPUT_SEL, + NI660X_G1_INPUT_SEL, + NI660X_G0_AUTO_INC, + NI660X_G1_AUTO_INC, + NI660X_G01_RESET, + NI660X_G0_INT_ENA, + NI660X_G1_INT_ENA, + NI660X_G0_CNT_MODE, + NI660X_G1_CNT_MODE, + NI660X_G0_GATE2, + NI660X_G1_GATE2, + NI660X_G0_DMA_CFG, + NI660X_G0_DMA_STATUS, + NI660X_G1_DMA_CFG, + NI660X_G1_DMA_STATUS, + NI660X_G2_INT_ACK, + NI660X_G2_STATUS, + NI660X_G3_INT_ACK, + NI660X_G3_STATUS, + NI660X_G23_STATUS, + NI660X_G2_CMD, + NI660X_G3_CMD, + NI660X_G2_HW_SAVE, + NI660X_G3_HW_SAVE, + NI660X_G2_SW_SAVE, + NI660X_G3_SW_SAVE, + NI660X_G2_MODE, + NI660X_G23_STATUS1, + NI660X_G3_MODE, + NI660X_G2_LOADA, + NI660X_G23_STATUS2, + NI660X_G2_LOADB, + NI660X_G3_LOADA, + NI660X_G3_LOADB, + NI660X_G2_INPUT_SEL, + NI660X_G3_INPUT_SEL, + NI660X_G2_AUTO_INC, + NI660X_G3_AUTO_INC, + NI660X_G23_RESET, + NI660X_G2_INT_ENA, + NI660X_G3_INT_ENA, + NI660X_G2_CNT_MODE, + NI660X_G3_CNT_MODE, + NI660X_G3_GATE2, + NI660X_G2_GATE2, + NI660X_G2_DMA_CFG, + NI660X_G2_DMA_STATUS, + NI660X_G3_DMA_CFG, + NI660X_G3_DMA_STATUS, + NI660X_DIO32_INPUT, + NI660X_DIO32_OUTPUT, + NI660X_CLK_CFG, + NI660X_GLOBAL_INT_STATUS, + NI660X_DMA_CFG, + NI660X_GLOBAL_INT_CFG, + NI660X_IO_CFG_0_1, + NI660X_IO_CFG_2_3, + NI660X_IO_CFG_4_5, + NI660X_IO_CFG_6_7, + NI660X_IO_CFG_8_9, + NI660X_IO_CFG_10_11, + NI660X_IO_CFG_12_13, + NI660X_IO_CFG_14_15, + NI660X_IO_CFG_16_17, + NI660X_IO_CFG_18_19, + NI660X_IO_CFG_20_21, + NI660X_IO_CFG_22_23, + NI660X_IO_CFG_24_25, + NI660X_IO_CFG_26_27, + NI660X_IO_CFG_28_29, + NI660X_IO_CFG_30_31, + NI660X_IO_CFG_32_33, + NI660X_IO_CFG_34_35, + NI660X_IO_CFG_36_37, + NI660X_IO_CFG_38_39, + NI660X_NUM_REGS, }; static inline unsigned IOConfigReg(unsigned pfi_channel) { - unsigned reg = IOConfigReg0_1 + pfi_channel / 2; - BUG_ON(reg > IOConfigReg38_39); + unsigned reg = NI660X_IO_CFG_0_1 + pfi_channel / 2; + BUG_ON(reg > NI660X_IO_CFG_38_39); return reg; } @@ -200,7 +200,7 @@ struct NI_660xRegisterData { enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */ }; -static const struct NI_660xRegisterData registerData[NumRegisters] = { +static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = { {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B}, {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B}, {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B}, @@ -347,11 +347,6 @@ static inline unsigned dma_select_mask(unsigned dma_channel) enum dma_selection { dma_selection_none = 0x1f, }; -static inline unsigned dma_selection_counter(unsigned counter_index) -{ - BUG_ON(counter_index >= counters_per_chip); - return counter_index; -} static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection) { @@ -444,229 +439,158 @@ static inline unsigned ni_660x_num_counters(struct comedi_device *dev) return board->n_chips * counters_per_chip; } -static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) +static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg) { - enum NI_660x_Register ni_660x_register; switch (reg) { - case NITIO_G0_Autoincrement_Reg: - ni_660x_register = G0AutoincrementRegister; - break; - case NITIO_G1_Autoincrement_Reg: - ni_660x_register = G1AutoincrementRegister; - break; - case NITIO_G2_Autoincrement_Reg: - ni_660x_register = G2AutoincrementRegister; - break; - case NITIO_G3_Autoincrement_Reg: - ni_660x_register = G3AutoincrementRegister; - break; - case NITIO_G0_Command_Reg: - ni_660x_register = G0CommandRegister; - break; - case NITIO_G1_Command_Reg: - ni_660x_register = G1CommandRegister; - break; - case NITIO_G2_Command_Reg: - ni_660x_register = G2CommandRegister; - break; - case NITIO_G3_Command_Reg: - ni_660x_register = G3CommandRegister; - break; - case NITIO_G0_HW_Save_Reg: - ni_660x_register = G0HWSaveRegister; - break; - case NITIO_G1_HW_Save_Reg: - ni_660x_register = G1HWSaveRegister; - break; - case NITIO_G2_HW_Save_Reg: - ni_660x_register = G2HWSaveRegister; - break; - case NITIO_G3_HW_Save_Reg: - ni_660x_register = G3HWSaveRegister; - break; - case NITIO_G0_SW_Save_Reg: - ni_660x_register = G0SWSaveRegister; - break; - case NITIO_G1_SW_Save_Reg: - ni_660x_register = G1SWSaveRegister; - break; - case NITIO_G2_SW_Save_Reg: - ni_660x_register = G2SWSaveRegister; - break; - case NITIO_G3_SW_Save_Reg: - ni_660x_register = G3SWSaveRegister; - break; - case NITIO_G0_Mode_Reg: - ni_660x_register = G0ModeRegister; - break; - case NITIO_G1_Mode_Reg: - ni_660x_register = G1ModeRegister; - break; - case NITIO_G2_Mode_Reg: - ni_660x_register = G2ModeRegister; - break; - case NITIO_G3_Mode_Reg: - ni_660x_register = G3ModeRegister; - break; - case NITIO_G0_LoadA_Reg: - ni_660x_register = G0LoadARegister; - break; - case NITIO_G1_LoadA_Reg: - ni_660x_register = G1LoadARegister; - break; - case NITIO_G2_LoadA_Reg: - ni_660x_register = G2LoadARegister; - break; - case NITIO_G3_LoadA_Reg: - ni_660x_register = G3LoadARegister; - break; - case NITIO_G0_LoadB_Reg: - ni_660x_register = G0LoadBRegister; - break; - case NITIO_G1_LoadB_Reg: - ni_660x_register = G1LoadBRegister; - break; - case NITIO_G2_LoadB_Reg: - ni_660x_register = G2LoadBRegister; - break; - case NITIO_G3_LoadB_Reg: - ni_660x_register = G3LoadBRegister; - break; - case NITIO_G0_Input_Select_Reg: - ni_660x_register = G0InputSelectRegister; - break; - case NITIO_G1_Input_Select_Reg: - ni_660x_register = G1InputSelectRegister; - break; - case NITIO_G2_Input_Select_Reg: - ni_660x_register = G2InputSelectRegister; - break; - case NITIO_G3_Input_Select_Reg: - ni_660x_register = G3InputSelectRegister; - break; - case NITIO_G01_Status_Reg: - ni_660x_register = G01StatusRegister; - break; - case NITIO_G23_Status_Reg: - ni_660x_register = G23StatusRegister; - break; - case NITIO_G01_Joint_Reset_Reg: - ni_660x_register = G01JointResetRegister; - break; - case NITIO_G23_Joint_Reset_Reg: - ni_660x_register = G23JointResetRegister; - break; - case NITIO_G01_Joint_Status1_Reg: - ni_660x_register = G01JointStatus1Register; - break; - case NITIO_G23_Joint_Status1_Reg: - ni_660x_register = G23JointStatus1Register; - break; - case NITIO_G01_Joint_Status2_Reg: - ni_660x_register = G01JointStatus2Register; - break; - case NITIO_G23_Joint_Status2_Reg: - ni_660x_register = G23JointStatus2Register; - break; - case NITIO_G0_Counting_Mode_Reg: - ni_660x_register = G0CountingModeRegister; - break; - case NITIO_G1_Counting_Mode_Reg: - ni_660x_register = G1CountingModeRegister; - break; - case NITIO_G2_Counting_Mode_Reg: - ni_660x_register = G2CountingModeRegister; - break; - case NITIO_G3_Counting_Mode_Reg: - ni_660x_register = G3CountingModeRegister; - break; - case NITIO_G0_Second_Gate_Reg: - ni_660x_register = G0SecondGateRegister; - break; - case NITIO_G1_Second_Gate_Reg: - ni_660x_register = G1SecondGateRegister; - break; - case NITIO_G2_Second_Gate_Reg: - ni_660x_register = G2SecondGateRegister; - break; - case NITIO_G3_Second_Gate_Reg: - ni_660x_register = G3SecondGateRegister; - break; - case NITIO_G0_DMA_Config_Reg: - ni_660x_register = G0DMAConfigRegister; - break; - case NITIO_G0_DMA_Status_Reg: - ni_660x_register = G0DMAStatusRegister; - break; - case NITIO_G1_DMA_Config_Reg: - ni_660x_register = G1DMAConfigRegister; - break; - case NITIO_G1_DMA_Status_Reg: - ni_660x_register = G1DMAStatusRegister; - break; - case NITIO_G2_DMA_Config_Reg: - ni_660x_register = G2DMAConfigRegister; - break; - case NITIO_G2_DMA_Status_Reg: - ni_660x_register = G2DMAStatusRegister; - break; - case NITIO_G3_DMA_Config_Reg: - ni_660x_register = G3DMAConfigRegister; - break; - case NITIO_G3_DMA_Status_Reg: - ni_660x_register = G3DMAStatusRegister; - break; - case NITIO_G0_Interrupt_Acknowledge_Reg: - ni_660x_register = G0InterruptAcknowledge; - break; - case NITIO_G1_Interrupt_Acknowledge_Reg: - ni_660x_register = G1InterruptAcknowledge; - break; - case NITIO_G2_Interrupt_Acknowledge_Reg: - ni_660x_register = G2InterruptAcknowledge; - break; - case NITIO_G3_Interrupt_Acknowledge_Reg: - ni_660x_register = G3InterruptAcknowledge; - break; - case NITIO_G0_Status_Reg: - ni_660x_register = G0StatusRegister; - break; - case NITIO_G1_Status_Reg: - ni_660x_register = G1StatusRegister; - break; - case NITIO_G2_Status_Reg: - ni_660x_register = G2StatusRegister; - break; - case NITIO_G3_Status_Reg: - ni_660x_register = G3StatusRegister; - break; - case NITIO_G0_Interrupt_Enable_Reg: - ni_660x_register = G0InterruptEnable; - break; - case NITIO_G1_Interrupt_Enable_Reg: - ni_660x_register = G1InterruptEnable; - break; - case NITIO_G2_Interrupt_Enable_Reg: - ni_660x_register = G2InterruptEnable; - break; - case NITIO_G3_Interrupt_Enable_Reg: - ni_660x_register = G3InterruptEnable; - break; + case NITIO_G0_AUTO_INC: + return NI660X_G0_AUTO_INC; + case NITIO_G1_AUTO_INC: + return NI660X_G1_AUTO_INC; + case NITIO_G2_AUTO_INC: + return NI660X_G2_AUTO_INC; + case NITIO_G3_AUTO_INC: + return NI660X_G3_AUTO_INC; + case NITIO_G0_CMD: + return NI660X_G0_CMD; + case NITIO_G1_CMD: + return NI660X_G1_CMD; + case NITIO_G2_CMD: + return NI660X_G2_CMD; + case NITIO_G3_CMD: + return NI660X_G3_CMD; + case NITIO_G0_HW_SAVE: + return NI660X_G0_HW_SAVE; + case NITIO_G1_HW_SAVE: + return NI660X_G1_HW_SAVE; + case NITIO_G2_HW_SAVE: + return NI660X_G2_HW_SAVE; + case NITIO_G3_HW_SAVE: + return NI660X_G3_HW_SAVE; + case NITIO_G0_SW_SAVE: + return NI660X_G0_SW_SAVE; + case NITIO_G1_SW_SAVE: + return NI660X_G1_SW_SAVE; + case NITIO_G2_SW_SAVE: + return NI660X_G2_SW_SAVE; + case NITIO_G3_SW_SAVE: + return NI660X_G3_SW_SAVE; + case NITIO_G0_MODE: + return NI660X_G0_MODE; + case NITIO_G1_MODE: + return NI660X_G1_MODE; + case NITIO_G2_MODE: + return NI660X_G2_MODE; + case NITIO_G3_MODE: + return NI660X_G3_MODE; + case NITIO_G0_LOADA: + return NI660X_G0_LOADA; + case NITIO_G1_LOADA: + return NI660X_G1_LOADA; + case NITIO_G2_LOADA: + return NI660X_G2_LOADA; + case NITIO_G3_LOADA: + return NI660X_G3_LOADA; + case NITIO_G0_LOADB: + return NI660X_G0_LOADB; + case NITIO_G1_LOADB: + return NI660X_G1_LOADB; + case NITIO_G2_LOADB: + return NI660X_G2_LOADB; + case NITIO_G3_LOADB: + return NI660X_G3_LOADB; + case NITIO_G0_INPUT_SEL: + return NI660X_G0_INPUT_SEL; + case NITIO_G1_INPUT_SEL: + return NI660X_G1_INPUT_SEL; + case NITIO_G2_INPUT_SEL: + return NI660X_G2_INPUT_SEL; + case NITIO_G3_INPUT_SEL: + return NI660X_G3_INPUT_SEL; + case NITIO_G01_STATUS: + return NI660X_G01_STATUS; + case NITIO_G23_STATUS: + return NI660X_G23_STATUS; + case NITIO_G01_RESET: + return NI660X_G01_RESET; + case NITIO_G23_RESET: + return NI660X_G23_RESET; + case NITIO_G01_STATUS1: + return NI660X_G01_STATUS1; + case NITIO_G23_STATUS1: + return NI660X_G23_STATUS1; + case NITIO_G01_STATUS2: + return NI660X_G01_STATUS2; + case NITIO_G23_STATUS2: + return NI660X_G23_STATUS2; + case NITIO_G0_CNT_MODE: + return NI660X_G0_CNT_MODE; + case NITIO_G1_CNT_MODE: + return NI660X_G1_CNT_MODE; + case NITIO_G2_CNT_MODE: + return NI660X_G2_CNT_MODE; + case NITIO_G3_CNT_MODE: + return NI660X_G3_CNT_MODE; + case NITIO_G0_GATE2: + return NI660X_G0_GATE2; + case NITIO_G1_GATE2: + return NI660X_G1_GATE2; + case NITIO_G2_GATE2: + return NI660X_G2_GATE2; + case NITIO_G3_GATE2: + return NI660X_G3_GATE2; + case NITIO_G0_DMA_CFG: + return NI660X_G0_DMA_CFG; + case NITIO_G0_DMA_STATUS: + return NI660X_G0_DMA_STATUS; + case NITIO_G1_DMA_CFG: + return NI660X_G1_DMA_CFG; + case NITIO_G1_DMA_STATUS: + return NI660X_G1_DMA_STATUS; + case NITIO_G2_DMA_CFG: + return NI660X_G2_DMA_CFG; + case NITIO_G2_DMA_STATUS: + return NI660X_G2_DMA_STATUS; + case NITIO_G3_DMA_CFG: + return NI660X_G3_DMA_CFG; + case NITIO_G3_DMA_STATUS: + return NI660X_G3_DMA_STATUS; + case NITIO_G0_INT_ACK: + return NI660X_G0_INT_ACK; + case NITIO_G1_INT_ACK: + return NI660X_G1_INT_ACK; + case NITIO_G2_INT_ACK: + return NI660X_G2_INT_ACK; + case NITIO_G3_INT_ACK: + return NI660X_G3_INT_ACK; + case NITIO_G0_STATUS: + return NI660X_G0_STATUS; + case NITIO_G1_STATUS: + return NI660X_G1_STATUS; + case NITIO_G2_STATUS: + return NI660X_G2_STATUS; + case NITIO_G3_STATUS: + return NI660X_G3_STATUS; + case NITIO_G0_INT_ENA: + return NI660X_G0_INT_ENA; + case NITIO_G1_INT_ENA: + return NI660X_G1_INT_ENA; + case NITIO_G2_INT_ENA: + return NI660X_G2_INT_ENA; + case NITIO_G3_INT_ENA: + return NI660X_G3_INT_ENA; default: BUG(); return 0; - break; } - return ni_660x_register; } static inline void ni_660x_write_register(struct comedi_device *dev, - unsigned chip_index, unsigned bits, - enum NI_660x_Register reg) + unsigned chip, unsigned bits, + enum ni_660x_register reg) { struct ni_660x_private *devpriv = dev->private; void __iomem *write_address = - devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] + registerData[reg].offset; switch (registerData[reg].size) { @@ -683,12 +607,12 @@ static inline void ni_660x_write_register(struct comedi_device *dev, } static inline unsigned ni_660x_read_register(struct comedi_device *dev, - unsigned chip_index, - enum NI_660x_Register reg) + unsigned chip, + enum ni_660x_register reg) { struct ni_660x_private *devpriv = dev->private; void __iomem *read_address = - devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip] + registerData[reg].offset; switch (registerData[reg].size) { @@ -709,18 +633,20 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg); - ni_660x_write_register(dev, counter->chip_index, bits, - ni_660x_register); + enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); + unsigned chip = counter->chip_index; + + ni_660x_write_register(dev, chip, bits, ni_660x_register); } static unsigned ni_gpct_read_register(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; - enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg); - return ni_660x_read_register(dev, counter->chip_index, - ni_660x_register); + enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg); + unsigned chip = counter->chip_index; + + return ni_660x_read_register(dev, chip, ni_660x_register); } static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private @@ -728,7 +654,9 @@ static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private struct ni_gpct *counter) { - return priv->mite_rings[counter->chip_index][counter->counter_index]; + unsigned chip = counter->chip_index; + + return priv->mite_rings[chip][counter->counter_index]; } static inline void ni_660x_set_dma_channel(struct comedi_device *dev, @@ -736,18 +664,17 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, struct ni_gpct *counter) { struct ni_660x_private *devpriv = dev->private; + unsigned chip = counter->chip_index; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); - devpriv->dma_configuration_soft_copies[counter->chip_index] &= - ~dma_select_mask(mite_channel); - devpriv->dma_configuration_soft_copies[counter->chip_index] |= - dma_select_bits(mite_channel, - dma_selection_counter(counter->counter_index)); - ni_660x_write_register(dev, counter->chip_index, - devpriv->dma_configuration_soft_copies - [counter->chip_index] | - dma_reset_bit(mite_channel), DMAConfigRegister); + devpriv->dma_configuration_soft_copies[chip] &= + ~dma_select_mask(mite_channel); + devpriv->dma_configuration_soft_copies[chip] |= + dma_select_bits(mite_channel, counter->counter_index); + ni_660x_write_register(dev, chip, + devpriv->dma_configuration_soft_copies[chip] | + dma_reset_bit(mite_channel), NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -757,16 +684,17 @@ static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, struct ni_gpct *counter) { struct ni_660x_private *devpriv = dev->private; + unsigned chip = counter->chip_index; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); - devpriv->dma_configuration_soft_copies[counter->chip_index] &= + devpriv->dma_configuration_soft_copies[chip] &= ~dma_select_mask(mite_channel); - devpriv->dma_configuration_soft_copies[counter->chip_index] |= + devpriv->dma_configuration_soft_copies[chip] |= dma_select_bits(mite_channel, dma_selection_none); - ni_660x_write_register(dev, counter->chip_index, - devpriv->dma_configuration_soft_copies - [counter->chip_index], DMAConfigRegister); + ni_660x_write_register(dev, chip, + devpriv->dma_configuration_soft_copies[chip], + NI660X_DMA_CFG); mmiowb(); spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } @@ -815,11 +743,9 @@ static void ni_660x_release_mite_channel(struct comedi_device *dev, static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_gpct *counter = s->private; int retval; - struct ni_gpct *counter = subdev_to_counter(s); -/* const struct comedi_cmd *cmd = &s->async->cmd; */ - retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT); if (retval) { comedi_error(dev, @@ -827,22 +753,13 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return retval; } ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); - retval = ni_tio_cmd(counter, s->async); - return retval; -} - -static int ni_660x_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) -{ - struct ni_gpct *counter = subdev_to_counter(s); - - return ni_tio_cmdtest(counter, cmd); + return ni_tio_cmd(dev, s); } static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct ni_gpct *counter = subdev_to_counter(s); + struct ni_gpct *counter = s->private; int retval; retval = ni_tio_cancel(counter); @@ -850,23 +767,28 @@ static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return retval; } -static void set_tio_counterswap(struct comedi_device *dev, int chipset) +static void set_tio_counterswap(struct comedi_device *dev, int chip) { - /* See P. 3.5 of the Register-Level Programming manual. The - CounterSwap bit has to be set on the second chip, otherwise - it will try to use the same pins as the first chip. + unsigned bits = 0; + + /* + * See P. 3.5 of the Register-Level Programming manual. + * The CounterSwap bit has to be set on the second chip, + * otherwise it will try to use the same pins as the + * first chip. */ - if (chipset) - ni_660x_write_register(dev, chipset, CounterSwap, - ClockConfigRegister); - else - ni_660x_write_register(dev, chipset, 0, ClockConfigRegister); + if (chip) + bits = CounterSwap; + + ni_660x_write_register(dev, chip, bits, NI660X_CLK_CFG); } static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { - ni_tio_handle_interrupt(subdev_to_counter(s), s); + struct ni_gpct *counter = s->private; + + ni_tio_handle_interrupt(counter, s); if (s->async->events) { if (s->async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) { @@ -901,11 +823,12 @@ static int ni_660x_input_poll(struct comedi_device *dev, struct comedi_subdevice *s) { struct ni_660x_private *devpriv = dev->private; + struct ni_gpct *counter = s->private; unsigned long flags; /* lock to avoid race with comedi_poll */ spin_lock_irqsave(&devpriv->interrupt_lock, flags); - mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async); + mite_sync_input_dma(counter->mite_chan, s->async); spin_unlock_irqrestore(&devpriv->interrupt_lock, flags); return comedi_buf_read_n_available(s->async); } @@ -915,10 +838,10 @@ static int ni_660x_buf_change(struct comedi_device *dev, unsigned long new_size) { struct ni_660x_private *devpriv = dev->private; + struct ni_gpct *counter = s->private; int ret; - ret = mite_buf_change(mite_ring(devpriv, subdev_to_counter(s)), - s->async); + ret = mite_buf_change(mite_ring(devpriv, counter), s->async); if (ret < 0) return ret; @@ -974,13 +897,6 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev) } } -static int -ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - return ni_tio_rinsn(subdev_to_counter(s), insn, data); -} - static void init_tio_chip(struct comedi_device *dev, int chipset) { struct ni_660x_private *devpriv = dev->private; @@ -994,25 +910,11 @@ static void init_tio_chip(struct comedi_device *dev, int chipset) } ni_660x_write_register(dev, chipset, devpriv->dma_configuration_soft_copies[chipset], - DMAConfigRegister); + NI660X_DMA_CFG); for (i = 0; i < NUM_PFI_CHANNELS; ++i) ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); } -static int -ni_660x_GPCT_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - return ni_tio_insn_config(subdev_to_counter(s), insn, data); -} - -static int ni_660x_GPCT_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - return ni_tio_winsn(subdev_to_counter(s), insn, data); -} - static int ni_660x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1024,13 +926,13 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev, s->state &= ~(data[0] << base_bitfield_channel); s->state |= (data[0] & data[1]) << base_bitfield_channel; /* Write out the new digital output lines */ - ni_660x_write_register(dev, 0, s->state, DIO32Output); + ni_660x_write_register(dev, 0, s->state, NI660X_DIO32_OUTPUT); } /* on return, data[1] contains the value of the digital * input and output lines. */ - data[1] = - (ni_660x_read_register(dev, 0, - DIO32Input) >> base_bitfield_channel); + data[1] = (ni_660x_read_register(dev, 0, NI660X_DIO32_INPUT) >> + base_bitfield_channel); + return insn->n; } @@ -1215,7 +1117,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, s->insn_config = ni_660x_dio_insn_config; /* we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */ - ni_660x_write_register(dev, 0, 0, STCDIOControl); + ni_660x_write_register(dev, 0, 0, NI660X_STC_DIO_CONTROL); devpriv->counter_dev = ni_gpct_device_construct(dev, &ni_gpct_write_register, @@ -1234,12 +1136,12 @@ static int ni_660x_auto_attach(struct comedi_device *dev, SDF_CMD_READ /* | SDF_CMD_WRITE */ ; s->n_chan = 3; s->maxdata = 0xffffffff; - s->insn_read = ni_660x_GPCT_rinsn; - s->insn_write = ni_660x_GPCT_winsn; - s->insn_config = ni_660x_GPCT_insn_config; + s->insn_read = ni_tio_insn_read; + s->insn_write = ni_tio_insn_write; + s->insn_config = ni_tio_insn_config; s->do_cmd = &ni_660x_cmd; s->len_chanlist = 1; - s->do_cmdtest = &ni_660x_cmdtest; + s->do_cmdtest = ni_tio_cmdtest; s->cancel = &ni_660x_cancel; s->poll = &ni_660x_input_poll; s->async_dma_dir = DMA_BIDIRECTIONAL; @@ -1284,7 +1186,7 @@ static int ni_660x_auto_attach(struct comedi_device *dev, if (board->n_chips > 1) global_interrupt_config_bits |= Cascade_Int_Enable_Bit; ni_660x_write_register(dev, 0, global_interrupt_config_bits, - GlobalInterruptConfigRegister); + NI660X_GLOBAL_INT_CFG); dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); return 0; } @@ -1320,7 +1222,7 @@ static int ni_660x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { +static const struct pci_device_id ni_660x_pci_table[] = { { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 }, { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 }, { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 }, diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index e4414cf110e7..8550fdc4ccd3 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -282,7 +282,7 @@ static int ni_670x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_670x_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { +static const struct pci_device_id ni_670x_pci_table[] = { { PCI_VDEVICE(NI, 0x1290), BOARD_PCI6704 }, { PCI_VDEVICE(NI, 0x1920), BOARD_PXI6704 }, { PCI_VDEVICE(NI, 0x2c90), BOARD_PCI6703 }, diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 63c847932eb8..f83eb9ebe278 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -74,9 +74,6 @@ TRIG_WAKE_EOS #define A2150_SIZE 28 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */ -/* #define A2150_DEBUG enable debugging code */ -#undef A2150_DEBUG /* disable debugging code */ - /* Registers and bits */ #define CONFIG_REG 0x0 #define CHANNEL_BITS(x) ((x) & 0x7) @@ -127,10 +124,9 @@ struct a2150_board { /* analog input range */ static const struct comedi_lrange range_a2150 = { - 1, - { - RANGE(-2.828, 2.828), - } + 1, { + BIP_RANGE(2.828) + } }; /* enum must match board indices */ @@ -167,19 +163,6 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel, unsigned int num_channels); -#ifdef A2150_DEBUG - -static void ni_dump_regs(struct comedi_device *dev) -{ - struct a2150_private *devpriv = dev->private; - - printk("config bits 0x%x\n", devpriv->config_bits); - printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits); - printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG)); -} - -#endif - /* interrupt service routine */ static irqreturn_t a2150_interrupt(int irq, void *d) { @@ -411,11 +394,6 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int old_config_bits = devpriv->config_bits; unsigned int trigger_bits; - if (!dev->irq || !devpriv->dma) { - comedi_error(dev, - " irq and dma required, cannot do hardware conversions"); - return -1; - } if (cmd->flags & TRIG_RT) { comedi_error(dev, " dma incompatible with hard real-time interrupt (TRIG_RT), aborting"); @@ -506,9 +484,6 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* start acquisition for soft trigger */ if (cmd->start_src == TRIG_NOW) outw(0, dev->iobase + FIFO_START_REG); -#ifdef A2150_DEBUG - ni_dump_regs(dev); -#endif return 0; } @@ -573,13 +548,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, comedi_error(dev, "timeout"); return -ETIME; } -#ifdef A2150_DEBUG - ni_dump_regs(dev); -#endif data[n] = inw(dev->iobase + FIFO_DATA_REG); -#ifdef A2150_DEBUG - printk(" data is %i\n", data[n]); -#endif data[n] ^= 0x8000; } @@ -728,64 +697,56 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - /* grab our IRQ */ - if (irq) { - /* check that irq is supported */ - if (irq < 3 || irq == 8 || irq == 13 || irq > 15) { - printk(" invalid irq line %u\n", irq); - return -EINVAL; - } - if (request_irq(irq, a2150_interrupt, 0, - dev->driver->driver_name, dev)) { - printk("unable to allocate irq %u\n", irq); - return -EINVAL; - } - devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); - dev->irq = irq; - } - /* initialize dma */ - if (dma) { - if (dma == 4 || dma > 7) { - printk(" invalid dma channel %u\n", dma); - return -EINVAL; - } - if (request_dma(dma, dev->driver->driver_name)) { - printk(" failed to allocate dma channel %u\n", dma); - return -EINVAL; - } - devpriv->dma = dma; - devpriv->dma_buffer = - kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); - if (devpriv->dma_buffer == NULL) - return -ENOMEM; - - disable_dma(dma); - set_dma_mode(dma, DMA_MODE_READ); - - devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); - } - dev->board_ptr = a2150_boards + a2150_probe(dev); thisboard = comedi_board(dev); dev->board_name = thisboard->name; + if ((irq >= 3 && irq <= 7) || (irq >= 9 && irq <= 12) || + irq == 14 || irq == 15) { + ret = request_irq(irq, a2150_interrupt, 0, + dev->board_name, dev); + if (ret == 0) { + devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); + dev->irq = irq; + } + } + + if (dev->irq && dma <= 7 && dma != 4) { + ret = request_dma(dma, dev->board_name); + if (ret == 0) { + devpriv->dma = dma; + devpriv->dma_buffer = kmalloc(A2150_DMA_BUFFER_SIZE, + GFP_KERNEL | GFP_DMA); + if (!devpriv->dma_buffer) + return -ENOMEM; + + disable_dma(dma); + set_dma_mode(dma, DMA_MODE_READ); + + devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); + } + } + ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; /* analog input subdevice */ s = &dev->subdevices[0]; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER; s->n_chan = 4; - s->len_chanlist = 4; s->maxdata = 0xffff; s->range_table = &range_a2150; - s->do_cmd = a2150_ai_cmd; - s->do_cmdtest = a2150_ai_cmdtest; s->insn_read = a2150_ai_rinsn; - s->cancel = a2150_cancel; + if (dev->irq && devpriv->dma) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->do_cmd = a2150_ai_cmd; + s->do_cmdtest = a2150_ai_cmdtest; + s->cancel = a2150_cancel; + } /* need to do this for software counting of completed conversions, to * prevent hardware count from stopping acquisition */ diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index 856c73d8b7cd..d03935257b97 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -98,8 +98,6 @@ are not supported. #include "ni_stc.h" #include "8255.h" -#undef DEBUG - #define ATMIO 1 #undef PCIMIO @@ -437,19 +435,6 @@ static int ni_atmio_attach(struct comedi_device *dev, if (ret) return ret; -#ifdef DEBUG - /* board existence sanity check */ - { - int i; - - printk(" board fingerprint:"); - for (i = 0; i < 16; i += 2) { - printk(" %04x %02x", inw(dev->iobase + i), - inb(dev->iobase + i + 1)); - } - } -#endif - /* get board type */ board = ni_getboardtype(dev); diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index a9f7d40d6db2..e8cd5ddb85c5 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -105,40 +105,31 @@ struct atmio16_board_t { }; /* range structs */ -static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, { - BIP_RANGE - (10), - BIP_RANGE - (1), - BIP_RANGE - (0.1), - BIP_RANGE - (0.02) - } +static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { + 4, { + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02) + } }; -static const struct comedi_lrange range_atmio16d_ai_5_bipolar = { 4, { - BIP_RANGE - (5), - BIP_RANGE - (0.5), - BIP_RANGE - (0.05), - BIP_RANGE - (0.01) - } +static const struct comedi_lrange range_atmio16d_ai_5_bipolar = { + 4, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.01) + } }; -static const struct comedi_lrange range_atmio16d_ai_unipolar = { 4, { - UNI_RANGE - (10), - UNI_RANGE - (1), - UNI_RANGE - (0.1), - UNI_RANGE - (0.02) - } +static const struct comedi_lrange range_atmio16d_ai_unipolar = { + 4, { + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.02) + } }; /* private data struct */ @@ -229,7 +220,7 @@ static void reset_atmio16d(struct comedi_device *dev) static irqreturn_t atmio16d_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG)); @@ -495,18 +486,13 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, break; } if (status & STAT_AD_OVERFLOW) { - printk(KERN_INFO "atmio16d: a/d FIFO overflow\n"); outw(0, dev->iobase + AD_CLEAR_REG); - return -ETIME; } } /* end waiting, now check if it timed out */ - if (t == ATMIO16D_TIMEOUT) { - printk(KERN_INFO "atmio16d: timeout\n"); - + if (t == ATMIO16D_TIMEOUT) return -ETIME; - } } return i; @@ -636,7 +622,6 @@ static int atmio16d_attach(struct comedi_device *dev, const struct atmio16_board_t *board = comedi_board(dev); struct atmio16d_private *devpriv; struct comedi_subdevice *s; - unsigned int irq; int ret; ret = comedi_request_region(dev, it->options[0], ATMIO16D_SIZE); @@ -654,19 +639,11 @@ static int atmio16d_attach(struct comedi_device *dev, /* reset the atmio16d hardware */ reset_atmio16d(dev); - /* check if our interrupt is available and get it */ - irq = it->options[1]; - if (irq) { - - ret = request_irq(irq, atmio16d_interrupt, 0, "atmio16d", dev); - if (ret < 0) { - printk(KERN_INFO "failed to allocate irq %u\n", irq); - return ret; - } - dev->irq = irq; - printk(KERN_INFO "( irq = %u )\n", irq); - } else { - printk(KERN_INFO "( no irq )"); + if (it->options[1]) { + ret = request_irq(it->options[1], atmio16d_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } /* set device options */ @@ -682,16 +659,11 @@ static int atmio16d_attach(struct comedi_device *dev, /* setup sub-devices */ s = &dev->subdevices[0]; - dev->read_subdev = s; /* ai subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = (devpriv->adc_mux ? 16 : 8); - s->len_chanlist = 16; s->insn_read = atmio16d_ai_insn_read; - s->do_cmdtest = atmio16d_ai_cmdtest; - s->do_cmd = atmio16d_ai_cmd; - s->cancel = atmio16d_ai_cancel; s->maxdata = 0xfff; /* 4095 decimal */ switch (devpriv->adc_range) { case adc_bipolar10: @@ -704,6 +676,14 @@ static int atmio16d_attach(struct comedi_device *dev, s->range_table = &range_atmio16d_ai_unipolar; break; } + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = 16; + s->do_cmdtest = atmio16d_ai_cmdtest; + s->do_cmd = atmio16d_ai_cmd; + s->cancel = atmio16d_ai_cancel; + } /* ao subdevice */ s = &dev->subdevices[1]; @@ -756,7 +736,6 @@ static int atmio16d_attach(struct comedi_device *dev, s->n_chan = 0; s->maxdata = 0 #endif - printk("\n"); return 0; } diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c index 8be681fca907..739597068297 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_pci.c +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -107,7 +107,7 @@ static struct comedi_driver labpc_pci_comedi_driver = { .detach = labpc_pci_detach, }; -static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { +static const struct pci_device_id labpc_pci_table[] = { { PCI_VDEVICE(NI, 0x161), BOARD_NI_PCI1200 }, { 0 } }; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 5113397bfecf..457b88481db0 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -52,10 +52,6 @@ fully tested as yet. Terry Barnaby, BEAM Ltd. */ -/* #define DEBUG_INTERRUPT */ -/* #define DEBUG_STATUS_A */ -/* #define DEBUG_STATUS_B */ - #include #include #include @@ -63,10 +59,6 @@ #include "mite.h" #include "comedi_fc.h" -#ifndef MDPRINTK -#define MDPRINTK(format, args...) -#endif - /* A timeout count */ #define NI_TIMEOUT 1000 static const unsigned old_RTSI_clock_channel = 7; @@ -86,111 +78,109 @@ static const short ni_gainlkup[][16] = { [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; -static const struct comedi_lrange range_ni_E_ai = { 16, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1, 1), - RANGE(-0.5, 0.5), - RANGE(-0.25, 0.25), - RANGE(-0.1, 0.1), - RANGE(-0.05, 0.05), - RANGE(0, 20), - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 2), - RANGE(0, 1), - RANGE(0, 0.5), - RANGE(0, 0.2), - RANGE(0, 0.1), - } +static const struct comedi_lrange range_ni_E_ai = { + 16, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.25), + BIP_RANGE(0.1), + BIP_RANGE(0.05), + UNI_RANGE(20), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5), + UNI_RANGE(0.2), + UNI_RANGE(0.1) + } }; -static const struct comedi_lrange range_ni_E_ai_limited = { 8, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-1, 1), - RANGE(-0.1, - 0.1), - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 1), - RANGE(0, 0.1), - } +static const struct comedi_lrange range_ni_E_ai_limited = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(1), + BIP_RANGE(0.1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(1), + UNI_RANGE(0.1) + } }; -static const struct comedi_lrange range_ni_E_ai_limited14 = { 14, { - RANGE(-10, - 10), - RANGE(-5, 5), - RANGE(-2, 2), - RANGE(-1, 1), - RANGE(-0.5, - 0.5), - RANGE(-0.2, - 0.2), - RANGE(-0.1, - 0.1), - RANGE(0, 10), - RANGE(0, 5), - RANGE(0, 2), - RANGE(0, 1), - RANGE(0, - 0.5), - RANGE(0, - 0.2), - RANGE(0, - 0.1), - } +static const struct comedi_lrange range_ni_E_ai_limited14 = { + 14, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.2), + BIP_RANGE(0.1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1), + UNI_RANGE(0.5), + UNI_RANGE(0.2), + UNI_RANGE(0.1) + } }; -static const struct comedi_lrange range_ni_E_ai_bipolar4 = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-0.5, - 0.5), - RANGE(-0.05, - 0.05), - } +static const struct comedi_lrange range_ni_E_ai_bipolar4 = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05) + } }; -static const struct comedi_lrange range_ni_E_ai_611x = { 8, { - RANGE(-50, 50), - RANGE(-20, 20), - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2, 2), - RANGE(-1, 1), - RANGE(-0.5, 0.5), - RANGE(-0.2, 0.2), - } +static const struct comedi_lrange range_ni_E_ai_611x = { + 8, { + BIP_RANGE(50), + BIP_RANGE(20), + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.2) + } }; -static const struct comedi_lrange range_ni_M_ai_622x = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-1, 1), - RANGE(-0.2, 0.2), - } +static const struct comedi_lrange range_ni_M_ai_622x = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(1), + BIP_RANGE(0.2) + } }; -static const struct comedi_lrange range_ni_M_ai_628x = { 7, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2, 2), - RANGE(-1, 1), - RANGE(-0.5, 0.5), - RANGE(-0.2, 0.2), - RANGE(-0.1, 0.1), - } +static const struct comedi_lrange range_ni_M_ai_628x = { + 7, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + BIP_RANGE(0.5), + BIP_RANGE(0.2), + BIP_RANGE(0.1) + } }; -static const struct comedi_lrange range_ni_E_ao_ext = { 4, { - RANGE(-10, 10), - RANGE(0, 10), - RANGE_ext(-1, 1), - RANGE_ext(0, 1), - } +static const struct comedi_lrange range_ni_E_ao_ext = { + 4, { + BIP_RANGE(10), + UNI_RANGE(10), + RANGE_ext(-1, 1), + RANGE_ext(0, 1) + } }; static const struct comedi_lrange *const ni_range_lkup[] = { @@ -266,17 +256,6 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s); static int ni_read_eeprom(struct comedi_device *dev, int addr); -#ifdef DEBUG_STATUS_A -static void ni_mio_print_status_a(int status); -#else -#define ni_mio_print_status_a(a) -#endif -#ifdef DEBUG_STATUS_B -static void ni_mio_print_status_b(int status); -#else -#define ni_mio_print_status_b(a) -#endif - static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s); #ifndef PCIDMA static void ni_handle_fifo_half_full(struct comedi_device *dev); @@ -297,19 +276,8 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s); static int ni_8255_callback(int dir, int port, int data, unsigned long arg); -static int ni_gpct_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ni_gpct_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ni_gpct_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); #ifdef PCIDMA static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int ni_gpct_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); #endif static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s); @@ -322,10 +290,6 @@ static int cs5529_do_conversion(struct comedi_device *dev, static int cs5529_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); -#ifdef NI_CS5529_DEBUG -static unsigned int cs5529_config_read(struct comedi_device *dev, - unsigned int reg_select_bits); -#endif static void cs5529_config_write(struct comedi_device *dev, unsigned int value, unsigned int reg_select_bits); @@ -487,11 +451,10 @@ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev, { unsigned bitfield; - if (mite_channel >= 0) { + if (mite_channel >= 0) bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel); - } else { + else bitfield = 0; - } ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index), bitfield); } @@ -907,9 +870,8 @@ static void mite_handle_b_linkc(struct mite_struct *mite, unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); - if (devpriv->ao_mite_chan) { + if (devpriv->ao_mite_chan) mite_sync_output_dma(devpriv->ao_mite_chan, s->async); - } spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); } @@ -957,9 +919,8 @@ static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s) #endif } /* handle special case of single scan using AI_End_On_End_Of_Scan */ - if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) { + if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) shutdown_ai_command(dev); - } } static void shutdown_ai_command(struct comedi_device *dev) @@ -1023,19 +984,15 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) struct ni_private *devpriv = dev->private; unsigned short ack = 0; - if (a_status & AI_SC_TC_St) { + if (a_status & AI_SC_TC_St) ack |= AI_SC_TC_Interrupt_Ack; - } - if (a_status & AI_START1_St) { + if (a_status & AI_START1_St) ack |= AI_START1_Interrupt_Ack; - } - if (a_status & AI_START_St) { + if (a_status & AI_START_St) ack |= AI_START_Interrupt_Ack; - } - if (a_status & AI_STOP_St) { + if (a_status & AI_STOP_St) /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */ - ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */ ; - } + ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */; if (ack) devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register); } @@ -1050,16 +1007,9 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, if (s->type == COMEDI_SUBD_UNUSED) return; -#ifdef DEBUG_INTERRUPT - printk - ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n", - status, ai_mite_status); - ni_mio_print_status_a(status); -#endif #ifdef PCIDMA - if (ai_mite_status & CHSR_LINKC) { + if (ai_mite_status & CHSR_LINKC) ni_sync_ai_dma(dev); - } if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | @@ -1067,7 +1017,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, printk ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n", ai_mite_status); - /* mite_print_chsr(ai_mite_status); */ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; /* disable_irq(dev->irq); */ } @@ -1092,7 +1041,6 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, AI_SC_TC_Error_St)) { printk("ni_mio_common: ai error a_status=%04x\n", status); - ni_mio_print_status_a(status); shutdown_ai_command(dev); @@ -1105,12 +1053,8 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, return; } if (status & AI_SC_TC_St) { -#ifdef DEBUG_INTERRUPT - printk("ni_mio_common: SC_TC interrupt\n"); -#endif - if (!devpriv->ai_continuous) { + if (!devpriv->ai_continuous) shutdown_ai_command(dev); - } } } #ifndef PCIDMA @@ -1129,20 +1073,10 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, } #endif /* !PCIDMA */ - if ((status & AI_STOP_St)) { + if ((status & AI_STOP_St)) ni_handle_eos(dev, s); - } ni_event(dev, s); - -#ifdef DEBUG_INTERRUPT - status = devpriv->stc_readw(dev, AI_Status_1_Register); - if (status & Interrupt_A_St) { - printk - ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n", - status); - } -#endif } static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) @@ -1150,27 +1084,20 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) struct ni_private *devpriv = dev->private; unsigned short ack = 0; - if (b_status & AO_BC_TC_St) { + if (b_status & AO_BC_TC_St) ack |= AO_BC_TC_Interrupt_Ack; - } - if (b_status & AO_Overrun_St) { + if (b_status & AO_Overrun_St) ack |= AO_Error_Interrupt_Ack; - } - if (b_status & AO_START_St) { + if (b_status & AO_START_St) ack |= AO_START_Interrupt_Ack; - } - if (b_status & AO_START1_St) { + if (b_status & AO_START1_St) ack |= AO_START1_Interrupt_Ack; - } - if (b_status & AO_UC_TC_St) { + if (b_status & AO_UC_TC_St) ack |= AO_UC_TC_Interrupt_Ack; - } - if (b_status & AO_UI2_TC_St) { + if (b_status & AO_UI2_TC_St) ack |= AO_UI2_TC_Interrupt_Ack; - } - if (b_status & AO_UPDATE_St) { + if (b_status & AO_UPDATE_St) ack |= AO_UPDATE_Interrupt_Ack; - } if (ack) devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register); } @@ -1182,17 +1109,10 @@ static void handle_b_interrupt(struct comedi_device *dev, struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; /* unsigned short ack=0; */ -#ifdef DEBUG_INTERRUPT - printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", - b_status, ao_mite_status); - ni_mio_print_status_b(b_status); -#endif - #ifdef PCIDMA /* Currently, mite.c requires us to handle LINKC */ - if (ao_mite_status & CHSR_LINKC) { + if (ao_mite_status & CHSR_LINKC) mite_handle_b_linkc(devpriv->mite, dev); - } if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | @@ -1200,7 +1120,6 @@ static void handle_b_interrupt(struct comedi_device *dev, printk ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n", ao_mite_status); - /* mite_print_chsr(ao_mite_status); */ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } #endif @@ -1214,12 +1133,9 @@ static void handle_b_interrupt(struct comedi_device *dev, s->async->events |= COMEDI_CB_OVERFLOW; } - if (b_status & AO_BC_TC_St) { - MDPRINTK - ("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n", - b_status, devpriv->stc_readw(dev, AO_Status_2_Register)); + if (b_status & AO_BC_TC_St) s->async->events |= COMEDI_CB_EOA; - } + #ifndef PCIDMA if (b_status & AO_FIFO_Request_St) { int ret; @@ -1238,50 +1154,6 @@ static void handle_b_interrupt(struct comedi_device *dev, ni_event(dev, s); } -#ifdef DEBUG_STATUS_A -static const char *const status_a_strings[] = { - "passthru0", "fifo", "G0_gate", "G0_TC", - "stop", "start", "sc_tc", "start1", - "start2", "sc_tc_error", "overflow", "overrun", - "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a" -}; - -static void ni_mio_print_status_a(int status) -{ - int i; - - printk("A status:"); - for (i = 15; i >= 0; i--) { - if (status & (1 << i)) { - printk(" %s", status_a_strings[i]); - } - } - printk("\n"); -} -#endif - -#ifdef DEBUG_STATUS_B -static const char *const status_b_strings[] = { - "passthru1", "fifo", "G1_gate", "G1_TC", - "UI2_TC", "UPDATE", "UC_TC", "BC_TC", - "start1", "overrun", "start", "bc_tc_error", - "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b" -}; - -static void ni_mio_print_status_b(int status) -{ - int i; - - printk("B status:"); - for (i = 15; i >= 0; i--) { - if (status & (1 << i)) { - printk(" %s", status_b_strings[i]); - } - } - printk("\n"); -} -#endif - #ifndef PCIDMA static void ni_ao_fifo_load(struct comedi_device *dev, @@ -1324,9 +1196,8 @@ static void ni_ao_fifo_load(struct comedi_device *dev, chan %= cmd->chanlist_len; } async->cur_chan = chan; - if (err == 0) { + if (err == 0) async->events |= COMEDI_CB_OVERFLOW; - } } /* @@ -2392,7 +2263,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int stop_count; int interrupt_a_enable = 0; - MDPRINTK("ni_ai_cmd\n"); if (dev->irq == 0) { comedi_error(dev, "cannot run command without an irq"); return -EIO; @@ -2630,15 +2500,11 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) ni_set_bits(dev, Interrupt_A_Enable_Register, interrupt_a_enable, 1); - - MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n", - devpriv->int_a_enable_reg); } else { /* interrupt on nothing */ ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0); /* XXX start polling if necessary */ - MDPRINTK("interrupting on nothing\n"); } /* end configuration */ @@ -2664,7 +2530,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (retval) return retval; } - /* mite_dump_regs(devpriv->mite); */ #endif switch (cmd->start_src) { @@ -2682,8 +2547,6 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; } - MDPRINTK("exit ni_ai_cmd\n"); - return 0; } @@ -3248,11 +3111,10 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source; devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); - if (cmd->stop_src == TRIG_NONE) { + if (cmd->stop_src == TRIG_NONE) devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register); - } else { + else devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register); - } devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register); devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source; devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); @@ -3513,9 +3375,8 @@ static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) if (board->reg_type & ni_reg_6xxx_mask) { unsigned immediate_bits = 0; unsigned i; - for (i = 0; i < s->n_chan; ++i) { + for (i = 0; i < s->n_chan; ++i) immediate_bits |= 1 << i; - } ao_win_out(immediate_bits, AO_Immediate_671x); ao_win_out(CLEAR_WG, AO_Misc_611x); } @@ -3689,9 +3550,8 @@ static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EIO; } retval = ni_request_cdo_mite_channel(dev); - if (retval < 0) { + if (retval < 0) return retval; - } s->async->inttrig = &ni_cdo_inttrig; return 0; } @@ -3773,9 +3633,8 @@ static void handle_cdio_interrupt(struct comedi_device *dev) unsigned long flags; #endif - if ((board->reg_type & ni_reg_m_series_mask) == 0) { + if ((board->reg_type & ni_reg_m_series_mask) == 0) return; - } #ifdef PCIDMA spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->cdo_mite_chan) { @@ -3793,15 +3652,15 @@ static void handle_cdio_interrupt(struct comedi_device *dev) cdio_status = ni_readl(M_Offset_CDIO_Status); if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) { -/* printk("cdio error: statux=0x%x\n", cdio_status); */ + /* printk("cdio error: statux=0x%x\n", cdio_status); */ ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); /* XXX just guessing this is needed and does something useful */ s->async->events |= COMEDI_CB_OVERFLOW; } if (cdio_status & CDO_FIFO_Empty_Bit) { -/* printk("cdio fifo empty\n"); */ + /* printk("cdio fifo empty\n"); */ ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit, M_Offset_CDIO_Command); -/* s->async->events |= COMEDI_CB_EOA; */ + /* s->async->events |= COMEDI_CB_EOA; */ } ni_event(dev, s); } @@ -3819,10 +3678,6 @@ static int ni_serial_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_SERIAL_CLOCK: - -#ifdef DEBUG_DIO - printk("SPI serial clock Config cd\n", data[1]); -#endif devpriv->serial_hw_mode = 1; devpriv->dio_control |= DIO_HW_Serial_Enable; @@ -3874,9 +3729,8 @@ static int ni_serial_insn_config(struct comedi_device *dev, case INSN_CONFIG_BIDIRECTIONAL_DATA: - if (devpriv->serial_interval_ns == 0) { + if (devpriv->serial_interval_ns == 0) return -EINVAL; - } byte_out = data[1] & 0xFF; @@ -3911,10 +3765,6 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, unsigned int status1; int err = 0, count = 20; -#ifdef DEBUG_DIO - printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out); -#endif - devpriv->dio_output &= ~DIO_Serial_Data_Mask; devpriv->dio_output |= DIO_Serial_Data_Out(data_out); devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register); @@ -3948,12 +3798,8 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, DIO_Serial_IO_In_Progress_St goes high one bit too early. */ udelay((devpriv->serial_interval_ns + 999) / 1000); - if (data_in != NULL) { + if (data_in != NULL) *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register); -#ifdef DEBUG_DIO - printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in); -#endif - } Error: devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register); @@ -3969,10 +3815,6 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, struct ni_private *devpriv = dev->private; unsigned char mask, input = 0; -#ifdef DEBUG_DIO - printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out); -#endif - /* Wait for one bit before transfer */ udelay((devpriv->serial_interval_ns + 999) / 1000); @@ -3981,9 +3823,8 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, because it is a per-subdevice field, and serial is a separate subdevice from DIO. */ devpriv->dio_output &= ~DIO_SDOUT; - if (data_out & mask) { + if (data_out & mask) devpriv->dio_output |= DIO_SDOUT; - } devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register); @@ -4003,15 +3844,12 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, /* Input current bit */ if (devpriv->stc_readw(dev, - DIO_Parallel_Input_Register) & DIO_SDIN) - { -/* printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */ + DIO_Parallel_Input_Register) & DIO_SDIN) { + /* printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */ input |= mask; } } -#ifdef DEBUG_DIO - printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input); -#endif + if (data_in) *data_in = input; @@ -4023,9 +3861,8 @@ static void mio_common_detach(struct comedi_device *dev) struct ni_private *devpriv = dev->private; if (devpriv) { - if (devpriv->counter_dev) { + if (devpriv->counter_dev) ni_gpct_device_destroy(devpriv->counter_dev); - } } } @@ -4044,82 +3881,82 @@ static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg) { unsigned stc_register; switch (reg) { - case NITIO_G0_Autoincrement_Reg: + case NITIO_G0_AUTO_INC: stc_register = G_Autoincrement_Register(0); break; - case NITIO_G1_Autoincrement_Reg: + case NITIO_G1_AUTO_INC: stc_register = G_Autoincrement_Register(1); break; - case NITIO_G0_Command_Reg: + case NITIO_G0_CMD: stc_register = G_Command_Register(0); break; - case NITIO_G1_Command_Reg: + case NITIO_G1_CMD: stc_register = G_Command_Register(1); break; - case NITIO_G0_HW_Save_Reg: + case NITIO_G0_HW_SAVE: stc_register = G_HW_Save_Register(0); break; - case NITIO_G1_HW_Save_Reg: + case NITIO_G1_HW_SAVE: stc_register = G_HW_Save_Register(1); break; - case NITIO_G0_SW_Save_Reg: + case NITIO_G0_SW_SAVE: stc_register = G_Save_Register(0); break; - case NITIO_G1_SW_Save_Reg: + case NITIO_G1_SW_SAVE: stc_register = G_Save_Register(1); break; - case NITIO_G0_Mode_Reg: + case NITIO_G0_MODE: stc_register = G_Mode_Register(0); break; - case NITIO_G1_Mode_Reg: + case NITIO_G1_MODE: stc_register = G_Mode_Register(1); break; - case NITIO_G0_LoadA_Reg: + case NITIO_G0_LOADA: stc_register = G_Load_A_Register(0); break; - case NITIO_G1_LoadA_Reg: + case NITIO_G1_LOADA: stc_register = G_Load_A_Register(1); break; - case NITIO_G0_LoadB_Reg: + case NITIO_G0_LOADB: stc_register = G_Load_B_Register(0); break; - case NITIO_G1_LoadB_Reg: + case NITIO_G1_LOADB: stc_register = G_Load_B_Register(1); break; - case NITIO_G0_Input_Select_Reg: + case NITIO_G0_INPUT_SEL: stc_register = G_Input_Select_Register(0); break; - case NITIO_G1_Input_Select_Reg: + case NITIO_G1_INPUT_SEL: stc_register = G_Input_Select_Register(1); break; - case NITIO_G01_Status_Reg: + case NITIO_G01_STATUS: stc_register = G_Status_Register; break; - case NITIO_G01_Joint_Reset_Reg: + case NITIO_G01_RESET: stc_register = Joint_Reset_Register; break; - case NITIO_G01_Joint_Status1_Reg: + case NITIO_G01_STATUS1: stc_register = Joint_Status_1_Register; break; - case NITIO_G01_Joint_Status2_Reg: + case NITIO_G01_STATUS2: stc_register = Joint_Status_2_Register; break; - case NITIO_G0_Interrupt_Acknowledge_Reg: + case NITIO_G0_INT_ACK: stc_register = Interrupt_A_Ack_Register; break; - case NITIO_G1_Interrupt_Acknowledge_Reg: + case NITIO_G1_INT_ACK: stc_register = Interrupt_B_Ack_Register; break; - case NITIO_G0_Status_Reg: + case NITIO_G0_STATUS: stc_register = AI_Status_1_Register; break; - case NITIO_G1_Status_Reg: + case NITIO_G1_STATUS: stc_register = AO_Status_1_Register; break; - case NITIO_G0_Interrupt_Enable_Reg: + case NITIO_G0_INT_ENA: stc_register = Interrupt_A_Enable_Register; break; - case NITIO_G1_Interrupt_Enable_Reg: + case NITIO_G1_INT_ENA: stc_register = Interrupt_B_Enable_Register; break; default: @@ -4147,52 +3984,52 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, switch (reg) { /* m-series-only registers */ - case NITIO_G0_Counting_Mode_Reg: + case NITIO_G0_CNT_MODE: ni_writew(bits, M_Offset_G0_Counting_Mode); break; - case NITIO_G1_Counting_Mode_Reg: + case NITIO_G1_CNT_MODE: ni_writew(bits, M_Offset_G1_Counting_Mode); break; - case NITIO_G0_Second_Gate_Reg: + case NITIO_G0_GATE2: ni_writew(bits, M_Offset_G0_Second_Gate); break; - case NITIO_G1_Second_Gate_Reg: + case NITIO_G1_GATE2: ni_writew(bits, M_Offset_G1_Second_Gate); break; - case NITIO_G0_DMA_Config_Reg: + case NITIO_G0_DMA_CFG: ni_writew(bits, M_Offset_G0_DMA_Config); break; - case NITIO_G1_DMA_Config_Reg: + case NITIO_G1_DMA_CFG: ni_writew(bits, M_Offset_G1_DMA_Config); break; - case NITIO_G0_ABZ_Reg: + case NITIO_G0_ABZ: ni_writew(bits, M_Offset_G0_MSeries_ABZ); break; - case NITIO_G1_ABZ_Reg: + case NITIO_G1_ABZ: ni_writew(bits, M_Offset_G1_MSeries_ABZ); break; /* 32 bit registers */ - case NITIO_G0_LoadA_Reg: - case NITIO_G1_LoadA_Reg: - case NITIO_G0_LoadB_Reg: - case NITIO_G1_LoadB_Reg: + case NITIO_G0_LOADA: + case NITIO_G1_LOADA: + case NITIO_G0_LOADB: + case NITIO_G1_LOADB: stc_register = ni_gpct_to_stc_register(reg); devpriv->stc_writel(dev, bits, stc_register); break; /* 16 bit registers */ - case NITIO_G0_Interrupt_Enable_Reg: + case NITIO_G0_INT_ENA: BUG_ON(bits & ~gpct_interrupt_a_enable_mask); ni_set_bitfield(dev, Interrupt_A_Enable_Register, gpct_interrupt_a_enable_mask, bits); break; - case NITIO_G1_Interrupt_Enable_Reg: + case NITIO_G1_INT_ENA: BUG_ON(bits & ~gpct_interrupt_b_enable_mask); ni_set_bitfield(dev, Interrupt_B_Enable_Register, gpct_interrupt_b_enable_mask, bits); break; - case NITIO_G01_Joint_Reset_Reg: + case NITIO_G01_RESET: BUG_ON(bits & ~gpct_joint_reset_mask); /* fall-through */ default: @@ -4210,21 +4047,18 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter, switch (reg) { /* m-series only registers */ - case NITIO_G0_DMA_Status_Reg: + case NITIO_G0_DMA_STATUS: return ni_readw(M_Offset_G0_DMA_Status); - break; - case NITIO_G1_DMA_Status_Reg: + case NITIO_G1_DMA_STATUS: return ni_readw(M_Offset_G1_DMA_Status); - break; /* 32 bit registers */ - case NITIO_G0_HW_Save_Reg: - case NITIO_G1_HW_Save_Reg: - case NITIO_G0_SW_Save_Reg: - case NITIO_G1_SW_Save_Reg: + case NITIO_G0_HW_SAVE: + case NITIO_G1_HW_SAVE: + case NITIO_G0_SW_SAVE: + case NITIO_G1_SW_SAVE: stc_register = ni_gpct_to_stc_register(reg); return devpriv->stc_readl(dev, stc_register); - break; /* 16 bit registers */ default: @@ -4391,11 +4225,10 @@ static int ni_E_init(struct comedi_device *dev) s->maxdata = (1 << board->aobits) - 1; s->range_table = board->ao_range_table; s->insn_read = &ni_ao_insn_read; - if (board->reg_type & ni_reg_6xxx_mask) { + if (board->reg_type & ni_reg_6xxx_mask) s->insn_write = &ni_ao_insn_write_671x; - } else { + else s->insn_write = &ni_ao_insn_write; - } s->insn_config = &ni_ao_insn_config; #ifdef PCIDMA if (board->n_aochan) { @@ -4429,7 +4262,7 @@ static int ni_E_init(struct comedi_device *dev) s->n_chan = board->num_p0_dio_channels; if (board->reg_type & ni_reg_m_series_mask) { s->subdev_flags |= - SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ; + SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */; s->insn_bits = &ni_m_series_dio_insn_bits; s->insn_config = &ni_m_series_dio_insn_config; s->do_cmd = &ni_cdio_cmd; @@ -4449,11 +4282,10 @@ static int ni_E_init(struct comedi_device *dev) /* 8255 device */ s = &dev->subdevices[NI_8255_DIO_SUBDEV]; - if (board->has_8255) { + if (board->has_8255) subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev); - } else { + else s->type = COMEDI_SUBD_UNUSED; - } /* formerly general purpose counter/timer device, but no longer used */ s = &dev->subdevices[NI_UNUSED_SUBDEV]; @@ -4511,9 +4343,8 @@ static int ni_E_init(struct comedi_device *dev) s->n_chan = 10; } s->maxdata = 1; - if (board->reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) s->insn_bits = &ni_pfi_insn_bits; - } s->insn_config = &ni_pfi_insn_config; ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0); @@ -4553,11 +4384,10 @@ static int ni_E_init(struct comedi_device *dev) s->insn_config = ni_rtsi_insn_config; ni_rtsi_init(dev); - if (board->reg_type & ni_reg_m_series_mask) { + if (board->reg_type & ni_reg_m_series_mask) counter_variant = ni_gpct_variant_m_series; - } else { + else counter_variant = ni_gpct_variant_e_series; - } devpriv->counter_dev = ni_gpct_device_construct(dev, &ni_gpct_write_register, &ni_gpct_read_register, @@ -4573,14 +4403,14 @@ static int ni_E_init(struct comedi_device *dev) s->maxdata = 0xffffffff; else s->maxdata = 0xffffff; - s->insn_read = &ni_gpct_insn_read; - s->insn_write = &ni_gpct_insn_write; - s->insn_config = &ni_gpct_insn_config; + s->insn_read = ni_tio_insn_read; + s->insn_write = ni_tio_insn_read; + s->insn_config = ni_tio_insn_config; #ifdef PCIDMA s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */; s->do_cmd = &ni_gpct_cmd; s->len_chanlist = 1; - s->do_cmdtest = &ni_gpct_cmdtest; + s->do_cmdtest = ni_tio_cmdtest; s->cancel = &ni_gpct_cancel; s->async_dma_dir = DMA_BIDIRECTIONAL; #endif @@ -4901,7 +4731,7 @@ static int pack_ad8842(int addr, int val, int *bitstring); struct caldac_struct { int n_chans; int n_bits; - int (*packbits) (int, int, int *); + int (*packbits)(int, int, int *); }; static struct caldac_struct caldacs[] = { @@ -4944,9 +4774,8 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) if (diffbits) { unsigned int *maxdata_list; - if (n_chans > MAX_N_CALDACS) { + if (n_chans > MAX_N_CALDACS) printk("BUG! MAX_N_CALDACS too small\n"); - } s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list; chan = 0; for (i = 0; i < n_dacs; i++) { @@ -5143,36 +4972,11 @@ static void GPCT_Reset(struct comedi_device *dev, int chan) #endif -static int ni_gpct_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct ni_gpct *counter = s->private; - return ni_tio_insn_config(counter, insn, data); -} - -static int ni_gpct_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct ni_gpct *counter = s->private; - return ni_tio_rinsn(counter, insn, data); -} - -static int ni_gpct_insn_write(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct ni_gpct *counter = s->private; - return ni_tio_winsn(counter, insn, data); -} - #ifdef PCIDMA static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - int retval; struct ni_gpct *counter = s->private; -/* const struct comedi_cmd *cmd = &s->async->cmd; */ + int retval; retval = ni_request_gpct_mite_channel(dev, counter->counter_index, COMEDI_INPUT); @@ -5183,19 +4987,8 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); ni_e_series_enable_second_irq(dev, counter->counter_index, 1); - retval = ni_tio_cmd(counter, s->async); - return retval; -} -#endif -#ifdef PCIDMA -static int ni_gpct_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) -{ - struct ni_gpct *counter = s->private; - - return ni_tio_cmdtest(counter, cmd); - return -ENOTSUPP; + return ni_tio_cmd(dev, s); } #endif @@ -5330,9 +5123,8 @@ static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel, struct ni_private *devpriv __maybe_unused = dev->private; unsigned bits; - if ((board->reg_type & ni_reg_m_series_mask) == 0) { + if ((board->reg_type & ni_reg_m_series_mask) == 0) return -ENOTSUPP; - } bits = ni_readl(M_Offset_PFI_Filter); bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel); bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter); @@ -5413,9 +5205,8 @@ static void ni_rtsi_init(struct comedi_device *dev) /* Set clock mode to internal */ devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit; - if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) { + if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) printk("ni_set_master_clock failed, bug?"); - } /* default internal lines routing to RTSI bus lines */ devpriv->rtsi_trig_a_output_reg = RTSI_Trig_Output_Bits(0, @@ -5598,9 +5389,8 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, devpriv->clock_source = source; /* it seems to typically take a few hundred microseconds for PLL to lock */ for (i = 0; i < timeout; ++i) { - if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) { + if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) break; - } udelay(1); } if (i == timeout) { @@ -5822,13 +5612,11 @@ static int cs5529_wait_for_idle(struct comedi_device *dev) for (i = 0; i < timeout; i++) { status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx); - if ((status & CSS_ADC_BUSY) == 0) { + if ((status & CSS_ADC_BUSY) == 0) break; - } set_current_state(TASK_INTERRUPTIBLE); - if (schedule_timeout(1)) { + if (schedule_timeout(1)) return -EIO; - } } /* printk("looped %i times waiting for idle\n", i); */ if (i == timeout) { @@ -5854,9 +5642,8 @@ static void cs5529_command(struct comedi_device *dev, unsigned short value) udelay(1); } /* printk("looped %i times writing command to cs5529\n", i); */ - if (i == timeout) { + if (i == timeout) comedi_error(dev, "possible problem - never saw adc go busy?"); - } } /* write to cs5529 register */ @@ -5873,25 +5660,6 @@ static void cs5529_config_write(struct comedi_device *dev, unsigned int value, comedi_error(dev, "time or signal in cs5529_config_write()"); } -#ifdef NI_CS5529_DEBUG -/* read from cs5529 register */ -static unsigned int cs5529_config_read(struct comedi_device *dev, - unsigned int reg_select_bits) -{ - unsigned int value; - - reg_select_bits &= CSCMD_REGISTER_SELECT_MASK; - cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits); - if (cs5529_wait_for_idle(dev)) - comedi_error(dev, "timeout or signal in cs5529_config_read()"); - value = (ni_ao_win_inw(dev, - CAL_ADC_Config_Data_High_Word_67xx) << 16) & - 0xff0000; - value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff; - return value; -} -#endif - static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data) { int retval; @@ -5967,13 +5735,6 @@ static int init_cs5529(struct comedi_device *dev) CSCMD_CONFIG_REGISTER); if (cs5529_wait_for_idle(dev)) comedi_error(dev, "timeout or signal in init_cs5529()\n"); -#endif -#ifdef NI_CS5529_DEBUG - printk("config: 0x%x\n", cs5529_config_read(dev, - CSCMD_CONFIG_REGISTER)); - printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER)); - printk("offset: 0x%x\n", cs5529_config_read(dev, - CSCMD_OFFSET_REGISTER)); #endif return 0; } diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 229a273f2016..de421486b758 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -47,8 +47,6 @@ See the notes in the ni_atmio.o driver. #include #include -#undef DEBUG - #define ATMIO 1 #undef PCIMIO diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index e3a8fa96d9b3..30c46a3c1767 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -47,8 +47,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org */ #define USE_DMA -/* #define DEBUG 1 */ -/* #define DEBUG_FLAGS */ #include #include @@ -60,13 +58,6 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org #include "comedi_fc.h" #include "mite.h" -#undef DPRINTK -#ifdef DEBUG -#define DPRINTK(format, args...) pr_debug(format, ## args) -#else -#define DPRINTK(format, args...) do { } while (0) -#endif - #define PCI_DIO_SIZE 4096 #define PCI_MITE_SIZE 4096 @@ -319,14 +310,6 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode); static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s); -#ifdef DEBUG_FLAGS -static void ni_pcidio_print_flags(unsigned int flags); -static void ni_pcidio_print_status(unsigned int status); -#else -#define ni_pcidio_print_flags(x) -#define ni_pcidio_print_status(x) -#endif - static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) { struct nidio96_private *devpriv = dev->private; @@ -401,7 +384,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct nidio96_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; @@ -427,19 +410,10 @@ static irqreturn_t nidio_interrupt(int irq, void *d) Interrupt_And_Window_Status); flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n", - status, flags); - ni_pcidio_print_flags(flags); - ni_pcidio_print_status(status); - spin_lock(&devpriv->mite_channel_lock); if (devpriv->di_mite_chan) m_status = mite_get_status(devpriv->di_mite_chan); -#ifdef MITE_DEBUG - mite_print_chsr(m_status); -#endif - /* mite_dump_regs(mite); */ if (m_status & CHSR_INT) { if (m_status & CHSR_LINKC) { writel(CHOR_CLRLC, @@ -450,7 +424,8 @@ static irqreturn_t nidio_interrupt(int irq, void *d) } if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY | CHSR_DRQ1 | CHSR_MRDY)) { - DPRINTK("unknown mite interrupt, disabling IRQ\n"); + dev_dbg(dev->class_dev, + "unknown mite interrupt, disabling IRQ\n"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; disable_irq(dev->irq); } @@ -460,7 +435,7 @@ static irqreturn_t nidio_interrupt(int irq, void *d) while (status & DataLeft) { work++; if (work > 20) { - DPRINTK("too much work in interrupt\n"); + dev_dbg(dev->class_dev, "too much work in interrupt\n"); writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); @@ -470,11 +445,11 @@ static irqreturn_t nidio_interrupt(int irq, void *d) flags &= IntEn; if (flags & TransferReady) { - /* DPRINTK("TransferReady\n"); */ while (flags & TransferReady) { work++; if (work > 100) { - DPRINTK("too much work in interrupt\n"); + dev_dbg(dev->class_dev, + "too much work in interrupt\n"); writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control @@ -488,21 +463,13 @@ static irqreturn_t nidio_interrupt(int irq, void *d) data2 = (auxdata & 0xffff0000) >> 16; comedi_buf_put(async, data1); comedi_buf_put(async, data2); - /* DPRINTK("read:%d, %d\n",data1,data2); */ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); } - /* DPRINTK("buf_int_count: %d\n", - async->buf_int_count); */ - /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n", - IntEn,flags,status); */ - /* ni_pcidio_print_flags(flags); */ - /* ni_pcidio_print_status(status); */ async->events |= COMEDI_CB_BLOCK; } if (flags & CountExpired) { - DPRINTK("CountExpired\n"); writeb(ClearExpired, devpriv->mite->daq_io_addr + Group_1_Second_Clear); @@ -511,41 +478,26 @@ static irqreturn_t nidio_interrupt(int irq, void *d) writeb(0x00, devpriv->mite->daq_io_addr + OpMode); break; } else if (flags & Waited) { - DPRINTK("Waited\n"); writeb(ClearWaited, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; break; } else if (flags & PrimaryTC) { - DPRINTK("PrimaryTC\n"); writeb(ClearPrimaryTC, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA; } else if (flags & SecondaryTC) { - DPRINTK("SecondaryTC\n"); writeb(ClearSecondaryTC, devpriv->mite->daq_io_addr + Group_1_First_Clear); async->events |= COMEDI_CB_EOA; } -#if 0 - else { - DPRINTK("ni_pcidio: unknown interrupt\n"); - async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - writeb(0x00, - devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); - } -#endif + flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags); status = readb(devpriv->mite->daq_io_addr + Interrupt_And_Window_Status); - /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x," - "status=0x%02x\n", IntEn, flags, status); */ - /* ni_pcidio_print_flags(flags); */ - /* ni_pcidio_print_status(status); */ } out: @@ -562,82 +514,6 @@ out: return IRQ_HANDLED; } -#ifdef DEBUG_FLAGS -static const char *bit_set_string(unsigned int bits, unsigned int bit, - const char *const strings[]) -{ - return (bits & (1U << bit)) ? strings[bit] : ""; -} - -static const char *const flags_strings[] = { - " TransferReady", " CountExpired", " 2", " 3", - " 4", " Waited", " PrimaryTC", " SecondaryTC", -}; - - -static void ni_pcidio_print_flags(unsigned int flags) -{ - pr_debug("group_1_flags:%s%s%s%s%s%s%s%s\n", - bit_set_string(flags, 7, flags_strings), - bit_set_string(flags, 6, flags_strings), - bit_set_string(flags, 5, flags_strings), - bit_set_string(flags, 4, flags_strings), - bit_set_string(flags, 3, flags_strings), - bit_set_string(flags, 2, flags_strings), - bit_set_string(flags, 1, flags_strings), - bit_set_string(flags, 0, flags_strings)); -} - -static const char *const status_strings[] = { - " DataLeft1", " Reserved1", " Req1", " StopTrig1", - " DataLeft2", " Reserved2", " Req2", " StopTrig2", -}; - -static void ni_pcidio_print_status(unsigned int flags) -{ - pr_debug("group_status:%s%s%s%s%s%s%s%s\n", - bit_set_string(flags, 7, status_strings), - bit_set_string(flags, 6, status_strings), - bit_set_string(flags, 5, status_strings), - bit_set_string(flags, 4, status_strings), - bit_set_string(flags, 3, status_strings), - bit_set_string(flags, 2, status_strings), - bit_set_string(flags, 1, status_strings), - bit_set_string(flags, 0, status_strings)); -} -#endif - -#ifdef unused -static void debug_int(struct comedi_device *dev) -{ - struct nidio96_private *devpriv = dev->private; - int a, b; - static int n_int; - struct timeval tv; - - do_gettimeofday(&tv); - a = readb(devpriv->mite->daq_io_addr + Group_Status); - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - - if (n_int < 10) { - DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b, - (int)tv.tv_usec); - } - - while (b & 1) { - writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO); - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - } - - b = readb(devpriv->mite->daq_io_addr + Group_1_Flags); - - if (n_int < 10) { - DPRINTK("new status 0x%02x\n", b); - n_int++; - } -} -#endif - static int ni_pcidio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -883,7 +759,6 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) s->async->inttrig = ni_pcidio_inttrig; } - DPRINTK("ni_pcidio: command started\n"); return 0; } @@ -1074,6 +949,19 @@ static int pci_6534_upload_firmware(struct comedi_device *dev) return ret; } +static void nidio_reset_board(struct comedi_device *dev) +{ + struct nidio96_private *devpriv = dev->private; + void __iomem *daq_mmio = devpriv->mite->daq_io_addr; + + writel(0, daq_mmio + Port_IO(0)); + writel(0, daq_mmio + Port_Pin_Directions(0)); + writel(0, daq_mmio + Port_Pin_Mask(0)); + + /* disable interrupts on board */ + writeb(0, daq_mmio + Master_DMA_And_Interrupt_Control); +} + static int nidio_auto_attach(struct comedi_device *dev, unsigned long context) { @@ -1115,13 +1003,14 @@ static int nidio_auto_attach(struct comedi_device *dev, if (devpriv->di_mite_ring == NULL) return -ENOMEM; - irq = mite_irq(devpriv->mite); if (board->uses_firmware) { ret = pci_6534_upload_firmware(dev); if (ret < 0) return ret; } + nidio_reset_board(dev); + ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; @@ -1149,21 +1038,13 @@ static int nidio_auto_attach(struct comedi_device *dev, s->async_dma_dir = DMA_BIDIRECTIONAL; s->poll = &ni_pcidio_poll; - writel(0, devpriv->mite->daq_io_addr + Port_IO(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0)); - writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0)); - - /* disable interrupts on board */ - writeb(0x00, - devpriv->mite->daq_io_addr + - Master_DMA_And_Interrupt_Control); - - ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, - "ni_pcidio", dev); - if (ret < 0) - dev_warn(dev->class_dev, "irq not available\n"); - - dev->irq = irq; + irq = mite_irq(devpriv->mite); + if (irq) { + ret = request_irq(irq, nidio_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = irq; + } return 0; } @@ -1200,7 +1081,7 @@ static int ni_pcidio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = { +static const struct pci_device_id ni_pcidio_pci_table[] = { { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS }, { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 }, { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 }, diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 536be83af549..0ed980455875 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -116,8 +116,6 @@ Bugs: #include "ni_stc.h" #include "mite.h" -/* #define PCI_DEBUG */ - #define PCIDMA #define PCIMIO 1 @@ -134,24 +132,26 @@ Bugs: 63 different possibilities. An AO channel can not act as it's own OFFSET or REFERENCE. */ -static const struct comedi_lrange range_ni_M_628x_ao = { 8, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2, 2), - RANGE(-1, 1), - RANGE(-5, 15), - RANGE(0, 10), - RANGE(3, 7), - RANGE(4, 6), - RANGE_ext(-1, 1) - } +static const struct comedi_lrange range_ni_M_628x_ao = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + RANGE(-5, 15), + UNI_RANGE(10), + RANGE(3, 7), + RANGE(4, 6), + RANGE_ext(-1, 1) + } }; -static const struct comedi_lrange range_ni_M_625x_ao = { 3, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE_ext(-1, 1) - } +static const struct comedi_lrange range_ni_M_625x_ao = { + 3, { + BIP_RANGE(10), + BIP_RANGE(5), + RANGE_ext(-1, 1) + } }; enum ni_pcimio_boardid { @@ -1178,9 +1178,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, offset = M_Offset_AO_FIFO_Clear; break; case DIO_Control_Register: - printk - ("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n", - __func__, reg); + dev_dbg(dev->class_dev, + "%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n", + __func__, reg); return; break; case G_Autoincrement_Register(0): @@ -1471,6 +1471,7 @@ static int pcimio_auto_attach(struct comedi_device *dev, struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct ni_board_struct *board = NULL; struct ni_private *devpriv; + unsigned int irq; int ret; if (context < ARRAY_SIZE(ni_boards)) @@ -1532,18 +1533,12 @@ static int pcimio_auto_attach(struct comedi_device *dev, if (board->reg_type == ni_reg_6143) init_6143(dev); - dev->irq = mite_irq(devpriv->mite); - - if (dev->irq == 0) { - pr_warn("unknown irq (bad)\n"); - } else { - pr_debug("( irq = %u )\n", dev->irq); - ret = request_irq(dev->irq, ni_E_interrupt, NI_E_IRQ_FLAGS, - DRV_NAME, dev); - if (ret < 0) { - pr_warn("irq not available\n"); - dev->irq = 0; - } + irq = mite_irq(devpriv->mite); + if (irq) { + ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS, + dev->board_name, dev); + if (ret == 0) + dev->irq = irq; } ret = ni_E_init(dev); @@ -1639,7 +1634,7 @@ static int ni_pcimio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcimio_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(ni_pcimio_pci_table) = { +static const struct pci_device_id ni_pcimio_pci_table[] = { { PCI_VDEVICE(NI, 0x0162), BOARD_PCIMIO_16XE_50 }, /* 0x1620? */ { PCI_VDEVICE(NI, 0x1170), BOARD_PCIMIO_16XE_10 }, { PCI_VDEVICE(NI, 0x1180), BOARD_PCIMIO_16E_1 }, diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 9b120c77d83a..92691b491c24 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -53,10 +53,6 @@ static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter, unsigned generic_clock_source); static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter); -MODULE_AUTHOR("Comedi "); -MODULE_DESCRIPTION("Comedi support for NI general-purpose counters"); -MODULE_LICENSE("GPL"); - static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum ni_gpct_variant variant) @@ -277,19 +273,6 @@ static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n) static const unsigned int counter_status_mask = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING; -static int __init ni_tio_init_module(void) -{ - return 0; -} - -module_init(ni_tio_init_module); - -static void __exit ni_tio_cleanup_module(void) -{ -} - -module_exit(ni_tio_cleanup_module); - struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device *dev, void (*write_register) (struct ni_gpct @@ -362,74 +345,64 @@ static int ni_tio_second_gate_registers_present(const struct ni_gpct_device static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) { - write_register(counter, Gi_Reset_Bit(counter->counter_index), - NITIO_Gxx_Joint_Reset_Reg(counter->counter_index)); + unsigned cidx = counter->counter_index; + + write_register(counter, Gi_Reset_Bit(cidx), NITIO_RESET_REG(cidx)); } void ni_tio_init_counter(struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; ni_tio_reset_count_and_disarm(counter); + /* initialize counter registers */ - counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] = - 0x0; - write_register(counter, - counter_dev-> - regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)], - NITIO_Gi_Autoincrement_Reg(counter->counter_index)); - ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), + counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0; + write_register(counter, counter_dev->regs[NITIO_AUTO_INC_REG(cidx)], + NITIO_AUTO_INC_REG(cidx)); + + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), ~0, Gi_Synchronize_Gate_Bit); - ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0, - 0); - counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0; - write_register(counter, - counter_dev-> - regs[NITIO_Gi_LoadA_Reg(counter->counter_index)], - NITIO_Gi_LoadA_Reg(counter->counter_index)); - counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0; - write_register(counter, - counter_dev-> - regs[NITIO_Gi_LoadB_Reg(counter->counter_index)], - NITIO_Gi_LoadB_Reg(counter->counter_index)); - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0, - 0); - if (ni_tio_counting_mode_registers_present(counter_dev)) { - ni_tio_set_bits(counter, - NITIO_Gi_Counting_Mode_Reg(counter-> - counter_index), ~0, - 0); - } + + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); + + counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0; + write_register(counter, counter_dev->regs[NITIO_LOADA_REG(cidx)], + NITIO_LOADA_REG(cidx)); + + counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0; + write_register(counter, counter_dev->regs[NITIO_LOADB_REG(cidx)], + NITIO_LOADB_REG(cidx)); + + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); + + if (ni_tio_counting_mode_registers_present(counter_dev)) + ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); + if (ni_tio_second_gate_registers_present(counter_dev)) { - counter_dev-> - regs[NITIO_Gi_Second_Gate_Reg(counter->counter_index)] = - 0x0; + counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0; write_register(counter, - counter_dev-> - regs[NITIO_Gi_Second_Gate_Reg - (counter->counter_index)], - NITIO_Gi_Second_Gate_Reg(counter-> - counter_index)); + counter_dev->regs[NITIO_GATE2_REG(cidx)], + NITIO_GATE2_REG(cidx)); } - ni_tio_set_bits(counter, - NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0, - 0x0); - ni_tio_set_bits(counter, - NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), - ~0, 0x0); + + ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0); + + ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0); } EXPORT_SYMBOL_GPL(ni_tio_init_counter); static unsigned int ni_tio_counter_status(struct ni_gpct *counter) { - unsigned int status = 0; + unsigned cidx = counter->counter_index; const unsigned bits = read_register(counter, - NITIO_Gxx_Status_Reg(counter-> - counter_index)); - if (bits & Gi_Armed_Bit(counter->counter_index)) { + NITIO_SHARED_STATUS_REG(cidx)); + unsigned int status = 0; + + if (bits & Gi_Armed_Bit(cidx)) { status |= COMEDI_COUNTER_ARMED; - if (bits & Gi_Counting_Bit(counter->counter_index)) + if (bits & Gi_Counting_Bit(cidx)) status |= COMEDI_COUNTER_COUNTING; } return status; @@ -438,8 +411,8 @@ static unsigned int ni_tio_counter_status(struct ni_gpct *counter) static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned counting_mode_reg = - NITIO_Gi_Counting_Mode_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx); static const uint64_t min_normal_sync_period_ps = 25000; const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter, ni_tio_generic_clock_src_select @@ -476,6 +449,7 @@ static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync) static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; unsigned mode_reg_mask; unsigned mode_reg_values; unsigned input_select_bits = 0; @@ -502,7 +476,7 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) default: break; } - ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), mode_reg_mask, mode_reg_values); if (ni_tio_counting_mode_registers_present(counter_dev)) { @@ -515,15 +489,13 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask; if (mode & NI_GPCT_INDEX_ENABLE_BIT) counting_mode_bits |= Gi_Index_Mode_Bit; - ni_tio_set_bits(counter, - NITIO_Gi_Counting_Mode_Reg(counter-> - counter_index), + ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask | Gi_Index_Mode_Bit, counting_mode_bits); ni_tio_set_sync_mode(counter, 0); } - ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Up_Down_Mask, (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift); @@ -532,8 +504,7 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) input_select_bits |= Gi_Or_Gate_Bit; if (mode & NI_GPCT_INVERT_OUTPUT_BIT) input_select_bits |= Gi_Output_Polarity_Bit; - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit | Gi_Output_Polarity_Bit, input_select_bits); @@ -543,7 +514,7 @@ static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode) int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) { struct ni_gpct_device *counter_dev = counter->counter_dev; - + unsigned cidx = counter->counter_index; unsigned command_transient_bits = 0; if (arm) { @@ -581,9 +552,7 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) } break; } - ni_tio_set_bits(counter, - NITIO_Gi_Counting_Mode_Reg - (counter->counter_index), + ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), Gi_HW_Arm_Select_Mask (counter_dev->variant) | Gi_HW_Arm_Enable_Bit, @@ -592,8 +561,7 @@ int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger) } else { command_transient_bits |= Gi_Disarm_Bit; } - ni_tio_set_bits_transient(counter, - NITIO_Gi_Command_Reg(counter->counter_index), + ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, command_transient_bits); return 0; } @@ -717,8 +685,8 @@ static void ni_tio_set_source_subselect(struct ni_gpct *counter, unsigned int clock_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); if (counter_dev->variant != ni_gpct_variant_m_series) return; @@ -747,6 +715,7 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, unsigned int period_ns) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; unsigned input_select_bits = 0; static const uint64_t pico_per_nano = 1000; @@ -766,8 +735,7 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, } if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) input_select_bits |= Gi_Source_Polarity_Bit; - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), Gi_Source_Select_Mask | Gi_Source_Polarity_Bit, input_select_bits); ni_tio_set_source_subselect(counter, clock_source); @@ -791,9 +759,7 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, return -EINVAL; break; } - ni_tio_set_bits(counter, - NITIO_Gi_Counting_Mode_Reg(counter-> - counter_index), + ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), Gi_Prescale_X2_Bit(counter_dev->variant) | Gi_Prescale_X8_Bit(counter_dev->variant), counting_mode_bits); @@ -806,15 +772,12 @@ static int ni_tio_set_clock_src(struct ni_gpct *counter, static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter, - NITIO_Gi_Counting_Mode_Reg - (counter-> - counter_index)); + unsigned cidx = counter->counter_index; + const unsigned counting_mode_bits = + ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx)); unsigned bits = 0; - if (ni_tio_get_soft_copy(counter, - NITIO_Gi_Input_Select_Reg - (counter->counter_index)) & + if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & Gi_Source_Polarity_Bit) bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT; if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant)) @@ -827,15 +790,13 @@ static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter) static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); unsigned clock_source = 0; unsigned i; - const unsigned input_select = (ni_tio_get_soft_copy(counter, - NITIO_Gi_Input_Select_Reg - (counter->counter_index)) - & Gi_Source_Select_Mask) >> - Gi_Source_Select_Shift; + const unsigned input_select = + (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & + Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; switch (input_select) { case NI_M_Series_Timebase_1_Clock: @@ -895,12 +856,11 @@ static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter) static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter) { unsigned clock_source = 0; + unsigned cidx = counter->counter_index; + const unsigned input_select = + (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & + Gi_Source_Select_Mask) >> Gi_Source_Select_Shift; unsigned i; - const unsigned input_select = (ni_tio_get_soft_copy(counter, - NITIO_Gi_Input_Select_Reg - (counter->counter_index)) - & Gi_Source_Select_Mask) >> - Gi_Source_Select_Shift; switch (input_select) { case NI_660x_Timebase_1_Clock: @@ -1022,6 +982,7 @@ static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter, unsigned int gate_source) { const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask; + unsigned cidx = counter->counter_index; unsigned mode_values = 0; if (gate_source & CR_INVERT) @@ -1030,7 +991,7 @@ static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter, mode_values |= Gi_Rising_Edge_Gating_Bits; else mode_values |= Gi_Level_Gating_Bits; - ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), mode_mask, mode_values); } @@ -1038,6 +999,7 @@ static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source) { const unsigned selected_gate = CR_CHAN(gate_source); + unsigned cidx = counter->counter_index; /* bits of selected_gate that may be meaningful to input select register */ const unsigned selected_gate_mask = 0x1f; unsigned ni_660x_gate_select; @@ -1075,8 +1037,7 @@ static int ni_660x_set_first_gate(struct ni_gpct *counter, return -EINVAL; break; } - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select)); return 0; @@ -1086,6 +1047,7 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter, unsigned int gate_source) { const unsigned selected_gate = CR_CHAN(gate_source); + unsigned cidx = counter->counter_index; /* bits of selected_gate that may be meaningful to input select register */ const unsigned selected_gate_mask = 0x1f; unsigned ni_m_series_gate_select; @@ -1124,8 +1086,7 @@ static int ni_m_series_set_first_gate(struct ni_gpct *counter, return -EINVAL; break; } - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_m_series_gate_select)); return 0; @@ -1135,8 +1096,8 @@ static int ni_660x_set_second_gate(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); const unsigned selected_second_gate = CR_CHAN(gate_source); /* bits of second_gate that may be meaningful to second gate register */ static const unsigned selected_second_gate_mask = 0x1f; @@ -1194,8 +1155,8 @@ static int ni_m_series_set_second_gate(struct ni_gpct *counter, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); const unsigned selected_second_gate = CR_CHAN(gate_source); /* bits of second_gate that may be meaningful to second gate register */ static const unsigned selected_second_gate_mask = 0x1f; @@ -1222,15 +1183,13 @@ int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, unsigned int gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); switch (gate_index) { case 0: if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) { - ni_tio_set_bits(counter, - NITIO_Gi_Mode_Reg(counter-> - counter_index), + ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), Gi_Gating_Mode_Mask, Gi_Gating_Disabled_Bits); return 0; @@ -1292,11 +1251,12 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, unsigned int source) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; if (counter_dev->variant == ni_gpct_variant_m_series) { unsigned int abz_reg, shift, mask; - abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index); + abz_reg = NITIO_ABZ_REG(cidx); switch (index) { case NI_GPCT_SOURCE_ENCODER_A: shift = 10; @@ -1319,7 +1279,6 @@ static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index, counter_dev->regs[abz_reg] &= ~mask; counter_dev->regs[abz_reg] |= (source << shift) & mask; write_register(counter, counter_dev->regs[abz_reg], abz_reg); -/* printk("%s %x %d %d\n", __func__, counter_dev->regs[abz_reg], index, source); */ return 0; } return -EINVAL; @@ -1491,12 +1450,10 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, unsigned int *gate_source) { struct ni_gpct_device *counter_dev = counter->counter_dev; - const unsigned mode_bits = ni_tio_get_soft_copy(counter, - NITIO_Gi_Mode_Reg - (counter-> - counter_index)); - const unsigned second_gate_reg = - NITIO_Gi_Second_Gate_Reg(counter->counter_index); + unsigned cidx = counter->counter_index; + const unsigned mode_bits = + ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)); + const unsigned second_gate_reg = NITIO_GATE2_REG(cidx); unsigned gate_select_bits; switch (gate_index) { @@ -1508,8 +1465,7 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, } else { gate_select_bits = (ni_tio_get_soft_copy(counter, - NITIO_Gi_Input_Select_Reg - (counter->counter_index)) & + NITIO_INPUT_SEL_REG(cidx)) & Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift; } switch (counter_dev->variant) { @@ -1577,9 +1533,13 @@ static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index, return 0; } -int ni_tio_insn_config(struct ni_gpct *counter, - struct comedi_insn *insn, unsigned int *data) +int ni_tio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct ni_gpct *counter = s->private; + switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: return ni_tio_set_counter_mode(counter, data[1]); @@ -1623,11 +1583,15 @@ int ni_tio_insn_config(struct ni_gpct *counter, } EXPORT_SYMBOL_GPL(ni_tio_insn_config); -int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn *insn, - unsigned int *data) +int ni_tio_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; const unsigned channel = CR_CHAN(insn->chanspec); + unsigned cidx = counter->counter_index; unsigned first_read; unsigned second_read; unsigned correct_read; @@ -1636,65 +1600,57 @@ int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn *insn, return 0; switch (channel) { case 0: - ni_tio_set_bits(counter, - NITIO_Gi_Command_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0); - ni_tio_set_bits(counter, - NITIO_Gi_Command_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, Gi_Save_Trace_Bit); /* The count doesn't get latched until the next clock edge, so it is possible the count may change (once) while we are reading. Since the read of the SW_Save_Reg isn't atomic (apparently even when it's a 32 bit register according to 660x docs), we need to read twice and make sure the reading hasn't changed. If it has, a third read will be correct since the count value will definitely have latched by then. */ - first_read = - read_register(counter, - NITIO_Gi_SW_Save_Reg(counter->counter_index)); - second_read = - read_register(counter, - NITIO_Gi_SW_Save_Reg(counter->counter_index)); + first_read = read_register(counter, NITIO_SW_SAVE_REG(cidx)); + second_read = read_register(counter, NITIO_SW_SAVE_REG(cidx)); if (first_read != second_read) correct_read = - read_register(counter, - NITIO_Gi_SW_Save_Reg(counter-> - counter_index)); + read_register(counter, NITIO_SW_SAVE_REG(cidx)); else correct_read = first_read; data[0] = correct_read; return 0; break; case 1: - data[0] = - counter_dev-> - regs[NITIO_Gi_LoadA_Reg(counter->counter_index)]; + data[0] = counter_dev->regs[NITIO_LOADA_REG(cidx)]; break; case 2: - data[0] = - counter_dev-> - regs[NITIO_Gi_LoadB_Reg(counter->counter_index)]; + data[0] = counter_dev->regs[NITIO_LOADB_REG(cidx)]; break; } return 0; } -EXPORT_SYMBOL_GPL(ni_tio_rinsn); +EXPORT_SYMBOL_GPL(ni_tio_insn_read); static unsigned ni_tio_next_load_register(struct ni_gpct *counter) { - const unsigned bits = read_register(counter, - NITIO_Gxx_Status_Reg(counter-> - counter_index)); + unsigned cidx = counter->counter_index; + const unsigned bits = + read_register(counter, NITIO_SHARED_STATUS_REG(cidx)); - if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) - return NITIO_Gi_LoadB_Reg(counter->counter_index); + if (bits & Gi_Next_Load_Source_Bit(cidx)) + return NITIO_LOADB_REG(cidx); else - return NITIO_Gi_LoadA_Reg(counter->counter_index); + return NITIO_LOADA_REG(cidx); } -int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn *insn, - unsigned int *data) +int ni_tio_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; const unsigned channel = CR_CHAN(insn->chanspec); + unsigned cidx = counter->counter_index; unsigned load_reg; if (insn->n < 1) @@ -1705,24 +1661,18 @@ int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn *insn, /* Don't disturb load source select, just use whichever load register is already selected. */ load_reg = ni_tio_next_load_register(counter); write_register(counter, data[0], load_reg); - ni_tio_set_bits_transient(counter, - NITIO_Gi_Command_Reg(counter-> - counter_index), + ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), 0, 0, Gi_Load_Bit); /* restore state of load reg to whatever the user set last set it to */ write_register(counter, counter_dev->regs[load_reg], load_reg); break; case 1: - counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = - data[0]; - write_register(counter, data[0], - NITIO_Gi_LoadA_Reg(counter->counter_index)); + counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0]; + write_register(counter, data[0], NITIO_LOADA_REG(cidx)); break; case 2: - counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = - data[0]; - write_register(counter, data[0], - NITIO_Gi_LoadB_Reg(counter->counter_index)); + counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0]; + write_register(counter, data[0], NITIO_LOADB_REG(cidx)); break; default: return -EINVAL; @@ -1730,4 +1680,19 @@ int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn *insn, } return 0; } -EXPORT_SYMBOL_GPL(ni_tio_winsn); +EXPORT_SYMBOL_GPL(ni_tio_insn_write); + +static int __init ni_tio_init_module(void) +{ + return 0; +} +module_init(ni_tio_init_module); + +static void __exit ni_tio_cleanup_module(void) +{ +} +module_exit(ni_tio_cleanup_module); + +MODULE_AUTHOR("Comedi "); +MODULE_DESCRIPTION("Comedi support for NI general-purpose counters"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 7e13697b3254..68378dab4e70 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -25,77 +25,77 @@ struct mite_struct; struct ni_gpct_device; enum ni_gpct_register { - NITIO_G0_Autoincrement_Reg, - NITIO_G1_Autoincrement_Reg, - NITIO_G2_Autoincrement_Reg, - NITIO_G3_Autoincrement_Reg, - NITIO_G0_Command_Reg, - NITIO_G1_Command_Reg, - NITIO_G2_Command_Reg, - NITIO_G3_Command_Reg, - NITIO_G0_HW_Save_Reg, - NITIO_G1_HW_Save_Reg, - NITIO_G2_HW_Save_Reg, - NITIO_G3_HW_Save_Reg, - NITIO_G0_SW_Save_Reg, - NITIO_G1_SW_Save_Reg, - NITIO_G2_SW_Save_Reg, - NITIO_G3_SW_Save_Reg, - NITIO_G0_Mode_Reg, - NITIO_G1_Mode_Reg, - NITIO_G2_Mode_Reg, - NITIO_G3_Mode_Reg, - NITIO_G0_LoadA_Reg, - NITIO_G1_LoadA_Reg, - NITIO_G2_LoadA_Reg, - NITIO_G3_LoadA_Reg, - NITIO_G0_LoadB_Reg, - NITIO_G1_LoadB_Reg, - NITIO_G2_LoadB_Reg, - NITIO_G3_LoadB_Reg, - NITIO_G0_Input_Select_Reg, - NITIO_G1_Input_Select_Reg, - NITIO_G2_Input_Select_Reg, - NITIO_G3_Input_Select_Reg, - NITIO_G0_Counting_Mode_Reg, - NITIO_G1_Counting_Mode_Reg, - NITIO_G2_Counting_Mode_Reg, - NITIO_G3_Counting_Mode_Reg, - NITIO_G0_Second_Gate_Reg, - NITIO_G1_Second_Gate_Reg, - NITIO_G2_Second_Gate_Reg, - NITIO_G3_Second_Gate_Reg, - NITIO_G01_Status_Reg, - NITIO_G23_Status_Reg, - NITIO_G01_Joint_Reset_Reg, - NITIO_G23_Joint_Reset_Reg, - NITIO_G01_Joint_Status1_Reg, - NITIO_G23_Joint_Status1_Reg, - NITIO_G01_Joint_Status2_Reg, - NITIO_G23_Joint_Status2_Reg, - NITIO_G0_DMA_Config_Reg, - NITIO_G1_DMA_Config_Reg, - NITIO_G2_DMA_Config_Reg, - NITIO_G3_DMA_Config_Reg, - NITIO_G0_DMA_Status_Reg, - NITIO_G1_DMA_Status_Reg, - NITIO_G2_DMA_Status_Reg, - NITIO_G3_DMA_Status_Reg, - NITIO_G0_ABZ_Reg, - NITIO_G1_ABZ_Reg, - NITIO_G0_Interrupt_Acknowledge_Reg, - NITIO_G1_Interrupt_Acknowledge_Reg, - NITIO_G2_Interrupt_Acknowledge_Reg, - NITIO_G3_Interrupt_Acknowledge_Reg, - NITIO_G0_Status_Reg, - NITIO_G1_Status_Reg, - NITIO_G2_Status_Reg, - NITIO_G3_Status_Reg, - NITIO_G0_Interrupt_Enable_Reg, - NITIO_G1_Interrupt_Enable_Reg, - NITIO_G2_Interrupt_Enable_Reg, - NITIO_G3_Interrupt_Enable_Reg, - NITIO_Num_Registers, + NITIO_G0_AUTO_INC, + NITIO_G1_AUTO_INC, + NITIO_G2_AUTO_INC, + NITIO_G3_AUTO_INC, + NITIO_G0_CMD, + NITIO_G1_CMD, + NITIO_G2_CMD, + NITIO_G3_CMD, + NITIO_G0_HW_SAVE, + NITIO_G1_HW_SAVE, + NITIO_G2_HW_SAVE, + NITIO_G3_HW_SAVE, + NITIO_G0_SW_SAVE, + NITIO_G1_SW_SAVE, + NITIO_G2_SW_SAVE, + NITIO_G3_SW_SAVE, + NITIO_G0_MODE, + NITIO_G1_MODE, + NITIO_G2_MODE, + NITIO_G3_MODE, + NITIO_G0_LOADA, + NITIO_G1_LOADA, + NITIO_G2_LOADA, + NITIO_G3_LOADA, + NITIO_G0_LOADB, + NITIO_G1_LOADB, + NITIO_G2_LOADB, + NITIO_G3_LOADB, + NITIO_G0_INPUT_SEL, + NITIO_G1_INPUT_SEL, + NITIO_G2_INPUT_SEL, + NITIO_G3_INPUT_SEL, + NITIO_G0_CNT_MODE, + NITIO_G1_CNT_MODE, + NITIO_G2_CNT_MODE, + NITIO_G3_CNT_MODE, + NITIO_G0_GATE2, + NITIO_G1_GATE2, + NITIO_G2_GATE2, + NITIO_G3_GATE2, + NITIO_G01_STATUS, + NITIO_G23_STATUS, + NITIO_G01_RESET, + NITIO_G23_RESET, + NITIO_G01_STATUS1, + NITIO_G23_STATUS1, + NITIO_G01_STATUS2, + NITIO_G23_STATUS2, + NITIO_G0_DMA_CFG, + NITIO_G1_DMA_CFG, + NITIO_G2_DMA_CFG, + NITIO_G3_DMA_CFG, + NITIO_G0_DMA_STATUS, + NITIO_G1_DMA_STATUS, + NITIO_G2_DMA_STATUS, + NITIO_G3_DMA_STATUS, + NITIO_G0_ABZ, + NITIO_G1_ABZ, + NITIO_G0_INT_ACK, + NITIO_G1_INT_ACK, + NITIO_G2_INT_ACK, + NITIO_G3_INT_ACK, + NITIO_G0_STATUS, + NITIO_G1_STATUS, + NITIO_G2_STATUS, + NITIO_G3_STATUS, + NITIO_G0_INT_ENA, + NITIO_G1_INT_ENA, + NITIO_G2_INT_ENA, + NITIO_G3_INT_ENA, + NITIO_NUM_REGS, }; enum ni_gpct_variant { @@ -122,48 +122,35 @@ struct ni_gpct_device { enum ni_gpct_variant variant; struct ni_gpct *counters; unsigned num_counters; - unsigned regs[NITIO_Num_Registers]; + unsigned regs[NITIO_NUM_REGS]; spinlock_t regs_lock; }; -extern struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device - *dev, - void (*write_register) - (struct ni_gpct * - counter, unsigned bits, - enum ni_gpct_register - reg), - unsigned (*read_register) - (struct ni_gpct * - counter, - enum ni_gpct_register - reg), - enum ni_gpct_variant - variant, - unsigned num_counters); -extern void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev); -extern void ni_tio_init_counter(struct ni_gpct *counter); -extern int ni_tio_rinsn(struct ni_gpct *counter, - struct comedi_insn *insn, unsigned int *data); -extern int ni_tio_insn_config(struct ni_gpct *counter, - struct comedi_insn *insn, unsigned int *data); -extern int ni_tio_winsn(struct ni_gpct *counter, - struct comedi_insn *insn, unsigned int *data); -extern int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async); -extern int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd); -extern int ni_tio_cancel(struct ni_gpct *counter); -extern void ni_tio_handle_interrupt(struct ni_gpct *counter, - struct comedi_subdevice *s); -extern void ni_tio_set_mite_channel(struct ni_gpct *counter, - struct mite_channel *mite_chan); -extern void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, - int *gate_error, int *tc_error, - int *perm_stale_data, - int *stale_data); - -static inline struct ni_gpct *subdev_to_counter(struct comedi_subdevice *s) -{ - return s->private; -} +struct ni_gpct_device * +ni_gpct_device_construct(struct comedi_device *, + void (*write_register)(struct ni_gpct *, + unsigned bits, + enum ni_gpct_register), + unsigned (*read_register)(struct ni_gpct *, + enum ni_gpct_register), + enum ni_gpct_variant, + unsigned num_counters); +void ni_gpct_device_destroy(struct ni_gpct_device *); +void ni_tio_init_counter(struct ni_gpct *); +int ni_tio_insn_read(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *data); +int ni_tio_insn_config(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *data); +int ni_tio_insn_write(struct comedi_device *, struct comedi_subdevice *, + struct comedi_insn *, unsigned int *data); +int ni_tio_cmd(struct comedi_device *, struct comedi_subdevice *); +int ni_tio_cmdtest(struct comedi_device *, struct comedi_subdevice *, + struct comedi_cmd *); +int ni_tio_cancel(struct ni_gpct *); +void ni_tio_handle_interrupt(struct ni_gpct *, struct comedi_subdevice *); +void ni_tio_set_mite_channel(struct ni_gpct *, struct mite_channel *); +void ni_tio_acknowledge_and_confirm(struct ni_gpct *, + int *gate_error, int *tc_error, + int *perm_stale_data, int *stale_data); #endif /* _COMEDI_NI_TIO_H */ diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index b009876754a8..15b81b8fc5c4 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -21,409 +21,26 @@ #include "ni_tio.h" -static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Autoincrement_Reg; - break; - case 1: - return NITIO_G1_Autoincrement_Reg; - break; - case 2: - return NITIO_G2_Autoincrement_Reg; - break; - case 3: - return NITIO_G3_Autoincrement_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Command_Reg; - break; - case 1: - return NITIO_G1_Command_Reg; - break; - case 2: - return NITIO_G2_Command_Reg; - break; - case 3: - return NITIO_G3_Command_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Counting_Mode_Reg; - break; - case 1: - return NITIO_G1_Counting_Mode_Reg; - break; - case 2: - return NITIO_G2_Counting_Mode_Reg; - break; - case 3: - return NITIO_G3_Counting_Mode_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Input_Select_Reg; - break; - case 1: - return NITIO_G1_Input_Select_Reg; - break; - case 2: - return NITIO_G2_Input_Select_Reg; - break; - case 3: - return NITIO_G3_Input_Select_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - case 1: - return NITIO_G01_Joint_Reset_Reg; - break; - case 2: - case 3: - return NITIO_G23_Joint_Reset_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - case 1: - return NITIO_G01_Joint_Status1_Reg; - break; - case 2: - case 3: - return NITIO_G23_Joint_Status1_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned - counter_index) -{ - switch (counter_index) { - case 0: - case 1: - return NITIO_G01_Joint_Status2_Reg; - break; - case 2: - case 3: - return NITIO_G23_Joint_Status2_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index) -{ - switch (counter_index) { - case 0: - case 1: - return NITIO_G01_Status_Reg; - break; - case 2: - case 3: - return NITIO_G23_Status_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_LoadA_Reg(unsigned counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_LoadA_Reg; - break; - case 1: - return NITIO_G1_LoadA_Reg; - break; - case 2: - return NITIO_G2_LoadA_Reg; - break; - case 3: - return NITIO_G3_LoadA_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_LoadB_Reg(unsigned counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_LoadB_Reg; - break; - case 1: - return NITIO_G1_LoadB_Reg; - break; - case 2: - return NITIO_G2_LoadB_Reg; - break; - case 3: - return NITIO_G3_LoadB_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Mode_Reg(unsigned counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Mode_Reg; - break; - case 1: - return NITIO_G1_Mode_Reg; - break; - case 2: - return NITIO_G2_Mode_Reg; - break; - case 3: - return NITIO_G3_Mode_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_SW_Save_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_SW_Save_Reg; - break; - case 1: - return NITIO_G1_SW_Save_Reg; - break; - case 2: - return NITIO_G2_SW_Save_Reg; - break; - case 3: - return NITIO_G3_SW_Save_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Second_Gate_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Second_Gate_Reg; - break; - case 1: - return NITIO_G1_Second_Gate_Reg; - break; - case 2: - return NITIO_G2_Second_Gate_Reg; - break; - case 3: - return NITIO_G3_Second_Gate_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_DMA_Config_Reg; - break; - case 1: - return NITIO_G1_DMA_Config_Reg; - break; - case 2: - return NITIO_G2_DMA_Config_Reg; - break; - case 3: - return NITIO_G3_DMA_Config_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_DMA_Status_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_DMA_Status_Reg; - break; - case 1: - return NITIO_G1_DMA_Status_Reg; - break; - case 2: - return NITIO_G2_DMA_Status_Reg; - break; - case 3: - return NITIO_G3_DMA_Status_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_ABZ_Reg; - break; - case 1: - return NITIO_G1_ABZ_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg( - int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Interrupt_Acknowledge_Reg; - break; - case 1: - return NITIO_G1_Interrupt_Acknowledge_Reg; - break; - case 2: - return NITIO_G2_Interrupt_Acknowledge_Reg; - break; - case 3: - return NITIO_G3_Interrupt_Acknowledge_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Status_Reg; - break; - case 1: - return NITIO_G1_Status_Reg; - break; - case 2: - return NITIO_G2_Status_Reg; - break; - case 3: - return NITIO_G3_Status_Reg; - break; - default: - BUG(); - break; - } - return 0; -} - -static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg( - int counter_index) -{ - switch (counter_index) { - case 0: - return NITIO_G0_Interrupt_Enable_Reg; - break; - case 1: - return NITIO_G1_Interrupt_Enable_Reg; - break; - case 2: - return NITIO_G2_Interrupt_Enable_Reg; - break; - case 3: - return NITIO_G3_Interrupt_Enable_Reg; - break; - default: - BUG(); - break; - } - return 0; -} +#define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x)) +#define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x)) +#define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x)) +#define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x)) +#define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x)) +#define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x)) +#define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x)) +#define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x)) +#define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x)) +#define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x)) +#define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2)) +#define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2)) +#define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2)) +#define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2)) +#define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x)) +#define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x)) +#define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x)) +#define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x)) +#define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x)) +#define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x)) enum Gi_Auto_Increment_Reg_Bits { Gi_Auto_Increment_Mask = 0xff @@ -699,14 +316,14 @@ static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index) static inline void write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) { - BUG_ON(reg >= NITIO_Num_Registers); + BUG_ON(reg >= NITIO_NUM_REGS); counter->counter_dev->write_register(counter, bits, reg); } static inline unsigned read_register(struct ni_gpct *counter, enum ni_gpct_register reg) { - BUG_ON(reg >= NITIO_Num_Registers); + BUG_ON(reg >= NITIO_NUM_REGS); return counter->counter_dev->read_register(counter, reg); } @@ -738,7 +355,7 @@ static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned long flags; - BUG_ON(register_index >= NITIO_Num_Registers); + BUG_ON(register_index >= NITIO_NUM_REGS); spin_lock_irqsave(&counter_dev->regs_lock, flags); counter_dev->regs[register_index] &= ~bit_mask; counter_dev->regs[register_index] |= (bit_values & bit_mask); @@ -773,7 +390,7 @@ static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, unsigned long flags; unsigned value; - BUG_ON(register_index >= NITIO_Num_Registers); + BUG_ON(register_index >= NITIO_NUM_REGS); spin_lock_irqsave(&counter_dev->regs_lock, flags); value = counter_dev->regs[register_index]; spin_unlock_irqrestore(&counter_dev->regs_lock, flags); diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 45691efefd05..7d64f8892f08 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -49,14 +49,11 @@ TODO: #include "ni_tio_internal.h" #include "mite.h" -MODULE_AUTHOR("Comedi "); -MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters"); -MODULE_LICENSE("GPL"); - static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, short read_not_write) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; unsigned input_select_bits = 0; if (enable) { @@ -65,8 +62,7 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, else input_select_bits |= Gi_Write_Acknowledges_Irq; } - ni_tio_set_bits(counter, - NITIO_Gi_Input_Select_Reg(counter->counter_index), + ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq, input_select_bits); switch (counter_dev->variant) { @@ -83,9 +79,7 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, } if (read_not_write == 0) gi_dma_config_bits |= Gi_DMA_Write_Bit; - ni_tio_set_bits(counter, - NITIO_Gi_DMA_Config_Reg(counter-> - counter_index), + ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit | Gi_DMA_Write_Bit, gi_dma_config_bits); } @@ -122,6 +116,7 @@ static int ni_tio_input_inttrig(struct comedi_device *dev, static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) { struct ni_gpct_device *counter_dev = counter->counter_dev; + unsigned cidx = counter->counter_index; struct comedi_cmd *cmd = &async->cmd; int retval = 0; @@ -140,8 +135,7 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) BUG(); break; } - ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), - Gi_Save_Trace_Bit, 0); + ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0); ni_tio_configure_dma(counter, 1, 1); switch (cmd->start_src) { case TRIG_NOW: @@ -185,6 +179,7 @@ static int ni_tio_output_cmd(struct ni_gpct *counter, static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async) { struct comedi_cmd *cmd = &async->cmd; + unsigned cidx = counter->counter_index; int set_gate_source = 0; unsigned gate_source; int retval = 0; @@ -199,19 +194,17 @@ static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async) if (set_gate_source) retval = ni_tio_set_gate_src(counter, 0, gate_source); if (cmd->flags & TRIG_WAKE_EOS) { - ni_tio_set_bits(counter, - NITIO_Gi_Interrupt_Enable_Reg(counter-> - counter_index), - Gi_Gate_Interrupt_Enable_Bit(counter-> - counter_index), - Gi_Gate_Interrupt_Enable_Bit(counter-> - counter_index)); + ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), + Gi_Gate_Interrupt_Enable_Bit(cidx), + Gi_Gate_Interrupt_Enable_Bit(cidx)); } return retval; } -int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) +int ni_tio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_gpct *counter = s->private; + struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; int retval = 0; unsigned long flags; @@ -237,8 +230,11 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) } EXPORT_SYMBOL_GPL(ni_tio_cmd); -int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) +int ni_tio_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { + struct ni_gpct *counter = s->private; int err = 0; unsigned int sources; @@ -301,6 +297,7 @@ EXPORT_SYMBOL_GPL(ni_tio_cmdtest); int ni_tio_cancel(struct ni_gpct *counter) { + unsigned cidx = counter->counter_index; unsigned long flags; ni_tio_arm(counter, 0, 0); @@ -310,10 +307,8 @@ int ni_tio_cancel(struct ni_gpct *counter) spin_unlock_irqrestore(&counter->lock, flags); ni_tio_configure_dma(counter, 0, 0); - ni_tio_set_bits(counter, - NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), - Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), - 0x0); + ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), + Gi_Gate_Interrupt_Enable_Bit(cidx), 0x0); return 0; } EXPORT_SYMBOL_GPL(ni_tio_cancel); @@ -353,14 +348,11 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, int *tc_error, int *perm_stale_data, int *stale_data) { + unsigned cidx = counter->counter_index; const unsigned short gxx_status = read_register(counter, - NITIO_Gxx_Status_Reg - (counter-> - counter_index)); + NITIO_SHARED_STATUS_REG(cidx)); const unsigned short gi_status = read_register(counter, - NITIO_Gi_Status_Reg - (counter-> - counter_index)); + NITIO_STATUS_REG(cidx)); unsigned ack = 0; if (gate_error) @@ -372,8 +364,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, if (stale_data) *stale_data = 0; - if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) { - ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index); + if (gxx_status & Gi_Gate_Error_Bit(cidx)) { + ack |= Gi_Gate_Error_Confirm_Bit(cidx); if (gate_error) { /*660x don't support automatic acknowledgement of gate interrupt via dma read/write @@ -384,8 +376,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, } } } - if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) { - ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index); + if (gxx_status & Gi_TC_Error_Bit(cidx)) { + ack |= Gi_TC_Error_Confirm_Bit(cidx); if (tc_error) *tc_error = 1; } @@ -396,21 +388,15 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, ack |= Gi_Gate_Interrupt_Ack_Bit; } if (ack) - write_register(counter, ack, - NITIO_Gi_Interrupt_Acknowledge_Reg - (counter->counter_index)); - if (ni_tio_get_soft_copy - (counter, - NITIO_Gi_Mode_Reg(counter->counter_index)) & + write_register(counter, ack, NITIO_INT_ACK_REG(cidx)); + if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) & Gi_Loading_On_Gate_Bit) { - if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) { + if (gxx_status & Gi_Stale_Data_Bit(cidx)) { if (stale_data) *stale_data = 1; } - if (read_register(counter, - NITIO_Gxx_Joint_Status2_Reg - (counter->counter_index)) & - Gi_Permanent_Stale_Bit(counter->counter_index)) { + if (read_register(counter, NITIO_STATUS2_REG(cidx)) & + Gi_Permanent_Stale_Bit(cidx)) { dev_info(counter->counter_dev->dev->class_dev, "%s: Gi_Permanent_Stale_Data detected.\n", __func__); @@ -424,6 +410,7 @@ EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm); void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *s) { + unsigned cidx = counter->counter_index; unsigned gpct_mite_status; unsigned long flags; int gate_error; @@ -442,9 +429,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, switch (counter->counter_dev->variant) { case ni_gpct_variant_m_series: case ni_gpct_variant_660x: - if (read_register(counter, - NITIO_Gi_DMA_Status_Reg - (counter->counter_index)) & Gi_DRQ_Error_Bit) { + if (read_register(counter, NITIO_DMA_STATUS_REG(cidx)) & + Gi_DRQ_Error_Bit) { dev_notice(counter->counter_dev->dev->class_dev, "%s: Gi_DRQ_Error detected.\n", __func__); s->async->events |= COMEDI_CB_OVERFLOW; @@ -484,11 +470,13 @@ static int __init ni_tiocmd_init_module(void) { return 0; } - module_init(ni_tiocmd_init_module); static void __exit ni_tiocmd_cleanup_module(void) { } - module_exit(ni_tiocmd_cleanup_module); + +MODULE_AUTHOR("Comedi "); +MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 03315abcca19..53613b385f35 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -162,156 +162,172 @@ #define MAX_CHANLIST_LEN 256 /* length of scan list */ -static const struct comedi_lrange range_pcl812pg_ai = { 5, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - BIP_RANGE(0.3125), - } +static const struct comedi_lrange range_pcl812pg_ai = { + 5, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + BIP_RANGE(0.3125) + } }; -static const struct comedi_lrange range_pcl812pg2_ai = { 5, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - } +static const struct comedi_lrange range_pcl812pg2_ai = { + 5, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range812_bipolar1_25 = { 1, { - BIP_RANGE(1.25), - } +static const struct comedi_lrange range812_bipolar1_25 = { + 1, { + BIP_RANGE(1.25) + } }; -static const struct comedi_lrange range812_bipolar0_625 = { 1, { - BIP_RANGE - (0.625), - } +static const struct comedi_lrange range812_bipolar0_625 = { + 1, { + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range812_bipolar0_3125 = { 1, { - BIP_RANGE - (0.3125), - } +static const struct comedi_lrange range812_bipolar0_3125 = { + 1, { + BIP_RANGE(0.3125) + } }; -static const struct comedi_lrange range_pcl813b_ai = { 4, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - } +static const struct comedi_lrange range_pcl813b_ai = { + 4, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range_pcl813b2_ai = { 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - } +static const struct comedi_lrange range_pcl813b2_ai = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; -static const struct comedi_lrange range_iso813_1_ai = { 5, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - BIP_RANGE(0.3125), - } +static const struct comedi_lrange range_iso813_1_ai = { + 5, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + BIP_RANGE(0.3125) + } }; -static const struct comedi_lrange range_iso813_1_2_ai = { 5, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - UNI_RANGE(0.625), - } +static const struct comedi_lrange range_iso813_1_2_ai = { + 5, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + UNI_RANGE(0.625) + } }; -static const struct comedi_lrange range_iso813_2_ai = { 4, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - } +static const struct comedi_lrange range_iso813_2_ai = { + 4, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range_iso813_2_2_ai = { 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - } +static const struct comedi_lrange range_iso813_2_2_ai = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; -static const struct comedi_lrange range_acl8113_1_ai = { 4, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - } +static const struct comedi_lrange range_acl8113_1_ai = { + 4, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range_acl8113_1_2_ai = { 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - } +static const struct comedi_lrange range_acl8113_1_2_ai = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; -static const struct comedi_lrange range_acl8113_2_ai = { 3, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - } +static const struct comedi_lrange range_acl8113_2_ai = { + 3, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25) + } }; -static const struct comedi_lrange range_acl8113_2_2_ai = { 3, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - } +static const struct comedi_lrange range_acl8113_2_2_ai = { + 3, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5) + } }; -static const struct comedi_lrange range_acl8112dg_ai = { 9, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - BIP_RANGE(10), - } +static const struct comedi_lrange range_acl8112dg_ai = { + 9, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + BIP_RANGE(10) + } }; -static const struct comedi_lrange range_acl8112hg_ai = { 12, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01), - BIP_RANGE(10), - BIP_RANGE(1), - BIP_RANGE(0.1), - BIP_RANGE(0.01), - } +static const struct comedi_lrange range_acl8112hg_ai = { + 12, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.005), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01), + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.01) + } }; -static const struct comedi_lrange range_a821pgh_ai = { 4, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - } +static const struct comedi_lrange range_a821pgh_ai = { + 4, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.005) + } }; struct pcl812_board { @@ -404,9 +420,7 @@ static int pcl812_ai_insn_read(struct comedi_device *dev, goto conv_finish; udelay(1); } - printk - ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D insn read timeout\n"); outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE); return -ETIME; @@ -441,9 +455,7 @@ static int acl8216_ai_insn_read(struct comedi_device *dev, goto conv_finish; udelay(1); } - printk - ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D insn read timeout\n"); outb(0, dev->iobase + PCL812_MODE); return -ETIME; @@ -759,7 +771,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) unsigned int mask, timeout; struct comedi_device *dev = d; struct pcl812_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned int next_chan; s->async->events = 0; @@ -786,10 +798,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) } if (err) { - printk - ("comedi%d: pcl812: (%s at 0x%lx) " - "A/D cmd IRQ without DRDY!\n", - dev->minor, dev->board_name, dev->iobase); + dev_dbg(dev->class_dev, "A/D cmd IRQ without DRDY!\n"); pcl812_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -865,7 +874,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl812_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned long dma_flags; int len, bufptr; unsigned short *ptr; @@ -1095,7 +1104,6 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl812_board *board = comedi_board(dev); struct pcl812_private *devpriv; int ret, subdev; - unsigned int irq; unsigned int dma; unsigned long pages; struct comedi_subdevice *s; @@ -1109,31 +1117,13 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, " - "DISABLING IT", irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl812, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, " - "DISABLING IT", irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_INFO ", irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl812, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - dma = 0; devpriv->dma = dma; if (!dev->irq) @@ -1141,21 +1131,22 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (((1 << dma) & board->DMAbits) == 0) { - printk(", DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); if (ret) { - printk(KERN_ERR ", unable to allocate DMA %u, FAIL!\n", - dma); + dev_err(dev->class_dev, + "unable to allocate DMA %u, FAIL!\n", dma); return -EBUSY; /* DMA isn't free */ } devpriv->dma = dma; - printk(KERN_INFO ", dma=%u", dma); pages = 1; /* we want 8KB */ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[0]) { - printk(", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); /* * maybe experiment with try_to_free_pages() * will help .... @@ -1167,7 +1158,8 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages); devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { - printk(KERN_ERR ", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); return -EBUSY; } devpriv->dmapages[1] = pages; @@ -1225,7 +1217,6 @@ no_dma: break; } s->maxdata = board->ai_maxdata; - s->len_chanlist = MAX_CHANLIST_LEN; s->range_table = board->rangelist_ai; if (board->board_type == boardACL8216) s->insn_read = acl8216_ai_insn_read; @@ -1233,13 +1224,14 @@ no_dma: s->insn_read = pcl812_ai_insn_read; devpriv->use_MPC = board->haveMPC508; - s->cancel = pcl812_ai_cancel; if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = MAX_CHANLIST_LEN; s->do_cmdtest = pcl812_ai_cmdtest; s->do_cmd = pcl812_ai_cmd; s->poll = pcl812_ai_poll; + s->cancel = pcl812_ai_cancel; } switch (board->board_type) { case boardPCL812PG: @@ -1269,10 +1261,6 @@ no_dma: default: s->range_table = &range_bipolar10; break; - printk - (", incorrect range number %d, changing " - "to 0 (+/-10V)", it->options[4]); - break; } break; break; @@ -1299,10 +1287,6 @@ no_dma: default: s->range_table = &range_iso813_1_ai; break; - printk - (", incorrect range number %d, " - "changing to 0 ", it->options[1]); - break; } break; case boardACL8113: @@ -1324,10 +1308,6 @@ no_dma: default: s->range_table = &range_acl8113_1_ai; break; - printk - (", incorrect range number %d, " - "changing to 0 ", it->options[1]); - break; } break; } @@ -1341,7 +1321,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = board->n_aochan; s->maxdata = 0xfff; - s->len_chanlist = 1; s->range_table = board->rangelist_ao; s->insn_read = pcl812_ao_insn_read; s->insn_write = pcl812_ao_insn_write; @@ -1370,7 +1349,6 @@ no_dma: s->subdev_flags = SDF_READABLE; s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl812_di_insn_bits; subdev++; @@ -1383,7 +1361,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE; s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl812_do_insn_bits; subdev++; @@ -1402,7 +1379,7 @@ no_dma: break; case boardA821: devpriv->max_812_ai_mode0_rangewait = 1; - devpriv->mode_reg_int = (irq << 4) & 0xf0; + devpriv->mode_reg_int = (dev->irq << 4) & 0xf0; break; case boardPCL813B: case boardPCL813: @@ -1413,7 +1390,6 @@ no_dma: break; } - printk(KERN_INFO "\n"); devpriv->valid = 1; pcl812_reset(dev); diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index ab9d2bd26a20..e9d470459933 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -44,14 +44,10 @@ Configuration Options: #include "comedi_fc.h" #include "8253.h" -#define DEBUG(x) x - /* boards constants */ /* IO space len */ #define PCLx1x_RANGE 16 -/* #define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y) */ - /* INTEL 8254 counters */ #define PCL816_CTR0 4 #define PCL816_CTR1 5 @@ -85,16 +81,17 @@ Configuration Options: #define MAGIC_DMA_WORD 0x5a5a -static const struct comedi_lrange range_pcl816 = { 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - } +static const struct comedi_lrange range_pcl816 = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; struct pcl816_board { @@ -132,7 +129,6 @@ struct pcl816_private { unsigned int ai_scans; /* len of scanlist */ unsigned char ai_neverending; /* if=1, then we do neverending record (you must use cancel()) */ - int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ int irq_was_now_closed; /* when IRQ finish, there's stored int816_mode for last interrupt */ int int816_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ @@ -143,7 +139,6 @@ struct pcl816_private { unsigned int ai_act_chanlist_pos; /* actual position in MUX list */ unsigned int ai_n_chan; /* how many channels per scan */ unsigned int ai_poll_ptr; /* how many sampes transfer poll */ - struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ }; /* @@ -176,7 +171,6 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, int n; int timeout; - DPRINTK("mode 0 analog input\n"); /* software trigger, DMA and INT off */ outb(0, dev->iobase + PCL816_CONTROL); /* clear INT (conversion end) flag */ @@ -228,7 +222,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned char low, hi; int timeout = 50; /* wait max 50us */ @@ -322,7 +316,7 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int len, bufptr, this_dma_buf; unsigned long dma_flags; unsigned short *ptr; @@ -372,8 +366,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) struct comedi_device *dev = d; struct pcl816_private *devpriv = dev->private; - DPRINTK(""); - if (!dev->attached) { comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; @@ -389,8 +381,7 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) } outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */ - if (!dev->irq || !devpriv->irq_free || !devpriv->irq_blocked || - !devpriv->int816_mode) { + if (!dev->irq || !devpriv->irq_blocked || !devpriv->int816_mode) { if (devpriv->irq_was_now_closed) { devpriv->irq_was_now_closed = 0; /* comedi_error(dev,"last IRQ.."); */ @@ -403,22 +394,6 @@ static irqreturn_t interrupt_pcl816(int irq, void *d) return IRQ_NONE; } -/* -============================================================================== - COMMAND MODE -*/ -static void pcl816_cmdtest_out(int e, struct comedi_cmd *cmd) -{ - printk(KERN_INFO "pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e, - cmd->start_src, cmd->scan_begin_src, cmd->convert_src); - printk(KERN_INFO "pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e, - cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg); - printk(KERN_INFO "pcl816 e=%d stopsrc=%x scanend=%x\n", e, - cmd->stop_src, cmd->scan_end_src); - printk(KERN_INFO "pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", - e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len); -} - /* ============================================================================== */ @@ -429,10 +404,6 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, int err = 0; int tmp, divisor1 = 0, divisor2 = 0; - DEBUG(printk(KERN_INFO "pcl816 pcl812_ai_cmdtest\n"); - pcl816_cmdtest_out(-1, cmd); - ); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); @@ -566,15 +537,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->ai_neverending = 1; } - /* don't we want wake up every scan? */ - if ((cmd->flags & TRIG_WAKE_EOS)) { - printk(KERN_INFO - "pl816: You wankt WAKE_EOS but I dont want handle it"); - /* devpriv->ai_eos=1; */ - /* if (devpriv->ai_n_chan==1) */ - /* devpriv->dma=0; // DMA is useless for this situation */ - } - if (devpriv->dma) { bytes = devpriv->hwdmasize[0]; if (!devpriv->ai_neverending) { @@ -630,7 +592,6 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) break; } - DPRINTK("pcl816 END: pcl812_ai_cmd()\n"); return 0; } @@ -685,8 +646,6 @@ static int pcl816_ai_cancel(struct comedi_device *dev, { struct pcl816_private *devpriv = dev->private; -/* DEBUG(printk("pcl816_ai_cancel()\n");) */ - if (devpriv->irq_blocked > 0) { switch (devpriv->int816_mode) { case INT_TYPE_AI1_DMA: @@ -719,9 +678,7 @@ static int pcl816_ai_cancel(struct comedi_device *dev, break; } } - - DEBUG(printk("comedi: pcl816_ai_cancel() successful\n");) - return 0; + return 0; } /* @@ -788,8 +745,8 @@ start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1, udelay(1); if (mode == 1) { - DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1, - divisor2); + dev_dbg(dev->class_dev, "mode %d, divisor1 %d, divisor2 %d\n", + mode, divisor1, divisor2); outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2); outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2); outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1); @@ -823,11 +780,6 @@ check_channel_list(struct comedi_device *dev, /* first channel is every time ok */ chansegment[0] = chanlist[0]; for (i = 1, seglen = 1; i < chanlen; i++, seglen++) { - /* build part of chanlist */ - DEBUG(printk(KERN_INFO "%d. %d %d\n", i, - CR_CHAN(chanlist[i]), - CR_RANGE(chanlist[i]));) - /* we detect loop, this must by finish */ if (chanlist[0] == chanlist[i]) break; @@ -835,12 +787,10 @@ check_channel_list(struct comedi_device *dev, (CR_CHAN(chansegment[i - 1]) + 1) % chanlen; if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk(KERN_WARNING - "comedi%d: pcl816: channel list must " - "be continuous! chanlist[%i]=%d but " - "must be %d or %d!\n", dev->minor, - i, CR_CHAN(chanlist[i]), nowmustbechan, - CR_CHAN(chanlist[0])); + dev_dbg(dev->class_dev, + "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); return 0; } /* well, this is next correct channel in list */ @@ -849,22 +799,15 @@ check_channel_list(struct comedi_device *dev, /* check whole chanlist */ for (i = 0, segpos = 0; i < chanlen; i++) { - DEBUG(printk("%d %d=%d %d\n", - CR_CHAN(chansegment[i % seglen]), - CR_RANGE(chansegment[i % seglen]), - CR_CHAN(chanlist[i]), - CR_RANGE(chanlist[i]));) if (chanlist[i] != chansegment[i % seglen]) { - printk(KERN_WARNING - "comedi%d: pcl816: bad channel or range" - " number! chanlist[%i]=%d,%d,%d and not" - " %d,%d,%d!\n", dev->minor, i, - CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); + dev_dbg(dev->class_dev, + "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); return 0; /* chan/gain list is strange */ } } @@ -909,7 +852,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl816_board *board = comedi_board(dev); struct pcl816_private *devpriv; int ret; - unsigned int irq, dma; + unsigned int dma; unsigned long pages; /* int i; */ struct comedi_subdevice *s; @@ -919,7 +862,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; if (pcl816_check(dev->iobase)) { - printk(KERN_ERR ", I cann't detect board. FAIL!\n"); + dev_err(dev->class_dev, "I can't detect board. FAIL!\n"); return -EIO; } @@ -927,43 +870,20 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - /* grab our IRQ */ - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, " - "DISABLING IT", irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl816, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, " - "DISABLING IT", irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_INFO ", irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl816, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - if (irq) /* 1=we have allocated irq */ - devpriv->irq_free = 1; - else - devpriv->irq_free = 0; - devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */ devpriv->int816_mode = 0; /* mode of irq */ /* grab our DMA */ dma = 0; devpriv->dma = dma; - if (!devpriv->irq_free) + if (!dev->irq) goto no_dma; /* if we haven't IRQ, we can't use DMA */ if (board->DMAbits != 0) { /* board support DMA */ @@ -972,23 +892,24 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) goto no_dma; /* DMA disabled */ if (((1 << dma) & board->DMAbits) == 0) { - printk(", DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); if (ret) { - printk(KERN_ERR - ", unable to allocate DMA %u, FAIL!\n", dma); + dev_err(dev->class_dev, + "unable to allocate DMA %u, FAIL!\n", dma); return -EBUSY; /* DMA isn't free */ } devpriv->dma = dma; - printk(KERN_INFO ", dma=%u", dma); pages = 2; /* we need 16KB */ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[0]) { - printk(", unable to allocate DMA buffer, FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); /* * maybe experiment with try_to_free_pages() * will help .... @@ -998,13 +919,11 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; - /* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) { - printk(KERN_ERR - ", unable to allocate DMA buffer, " - "FAIL!\n"); + dev_err(dev->class_dev, + "unable to allocate DMA buffer, FAIL!\n"); return -EBUSY; } devpriv->dmapages[1] = pages; @@ -1029,20 +948,20 @@ no_dma: s = &dev->subdevices[0]; if (board->n_aichan > 0) { s->type = COMEDI_SUBD_AI; - devpriv->sub_ai = s; - dev->read_subdev = s; - s->subdev_flags = SDF_READABLE | SDF_CMD_READ; + s->subdev_flags = SDF_CMD_READ | SDF_DIFF; s->n_chan = board->n_aichan; - s->subdev_flags |= SDF_DIFF; - /* printk (", %dchans DIFF DAC - %d", s->n_chan, i); */ s->maxdata = board->ai_maxdata; - s->len_chanlist = board->ai_chanlist; s->range_table = board->ai_range_type; - s->cancel = pcl816_ai_cancel; - s->do_cmdtest = pcl816_ai_cmdtest; - s->do_cmd = pcl816_ai_cmd; - s->poll = pcl816_ai_poll; s->insn_read = pcl816_ai_insn_read; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = board->ai_chanlist; + s->do_cmdtest = pcl816_ai_cmdtest; + s->do_cmd = pcl816_ai_cmd; + s->poll = pcl816_ai_poll; + s->cancel = pcl816_ai_cancel; + } } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1075,8 +994,6 @@ case COMEDI_SUBD_DO: pcl816_reset(dev); - printk("\n"); - return 0; } @@ -1085,7 +1002,7 @@ static void pcl816_detach(struct comedi_device *dev) struct pcl816_private *devpriv = dev->private; if (dev->private) { - pcl816_ai_cancel(dev, devpriv->sub_ai); + pcl816_ai_cancel(dev, dev->read_subdev); pcl816_reset(dev); if (devpriv->dma) free_dma(devpriv->dma); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 9e4d7e860509..fa1758ad49d5 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -188,56 +188,78 @@ A word or two about DMA. Driver support DMA operations at two ways: #define MAGIC_DMA_WORD 0x5a5a -static const struct comedi_lrange range_pcl818h_ai = { 9, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25), - BIP_RANGE(10), - } +static const struct comedi_lrange range_pcl818h_ai = { + 9, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25), + BIP_RANGE(10) + } }; -static const struct comedi_lrange range_pcl818hg_ai = { 10, { - BIP_RANGE(5), - BIP_RANGE(0.5), - BIP_RANGE(0.05), - BIP_RANGE(0.005), - UNI_RANGE(10), - UNI_RANGE(1), - UNI_RANGE(0.1), - UNI_RANGE(0.01), - BIP_RANGE(10), - BIP_RANGE(1), - BIP_RANGE(0.1), - BIP_RANGE(0.01), - } +static const struct comedi_lrange range_pcl818hg_ai = { + 10, { + BIP_RANGE(5), + BIP_RANGE(0.5), + BIP_RANGE(0.05), + BIP_RANGE(0.005), + UNI_RANGE(10), + UNI_RANGE(1), + UNI_RANGE(0.1), + UNI_RANGE(0.01), + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.01) + } }; -static const struct comedi_lrange range_pcl818l_l_ai = { 4, { - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - BIP_RANGE(0.625), - } +static const struct comedi_lrange range_pcl818l_l_ai = { + 4, { + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + BIP_RANGE(0.625) + } }; -static const struct comedi_lrange range_pcl818l_h_ai = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - } +static const struct comedi_lrange range_pcl818l_h_ai = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25) + } +}; + +static const struct comedi_lrange range718_bipolar1 = { + 1, { + BIP_RANGE(1) + } }; -static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} }; static const struct comedi_lrange range718_bipolar0_5 = { - 1, {BIP_RANGE(0.5),} }; -static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} }; -static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} }; + 1, { + BIP_RANGE(0.5) + } +}; + +static const struct comedi_lrange range718_unipolar2 = { + 1, { + UNI_RANGE(2) + } +}; + +static const struct comedi_lrange range718_unipolar1 = { + 1, { + BIP_RANGE(1) + } +}; struct pcl818_board { @@ -274,7 +296,6 @@ struct pcl818_private { unsigned char neverending_ai; /* if=1, then we do neverending record (you must use cancel()) */ unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */ int i8253_osc_base; /* 1/frequency of on board oscilator in ns */ - int irq_free; /* 1=have allocated IRQ */ int irq_blocked; /* 1=IRQ now uses any subdev */ int irq_was_now_closed; /* when IRQ finish, there's stored int818_mode for last interrupt */ int ai_mode; /* who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma */ @@ -291,7 +312,6 @@ struct pcl818_private { unsigned int ai_data_len; /* len of data buffer */ unsigned int ai_timer1; /* timers */ unsigned int ai_timer2; - struct comedi_subdevice *sub_ai; /* ptr to AI subdevice */ unsigned char usefifo; /* 1=use fifo */ unsigned int ao_readback[2]; }; @@ -441,7 +461,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; unsigned char low; int timeout = 50; /* wait max 50us */ @@ -463,10 +483,10 @@ conv_finish: outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n", - (low & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos]); + dev_dbg(dev->class_dev, + "A/D mode1/3 IRQ - channel dropout %x!=%x !\n", + (low & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos]); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -478,7 +498,6 @@ conv_finish: s->async->cur_chan++; if (s->async->cur_chan >= devpriv->ai_n_chan) { - /* printk("E"); */ s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -501,7 +520,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i, len, bufptr; unsigned long flags; unsigned short *ptr; @@ -523,7 +542,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) release_dma_lock(flags); enable_dma(devpriv->dma); } - printk("comedi: A/D mode1/3 IRQ \n"); devpriv->dma_runs_to_end--; outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ @@ -534,11 +552,11 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) for (i = 0; i < len; i++) { if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n", - (ptr[bufptr] & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos], - devpriv->act_chanlist_pos); + dev_dbg(dev->class_dev, + "A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n", + (ptr[bufptr] & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos], + devpriv->act_chanlist_pos); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -562,7 +580,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); - /* printk("done int ai13 dma\n"); */ return IRQ_HANDLED; } } @@ -580,7 +597,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) { struct comedi_device *dev = d; struct pcl818_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; int i, len; unsigned char lo; @@ -612,10 +629,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) for (i = 0; i < len; i++) { lo = inb(dev->iobase + PCL818_FI_DATALO); if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */ - printk - ("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n", - (lo & 0xf), - devpriv->act_chanlist[devpriv->act_chanlist_pos]); + dev_dbg(dev->class_dev, + "A/D mode1/3 FIFO - channel dropout %d!=%d !\n", + (lo & 0xf), + devpriv->act_chanlist[devpriv->act_chanlist_pos]); pcl818_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; comedi_event(dev, s); @@ -661,7 +678,6 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) comedi_error(dev, "premature interrupt"); return IRQ_HANDLED; } - /* printk("I\n"); */ if (devpriv->irq_blocked && devpriv->irq_was_now_closed) { if ((devpriv->neverending_ai || (!devpriv->neverending_ai && @@ -673,10 +689,9 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) being reprogrammed while a DMA transfer is in progress. */ - struct comedi_subdevice *s = &dev->subdevices[0]; devpriv->ai_act_scan = 0; devpriv->neverending_ai = 0; - pcl818_ai_cancel(dev, s); + pcl818_ai_cancel(dev, dev->read_subdev); } outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ @@ -705,8 +720,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */ - if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked) - || (!devpriv->ai_mode)) { + if (!devpriv->irq_blocked || !devpriv->ai_mode) { comedi_error(dev, "bad IRQ!"); return IRQ_NONE; } @@ -726,7 +740,6 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, unsigned int flags; unsigned int bytes; - printk("mode13dma_int, mode: %d\n", mode); disable_dma(devpriv->dma); /* disable dma */ bytes = devpriv->hwdmasize[0]; if (!devpriv->neverending_ai) { @@ -753,7 +766,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, } else { devpriv->ai_mode = INT_TYPE_AI3_DMA; outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */ - }; + } } /* @@ -768,12 +781,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, int divisor1 = 0, divisor2 = 0; unsigned int seglen; - dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode()\n"); - if (!dev->irq) { - comedi_error(dev, "IRQ not defined!"); - return -EINVAL; - } - if (devpriv->irq_blocked) return -EBUSY; @@ -824,7 +831,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, case 0: if (!devpriv->usefifo) { /* IRQ */ - /* printk("IRQ\n"); */ if (mode == 1) { devpriv->ai_mode = INT_TYPE_AI1_INT; /* Pacer+IRQ */ @@ -853,7 +859,6 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, start_pacer(dev, mode, divisor1, divisor2); - dev_dbg(dev->class_dev, "pcl818_ai_cmd_mode() end\n"); return 0; } @@ -899,10 +904,6 @@ static int check_channel_list(struct comedi_device *dev, chansegment[0] = chanlist[0]; /* build part of chanlist */ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { - - /* printk("%d. %d * %d\n",i, - * CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));*/ - /* we detect loop, this must by finish */ if (chanlist[0] == chanlist[i]) @@ -910,10 +911,10 @@ static int check_channel_list(struct comedi_device *dev, nowmustbechan = (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan; if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continuous :-( */ - printk - ("comedi%d: pcl818: channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", - dev->minor, i, CR_CHAN(chanlist[i]), - nowmustbechan, CR_CHAN(chanlist[0])); + dev_dbg(dev->class_dev, + "channel list must be continuous! chanlist[%i]=%d but must be %d or %d!\n", + i, CR_CHAN(chanlist[i]), nowmustbechan, + CR_CHAN(chanlist[0])); return 0; } /* well, this is next correct channel in list */ @@ -922,23 +923,21 @@ static int check_channel_list(struct comedi_device *dev, /* check whole chanlist */ for (i = 0, segpos = 0; i < n_chan; i++) { - /* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i])); */ if (chanlist[i] != chansegment[i % seglen]) { - printk - ("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", - dev->minor, i, CR_CHAN(chansegment[i]), - CR_RANGE(chansegment[i]), - CR_AREF(chansegment[i]), - CR_CHAN(chanlist[i % seglen]), - CR_RANGE(chanlist[i % seglen]), - CR_AREF(chansegment[i % seglen])); + dev_dbg(dev->class_dev, + "bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n", + i, CR_CHAN(chansegment[i]), + CR_RANGE(chansegment[i]), + CR_AREF(chansegment[i]), + CR_CHAN(chanlist[i % seglen]), + CR_RANGE(chanlist[i % seglen]), + CR_AREF(chansegment[i % seglen])); return 0; /* chan/gain list is strange */ } } } else { seglen = 1; } - printk("check_channel_list: seglen %d\n", seglen); return seglen; } @@ -1067,7 +1066,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_cmd *cmd = &s->async->cmd; int retval; - dev_dbg(dev->class_dev, "pcl818_ai_cmd()\n"); devpriv->ai_n_chan = cmd->chanlist_len; devpriv->ai_chanlist = cmd->chanlist; devpriv->ai_flags = cmd->flags; @@ -1084,7 +1082,6 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd->convert_src == TRIG_TIMER) { /* mode 1 */ devpriv->ai_timer1 = cmd->convert_arg; retval = pcl818_ai_cmd_mode(1, dev, s); - dev_dbg(dev->class_dev, "pcl818_ai_cmd() end\n"); return retval; } if (cmd->convert_src == TRIG_EXT) { /* mode 3 */ @@ -1105,7 +1102,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev, struct pcl818_private *devpriv = dev->private; if (devpriv->irq_blocked > 0) { - dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n"); devpriv->irq_was_now_closed = 1; switch (devpriv->ai_mode) { @@ -1149,7 +1145,6 @@ static int pcl818_ai_cancel(struct comedi_device *dev, } end: - dev_dbg(dev->class_dev, "pcl818_ai_cancel() end\n"); return 0; } @@ -1216,7 +1211,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcl818_board *board = comedi_board(dev); struct pcl818_private *devpriv; int ret; - unsigned int irq; int dma; unsigned long pages; struct comedi_subdevice *s; @@ -1240,50 +1234,28 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - /* grab our IRQ */ - irq = 0; - if (board->IRQbits != 0) { /* board support IRQ */ - irq = it->options[1]; - if (irq) { /* we want to use IRQ */ - if (((1 << irq) & board->IRQbits) == 0) { - printk - (", IRQ %u is out of allowed range, DISABLING IT", - irq); - irq = 0; /* Bad IRQ */ - } else { - if (request_irq(irq, interrupt_pcl818, 0, - dev->board_name, dev)) { - printk - (", unable to allocate IRQ %u, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(KERN_DEBUG "irq=%u", irq); - } - } - } + if ((1 << it->options[1]) & board->IRQbits) { + ret = request_irq(it->options[1], interrupt_pcl818, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; } - dev->irq = irq; - if (irq) - devpriv->irq_free = 1; /* 1=we have allocated irq */ - else - devpriv->irq_free = 0; - devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */ devpriv->ai_mode = 0; /* mode of irq */ /* grab our DMA */ dma = 0; devpriv->dma = dma; - if (!devpriv->irq_free) + if (!dev->irq) goto no_dma; /* if we haven't IRQ, we can't use DMA */ if (board->DMAbits != 0) { /* board support DMA */ dma = it->options[2]; if (dma < 1) goto no_dma; /* DMA disabled */ if (((1 << dma) & board->DMAbits) == 0) { - printk(KERN_ERR "DMA is out of allowed range, FAIL!\n"); + dev_err(dev->class_dev, + "DMA is out of allowed range, FAIL!\n"); return -EINVAL; /* Bad DMA */ } ret = request_dma(dma, dev->board_name); @@ -1298,7 +1270,6 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->dmapages[0] = pages; devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]); devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE; - /* printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE); */ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages); if (!devpriv->dmabuf[1]) return -EBUSY; @@ -1318,27 +1289,24 @@ no_dma: s->type = COMEDI_SUBD_UNUSED; } else { s->type = COMEDI_SUBD_AI; - devpriv->sub_ai = s; s->subdev_flags = SDF_READABLE; if (check_single_ended(dev->iobase)) { s->n_chan = board->n_aichan_se; s->subdev_flags |= SDF_COMMON | SDF_GROUND; - printk(", %dchans S.E. DAC", s->n_chan); } else { s->n_chan = board->n_aichan_diff; s->subdev_flags |= SDF_DIFF; - printk(", %dchans DIFF DAC", s->n_chan); } s->maxdata = board->ai_maxdata; - s->len_chanlist = s->n_chan; s->range_table = board->ai_range_type; - s->cancel = pcl818_ai_cancel; s->insn_read = pcl818_ai_insn_read; - if (irq) { + if (dev->irq) { dev->read_subdev = s; s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; s->do_cmdtest = ai_cmdtest; s->do_cmd = ai_cmd; + s->cancel = pcl818_ai_cancel; } if (board->is_818) { if ((it->options[4] == 1) || (it->options[4] == 10)) @@ -1387,7 +1355,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->n_chan = board->n_aochan; s->maxdata = board->ao_maxdata; - s->len_chanlist = board->n_aochan; s->range_table = board->ao_range_type; s->insn_read = pcl818_ao_insn_read; s->insn_write = pcl818_ao_insn_write; @@ -1412,7 +1379,6 @@ no_dma: s->subdev_flags = SDF_READABLE; s->n_chan = board->n_dichan; s->maxdata = 1; - s->len_chanlist = board->n_dichan; s->range_table = &range_digital; s->insn_bits = pcl818_di_insn_bits; } @@ -1425,7 +1391,6 @@ no_dma: s->subdev_flags = SDF_WRITABLE; s->n_chan = board->n_dochan; s->maxdata = 1; - s->len_chanlist = board->n_dochan; s->range_table = &range_digital; s->insn_bits = pcl818_do_insn_bits; } @@ -1446,8 +1411,6 @@ no_dma: pcl818_reset(dev); - printk("\n"); - return 0; } @@ -1456,7 +1419,7 @@ static void pcl818_detach(struct comedi_device *dev) struct pcl818_private *devpriv = dev->private; if (devpriv) { - pcl818_ai_cancel(dev, devpriv->sub_ai); + pcl818_ai_cancel(dev, dev->read_subdev); pcl818_reset(dev); if (devpriv->dma) free_dma(devpriv->dma); diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index cc1dc7f66e5b..f4a49bd649f0 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -70,14 +70,11 @@ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg) { unsigned long iobase = arg; unsigned char inbres; - /* printk("8255cb %d %d %d %lx\n", dir,port,data,arg); */ if (dir) { - /* printk("8255 cb outb(%x, %lx)\n", data, iobase+port); */ outb(data, iobase + port); return 0; } else { inbres = inb(iobase + port); - /* printk("8255 cb inb(%lx) = %x\n", iobase+port, inbres); */ return inbres; } } @@ -137,8 +134,6 @@ static void do_3724_config(struct comedi_device *dev, port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; outb(buffer_config, dev->iobase + 8); /* update buffer register */ - /* printk("pcm3724 buffer_config (%lx) %d, %x\n", - dev->iobase + _8255_CR, chanspec, buffer_config); */ outb(config, port_8255_cfg); } @@ -177,7 +172,6 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, if (priv->dio_2 & 0xff) gatecfg |= GATE_A1; - /* printk("gate control %x\n", gatecfg); */ outb(gatecfg, dev->iobase + 9); } diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 14cee3ac92c5..c388f7f32227 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1,76 +1,76 @@ /* - comedi/drivers/pcmmio.c - Driver for Winsystems PC-104 based multifunction IO board. + * pcmmio.c + * Driver for Winsystems PC-104 based multifunction IO board. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2007 Calin A. Culianu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2007 Calin A. Culianu - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -*/ /* -Driver: pcmmio -Description: A driver for the PCM-MIO multifunction board -Devices: [Winsystems] PCM-MIO (pcmmio) -Author: Calin Culianu -Updated: Wed, May 16 2007 16:21:10 -0500 -Status: works - -A driver for the relatively new PCM-MIO multifunction board from -Winsystems. This board is a PC-104 based I/O board. It contains -four subdevices: - subdevice 0 - 16 channels of 16-bit AI - subdevice 1 - 8 channels of 16-bit AO - subdevice 2 - first 24 channels of the 48 channel of DIO - (with edge-triggered interrupt support) - subdevice 3 - last 24 channels of the 48 channel DIO - (no interrupt support for this bank of channels) - - Some notes: - - Synchronous reads and writes are the only things implemented for AI and AO, - even though the hardware itself can do streaming acquisition, etc. Anyone - want to add asynchronous I/O for AI/AO as a feature? Be my guest... - - Asynchronous I/O for the DIO subdevices *is* implemented, however! They are - basically edge-triggered interrupts for any configuration of the first - 24 DIO-lines. - - Also note that this interrupt support is untested. - - A few words about edge-detection IRQ support (commands on DIO): - - * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ - of the board to the comedi_config command. The board IRQ is not jumpered - but rather configured through software, so any IRQ from 1-15 is OK. - - * Due to the genericity of the comedi API, you need to create a special - comedi_command in order to use edge-triggered interrupts for DIO. - - * Use comedi_commands with TRIG_NOW. Your callback will be called each - time an edge is detected on the specified DIO line(s), and the data - values will be two sample_t's, which should be concatenated to form - one 32-bit unsigned int. This value is the mask of channels that had - edges detected from your channel list. Note that the bits positions - in the mask correspond to positions in your chanlist when you - specified the command and *not* channel id's! - - * To set the polarity of the edge-detection interrupts pass a nonzero value - for either CR_RANGE or CR_AREF for edge-up polarity, or a zero - value for both CR_RANGE and CR_AREF if you want edge-down polarity. - -Configuration Options: - [0] - I/O port base address - [1] - IRQ (optional -- for edge-detect interrupt support only, - leave out if you don't need this feature) -*/ + * Driver: pcmmio + * Description: A driver for the PCM-MIO multifunction board + * Devices: (Winsystems) PCM-MIO [pcmmio] + * Author: Calin Culianu + * Updated: Wed, May 16 2007 16:21:10 -0500 + * Status: works + * + * A driver for the PCM-MIO multifunction board from Winsystems. This + * is a PC-104 based I/O board. It contains four subdevices: + * + * subdevice 0 - 16 channels of 16-bit AI + * subdevice 1 - 8 channels of 16-bit AO + * subdevice 2 - first 24 channels of the 48 channel of DIO + * (with edge-triggered interrupt support) + * subdevice 3 - last 24 channels of the 48 channel DIO + * (no interrupt support for this bank of channels) + * + * Some notes: + * + * Synchronous reads and writes are the only things implemented for analog + * input and output. The hardware itself can do streaming acquisition, etc. + * + * Asynchronous I/O for the DIO subdevices *is* implemented, however! They + * are basically edge-triggered interrupts for any configuration of the + * channels in subdevice 2. + * + * Also note that this interrupt support is untested. + * + * A few words about edge-detection IRQ support (commands on DIO): + * + * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ + * of the board to the comedi_config command. The board IRQ is not jumpered + * but rather configured through software, so any IRQ from 1-15 is OK. + * + * Due to the genericity of the comedi API, you need to create a special + * comedi_command in order to use edge-triggered interrupts for DIO. + * + * Use comedi_commands with TRIG_NOW. Your callback will be called each + * time an edge is detected on the specified DIO line(s), and the data + * values will be two sample_t's, which should be concatenated to form + * one 32-bit unsigned int. This value is the mask of channels that had + * edges detected from your channel list. Note that the bits positions + * in the mask correspond to positions in your chanlist when you + * specified the command and *not* channel id's! + * + * To set the polarity of the edge-detection interrupts pass a nonzero value + * for either CR_RANGE or CR_AREF for edge-up polarity, or a zero + * value for both CR_RANGE and CR_AREF if you want edge-down polarity. + * + * Configuration Options: + * [0] - I/O port base address + * [1] - IRQ (optional -- for edge-detect interrupt support only, + * leave out if you don't need this feature) + */ #include #include @@ -80,232 +80,211 @@ Configuration Options: #include "comedi_fc.h" -/* This stuff is all from pcmuio.c -- it refers to the DIO subdevices only */ -#define CHANS_PER_PORT 8 -#define PORTS_PER_ASIC 6 -#define INTR_PORTS_PER_ASIC 3 -#define MAX_CHANS_PER_SUBDEV 24 /* number of channels per comedi subdevice */ -#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT) -#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC) -#define INTR_CHANS_PER_ASIC 24 -#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT) -#define MAX_DIO_CHANS (PORTS_PER_ASIC*1*CHANS_PER_PORT) -#define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC) -#define CALC_N_DIO_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/) -/* IO Memory sizes */ -#define ASIC_IOSIZE (0x0B) -#define PCMMIO48_IOSIZE ASIC_IOSIZE - -/* Some offsets - these are all in the 16byte IO memory offset from - the base address. Note that there is a paging scheme to swap out - offsets 0x8-0xA using the PAGELOCK register. See the table below. - - Register(s) Pages R/W? Description - -------------------------------------------------------------- - REG_PORTx All R/W Read/Write/Configure IO - REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int. - REG_PAGELOCK All WriteOnly Select a page - REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity - REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int. - REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints. +/* + * Register I/O map */ -#define REG_PORT0 0x0 -#define REG_PORT1 0x1 -#define REG_PORT2 0x2 -#define REG_PORT3 0x3 -#define REG_PORT4 0x4 -#define REG_PORT5 0x5 -#define REG_INT_PENDING 0x6 -#define REG_PAGELOCK 0x7 /* - * page selector register, upper 2 bits select - * a page and bits 0-5 are used to 'lock down' - * a particular port above to make it readonly. - */ -#define REG_POL0 0x8 -#define REG_POL1 0x9 -#define REG_POL2 0xA -#define REG_ENAB0 0x8 -#define REG_ENAB1 0x9 -#define REG_ENAB2 0xA -#define REG_INT_ID0 0x8 -#define REG_INT_ID1 0x9 -#define REG_INT_ID2 0xA +#define PCMMIO_AI_LSB_REG 0x00 +#define PCMMIO_AI_MSB_REG 0x01 +#define PCMMIO_AI_CMD_REG 0x02 +#define PCMMIO_AI_CMD_SE (1 << 7) +#define PCMMIO_AI_CMD_ODD_CHAN (1 << 6) +#define PCMMIO_AI_CMD_CHAN_SEL(x) (((x) & 0x3) << 4) +#define PCMMIO_AI_CMD_RANGE(x) (((x) & 0x3) << 2) +#define PCMMIO_RESOURCE_REG 0x02 +#define PCMMIO_RESOURCE_IRQ(x) (((x) & 0xf) << 0) +#define PCMMIO_AI_STATUS_REG 0x03 +#define PCMMIO_AI_STATUS_DATA_READY (1 << 7) +#define PCMMIO_AI_STATUS_DATA_DMA_PEND (1 << 6) +#define PCMMIO_AI_STATUS_CMD_DMA_PEND (1 << 5) +#define PCMMIO_AI_STATUS_IRQ_PEND (1 << 4) +#define PCMMIO_AI_STATUS_DATA_DRQ_ENA (1 << 2) +#define PCMMIO_AI_STATUS_REG_SEL (1 << 3) +#define PCMMIO_AI_STATUS_CMD_DRQ_ENA (1 << 1) +#define PCMMIO_AI_STATUS_IRQ_ENA (1 << 0) +#define PCMMIO_AI_RES_ENA_REG 0x03 +#define PCMMIO_AI_RES_ENA_CMD_REG_ACCESS (0 << 3) +#define PCMMIO_AI_RES_ENA_AI_RES_ACCESS (1 << 3) +#define PCMMIO_AI_RES_ENA_DIO_RES_ACCESS (1 << 4) +#define PCMMIO_AI_2ND_ADC_OFFSET 0x04 -#define NUM_PAGED_REGS 3 -#define NUM_PAGES 4 -#define FIRST_PAGED_REG 0x8 -#define REG_PAGE_BITOFFSET 6 -#define REG_LOCK_BITOFFSET 0 -#define REG_PAGE_MASK (~((0x1<private) +static const struct comedi_lrange pcmmio_ao_ranges = { + 6, { + UNI_RANGE(5), + UNI_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(10), + BIP_RANGE(2.5), + RANGE(-2.5, 7.5) + } +}; -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The - * comedi core can convert between insn_bits and insn_read/write */ +struct pcmmio_private { + spinlock_t pagelock; /* protects the page registers */ + spinlock_t spinlock; /* protects the member variables */ + unsigned int enabled_mask; + unsigned int stop_count; + unsigned int active:1; + unsigned int continuous:1; + + unsigned int ao_readback[8]; +}; + +static void pcmmio_dio_write(struct comedi_device *dev, unsigned int val, + int page, int port) +{ + struct pcmmio_private *devpriv = dev->private; + unsigned long iobase = dev->iobase; + unsigned long flags; + + spin_lock_irqsave(&devpriv->pagelock, flags); + if (page == 0) { + /* Port registers are valid for any page */ + outb(val & 0xff, iobase + PCMMIO_PORT_REG(port + 0)); + outb((val >> 8) & 0xff, iobase + PCMMIO_PORT_REG(port + 1)); + outb((val >> 16) & 0xff, iobase + PCMMIO_PORT_REG(port + 2)); + } else { + outb(PCMMIO_PAGE(page), iobase + PCMMIO_PAGE_LOCK_REG); + outb(val & 0xff, iobase + PCMMIO_PAGE_REG(0)); + outb((val >> 8) & 0xff, iobase + PCMMIO_PAGE_REG(1)); + outb((val >> 16) & 0xff, iobase + PCMMIO_PAGE_REG(2)); + } + spin_unlock_irqrestore(&devpriv->pagelock, flags); +} + +static unsigned int pcmmio_dio_read(struct comedi_device *dev, + int page, int port) +{ + struct pcmmio_private *devpriv = dev->private; + unsigned long iobase = dev->iobase; + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&devpriv->pagelock, flags); + if (page == 0) { + /* Port registers are valid for any page */ + val = inb(iobase + PCMMIO_PORT_REG(port + 0)); + val |= (inb(iobase + PCMMIO_PORT_REG(port + 1)) << 8); + val |= (inb(iobase + PCMMIO_PORT_REG(port + 2)) << 16); + } else { + outb(PCMMIO_PAGE(page), iobase + PCMMIO_PAGE_LOCK_REG); + val = inb(iobase + PCMMIO_PAGE_REG(0)); + val |= (inb(iobase + PCMMIO_PAGE_REG(1)) << 8); + val |= (inb(iobase + PCMMIO_PAGE_REG(2)) << 16); + } + spin_unlock_irqrestore(&devpriv->pagelock, flags); + + return val; +} + +/* + * Each channel can be individually programmed for input or output. + * Writing a '0' to a channel causes the corresponding output pin + * to go to a high-z state (pulled high by an external 10K resistor). + * This allows it to be used as an input. When used in the input mode, + * a read reflects the inverted state of the I/O pin, such that a + * high on the pin will read as a '0' in the register. Writing a '1' + * to a bit position causes the pin to sink current (up to 12mA), + * effectively pulling it low. + */ static int pcmmio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - int byte_no; + /* subdevice 2 uses ports 0-2, subdevice 3 uses ports 3-5 */ + int port = s->index == 2 ? 0 : 3; + unsigned int chanmask = (1 << s->n_chan) - 1; + unsigned int mask; + unsigned int val; - /* NOTE: - reading a 0 means this channel was high - writine a 0 sets the channel high - reading a 1 means this channel was low - writing a 1 means set this channel low - - Therefore everything is always inverted. */ - - /* The insn data is a mask in data[0] and the new data - * in data[1], each channel cooresponding to a bit. */ - -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "write mask: %08x data: %08x\n", data[0], data[1]); -#endif - - s->state = 0; - - for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) { - /* address of 8-bit port */ - unsigned long ioaddr = subpriv->iobases[byte_no], - /* bit offset of port in 32-bit doubleword */ - offset = byte_no * 8; - /* this 8-bit port's data */ - unsigned char byte = 0, - /* The write mask for this port (if any) */ - write_mask_byte = (data[0] >> offset) & 0xff, - /* The data byte for this port */ - data_byte = (data[1] >> offset) & 0xff; - - byte = inb(ioaddr); /* read all 8-bits for this port */ - -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk - (KERN_DEBUG "byte %d wmb %02x db %02x offset %02d io %04x," - " data_in %02x ", byte_no, (unsigned)write_mask_byte, - (unsigned)data_byte, offset, ioaddr, (unsigned)byte); -#endif - - if (write_mask_byte) { - /* - * this byte has some write_bits - * -- so set the output lines - */ - /* clear bits for write mask */ - byte &= ~write_mask_byte; - /* set to inverted data_byte */ - byte |= ~data_byte & write_mask_byte; - /* Write out the new digital output state */ - outb(byte, ioaddr); - } -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "data_out_byte %02x\n", (unsigned)byte); -#endif - /* save the digital input lines for this byte.. */ - s->state |= ((unsigned int)byte) << offset; + mask = comedi_dio_update_state(s, data); + if (mask) { + /* + * Outputs are inverted, invert the state and + * update the channels. + * + * The s->io_bits mask makes sure the input channels + * are '0' so that the outputs pins stay in a high + * z-state. + */ + val = ~s->state & chanmask; + val &= s->io_bits; + pcmmio_dio_write(dev, val, 0, port); } - /* now return the DIO lines to data[1] - note they came inverted! */ - data[1] = ~s->state; + /* get inverted state of the channels from the port */ + val = pcmmio_dio_read(dev, 0, port); -#ifdef DAMMIT_ITS_BROKEN - /* DEBUG */ - printk(KERN_DEBUG "s->state %08x data_out %08x\n", s->state, data[1]); -#endif + /* return the true state of the channels */ + data[1] = ~val & chanmask; return insn->n; } @@ -315,376 +294,172 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int chan = CR_CHAN(insn->chanspec); - int byte_no = chan / 8; - int bit_no = chan % 8; + /* subdevice 2 uses ports 0-2, subdevice 3 uses ports 3-5 */ + int port = s->index == 2 ? 0 : 3; int ret; ret = comedi_dio_insn_config(dev, s, insn, data, 0); if (ret) return ret; - if (data[0] == INSN_CONFIG_DIO_INPUT) { - unsigned long ioaddr = subpriv->iobases[byte_no]; - unsigned char val; - - val = inb(ioaddr); - val &= ~(1 << bit_no); - outb(val, ioaddr); - } + if (data[0] == INSN_CONFIG_DIO_INPUT) + pcmmio_dio_write(dev, s->io_bits, 0, port); return insn->n; } -static void switch_page(struct comedi_device *dev, int asic, int page) +static void pcmmio_reset(struct comedi_device *dev) { - struct pcmmio_private *devpriv = dev->private; + /* Clear all the DIO port bits */ + pcmmio_dio_write(dev, 0, 0, 0); + pcmmio_dio_write(dev, 0, 0, 3); - if (asic < 0 || asic >= 1) - return; /* paranoia */ - if (page < 0 || page >= NUM_PAGES) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK; - devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET; - - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - devpriv->asics[asic].iobase + REG_PAGELOCK); + /* Clear all the paged registers */ + pcmmio_dio_write(dev, 0, PCMMIO_PAGE_POL, 0); + pcmmio_dio_write(dev, 0, PCMMIO_PAGE_ENAB, 0); + pcmmio_dio_write(dev, 0, PCMMIO_PAGE_INT_ID, 0); } -static void init_asics(struct comedi_device *dev) -{ /* sets up an - ASIC chip to defaults */ - struct pcmmio_private *devpriv = dev->private; - int asic; - - for (asic = 0; asic < 1; ++asic) { - int port, page; - unsigned long baseaddr = devpriv->asics[asic].iobase; - - switch_page(dev, asic, 0); /* switch back to page 0 */ - - /* first, clear all the DIO port bits */ - for (port = 0; port < PORTS_PER_ASIC; ++port) - outb(0, baseaddr + REG_PORT0 + port); - - /* Next, clear all the paged registers for each page */ - for (page = 1; page < NUM_PAGES; ++page) { - int reg; - /* now clear all the paged registers */ - switch_page(dev, asic, page); - for (reg = FIRST_PAGED_REG; - reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg) - outb(0, baseaddr + reg); - } - - /* DEBUG set rising edge interrupts on port0 of both asics */ - /*switch_page(dev, asic, PAGE_POL); - outb(0xff, baseaddr + REG_POL0); - switch_page(dev, asic, PAGE_ENAB); - outb(0xff, baseaddr + REG_ENAB0); */ - /* END DEBUG */ - - /* switch back to default page 0 */ - switch_page(dev, asic, 0); - } -} - -#ifdef notused -static void lock_port(struct comedi_device *dev, int asic, int port) -{ - struct pcmmio_private *devpriv = dev->private; - - if (asic < 0 || asic >= 1) - return; /* paranoia */ - if (port < 0 || port >= PORTS_PER_ASIC) - return; /* more paranoia */ - - devpriv->asics[asic].pagelock |= 0x1 << port; - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - devpriv->asics[asic].iobase + REG_PAGELOCK); - return; -} - -static void unlock_port(struct comedi_device *dev, int asic, int port) -{ - struct pcmmio_private *devpriv = dev->private; - - if (asic < 0 || asic >= 1) - return; /* paranoia */ - if (port < 0 || port >= PORTS_PER_ASIC) - return; /* more paranoia */ - devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK; - /* now write out the shadow register */ - outb(devpriv->asics[asic].pagelock, - devpriv->asics[asic].iobase + REG_PAGELOCK); -} -#endif /* notused */ - +/* devpriv->spinlock is already locked */ static void pcmmio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcmmio_private *devpriv = dev->private; - int nports, firstport, asic, port; - asic = subpriv->dio.intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->dio.intr.enabled_mask = 0; - subpriv->dio.intr.active = 0; + devpriv->enabled_mask = 0; + devpriv->active = 0; s->async->inttrig = NULL; - nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - /* disable all intrs for this subdev.. */ - outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port); + + /* disable all dio interrupts */ + pcmmio_dio_write(dev, 0, PCMMIO_PAGE_ENAB, 0); +} + +static void pcmmio_handle_dio_intr(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int triggered) +{ + struct pcmmio_private *devpriv = dev->private; + unsigned int oldevents = s->async->events; + unsigned int len = s->async->cmd.chanlist_len; + unsigned int val = 0; + unsigned long flags; + int i; + + spin_lock_irqsave(&devpriv->spinlock, flags); + + if (!devpriv->active) + goto done; + + if (!(triggered & devpriv->enabled_mask)) + goto done; + + for (i = 0; i < len; i++) { + unsigned int chan = CR_CHAN(s->async->cmd.chanlist[i]); + + if (triggered & (1 << chan)) + val |= (1 << i); } + + /* Write the scan to the buffer. */ + if (comedi_buf_put(s->async, val) && + comedi_buf_put(s->async, val >> 16)) { + s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); + } else { + /* Overflow! Stop acquisition!! */ + /* TODO: STOP_ACQUISITION_CALL_HERE!! */ + pcmmio_stop_intr(dev, s); + } + + /* Check for end of acquisition. */ + if (!devpriv->continuous) { + /* stop_src == TRIG_COUNT */ + if (devpriv->stop_count > 0) { + devpriv->stop_count--; + if (devpriv->stop_count == 0) { + s->async->events |= COMEDI_CB_EOA; + /* TODO: STOP_ACQUISITION_CALL_HERE!! */ + pcmmio_stop_intr(dev, s); + } + } + } + +done: + spin_unlock_irqrestore(&devpriv->spinlock, flags); + + if (oldevents != s->async->events) + comedi_event(dev, s); } static irqreturn_t interrupt_pcmmio(int irq, void *d) { - int asic, got1 = 0; - struct comedi_device *dev = (struct comedi_device *)d; - struct pcmmio_private *devpriv = dev->private; - int i; + struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; + unsigned int triggered; + unsigned char int_pend; - for (asic = 0; asic < MAX_ASICS; ++asic) { - if (irq == devpriv->asics[asic].irq) { - unsigned long flags; - unsigned triggered = 0; - unsigned long iobase = devpriv->asics[asic].iobase; - /* it is an interrupt for ASIC #asic */ - unsigned char int_pend; + /* are there any interrupts pending */ + int_pend = inb(dev->iobase + PCMMIO_INT_PENDING_REG) & 0x07; + if (!int_pend) + return IRQ_NONE; - spin_lock_irqsave(&devpriv->asics[asic].spinlock, - flags); + /* get, and clear, the pending interrupts */ + triggered = pcmmio_dio_read(dev, PCMMIO_PAGE_INT_ID, 0); + pcmmio_dio_write(dev, 0, PCMMIO_PAGE_INT_ID, 0); - int_pend = inb(iobase + REG_INT_PENDING) & 0x07; + pcmmio_handle_dio_intr(dev, s, triggered); - if (int_pend) { - int port; - for (port = 0; port < INTR_PORTS_PER_ASIC; - ++port) { - if (int_pend & (0x1 << port)) { - unsigned char - io_lines_with_edges = 0; - switch_page(dev, asic, - PAGE_INT_ID); - io_lines_with_edges = - inb(iobase + - REG_INT_ID0 + port); - - if (io_lines_with_edges) - /* - * clear pending - * interrupt - */ - outb(0, iobase + - REG_INT_ID0 + - port); - - triggered |= - io_lines_with_edges << - port * 8; - } - } - - ++got1; - } - - spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, - flags); - - if (triggered) { - struct comedi_subdevice *s; - /* - * TODO here: dispatch io lines to subdevs - * with commands.. - */ - printk - (KERN_DEBUG "got edge detect interrupt %d asic %d which_chans: %06x\n", - irq, asic, triggered); - for (i = 2; i < dev->n_subdevices; i++) { - s = &dev->subdevices[i]; - /* - * this is an interrupt subdev, - * and it matches this asic! - */ - if (subpriv->dio.intr.asic == asic) { - unsigned long flags; - unsigned oldevents; - - spin_lock_irqsave(&subpriv->dio. - intr.spinlock, - flags); - - oldevents = s->async->events; - - if (subpriv->dio.intr.active) { - unsigned mytrig = - ((triggered >> - subpriv->dio.intr.asic_chan) - & - ((0x1 << subpriv-> - dio.intr. - num_asic_chans) - - 1)) << subpriv-> - dio.intr.first_chan; - if (mytrig & - subpriv->dio. - intr.enabled_mask) { - unsigned int val - = 0; - unsigned int n, - ch, len; - - len = - s-> - async->cmd.chanlist_len; - for (n = 0; - n < len; - n++) { - ch = CR_CHAN(s->async->cmd.chanlist[n]); - if (mytrig & (1U << ch)) - val |= (1U << n); - } - /* Write the scan to the buffer. */ - if (comedi_buf_put(s->async, val) - && - comedi_buf_put - (s->async, - val >> 16)) { - s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS); - } else { - /* Overflow! Stop acquisition!! */ - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr - (dev, - s); - } - - /* Check for end of acquisition. */ - if (!subpriv->dio.intr.continuous) { - /* stop_src == TRIG_COUNT */ - if (subpriv->dio.intr.stop_count > 0) { - subpriv->dio.intr.stop_count--; - if (subpriv->dio.intr.stop_count == 0) { - s->async->events |= COMEDI_CB_EOA; - /* TODO: STOP_ACQUISITION_CALL_HERE!! */ - pcmmio_stop_intr - (dev, - s); - } - } - } - } - } - - spin_unlock_irqrestore - (&subpriv->dio.intr. - spinlock, flags); - - if (oldevents != - s->async->events) { - comedi_event(dev, s); - } - - } - - } - } - - } - } - if (!got1) - return IRQ_NONE; /* interrupt from other source */ return IRQ_HANDLED; } +/* devpriv->spinlock is already locked */ static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcmmio_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int bits = 0; + unsigned int pol_bits = 0; + int i; - if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) { + if (!devpriv->continuous && devpriv->stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; - subpriv->dio.intr.active = 0; + devpriv->active = 0; return 1; - } else { - unsigned bits = 0, pol_bits = 0, n; - int nports, firstport, asic, port; - struct comedi_cmd *cmd = &s->async->cmd; + } - asic = subpriv->dio.intr.asic; - if (asic < 0) - return 1; /* not an interrupt - subdev */ - subpriv->dio.intr.enabled_mask = 0; - subpriv->dio.intr.active = 1; - nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT; - firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT; - if (cmd->chanlist) { - for (n = 0; n < cmd->chanlist_len; n++) { - bits |= (1U << CR_CHAN(cmd->chanlist[n])); - pol_bits |= (CR_AREF(cmd->chanlist[n]) - || CR_RANGE(cmd-> - chanlist[n]) ? 1U : 0U) - << CR_CHAN(cmd->chanlist[n]); - } - } - bits &= ((0x1 << subpriv->dio.intr.num_asic_chans) - - 1) << subpriv->dio.intr.first_chan; - subpriv->dio.intr.enabled_mask = bits; + devpriv->enabled_mask = 0; + devpriv->active = 1; + if (cmd->chanlist) { + for (i = 0; i < cmd->chanlist_len; i++) { + unsigned int chanspec = cmd->chanlist[i]; + unsigned int chan = CR_CHAN(chanspec); + unsigned int range = CR_RANGE(chanspec); + unsigned int aref = CR_AREF(chanspec); - { - /* - * the below code configures the board - * to use a specific IRQ from 0-15. - */ - unsigned char b; - /* - * set resource enable register - * to enable IRQ operation - */ - outb(1 << 4, dev->iobase + 3); - /* set bits 0-3 of b to the irq number from 0-15 */ - b = dev->irq & ((1 << 4) - 1); - outb(b, dev->iobase + 2); - /* done, we told the board what irq to use */ - } - - switch_page(dev, asic, PAGE_ENAB); - for (port = firstport; port < firstport + nports; ++port) { - unsigned enab = - bits >> (subpriv->dio.intr.first_chan + (port - - firstport) - * 8) & 0xff, pol = - pol_bits >> (subpriv->dio.intr.first_chan + - (port - firstport) * 8) & 0xff; - /* set enab intrs for this subdev.. */ - outb(enab, - devpriv->asics[asic].iobase + REG_ENAB0 + port); - switch_page(dev, asic, PAGE_POL); - outb(pol, - devpriv->asics[asic].iobase + REG_ENAB0 + port); + bits |= (1 << chan); + pol_bits |= (((aref || range) ? 1 : 0) << chan); } } + bits &= ((1 << s->n_chan) - 1); + devpriv->enabled_mask = bits; + + /* set polarity and enable interrupts */ + pcmmio_dio_write(dev, pol_bits, PCMMIO_PAGE_POL, 0); + pcmmio_dio_write(dev, bits, PCMMIO_PAGE_ENAB, 0); + return 0; } static int pcmmio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); - if (subpriv->dio.intr.active) + spin_lock_irqsave(&devpriv->spinlock, flags); + if (devpriv->active) pcmmio_stop_intr(dev, s); - spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); + spin_unlock_irqrestore(&devpriv->spinlock, flags); return 0; } @@ -696,17 +471,18 @@ static int pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct pcmmio_private *devpriv = dev->private; unsigned long flags; int event = 0; if (trignum != 0) return -EINVAL; - spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); + spin_lock_irqsave(&devpriv->spinlock, flags); s->async->inttrig = NULL; - if (subpriv->dio.intr.active) + if (devpriv->active) event = pcmmio_start_intr(dev, s); - spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); + spin_unlock_irqrestore(&devpriv->spinlock, flags); if (event) comedi_event(dev, s); @@ -719,23 +495,24 @@ pcmmio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, */ static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned long flags; int event = 0; - spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags); - subpriv->dio.intr.active = 1; + spin_lock_irqsave(&devpriv->spinlock, flags); + devpriv->active = 1; /* Set up end of acquisition. */ switch (cmd->stop_src) { case TRIG_COUNT: - subpriv->dio.intr.continuous = 0; - subpriv->dio.intr.stop_count = cmd->stop_arg; + devpriv->continuous = 0; + devpriv->stop_count = cmd->stop_arg; break; default: /* TRIG_NONE */ - subpriv->dio.intr.continuous = 1; - subpriv->dio.intr.stop_count = 0; + devpriv->continuous = 1; + devpriv->stop_count = 0; break; } @@ -749,7 +526,7 @@ static int pcmmio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) event = pcmmio_start_intr(dev, s); break; } - spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags); + spin_unlock_irqrestore(&devpriv->spinlock, flags); if (event) comedi_event(dev, s); @@ -812,188 +589,171 @@ static int pcmmio_cmdtest(struct comedi_device *dev, return 0; } -static int adc_wait_ready(unsigned long iobase) +static int pcmmio_ai_wait_for_eoc(unsigned long iobase, unsigned int timeout) { - unsigned long retry = 100000; - while (retry--) - if (inb(iobase + 3) & 0x80) + unsigned char status; + + while (timeout--) { + status = inb(iobase + PCMMIO_AI_STATUS_REG); + if (status & PCMMIO_AI_STATUS_DATA_READY) return 0; - return 1; + } + return -ETIME; } -/* All this is for AI and AO */ -static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int pcmmio_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int n; - unsigned long iobase = subpriv->iobase; + unsigned long iobase = dev->iobase; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int aref = CR_AREF(insn->chanspec); + unsigned char cmd = 0; + unsigned int val; + int ret; + int i; /* - 1. write the CMD byte (to BASE+2) - 2. read junk lo byte (BASE+0) - 3. read junk hi byte (BASE+1) - 4. (mux settled so) write CMD byte again (BASE+2) - 5. read valid lo byte(BASE+0) - 6. read valid hi byte(BASE+1) - - Additionally note that the BASE += 4 if the channel >= 8 + * The PCM-MIO uses two Linear Tech LTC1859CG 8-channel A/D converters. + * The devices use a full duplex serial interface which transmits and + * receives data simultaneously. An 8-bit command is shifted into the + * ADC interface to configure it for the next conversion. At the same + * time, the data from the previous conversion is shifted out of the + * device. Consequently, the conversion result is delayed by one + * conversion from the command word. + * + * Setup the cmd for the conversions then do a dummy conversion to + * flush the junk data. Then do each conversion requested by the + * comedi_insn. Note that the last conversion will leave junk data + * in ADC which will get flushed on the next comedi_insn. */ - /* convert n samples */ - for (n = 0; n < insn->n; n++) { - unsigned chan = CR_CHAN(insn->chanspec), range = - CR_RANGE(insn->chanspec), aref = CR_AREF(insn->chanspec); - unsigned char command_byte = 0; - unsigned iooffset = 0; - unsigned short sample, adc_adjust = 0; - - if (chan > 7) - chan -= 8, iooffset = 4; /* - * use the second dword - * for channels > 7 - */ - - if (aref != AREF_DIFF) { - aref = AREF_GROUND; - command_byte |= 1 << 7; /* - * set bit 7 to indicate - * single-ended - */ - } - if (range < 2) - adc_adjust = 0x8000; /* - * bipolar ranges - * (-5,5 .. -10,10 need to be - * adjusted -- that is.. they - * need to wrap around by - * adding 0x8000 - */ - - if (chan % 2) { - command_byte |= 1 << 6; /* - * odd-numbered channels - * have bit 6 set - */ - } - - /* select the channel, bits 4-5 == chan/2 */ - command_byte |= ((chan / 2) & 0x3) << 4; - - /* set the range, bits 2-3 */ - command_byte |= (range & 0x3) << 2; - - /* need to do this twice to make sure mux settled */ - /* chan/range/aref select */ - outb(command_byte, iobase + iooffset + 2); - - /* wait for the adc to say it finised the conversion */ - adc_wait_ready(iobase + iooffset); - - /* select the chan/range/aref AGAIN */ - outb(command_byte, iobase + iooffset + 2); - - adc_wait_ready(iobase + iooffset); - - /* read data lo byte */ - sample = inb(iobase + iooffset + 0); - - /* read data hi byte */ - sample |= inb(iobase + iooffset + 1) << 8; - sample += adc_adjust; /* adjustment .. munge data */ - data[n] = sample; + if (chan > 7) { + chan -= 8; + iobase += PCMMIO_AI_2ND_ADC_OFFSET; } - /* return the number of samples read/written */ - return n; + + if (aref == AREF_GROUND) + cmd |= PCMMIO_AI_CMD_SE; + if (chan % 2) + cmd |= PCMMIO_AI_CMD_ODD_CHAN; + cmd |= PCMMIO_AI_CMD_CHAN_SEL(chan / 2); + cmd |= PCMMIO_AI_CMD_RANGE(range); + + outb(cmd, iobase + PCMMIO_AI_CMD_REG); + ret = pcmmio_ai_wait_for_eoc(iobase, 100000); + if (ret) + return ret; + + val = inb(iobase + PCMMIO_AI_LSB_REG); + val |= inb(iobase + PCMMIO_AI_MSB_REG) << 8; + + for (i = 0; i < insn->n; i++) { + outb(cmd, iobase + PCMMIO_AI_CMD_REG); + ret = pcmmio_ai_wait_for_eoc(iobase, 100000); + if (ret) + return ret; + + val = inb(iobase + PCMMIO_AI_LSB_REG); + val |= inb(iobase + PCMMIO_AI_MSB_REG) << 8; + + /* bipolar data is two's complement */ + if (comedi_range_is_bipolar(s, range)) + val = comedi_offset_munge(s, val); + + data[i] = val; + } + + return insn->n; } -static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int pcmmio_ao_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int n; - for (n = 0; n < insn->n; n++) { - unsigned chan = CR_CHAN(insn->chanspec); - if (chan < s->n_chan) - data[n] = subpriv->ao.shadow_samples[chan]; - } - return n; + struct pcmmio_private *devpriv = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); + int i; + + for (i = 0; i < insn->n; i++) + data[i] = devpriv->ao_readback[chan]; + + return insn->n; } -static int wait_dac_ready(unsigned long iobase) +static int pcmmio_ao_wait_for_eoc(unsigned long iobase, unsigned int timeout) { - unsigned long retry = 100000L; + unsigned char status; - /* This may seem like an absurd way to handle waiting and violates the - "no busy waiting" policy. The fact is that the hardware is - normally so fast that we usually only need one time through the loop - anyway. The longer timeout is for rare occasions and for detecting - non-existent hardware. */ - - while (retry--) { - if (inb(iobase + 3) & 0x80) + while (timeout--) { + status = inb(iobase + PCMMIO_AO_STATUS_REG); + if (status & PCMMIO_AO_STATUS_DATA_READY) return 0; - } - return 1; + return -ETIME; } -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int pcmmio_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - int n; - unsigned iobase = subpriv->iobase, iooffset = 0; + struct pcmmio_private *devpriv = dev->private; + unsigned long iobase = dev->iobase; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int val = devpriv->ao_readback[chan]; + unsigned char cmd = 0; + int ret; + int i; - for (n = 0; n < insn->n; n++) { - unsigned chan = CR_CHAN(insn->chanspec), range = - CR_RANGE(insn->chanspec); - if (chan < s->n_chan) { - unsigned char command_byte = 0, range_byte = - range & ((1 << 4) - 1); - if (chan >= 4) - chan -= 4, iooffset += 4; - /* set the range.. */ - outb(range_byte, iobase + iooffset + 0); - outb(0, iobase + iooffset + 1); + /* + * The PCM-MIO has two Linear Tech LTC2704 DAC devices. Each device + * is a 4-channel converter with software-selectable output range. + */ - /* tell it to begin */ - command_byte = (chan << 1) | 0x60; - outb(command_byte, iobase + iooffset + 2); - - wait_dac_ready(iobase + iooffset); - - /* low order byte */ - outb(data[n] & 0xff, iobase + iooffset + 0); - - /* high order byte */ - outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); - - /* - * set bit 4 of command byte to indicate - * data is loaded and trigger conversion - */ - command_byte = 0x70 | (chan << 1); - /* trigger converion */ - outb(command_byte, iobase + iooffset + 2); - - wait_dac_ready(iobase + iooffset); - - /* save to shadow register for ao_rinsn */ - subpriv->ao.shadow_samples[chan] = data[n]; - } + if (chan > 3) { + cmd |= PCMMIO_AO_CMD_CHAN_SEL(chan - 4); + iobase += PCMMIO_AO_2ND_DAC_OFFSET; + } else { + cmd |= PCMMIO_AO_CMD_CHAN_SEL(chan); } - return n; + + /* set the range for the channel */ + outb(PCMMIO_AO_LSB_SPAN(range), iobase + PCMMIO_AO_LSB_REG); + outb(0, iobase + PCMMIO_AO_MSB_REG); + outb(cmd | PCMMIO_AO_CMD_WR_SPAN_UPDATE, iobase + PCMMIO_AO_CMD_REG); + ret = pcmmio_ao_wait_for_eoc(iobase, 100000); + if (ret) + return ret; + + for (i = 0; i < insn->n; i++) { + val = data[i]; + + /* write the data to the channel */ + outb(val & 0xff, iobase + PCMMIO_AO_LSB_REG); + outb((val >> 8) & 0xff, iobase + PCMMIO_AO_MSB_REG); + outb(cmd | PCMMIO_AO_CMD_WR_CODE_UPDATE, + iobase + PCMMIO_AO_CMD_REG); + ret = pcmmio_ao_wait_for_eoc(iobase, 100000); + if (ret) + return ret; + + devpriv->ao_readback[chan] = val; + } + + return insn->n; } static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pcmmio_private *devpriv; struct comedi_subdevice *s; - int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, - thisasic_chanct = 0; - unsigned int irq[MAX_ASICS]; int ret; - irq[0] = it->options[1]; - ret = comedi_request_region(dev, it->options[0], 32); if (ret) return ret; @@ -1002,177 +762,99 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - for (asic = 0; asic < MAX_ASICS; ++asic) { - devpriv->asics[asic].num = asic; - devpriv->asics[asic].iobase = - dev->iobase + 16 + asic * ASIC_IOSIZE; - /* - * this gets actually set at the end of this function when we - * request_irqs - */ - devpriv->asics[asic].irq = 0; - spin_lock_init(&devpriv->asics[asic].spinlock); + spin_lock_init(&devpriv->pagelock); + spin_lock_init(&devpriv->spinlock); + + pcmmio_reset(dev); + + if (it->options[1]) { + ret = request_irq(it->options[1], interrupt_pcmmio, 0, + dev->board_name, dev); + if (ret == 0) { + dev->irq = it->options[1]; + + /* configure the interrupt routing on the board */ + outb(PCMMIO_AI_RES_ENA_DIO_RES_ACCESS, + dev->iobase + PCMMIO_AI_RES_ENA_REG); + outb(PCMMIO_RESOURCE_IRQ(dev->irq), + dev->iobase + PCMMIO_RESOURCE_REG); + } } - chans_left = CHANS_PER_ASIC * 1; - n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); - n_subdevs = n_dio_subdevs + 2; - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - printk(KERN_ERR "comedi%d: cannot allocate subdevice private data structures\n", - dev->minor); - return -ENOMEM; - } - - ret = comedi_alloc_subdevices(dev, n_subdevs); + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; - /* First, AI */ + /* Analog Input subdevice */ s = &dev->subdevices[0]; - s->private = &devpriv->sprivs[0]; - s->maxdata = 0xffff; - s->range_table = &ranges_ai; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->type = COMEDI_SUBD_AI; - s->n_chan = 16; - s->len_chanlist = s->n_chan; - s->insn_read = ai_rinsn; - subpriv->iobase = dev->iobase + 0; - /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = 16; + s->maxdata = 0xffff; + s->range_table = &pcmmio_ai_ranges; + s->insn_read = pcmmio_ai_insn_read; - /* Next, AO */ + /* initialize the resource enable register by clearing it */ + outb(PCMMIO_AI_RES_ENA_CMD_REG_ACCESS, + dev->iobase + PCMMIO_AI_RES_ENA_REG); + outb(PCMMIO_AI_RES_ENA_CMD_REG_ACCESS, + dev->iobase + PCMMIO_AI_RES_ENA_REG + PCMMIO_AI_2ND_ADC_OFFSET); + + /* Analog Output subdevice */ s = &dev->subdevices[1]; - s->private = &devpriv->sprivs[1]; - s->maxdata = 0xffff; - s->range_table = &ranges_ao; - s->subdev_flags = SDF_READABLE; - s->type = COMEDI_SUBD_AO; - s->n_chan = 8; - s->len_chanlist = s->n_chan; - s->insn_read = ao_rinsn; - s->insn_write = ao_winsn; - subpriv->iobase = dev->iobase + 8; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE; + s->n_chan = 8; + s->maxdata = 0xffff; + s->range_table = &pcmmio_ao_ranges; + s->insn_read = pcmmio_ao_insn_read; + s->insn_write = pcmmio_ao_insn_write; + /* initialize the resource enable register by clearing it */ - outb(0, subpriv->iobase + 3); - outb(0, subpriv->iobase + 4 + 3); - - port = 0; - asic = 0; - for (sdev_no = 2; sdev_no < dev->n_subdevices; ++sdev_no) { - int byte_no; - - s = &dev->subdevices[sdev_no]; - s->private = &devpriv->sprivs[sdev_no]; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmmio_dio_insn_bits; - s->insn_config = pcmmio_dio_insn_config; - s->n_chan = min(chans_left, MAX_CHANS_PER_SUBDEV); - subpriv->dio.intr.asic = -1; - subpriv->dio.intr.first_chan = -1; - subpriv->dio.intr.asic_chan = -1; - subpriv->dio.intr.num_asic_chans = -1; - subpriv->dio.intr.active = 0; - s->len_chanlist = 1; - - /* save the ioport address for each 'port' of 8 channels in the - subdevice */ - for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) { - if (port >= PORTS_PER_ASIC) { - port = 0; - ++asic; - thisasic_chanct = 0; - } - subpriv->iobases[byte_no] = - devpriv->asics[asic].iobase + port; - - if (thisasic_chanct < - CHANS_PER_PORT * INTR_PORTS_PER_ASIC - && subpriv->dio.intr.asic < 0) { - /* - * this is an interrupt subdevice, - * so setup the struct - */ - subpriv->dio.intr.asic = asic; - subpriv->dio.intr.active = 0; - subpriv->dio.intr.stop_count = 0; - subpriv->dio.intr.first_chan = byte_no * 8; - subpriv->dio.intr.asic_chan = thisasic_chanct; - subpriv->dio.intr.num_asic_chans = - s->n_chan - subpriv->dio.intr.first_chan; - s->cancel = pcmmio_cancel; - s->do_cmd = pcmmio_cmd; - s->do_cmdtest = pcmmio_cmdtest; - s->len_chanlist = - subpriv->dio.intr.num_asic_chans; - } - thisasic_chanct += CHANS_PER_PORT; - } - spin_lock_init(&subpriv->dio.intr.spinlock); - - chans_left -= s->n_chan; - - if (!chans_left) { - /* - * reset the asic to our first asic, - * to do intr subdevs - */ - asic = 0; - port = 0; - } + outb(0, dev->iobase + PCMMIO_AO_RESOURCE_ENA_REG); + outb(0, dev->iobase + PCMMIO_AO_2ND_DAC_OFFSET + + PCMMIO_AO_RESOURCE_ENA_REG); + /* Digital I/O subdevice with interrupt support */ + s = &dev->subdevices[2]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->len_chanlist = 1; + s->range_table = &range_digital; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->cancel = pcmmio_cancel; + s->do_cmd = pcmmio_cmd; + s->do_cmdtest = pcmmio_cmdtest; } - init_asics(dev); /* clear out all the registers, basically */ + /* Digital I/O subdevice */ + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pcmmio_dio_insn_bits; + s->insn_config = pcmmio_dio_insn_config; - for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, dev->board_name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; - } - devpriv->asics[asic].irq = irq[asic]; - } - - return 1; -} - -static void pcmmio_detach(struct comedi_device *dev) -{ - struct pcmmio_private *devpriv = dev->private; - int i; - - if (devpriv) { - for (i = 0; i < MAX_ASICS; ++i) { - if (devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - kfree(devpriv->sprivs); - } - comedi_legacy_detach(dev); + return 0; } static struct comedi_driver pcmmio_driver = { .driver_name = "pcmmio", .module = THIS_MODULE, .attach = pcmmio_attach, - .detach = pcmmio_detach, + .detach = comedi_legacy_detach, }; module_comedi_driver(pcmmio_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for Winsystems PCM-MIO PC/104 board"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 954fa96a50ac..a8f390f7a874 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -75,7 +75,6 @@ #include #include -#include #include "../comedidev.h" @@ -127,36 +126,53 @@ static const struct pcmuio_board pcmuio_boards[] = { }, }; -struct pcmuio_subdev_private { - /* The below is only used for intr subdevices */ - struct { - /* if non-negative, this subdev has an interrupt asic */ - int asic; - /* - * subdev-relative channel mask for channels - * we are interested in - */ - int enabled_mask; - int active; - int stop_count; - int continuous; - spinlock_t spinlock; - } intr; +struct pcmuio_asic { + spinlock_t pagelock; /* protects the page registers */ + spinlock_t spinlock; /* protects member variables */ + unsigned int enabled_mask; + unsigned int stop_count; + unsigned int active:1; + unsigned int continuous:1; }; struct pcmuio_private { - struct { - unsigned int irq; - spinlock_t spinlock; - } asics[PCMUIO_MAX_ASICS]; - struct pcmuio_subdev_private *sprivs; + struct pcmuio_asic asics[PCMUIO_MAX_ASICS]; + unsigned int irq2; }; +static inline unsigned long pcmuio_asic_iobase(struct comedi_device *dev, + int asic) +{ + return dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); +} + +static inline int pcmuio_subdevice_to_asic(struct comedi_subdevice *s) +{ + /* + * subdevice 0 and 1 are handled by the first asic + * subdevice 2 and 3 are handled by the second asic + */ + return s->index / 2; +} + +static inline int pcmuio_subdevice_to_port(struct comedi_subdevice *s) +{ + /* + * subdevice 0 and 2 use port registers 0-2 + * subdevice 1 and 3 use port registers 3-5 + */ + return (s->index % 2) ? 3 : 0; +} + static void pcmuio_write(struct comedi_device *dev, unsigned int val, int asic, int page, int port) { - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); + struct pcmuio_private *devpriv = dev->private; + struct pcmuio_asic *chip = &devpriv->asics[asic]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned long flags; + spin_lock_irqsave(&chip->pagelock, flags); if (page == 0) { /* Port registers are valid for any page */ outb(val & 0xff, iobase + PCMUIO_PORT_REG(port + 0)); @@ -168,14 +184,19 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val, outb((val >> 8) & 0xff, iobase + PCMUIO_PAGE_REG(1)); outb((val >> 16) & 0xff, iobase + PCMUIO_PAGE_REG(2)); } + spin_unlock_irqrestore(&chip->pagelock, flags); } static unsigned int pcmuio_read(struct comedi_device *dev, int asic, int page, int port) { - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); + struct pcmuio_private *devpriv = dev->private; + struct pcmuio_asic *chip = &devpriv->asics[asic]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned long flags; unsigned int val; + spin_lock_irqsave(&chip->pagelock, flags); if (page == 0) { /* Port registers are valid for any page */ val = inb(iobase + PCMUIO_PORT_REG(port + 0)); @@ -187,6 +208,7 @@ static unsigned int pcmuio_read(struct comedi_device *dev, val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8); val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16); } + spin_unlock_irqrestore(&chip->pagelock, flags); return val; } @@ -203,30 +225,35 @@ static unsigned int pcmuio_read(struct comedi_device *dev, */ static int pcmuio_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - unsigned int mask = data[0] & s->io_bits; /* outputs only */ - unsigned int bits = data[1]; - int asic = s->index / 2; - int port = (s->index % 2) ? 3 : 0; + int asic = pcmuio_subdevice_to_asic(s); + int port = pcmuio_subdevice_to_port(s); + unsigned int chanmask = (1 << s->n_chan) - 1; + unsigned int mask; unsigned int val; + mask = comedi_dio_update_state(s, data); + if (mask) { + /* + * Outputs are inverted, invert the state and + * update the channels. + * + * The s->io_bits mask makes sure the input channels + * are '0' so that the outputs pins stay in a high + * z-state. + */ + val = ~s->state & chanmask; + val &= s->io_bits; + pcmuio_write(dev, val, asic, 0, port); + } + /* get inverted state of the channels from the port */ val = pcmuio_read(dev, asic, 0, port); - /* get the true state of the channels */ - s->state = val ^ ((0x1 << s->n_chan) - 1); - - if (mask) { - s->state &= ~mask; - s->state |= (mask & bits); - - /* invert the state and update the channels */ - val = s->state ^ ((0x1 << s->n_chan) - 1); - pcmuio_write(dev, val, asic, 0, port); - } - - data[1] = s->state; + /* return the true state of the channels */ + data[1] = ~val & chanmask; return insn->n; } @@ -236,8 +263,8 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int asic = s->index / 2; - int port = (s->index % 2) ? 3 : 0; + int asic = pcmuio_subdevice_to_asic(s); + int port = pcmuio_subdevice_to_port(s); int ret; ret = comedi_dio_insn_config(dev, s, insn, data, 0); @@ -267,18 +294,16 @@ static void pcmuio_reset(struct comedi_device *dev) } } +/* chip->spinlock is already locked */ static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; - int asic; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; - asic = subpriv->intr.asic; - if (asic < 0) - return; /* not an interrupt subdev */ - - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 0; + chip->enabled_mask = 0; + chip->active = 0; s->async->inttrig = NULL; /* disable all intrs for this subdev.. */ @@ -289,29 +314,27 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, struct comedi_subdevice *s, unsigned triggered) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned int len = s->async->cmd.chanlist_len; unsigned oldevents = s->async->events; unsigned int val = 0; unsigned long flags; - unsigned mytrig; unsigned int i; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); + spin_lock_irqsave(&chip->spinlock, flags); - if (!subpriv->intr.active) + if (!chip->active) goto done; - mytrig = triggered; - mytrig &= ((0x1 << s->n_chan) - 1); - - if (!(mytrig & subpriv->intr.enabled_mask)) + if (!(triggered & chip->enabled_mask)) goto done; for (i = 0; i < len; i++) { unsigned int chan = CR_CHAN(s->async->cmd.chanlist[i]); - if (mytrig & (1U << chan)) - val |= (1U << i); + if (triggered & (1 << chan)) + val |= (1 << i); } /* Write the scan to the buffer. */ @@ -325,11 +348,11 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, } /* Check for end of acquisition. */ - if (!subpriv->intr.continuous) { + if (!chip->continuous) { /* stop_src == TRIG_COUNT */ - if (subpriv->intr.stop_count > 0) { - subpriv->intr.stop_count--; - if (subpriv->intr.stop_count == 0) { + if (chip->stop_count > 0) { + chip->stop_count--; + if (chip->stop_count == 0) { s->async->events |= COMEDI_CB_EOA; /* TODO: STOP_ACQUISITION_CALL_HERE!! */ pcmuio_stop_intr(dev, s); @@ -338,7 +361,7 @@ static void pcmuio_handle_intr_subdev(struct comedi_device *dev, } done: - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (oldevents != s->async->events) comedi_event(dev, s); @@ -346,114 +369,93 @@ done: static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic) { - struct pcmuio_private *devpriv = dev->private; - struct pcmuio_subdev_private *subpriv; - unsigned long iobase = dev->iobase + (asic * PCMUIO_ASIC_IOSIZE); - unsigned int triggered = 0; - int got1 = 0; - unsigned long flags; - unsigned char int_pend; - int i; + /* there are could be two asics so we can't use dev->read_subdev */ + struct comedi_subdevice *s = &dev->subdevices[asic * 2]; + unsigned long iobase = pcmuio_asic_iobase(dev, asic); + unsigned int val; - spin_lock_irqsave(&devpriv->asics[asic].spinlock, flags); + /* are there any interrupts pending */ + val = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07; + if (!val) + return 0; - int_pend = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07; - if (int_pend) { - triggered = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0); - pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0); + /* get, and clear, the pending interrupts */ + val = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0); + pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0); - ++got1; - } + /* handle the pending interrupts */ + pcmuio_handle_intr_subdev(dev, s, val); - spin_unlock_irqrestore(&devpriv->asics[asic].spinlock, flags); - - if (triggered) { - struct comedi_subdevice *s; - /* TODO here: dispatch io lines to subdevs with commands.. */ - for (i = 0; i < dev->n_subdevices; i++) { - s = &dev->subdevices[i]; - subpriv = s->private; - if (subpriv->intr.asic == asic) { - /* - * This is an interrupt subdev, and it - * matches this asic! - */ - pcmuio_handle_intr_subdev(dev, s, - triggered); - } - } - } - return got1; + return 1; } static irqreturn_t pcmuio_interrupt(int irq, void *d) { struct comedi_device *dev = d; struct pcmuio_private *devpriv = dev->private; - int got1 = 0; - int asic; + int handled = 0; - for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) { - if (irq == devpriv->asics[asic].irq) { - /* it is an interrupt for ASIC #asic */ - if (pcmuio_handle_asic_interrupt(dev, asic)) - got1++; - } - } - if (!got1) - return IRQ_NONE; /* interrupt from other source */ - return IRQ_HANDLED; + if (irq == dev->irq) + handled += pcmuio_handle_asic_interrupt(dev, 0); + if (irq == devpriv->irq2) + handled += pcmuio_handle_asic_interrupt(dev, 1); + + return handled ? IRQ_HANDLED : IRQ_NONE; } +/* chip->spinlock is already locked */ static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int bits = 0; + unsigned int pol_bits = 0; + int i; - if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) { + if (!chip->continuous && chip->stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; - subpriv->intr.active = 0; + chip->active = 0; return 1; - } else { - unsigned bits = 0, pol_bits = 0, n; - int asic; - struct comedi_cmd *cmd = &s->async->cmd; - - asic = subpriv->intr.asic; - if (asic < 0) - return 1; /* not an interrupt - subdev */ - subpriv->intr.enabled_mask = 0; - subpriv->intr.active = 1; - if (cmd->chanlist) { - for (n = 0; n < cmd->chanlist_len; n++) { - bits |= (1U << CR_CHAN(cmd->chanlist[n])); - pol_bits |= (CR_AREF(cmd->chanlist[n]) - || CR_RANGE(cmd-> - chanlist[n]) ? 1U : 0U) - << CR_CHAN(cmd->chanlist[n]); - } - } - bits &= ((0x1 << s->n_chan) - 1); - subpriv->intr.enabled_mask = bits; - - /* set pol and enab intrs for this subdev.. */ - pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0); - pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0); } + + chip->enabled_mask = 0; + chip->active = 1; + if (cmd->chanlist) { + for (i = 0; i < cmd->chanlist_len; i++) { + unsigned int chanspec = cmd->chanlist[i]; + unsigned int chan = CR_CHAN(chanspec); + unsigned int range = CR_RANGE(chanspec); + unsigned int aref = CR_AREF(chanspec); + + bits |= (1 << chan); + pol_bits |= ((aref || range) ? 1 : 0) << chan; + } + } + bits &= ((1 << s->n_chan) - 1); + chip->enabled_mask = bits; + + /* set pol and enab intrs for this subdev.. */ + pcmuio_write(dev, pol_bits, asic, PCMUIO_PAGE_POL, 0); + pcmuio_write(dev, bits, asic, PCMUIO_PAGE_ENAB, 0); + return 0; } static int pcmuio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); - if (subpriv->intr.active) + spin_lock_irqsave(&chip->spinlock, flags); + if (chip->active) pcmuio_stop_intr(dev, s); - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); return 0; } @@ -465,19 +467,21 @@ static int pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; int event = 0; if (trignum != 0) return -EINVAL; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); + spin_lock_irqsave(&chip->spinlock, flags); s->async->inttrig = NULL; - if (subpriv->intr.active) + if (chip->active) event = pcmuio_start_intr(dev, s); - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (event) comedi_event(dev, s); @@ -490,24 +494,26 @@ pcmuio_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, */ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - struct pcmuio_subdev_private *subpriv = s->private; + struct pcmuio_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; + int asic = pcmuio_subdevice_to_asic(s); + struct pcmuio_asic *chip = &devpriv->asics[asic]; unsigned long flags; int event = 0; - spin_lock_irqsave(&subpriv->intr.spinlock, flags); - subpriv->intr.active = 1; + spin_lock_irqsave(&chip->spinlock, flags); + chip->active = 1; /* Set up end of acquisition. */ switch (cmd->stop_src) { case TRIG_COUNT: - subpriv->intr.continuous = 0; - subpriv->intr.stop_count = cmd->stop_arg; + chip->continuous = 0; + chip->stop_count = cmd->stop_arg; break; default: /* TRIG_NONE */ - subpriv->intr.continuous = 1; - subpriv->intr.stop_count = 0; + chip->continuous = 1; + chip->stop_count = 0; break; } @@ -521,7 +527,7 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) event = pcmuio_start_intr(dev, s); break; } - spin_unlock_irqrestore(&subpriv->intr.spinlock, flags); + spin_unlock_irqrestore(&chip->spinlock, flags); if (event) comedi_event(dev, s); @@ -589,13 +595,8 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) const struct pcmuio_board *board = comedi_board(dev); struct comedi_subdevice *s; struct pcmuio_private *devpriv; - struct pcmuio_subdev_private *subpriv; - int sdev_no, n_subdevs, asic; - unsigned int irq[PCMUIO_MAX_ASICS]; int ret; - - irq[0] = it->options[1]; - irq[1] = it->options[2]; + int i; ret = comedi_request_region(dev, it->options[0], board->num_asics * PCMUIO_ASIC_IOSIZE); @@ -606,62 +607,60 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv) return -ENOMEM; - for (asic = 0; asic < PCMUIO_MAX_ASICS; ++asic) - spin_lock_init(&devpriv->asics[asic].spinlock); + for (i = 0; i < PCMUIO_MAX_ASICS; ++i) { + struct pcmuio_asic *chip = &devpriv->asics[i]; - n_subdevs = board->num_asics * 2; - devpriv->sprivs = kcalloc(n_subdevs, sizeof(*subpriv), GFP_KERNEL); - if (!devpriv->sprivs) - return -ENOMEM; - - ret = comedi_alloc_subdevices(dev, n_subdevs); - if (ret) - return ret; - - for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) { - s = &dev->subdevices[sdev_no]; - subpriv = &devpriv->sprivs[sdev_no]; - s->private = subpriv; - s->maxdata = 1; - s->range_table = &range_digital; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->type = COMEDI_SUBD_DIO; - s->insn_bits = pcmuio_dio_insn_bits; - s->insn_config = pcmuio_dio_insn_config; - s->n_chan = 24; - - /* subdevices 0 and 2 suppport interrupts */ - if ((sdev_no % 2) == 0) { - /* setup the interrupt subdevice */ - subpriv->intr.asic = sdev_no / 2; - dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->cancel = pcmuio_cancel; - s->do_cmd = pcmuio_cmd; - s->do_cmdtest = pcmuio_cmdtest; - s->len_chanlist = s->n_chan; - } else { - subpriv->intr.asic = -1; - s->len_chanlist = 1; - } - spin_lock_init(&subpriv->intr.spinlock); + spin_lock_init(&chip->pagelock); + spin_lock_init(&chip->spinlock); } pcmuio_reset(dev); - for (asic = 0; irq[0] && asic < PCMUIO_MAX_ASICS; ++asic) { - if (irq[asic] - && request_irq(irq[asic], pcmuio_interrupt, - IRQF_SHARED, board->name, dev)) { - int i; - /* unroll the allocated irqs.. */ - for (i = asic - 1; i >= 0; --i) { - free_irq(irq[i], dev); - devpriv->asics[i].irq = irq[i] = 0; - } - irq[asic] = 0; + if (it->options[1]) { + /* request the irq for the 1st asic */ + ret = request_irq(it->options[1], pcmuio_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + dev->irq = it->options[1]; + } + + if (board->num_asics == 2) { + if (it->options[2] == dev->irq) { + /* the same irq (or none) is used by both asics */ + devpriv->irq2 = it->options[2]; + } else if (it->options[2]) { + /* request the irq for the 2nd asic */ + ret = request_irq(it->options[2], pcmuio_interrupt, 0, + dev->board_name, dev); + if (ret == 0) + devpriv->irq2 = it->options[2]; + } + } + + ret = comedi_alloc_subdevices(dev, board->num_asics * 2); + if (ret) + return ret; + + for (i = 0; i < dev->n_subdevices; ++i) { + s = &dev->subdevices[i]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = pcmuio_dio_insn_bits; + s->insn_config = pcmuio_dio_insn_config; + + /* subdevices 0 and 2 can suppport interrupts */ + if ((i == 0 && dev->irq) || (i == 2 && devpriv->irq2)) { + /* setup the interrupt subdevice */ + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->len_chanlist = s->n_chan; + s->cancel = pcmuio_cancel; + s->do_cmd = pcmuio_cmd; + s->do_cmdtest = pcmuio_cmdtest; } - devpriv->asics[asic].irq = irq[asic]; } return 0; @@ -670,14 +669,13 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmuio_detach(struct comedi_device *dev) { struct pcmuio_private *devpriv = dev->private; - int i; if (devpriv) { - for (i = 0; i < PCMUIO_MAX_ASICS; ++i) { - if (devpriv->asics[i].irq) - free_irq(devpriv->asics[i].irq, dev); - } - kfree(devpriv->sprivs); + pcmuio_reset(dev); + + /* free the 2nd irq if used, the core will free the 1st one */ + if (devpriv->irq2 && devpriv->irq2 != dev->irq) + free_irq(devpriv->irq2, dev); } comedi_legacy_detach(dev); } diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index 0d254a1b78a7..55e3c2e2bc52 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -402,12 +402,9 @@ static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) udelay(1); dma_status = readb(dma_cs_addr); } - if (i == timeout) { - printk - ("plx9080: cancel() timed out waiting for dma %i done clear\n", - channel); + if (i == timeout) return -ETIMEDOUT; - } + /* disable and abort channel */ writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); /* wait for dma done bit */ @@ -416,12 +413,8 @@ static inline int plx9080_abort_dma(void __iomem *iobase, unsigned int channel) udelay(1); dma_status = readb(dma_cs_addr); } - if (i == timeout) { - printk - ("plx9080: cancel() timed out waiting for dma %i done set\n", - channel); + if (i == timeout) return -ETIMEDOUT; - } return 0; } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 44c8712ed9e0..0f026afde9be 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -495,8 +495,6 @@ static unsigned short rtd_convert_chan_gain(struct comedi_device *dev, case AREF_OTHER: /* ??? */ break; } - /*printk ("chan=%d r=%d a=%d -> 0x%x\n", - chan, range, aref, r); */ return r; } @@ -606,7 +604,6 @@ static int rtd_ai_rinsn(struct comedi_device *dev, /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); - /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */ d = d >> 3; /* low 3 bits are marker lines */ if (test_bit(0, devpriv->chan_is_bipolar)) /* convert to comedi unsigned data */ @@ -692,7 +689,7 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t rtd_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct comedi_subdevice *s = &dev->subdevices[0]; + struct comedi_subdevice *s = dev->read_subdev; struct rtd_private *devpriv = dev->private; u32 overrun; u16 status; @@ -1427,7 +1424,7 @@ static int rtd520_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data); } -static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = { +static const struct pci_device_id rtd520_pci_table[] = { { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 }, { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 }, { 0 } diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index b486099b543d..19da1dbea494 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -199,7 +199,7 @@ static bool s626_mc_test(struct comedi_device *dev, static const struct comedi_lrange s626_range_table = { 2, { BIP_RANGE(5), - BIP_RANGE(10), + BIP_RANGE(10) } }; @@ -1614,12 +1614,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d) static void s626_reset_adc(struct comedi_device *dev, uint8_t *ppl) { struct s626_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; uint32_t *rps; uint32_t jmp_adrs; uint16_t i; uint16_t n; uint32_t local_ppl; - struct comedi_cmd *cmd = &dev->subdevices->async->cmd; /* Stop RPS program in case it is currently running */ s626_mc_disable(dev, S626_MC1_ERPS1, S626_P_MC1); @@ -2079,12 +2080,6 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (cmd == NULL) return -EINVAL; - if (dev->irq == 0) { - comedi_error(dev, - "s626_ai_cmd: cannot run command without an irq"); - return -EIO; - } - s626_ai_load_polllist(ppl, cmd); devpriv->ai_cmd_running = 1; devpriv->ai_convert_count = 0; @@ -2645,6 +2640,7 @@ static void s626_initialize(struct comedi_device *dev) * a defined state after a PCI reset. */ { + struct comedi_subdevice *s = dev->read_subdev; uint8_t poll_list; uint16_t adc_data; uint16_t start_val; @@ -2656,7 +2652,7 @@ static void s626_initialize(struct comedi_device *dev) s626_reset_adc(dev, &poll_list); /* Get initial ADC value */ - s626_ai_rinsn(dev, dev->subdevices, NULL, data); + s626_ai_rinsn(dev, s, NULL, data); start_val = data[0]; /* @@ -2670,7 +2666,7 @@ static void s626_initialize(struct comedi_device *dev) * being unusually quiet or at the rail. */ for (index = 0; index < 500; index++) { - s626_ai_rinsn(dev, dev->subdevices, NULL, data); + s626_ai_rinsn(dev, s, NULL, data); adc_data = data[0]; if (adc_data != start_val) break; @@ -2833,7 +2829,7 @@ static int s626_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_DIFF; s->n_chan = S626_ADC_CHANNELS; s->maxdata = 0x3fff; s->range_table = &s626_range_table; @@ -2841,6 +2837,7 @@ static int s626_auto_attach(struct comedi_device *dev, s->insn_read = s626_ai_insn_read; if (dev->irq) { dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->do_cmd = s626_ai_cmd; s->do_cmdtest = s626_ai_cmdtest; s->cancel = s626_ai_cancel; @@ -2965,7 +2962,7 @@ static int s626_pci_probe(struct pci_dev *dev, * also subvendor:subdevice ids, because otherwise it will conflict with * Philips SAA7146 media/dvb based cards. */ -static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { +static const struct pci_device_id s626_pci_table[] = { { PCI_DEVICE_SUB(PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0x6000, 0x0272) }, { 0 } diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index daee2f42bde0..77e2059ff62e 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -698,7 +698,7 @@ static int skel_pci_probe(struct pci_dev *dev, * This is used by modprobe to translate PCI IDs to drivers. * Should only be used for PCI and ISA-PnP devices */ -static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { +static const struct pci_device_id skel_pci_table[] = { { PCI_VDEVICE(SKEL, 0x0100), BOARD_SKEL100 }, { PCI_VDEVICE(SKEL, 0x0200), BOARD_SKEL200 }, { 0 } diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 93eec2fc254c..adf7cb7086cc 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -38,7 +38,6 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -91,12 +90,14 @@ static int __unioxx5_define_chan_offset(int chan_num) } #if 0 /* not used? */ -static void __unioxx5_digital_config(struct unioxx5_subd_priv *usp, int mode) +static void __unioxx5_digital_config(struct comedi_subdevice *s, int mode) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int i, mask; mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00; - printk("COMEDI: mode = %d\n", mask); + dev_dbg(csdev, "mode = %d\n", mask); outb(1, usp->usp_iobase + 0); @@ -135,15 +136,18 @@ static void __unioxx5_analog_config(struct unioxx5_subd_priv *usp, int channel) usp->usp_prev_cn_val[channel_offset - 1] = conf; } -static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, +static int __unioxx5_digital_read(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int channel_offset, mask = 1 << (channel & 0x07); channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); + dev_err(csdev, + "undefined channel %d. channel range is 0 .. 23\n", + channel); return 0; } @@ -157,9 +161,11 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, +static int __unioxx5_analog_read(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int module_no, read_ch; char control; @@ -168,8 +174,9 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* defining if given module can work on input */ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { - pr_err("comedi%d: module in position %d with id 0x%02x is for output only", - minor, module_no, usp->usp_module_type[module_no]); + dev_err(csdev, + "module in position %d with id 0x%02x is for output only", + module_no, usp->usp_module_type[module_no]); return 0; } @@ -185,7 +192,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* if four bytes readding error occurs - return 0(false) */ if ((control & Rx4CA_ERR_MASK)) { - printk("COMEDI: 4 bytes error\n"); + dev_err(csdev, "4 bytes error\n"); return 0; } @@ -197,16 +204,19 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, +static int __unioxx5_digital_write(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int channel_offset, val; int mask = 1 << (channel & 0x07); channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", - minor, channel); + dev_err(csdev, + "undefined channel %d. channel range is 0 .. 23\n", + channel); return 0; } @@ -225,9 +235,11 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, return 1; } -static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, +static int __unioxx5_analog_write(struct comedi_subdevice *s, unsigned int *data, int channel, int minor) { + struct unioxx5_subd_priv *usp = s->private; + struct device *csdev = s->device->class_dev; int module, i; module = channel / 2; /* definig module number(0 .. 11) */ @@ -235,8 +247,9 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, /* defining if given module can work on output */ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { - pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n", - minor, module, usp->usp_module_type[module]); + dev_err(csdev, + "module in position %d with id 0x%0x is for input only!\n", + module, usp->usp_module_type[module]); return 0; } @@ -273,10 +286,10 @@ static int unioxx5_subdev_read(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { - if (!__unioxx5_digital_read(usp, data, channel, dev->minor)) + if (!__unioxx5_digital_read(subdev, data, channel, dev->minor)) return -1; } else { - if (!__unioxx5_analog_read(usp, data, channel, dev->minor)) + if (!__unioxx5_analog_read(subdev, data, channel, dev->minor)) return -1; } @@ -295,10 +308,10 @@ static int unioxx5_subdev_write(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type == MODULE_DIGITAL) { - if (!__unioxx5_digital_write(usp, data, channel, dev->minor)) + if (!__unioxx5_digital_write(subdev, data, channel, dev->minor)) return -1; } else { - if (!__unioxx5_analog_write(usp, data, channel, dev->minor)) + if (!__unioxx5_analog_write(subdev, data, channel, dev->minor)) return -1; } @@ -318,16 +331,15 @@ static int unioxx5_insn_config(struct comedi_device *dev, if (type != MODULE_DIGITAL) { dev_err(dev->class_dev, - "comedi%d: channel configuration accessible only for digital modules\n", - dev->minor); + "channel configuration accessible only for digital modules\n"); return -1; } channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { dev_err(dev->class_dev, - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - dev->minor, channel); + "undefined channel %d. channel range is 0 .. 23\n", + channel); return -1; } @@ -342,8 +354,7 @@ static int unioxx5_insn_config(struct comedi_device *dev, flags |= mask; break; default: - dev_err(dev->class_dev, - "comedi%d: unknown flag\n", dev->minor); + dev_err(dev->class_dev, "unknown flag\n"); return -1; } @@ -435,9 +446,10 @@ static int unioxx5_attach(struct comedi_device *dev, dev->iobase = iobase; iobase += UNIOXX5_SUBDEV_BASE; + n_subd = 0; - /* defining number of subdevices and getting they types (it must be 'g01') */ - for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { + /* getting number of subdevices with types 'g01' */ + for (i = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) { id = inb(ba + 0xE); num = inb(ba + 0xF); diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index da1d501d9e4e..71db683098d6 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -80,7 +80,6 @@ sampling rate. If you sample two channels you get 4kHz and so on. #include #include -#include #include #include #include diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 9707dd1239c4..5f85c55c1109 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -37,7 +37,6 @@ #include #include -#include #include #include #include @@ -138,7 +137,10 @@ * comedi constants */ static const struct comedi_lrange range_usbduxfast_ai_range = { - 2, {BIP_RANGE(0.75), BIP_RANGE(0.5)} + 2, { + BIP_RANGE(0.75), + BIP_RANGE(0.5) + } }; /* diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index a5363ded3668..3beeb1254152 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -1656,11 +1655,13 @@ static int usbduxsigma_auto_attach(struct comedi_device *dev, } offset = usbduxsigma_getstatusinfo(dev, 0); - if (offset < 0) + if (offset < 0) { dev_err(dev->class_dev, - "Communication to USBDUXSIGMA failed! Check firmware and cabling\n"); + "Communication to USBDUXSIGMA failed! Check firmware and cabling.\n"); + return offset; + } - dev_info(dev->class_dev, "attached, ADC_zero = %x\n", offset); + dev_info(dev->class_dev, "ADC_zero = %x\n", offset); return 0; } diff --git a/drivers/staging/comedi/kcomedilib/Makefile b/drivers/staging/comedi/kcomedilib/Makefile index 18ee99bdde08..3aff8ed08e2d 100644 --- a/drivers/staging/comedi/kcomedilib/Makefile +++ b/drivers/staging/comedi/kcomedilib/Makefile @@ -1,3 +1,5 @@ +ccflags-$(CONFIG_COMEDI_DEBUG) := -DDEBUG + obj-$(CONFIG_COMEDI_KCOMEDILIB) += kcomedilib.o kcomedilib-objs := kcomedilib_main.o diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index cd60677a3ed2..7dc5a18e69d4 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); struct comedi_device *comedi_open(const char *filename) { - struct comedi_device *dev; + struct comedi_device *dev, *retval = NULL; unsigned int minor; if (strncmp(filename, "/dev/comedi", 11) != 0) @@ -46,24 +46,27 @@ struct comedi_device *comedi_open(const char *filename) if (minor >= COMEDI_NUM_BOARD_MINORS) return NULL; - dev = comedi_dev_from_minor(minor); - - if (!dev || !dev->attached) + dev = comedi_dev_get_from_minor(minor); + if (!dev) return NULL; - if (!try_module_get(dev->driver->module)) - return NULL; + down_read(&dev->attach_lock); + if (dev->attached) + retval = dev; + else + retval = NULL; + up_read(&dev->attach_lock); - return dev; + if (retval == NULL) + comedi_dev_put(dev); + + return retval; } EXPORT_SYMBOL_GPL(comedi_open); -int comedi_close(struct comedi_device *d) +int comedi_close(struct comedi_device *dev) { - struct comedi_device *dev = (struct comedi_device *)d; - - module_put(dev->driver->module); - + comedi_dev_put(dev); return 0; } EXPORT_SYMBOL_GPL(comedi_close); @@ -73,7 +76,14 @@ static int comedi_do_insn(struct comedi_device *dev, unsigned int *data) { struct comedi_subdevice *s; - int ret = 0; + int ret; + + mutex_lock(&dev->mutex); + + if (!dev->attached) { + ret = -EINVAL; + goto error; + } /* a subdevice instruction */ if (insn->subdev >= dev->n_subdevices) { @@ -120,6 +130,7 @@ static int comedi_do_insn(struct comedi_device *dev, s->busy = NULL; error: + mutex_unlock(&dev->mutex); return ret; } @@ -169,9 +180,6 @@ int comedi_dio_bitfield2(struct comedi_device *dev, unsigned int subdev, unsigned int shift; int ret; - if (subdev >= dev->n_subdevices) - return -EINVAL; - base_channel = CR_CHAN(base_channel); n_chan = comedi_get_n_channels(dev, subdev); if (base_channel >= n_chan) @@ -211,23 +219,33 @@ int comedi_find_subdevice_by_type(struct comedi_device *dev, int type, unsigned int subd) { struct comedi_subdevice *s; + int ret = -ENODEV; - if (subd > dev->n_subdevices) - return -ENODEV; - - for (; subd < dev->n_subdevices; subd++) { - s = &dev->subdevices[subd]; - if (s->type == type) - return subd; - } - return -1; + down_read(&dev->attach_lock); + if (dev->attached) + for (; subd < dev->n_subdevices; subd++) { + s = &dev->subdevices[subd]; + if (s->type == type) { + ret = subd; + break; + } + } + up_read(&dev->attach_lock); + return ret; } EXPORT_SYMBOL_GPL(comedi_find_subdevice_by_type); int comedi_get_n_channels(struct comedi_device *dev, unsigned int subdevice) { - struct comedi_subdevice *s = &dev->subdevices[subdevice]; + int n; - return s->n_chan; + down_read(&dev->attach_lock); + if (!dev->attached || subdevice >= dev->n_subdevices) + n = 0; + else + n = dev->subdevices[subdevice].n_chan; + up_read(&dev->attach_lock); + + return n; } EXPORT_SYMBOL_GPL(comedi_get_n_channels); diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index ade00035d3bb..da6bc5855ebc 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -41,16 +41,20 @@ static int comedi_read(struct seq_file *m, void *v) "driver_name, board_name, n_subdevices"); for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) { - struct comedi_device *dev = comedi_dev_from_minor(i); + struct comedi_device *dev = comedi_dev_get_from_minor(i); + if (!dev) continue; + down_read(&dev->attach_lock); if (dev->attached) { devices_q = 1; seq_printf(m, "%2d: %-20s %-20s %4d\n", i, dev->driver->driver_name, dev->board_name, dev->n_subdevices); } + up_read(&dev->attach_lock); + comedi_dev_put(dev); } if (!devices_q) seq_puts(m, "no devices\n"); diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index 8fde55495d34..46b3da686384 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -83,8 +83,10 @@ int do_rangeinfo_ioctl(struct comedi_device *dev, } if (RANGE_LENGTH(it.range_type) != lr->length) { - DPRINTK("wrong length %d should be %d (0x%08x)\n", - RANGE_LENGTH(it.range_type), lr->length, it.range_type); + dev_dbg(dev->class_dev, + "wrong length %d should be %d (0x%08x)\n", + RANGE_LENGTH(it.range_type), + lr->length, it.range_type); return -EINVAL; } @@ -123,7 +125,8 @@ static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec) default: break; } - DPRINTK("subdevice does not support aref %i", aref); + dev_dbg(s->device->class_dev, "subdevice does not support aref %i", + aref); return 1; } diff --git a/drivers/staging/crystalhd/bc_dts_glob_lnx.h b/drivers/staging/crystalhd/bc_dts_glob_lnx.h index 981708f3ee39..92b0cff248cb 100644 --- a/drivers/staging/crystalhd/bc_dts_glob_lnx.h +++ b/drivers/staging/crystalhd/bc_dts_glob_lnx.h @@ -229,7 +229,7 @@ enum BC_DRV_CMD { DRV_CMD_REG_RD, /* Read Device Register */ DRV_CMD_REG_WR, /* Write Device Register */ DRV_CMD_FPGA_RD, /* Read FPGA Register */ - DRV_CMD_FPGA_WR, /* Wrtie FPGA Reister */ + DRV_CMD_FPGA_WR, /* Write FPGA Register */ DRV_CMD_MEM_RD, /* Read Device Memory */ DRV_CMD_MEM_WR, /* Write Device Memory */ DRV_CMD_RD_PCI_CFG, /* Read PCI Config Space */ diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 07a2f24d0d47..642f438793c3 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -798,7 +798,7 @@ static const struct crystalhd_cmd_tbl g_crystalhd_cproc_tbl[] = { * * Current gstreamer frame work does not provide any power management * related notification to user mode decoder plug-in. As a work-around - * we pass on the power mangement notification to our plug-in by completing + * we pass on the power management notification to our plug-in by completing * all outstanding requests with BC_STS_IO_USER_ABORT return code. */ enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx, @@ -1059,7 +1059,7 @@ bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx) { if (!ctx) { BCMLOG_ERR("Invalid arg..\n"); - return 0; + return false; } return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx); diff --git a/drivers/staging/crystalhd/crystalhd_cmds.h b/drivers/staging/crystalhd/crystalhd_cmds.h index 377cd9d68b08..b5bf59dbcde9 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.h +++ b/drivers/staging/crystalhd/crystalhd_cmds.h @@ -29,7 +29,7 @@ /* * NOTE:: This is the main interface file between the Linux layer - * and the harware layer. This file will use the definitions + * and the hardware layer. This file will use the definitions * from _dts_glob and dts_defs etc.. which are defined for * windows. */ diff --git a/drivers/staging/crystalhd/crystalhd_fw_if.h b/drivers/staging/crystalhd/crystalhd_fw_if.h index 4b363a5069d7..05615e2a231a 100644 --- a/drivers/staging/crystalhd/crystalhd_fw_if.h +++ b/drivers/staging/crystalhd/crystalhd_fw_if.h @@ -115,7 +115,7 @@ struct fgt_sei { unsigned char model_id; /* Model id. */ /* +unused SE based on Thomson spec */ - unsigned char color_desc_flag; /* Separate color descrition flag. */ + unsigned char color_desc_flag; /* Separate color description flag. */ unsigned char bit_depth_luma; /* Bit depth luma minus 8. */ unsigned char bit_depth_chroma; /* Bit depth chroma minus 8. */ unsigned char full_range_flag; /* Full range flag. */ diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index 043bd49843ff..8d0680d93684 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -398,7 +398,7 @@ static void crystalhd_hw_free_rx_pkt(struct crystalhd_hw *hw, * Call back from TX - IOQ deletion. * * This routine will release the TX DMA rings allocated - * druing setup_dma rings interface. + * during setup_dma rings interface. * * Memory is allocated per DMA ring basis. This is just * a place holder to be able to create the dio queues. diff --git a/drivers/staging/crystalhd/crystalhd_hw.h b/drivers/staging/crystalhd/crystalhd_hw.h index 37809442c553..d5cb68dfe695 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.h +++ b/drivers/staging/crystalhd/crystalhd_hw.h @@ -46,7 +46,7 @@ #define Cpu2HstMbx1 0x00100F04 #define MbxStat1 0x00100F08 #define Stream2Host_Intr_Sts 0x00100F24 -#define C011_RET_SUCCESS 0x0 /* Reutrn status of firmware command. */ +#define C011_RET_SUCCESS 0x0 /* Return status of firmware command. */ /* TS input status register */ #define TS_StreamAFIFOStatus 0x0010044C @@ -141,7 +141,7 @@ union link_misc_perst_deco_ctrl { uint32_t reserved0:3; /* Reserved.No Effect*/ uint32_t stop_bcm_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ - uint32_t reserved1:27; /* Reseved. No Effect*/ + uint32_t reserved1:27; /* Reserved. No Effect*/ }; uint32_t whole_reg; @@ -176,7 +176,7 @@ union link_misc_perst_decoder_ctrl { uint32_t res0:3; /* Reserved.No Effect*/ uint32_t stop_7412_clk:1; /* 1 ->Stops branch of 27MHz clk used to clk BCM7412*/ - uint32_t res1:27; /* Reseved. No Effect */ + uint32_t res1:27; /* Reserved. No Effect */ }; uint32_t whole_reg; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 190b9b924368..99eefd0291c3 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -703,7 +703,7 @@ static int chd_dec_pci_resume(struct pci_dev *pdev) } #endif -static DEFINE_PCI_DEVICE_TABLE(chd_dec_pci_id_table) = { +static const struct pci_device_id chd_dec_pci_id_table[] = { { PCI_VDEVICE(BROADCOM, 0x1612), 8 }, { 0, }, }; diff --git a/drivers/staging/crystalhd/crystalhd_lnx.h b/drivers/staging/crystalhd/crystalhd_lnx.h index bac572a8bc2e..816e1cd5db62 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.h +++ b/drivers/staging/crystalhd/crystalhd_lnx.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ /* OS specific PCI information structure and adapter information. */ struct crystalhd_adp { - /* Hardware borad/PCI specifics */ + /* Hardware board/PCI specifics */ char name[32]; struct pci_dev *pdev; diff --git a/drivers/staging/crystalhd/crystalhd_misc.c b/drivers/staging/crystalhd/crystalhd_misc.c index 51f698052aff..c3d024406337 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.c +++ b/drivers/staging/crystalhd/crystalhd_misc.c @@ -389,7 +389,7 @@ void *bc_kern_dma_alloc(struct crystalhd_adp *adp, uint32_t sz, void *temp = NULL; if (!adp || !sz || !phy_addr) { - BCMLOG_ERR("Invalide Arg..\n"); + BCMLOG_ERR("Invalid Arg..\n"); return temp; } @@ -415,7 +415,7 @@ void bc_kern_dma_free(struct crystalhd_adp *adp, uint32_t sz, void *ka, dma_addr_t phy_addr) { if (!adp || !ka || !sz || !phy_addr) { - BCMLOG_ERR("Invalide Arg..\n"); + BCMLOG_ERR("Invalid Arg..\n"); return; } diff --git a/drivers/staging/crystalhd/crystalhd_misc.h b/drivers/staging/crystalhd/crystalhd_misc.h index aa736c8855de..77ab72a2a061 100644 --- a/drivers/staging/crystalhd/crystalhd_misc.h +++ b/drivers/staging/crystalhd/crystalhd_misc.h @@ -206,7 +206,7 @@ extern void crystalhd_show_buffer(uint32_t off, uint8_t *buff, enum _chd_log_levels { BCMLOG_ERROR = 0x80000000, /* Don't disable this option */ BCMLOG_DATA = 0x40000000, /* Data, enable by default */ - BCMLOG_SPINLOCK = 0x20000000, /* Spcial case for Spin locks*/ + BCMLOG_SPINLOCK = 0x20000000, /* Special case for Spin locks*/ /* Following are allowed only in debug mode */ BCMLOG_INFO = 0x00000001, /* Generic informational */ diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c index 46a0d92173e0..c4c8c0f9c959 100644 --- a/drivers/staging/cxt1e1/comet.c +++ b/drivers/staging/cxt1e1/comet.c @@ -28,9 +28,9 @@ extern int cxt1e1_log_level; #define COMET_NUM_UNITS 5 /* Number of points per entry in table */ /* forward references */ -static void SetPwrLevel(comet_t *comet); -static void WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table); -static void WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); +static void SetPwrLevel(struct s_comet_reg *comet); +static void WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table); +static void WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]); void *TWV_table[12] = { @@ -58,7 +58,7 @@ lbo_tbl_lkup(int t1, int lbo) { return lbo - 1; } -void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, +void init_comet(void *ci, struct s_comet_reg *comet, u_int32_t port_mode, int clockmaster, u_int8_t moreParams) { u_int8_t isT1mode; @@ -159,8 +159,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* 60: t1 ALMI cfg */ /* Configure Line Coding */ - switch (port_mode) - { + switch (port_mode) { /* 1 - T1 B8ZS */ case CFG_FRAME_SF: pci_write_32((u_int32_t *) &comet->cdrc_cfg, 0); @@ -286,8 +285,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* 0x30: "BRIF cfg"; 0x20 is 'CMODE', 0x03 is (bit) rate */ /* note "rate bits can only be set once after reset" */ - if (clockmaster) - { + if (clockmaster) { /* CMODE == clockMode, 0=clock master (so all 3 others should be slave) */ /* rate = 1.544 Mb/s */ if (isT1mode) @@ -302,16 +300,17 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, /* Master Mode i.e.FPMODE=0 (@0x20) */ pci_write_32((u_int32_t *) &comet->brif_fpcfg, 0x00); - if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) - { + if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) { if (cxt1e1_log_level >= LOG_SBEBUG12) - pr_info(">> %s: clockmaster internal clock\n", __func__); + pr_info(">> %s: clockmaster internal clock\n", + __func__); /* internal oscillator */ pci_write_32((u_int32_t *) &comet->tx_time, 0x0d); } else { /* external clock source */ if (cxt1e1_log_level >= LOG_SBEBUG12) - pr_info(">> %s: clockmaster external clock\n", __func__); + pr_info(">> %s: clockmaster external clock\n", + __func__); /* loop timing(external) */ pci_write_32((u_int32_t *) &comet->tx_time, 0x09); } @@ -399,7 +398,7 @@ void init_comet(void *ci, comet_t *comet, u_int32_t port_mode, int clockmaster, ** Returns: Nothing */ static void -WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int8_t data) +WrtXmtWaveform(ci_t *ci, struct s_comet_reg *comet, u_int32_t sample, u_int32_t unit, u_int8_t data) { u_int8_t WaveformAddr; @@ -417,19 +416,20 @@ WrtXmtWaveform(ci_t *ci, comet_t *comet, u_int32_t sample, u_int32_t unit, u_int ** Returns: Nothing */ static void -WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, +WrtXmtWaveformTbl(ci_t *ci, struct s_comet_reg *comet, u_int8_t table[COMET_NUM_SAMPLES][COMET_NUM_UNITS]) { u_int32_t sample, unit; - for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) - { + for (sample = 0; sample < COMET_NUM_SAMPLES; sample++) { for (unit = 0; unit < COMET_NUM_UNITS; unit++) - WrtXmtWaveform(ci, comet, sample, unit, table[sample][unit]); + WrtXmtWaveform(ci, comet, sample, unit, + table[sample][unit]); } /* Enable transmitter and set output amplitude */ - pci_write_32((u_int32_t *) &comet->xlpg_cfg, table[COMET_NUM_SAMPLES][0]); + pci_write_32((u_int32_t *) &comet->xlpg_cfg, + table[COMET_NUM_SAMPLES][0]); } @@ -444,7 +444,7 @@ WrtXmtWaveformTbl(ci_t *ci, comet_t *comet, */ static void -WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) +WrtRcvEqualizerTbl(ci_t *ci, struct s_comet_reg *comet, u_int32_t *table) { u_int32_t ramaddr; volatile u_int32_t value; @@ -457,7 +457,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) /* for write order preservation when Optimizing driver */ pci_flush_write(ci); /* write the addr, initiate a read */ - pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); + pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, + (u_int8_t) ramaddr); /* for write order preservation when Optimizing driver */ pci_flush_write(ci); /* @@ -470,9 +471,12 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) } value = *table++; - pci_write_32((u_int32_t *) &comet->rlps_idata3, (u_int8_t) (value >> 24)); - pci_write_32((u_int32_t *) &comet->rlps_idata2, (u_int8_t) (value >> 16)); - pci_write_32((u_int32_t *) &comet->rlps_idata1, (u_int8_t) (value >> 8)); + pci_write_32((u_int32_t *) &comet->rlps_idata3, + (u_int8_t) (value >> 24)); + pci_write_32((u_int32_t *) &comet->rlps_idata2, + (u_int8_t) (value >> 16)); + pci_write_32((u_int32_t *) &comet->rlps_idata1, + (u_int8_t) (value >> 8)); pci_write_32((u_int32_t *) &comet->rlps_idata0, (u_int8_t) value); /* for write order preservation when Optimizing driver */ pci_flush_write(ci); @@ -484,7 +488,8 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) /* for write order preservation when optimizing driver */ pci_flush_write(ci); /* write the addr, initiate a read */ - pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, (u_int8_t) ramaddr); + pci_write_32((u_int32_t *) &comet->rlps_eq_iaddr, + (u_int8_t) ramaddr); /* for write order preservation when optimizing driver */ pci_flush_write(ci); @@ -508,7 +513,7 @@ WrtRcvEqualizerTbl(ci_t *ci, comet_t *comet, u_int32_t *table) */ static void -SetPwrLevel(comet_t *comet) +SetPwrLevel(struct s_comet_reg *comet) { volatile u_int32_t temp; @@ -550,12 +555,11 @@ SetPwrLevel(comet_t *comet) */ #if 0 static void -SetCometOps(comet_t *comet) +SetCometOps(struct s_comet_reg *comet) { volatile u_int8_t rd_value; - if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) - { + if (comet == mConfig.C4Func1Base + (COMET0_OFFSET >> 2)) { /* read the BRIF Configuration */ rd_value = (u_int8_t) pci_read_32((u_int32_t *) &comet->brif_cfg); rd_value &= ~0x20; diff --git a/drivers/staging/cxt1e1/comet.h b/drivers/staging/cxt1e1/comet.h index 03b9bb77a809..d5d286e47a4b 100644 --- a/drivers/staging/cxt1e1/comet.h +++ b/drivers/staging/cxt1e1/comet.h @@ -25,304 +25,313 @@ #define VINT32 volatile u_int32_t -struct s_comet_reg -{ - VINT32 gbl_cfg; /* 00 Global Cfg */ - VINT32 clkmon; /* 01 Clk Monitor */ - VINT32 rx_opt; /* 02 RX Options */ - VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */ - VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */ - VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */ - VINT32 tx_time; /* 06 TX Timing Options */ - VINT32 intr_1; /* 07 Intr Source #1 */ - VINT32 intr_2; /* 08 Intr Source #2 */ - VINT32 intr_3; /* 09 Intr Source #3 */ - VINT32 mdiag; /* 0A Master Diagnostics */ - VINT32 mtest; /* 0B Master Test */ - VINT32 adiag; /* 0C Analog Diagnostics */ - VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */ +struct s_comet_reg { + VINT32 gbl_cfg; /* 00 Global Cfg */ + VINT32 clkmon; /* 01 Clk Monitor */ + VINT32 rx_opt; /* 02 RX Options */ + VINT32 rx_line_cfg; /* 03 RX Line Interface Cfg */ + VINT32 tx_line_cfg; /* 04 TX Line Interface Cfg */ + VINT32 tx_frpass; /* 05 TX Framing & Bypass Options */ + VINT32 tx_time; /* 06 TX Timing Options */ + VINT32 intr_1; /* 07 Intr Source #1 */ + VINT32 intr_2; /* 08 Intr Source #2 */ + VINT32 intr_3; /* 09 Intr Source #3 */ + VINT32 mdiag; /* 0A Master Diagnostics */ + VINT32 mtest; /* 0B Master Test */ + VINT32 adiag; /* 0C Analog Diagnostics */ + VINT32 rev_id; /* 0D Rev/Chip Id/Global PMON Update */ #define pmon rev_id - VINT32 reset; /* 0E Reset */ - VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */ - VINT32 cdrc_cfg; /* 10 CDRC Cfg */ - VINT32 cdrc_ien; /* 11 CDRC Intr Enable */ - VINT32 cdrc_ists; /* 12 CDRC Intr Sts */ - VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */ + VINT32 reset; /* 0E Reset */ + VINT32 prgd_phctl; /* 0F PRGD Positioning/Ctl & HDLC Ctl */ + VINT32 cdrc_cfg; /* 10 CDRC Cfg */ + VINT32 cdrc_ien; /* 11 CDRC Intr Enable */ + VINT32 cdrc_ists; /* 12 CDRC Intr Sts */ + VINT32 cdrc_alos; /* 13 CDRC Alternate Loss of Signal */ - VINT32 rjat_ists; /* 14 RJAT Intr Sts */ - VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */ - VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */ - VINT32 rjat_cfg; /* 17 RJAT Cfg */ + VINT32 rjat_ists; /* 14 RJAT Intr Sts */ + VINT32 rjat_n1clk; /* 15 RJAT Reference Clk Divisor (N1) Ctl */ + VINT32 rjat_n2clk; /* 16 RJAT Output Clk Divisor (N2) Ctl */ + VINT32 rjat_cfg; /* 17 RJAT Cfg */ - VINT32 tjat_ists; /* 18 TJAT Intr Sts */ - VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */ - VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */ - VINT32 tjat_cfg; /* 1B TJAT Cfg */ + VINT32 tjat_ists; /* 18 TJAT Intr Sts */ + VINT32 tjat_n1clk; /* 19 TJAT Reference Clk Divisor (N1) Ctl */ + VINT32 tjat_n2clk; /* 1A TJAT Output Clk Divisor (N2) Ctl */ + VINT32 tjat_cfg; /* 1B TJAT Cfg */ - VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */ - VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */ - VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */ - VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */ + VINT32 rx_elst_cfg; /* 1C RX-ELST Cfg */ + VINT32 rx_elst_ists; /* 1D RX-ELST Intr Sts */ + VINT32 rx_elst_idle; /* 1E RX-ELST Idle Code */ + VINT32 _rx_elst_res1f; /* 1F RX-ELST Reserved */ - VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */ - VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */ - VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */ - VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */ - VINT32 __res24; /* 24 Reserved */ - VINT32 __res25; /* 25 Reserved */ - VINT32 __res26; /* 26 Reserved */ - VINT32 __res27; /* 27 Reserved */ + VINT32 tx_elst_cfg; /* 20 TX-ELST Cfg */ + VINT32 tx_elst_ists; /* 21 TX-ELST Intr Sts */ + VINT32 _tx_elst_res22; /* 22 TX-ELST Reserved */ + VINT32 _tx_elst_res23; /* 23 TX-ELST Reserved */ + VINT32 __res24; /* 24 Reserved */ + VINT32 __res25; /* 25 Reserved */ + VINT32 __res26; /* 26 Reserved */ + VINT32 __res27; /* 27 Reserved */ - VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */ - VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */ - VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */ - VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */ - VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */ - VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */ - VINT32 _rxce_res2E; /* 2E RXCE Reserved */ - VINT32 _rxce_res2F; /* 2F RXCE Reserved */ + VINT32 rxce1_ctl; /* 28 RXCE RX Data Link 1 Ctl */ + VINT32 rxce1_bits; /* 29 RXCE RX Data Link 1 Bit Select */ + VINT32 rxce2_ctl; /* 2A RXCE RX Data Link 2 Ctl */ + VINT32 rxce2_bits; /* 2B RXCE RX Data Link 2 Bit Select */ + VINT32 rxce3_ctl; /* 2C RXCE RX Data Link 3 Ctl */ + VINT32 rxce3_bits; /* 2D RXCE RX Data Link 3 Bit Select */ + VINT32 _rxce_res2E; /* 2E RXCE Reserved */ + VINT32 _rxce_res2F; /* 2F RXCE Reserved */ - VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */ - VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */ - VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */ - VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */ - VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */ - VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */ - VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */ - VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */ + VINT32 brif_cfg; /* 30 BRIF RX Backplane Cfg */ + VINT32 brif_fpcfg; /* 31 BRIF RX Backplane Frame Pulse Cfg */ + VINT32 brif_pfcfg; /* 32 BRIF RX Backplane Parity/F-Bit Cfg */ + VINT32 brif_tsoff; /* 33 BRIF RX Backplane Time Slot Offset */ + VINT32 brif_boff; /* 34 BRIF RX Backplane Bit Offset */ + VINT32 _brif_res35; /* 35 BRIF RX Backplane Reserved */ + VINT32 _brif_res36; /* 36 BRIF RX Backplane Reserved */ + VINT32 _brif_res37; /* 37 BRIF RX Backplane Reserved */ - VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */ - VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */ - VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */ - VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */ - VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */ - VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */ - VINT32 _txci_res3E; /* 3E TXCI Reserved */ - VINT32 _txci_res3F; /* 3F TXCI Reserved */ + VINT32 txci1_ctl; /* 38 TXCI TX Data Link 1 Ctl */ + VINT32 txci1_bits; /* 39 TXCI TX Data Link 2 Bit Select */ + VINT32 txci2_ctl; /* 3A TXCI TX Data Link 1 Ctl */ + VINT32 txci2_bits; /* 3B TXCI TX Data Link 2 Bit Select */ + VINT32 txci3_ctl; /* 3C TXCI TX Data Link 1 Ctl */ + VINT32 txci3_bits; /* 3D TXCI TX Data Link 2 Bit Select */ + VINT32 _txci_res3E; /* 3E TXCI Reserved */ + VINT32 _txci_res3F; /* 3F TXCI Reserved */ - VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */ - VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */ - VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */ - VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */ - VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */ - VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */ - VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */ - VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */ - VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */ - VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */ - VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */ - VINT32 __res_4B; /* 4B Reserved */ - VINT32 ibcd_cfg; /* 4C IBCD Cfg */ - VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */ - VINT32 ibcd_act; /* 4E IBCD Activate Code */ - VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */ + VINT32 btif_cfg; /* 40 BTIF TX Backplane Cfg */ + VINT32 btif_fpcfg; /* 41 BTIF TX Backplane Frame Pulse Cfg */ + VINT32 btif_pcfgsts; /* 42 BTIF TX Backplane Parity Cfg & Sts */ + VINT32 btif_tsoff; /* 43 BTIF TX Backplane Time Slot Offset */ + VINT32 btif_boff; /* 44 BTIF TX Backplane Bit Offset */ + VINT32 _btif_res45; /* 45 BTIF TX Backplane Reserved */ + VINT32 _btif_res46; /* 46 BTIF TX Backplane Reserved */ + VINT32 _btif_res47; /* 47 BTIF TX Backplane Reserved */ + VINT32 t1_frmr_cfg; /* 48 T1 FRMR Cfg */ + VINT32 t1_frmr_ien; /* 49 T1 FRMR Intr Enable */ + VINT32 t1_frmr_ists; /* 4A T1 FRMR Intr Sts */ + VINT32 __res_4B; /* 4B Reserved */ + VINT32 ibcd_cfg; /* 4C IBCD Cfg */ + VINT32 ibcd_ies; /* 4D IBCD Intr Enable/Sts */ + VINT32 ibcd_act; /* 4E IBCD Activate Code */ + VINT32 ibcd_deact; /* 4F IBCD Deactivate Code */ - VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */ - VINT32 sigx_acc_cos; /* 51 SIGX uP Access Sts/Change of Signaling State */ - VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect - * Addr/Ctl/Change of Signaling State */ - VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data - * Buffer/Change of Signaling State */ + VINT32 sigx_cfg; /* 50 SIGX Cfg/Change of Signaling State */ + VINT32 sigx_acc_cos; /* 51 SIGX + * uP Access Sts/Change of Signaling State */ + VINT32 sigx_iac_cos; /* 52 SIGX Channel Indirect + * Addr/Ctl/Change of Signaling State */ + VINT32 sigx_idb_cos; /* 53 SIGX Channel Indirect Data + * Buffer/Change of Signaling State */ - VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */ - VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */ - VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */ - VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */ + VINT32 t1_xbas_cfg; /* 54 T1 XBAS Cfg */ + VINT32 t1_xbas_altx; /* 55 T1 XBAS Alarm TX */ + VINT32 t1_xibc_ctl; /* 56 T1 XIBC Ctl */ + VINT32 t1_xibc_lbcode; /* 57 T1 XIBC Loopback Code */ - VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */ - VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */ - VINT32 pmon_feb_lsb; /* 5A PMON OFF/COFA/Far End Block Err Cnt (LSB) */ - VINT32 pmon_feb_msb; /* 5B PMON OFF/COFA/Far End Block Err Cnt (MSB) */ - VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */ - VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */ - VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */ - VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */ + VINT32 pmon_ies; /* 58 PMON Intr Enable/Sts */ + VINT32 pmon_fberr; /* 59 PMON Framing Bit Err Cnt */ + VINT32 pmon_feb_lsb; /* 5A PMON + * OFF/COFA/Far End Block Err Cnt (LSB) */ + VINT32 pmon_feb_msb; /* 5B PMON + * OFF/COFA/Far End Block Err Cnt (MSB) */ + VINT32 pmon_bed_lsb; /* 5C PMON Bit/Err/CRCE Cnt (LSB) */ + VINT32 pmon_bed_msb; /* 5D PMON Bit/Err/CRCE Cnt (MSB) */ + VINT32 pmon_lvc_lsb; /* 5E PMON LVC Cnt (LSB) */ + VINT32 pmon_lvc_msb; /* 5F PMON LVC Cnt (MSB) */ - VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */ - VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */ - VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */ - VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */ + VINT32 t1_almi_cfg; /* 60 T1 ALMI Cfg */ + VINT32 t1_almi_ien; /* 61 T1 ALMI Intr Enable */ + VINT32 t1_almi_ists; /* 62 T1 ALMI Intr Sts */ + VINT32 t1_almi_detsts; /* 63 T1 ALMI Alarm Detection Sts */ - VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */ - VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */ - VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */ - VINT32 t1_xboc_code; /* 67 T1 XBOC Code */ - VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */ - VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */ + VINT32 _t1_pdvd_res64; /* 64 T1 PDVD Reserved */ + VINT32 t1_pdvd_ies; /* 65 T1 PDVD Intr Enable/Sts */ + VINT32 _t1_xboc_res66; /* 66 T1 XBOC Reserved */ + VINT32 t1_xboc_code; /* 67 T1 XBOC Code */ + VINT32 _t1_xpde_res68; /* 68 T1 XPDE Reserved */ + VINT32 t1_xpde_ies; /* 69 T1 XPDE Intr Enable/Sts */ - VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */ - VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */ + VINT32 t1_rboc_ena; /* 6A T1 RBOC Enable */ + VINT32 t1_rboc_sts; /* 6B T1 RBOC Code Sts */ - VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */ - VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */ - VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect - * Addr/Ctl */ - VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data - * Buffer */ - VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */ - VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */ - VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect - * Addr/Ctl */ - VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data - * Buffer */ - VINT32 __res74; /* 74 Reserved */ - VINT32 __res75; /* 75 Reserved */ - VINT32 __res76; /* 76 Reserved */ - VINT32 __res77; /* 77 Reserved */ + VINT32 t1_tpsc_cfg; /* 6C TPSC Cfg */ + VINT32 t1_tpsc_sts; /* 6D TPSC uP Access Sts */ + VINT32 t1_tpsc_ciaddr; /* 6E TPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_tpsc_cidata; /* 6F TPSC Channel Indirect Data + * Buffer */ + VINT32 t1_rpsc_cfg; /* 70 RPSC Cfg */ + VINT32 t1_rpsc_sts; /* 71 RPSC uP Access Sts */ + VINT32 t1_rpsc_ciaddr; /* 72 RPSC Channel Indirect + * Addr/Ctl */ + VINT32 t1_rpsc_cidata; /* 73 RPSC Channel Indirect Data + * Buffer */ + VINT32 __res74; /* 74 Reserved */ + VINT32 __res75; /* 75 Reserved */ + VINT32 __res76; /* 76 Reserved */ + VINT32 __res77; /* 77 Reserved */ - VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */ - VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */ - VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */ - VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */ - VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */ - VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */ - VINT32 t1_aprm_1sec_5; /* 7E T1 APRM One Second Content MSB (Octect 5) */ - VINT32 t1_aprm_1sec_6; /* 7F T1 APRM One Second Content MSB (Octect 6) */ + VINT32 t1_aprm_cfg; /* 78 T1 APRM Cfg/Ctl */ + VINT32 t1_aprm_load; /* 79 T1 APRM Manual Load */ + VINT32 t1_aprm_ists; /* 7A T1 APRM Intr Sts */ + VINT32 t1_aprm_1sec_2; /* 7B T1 APRM One Second Content Octet 2 */ + VINT32 t1_aprm_1sec_3; /* 7C T1 APRM One Second Content Octet 3 */ + VINT32 t1_aprm_1sec_4; /* 7D T1 APRM One Second Content Octet 4 */ + VINT32 t1_aprm_1sec_5; /* 7E T1 APRM + * One Second Content MSB (Octect 5) */ + VINT32 t1_aprm_1sec_6; /* 7F T1 APRM + * One Second Content MSB (Octect 6) */ - VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */ - VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */ - VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */ - VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */ - VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */ - VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */ - VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword - * Select */ - VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */ - VINT32 __res88; /* 88 Reserved */ - VINT32 __res89; /* 89 Reserved */ - VINT32 __res8A; /* 8A Reserved */ - VINT32 __res8B; /* 8B Reserved */ + VINT32 e1_tran_cfg; /* 80 E1 TRAN Cfg */ + VINT32 e1_tran_txalarm; /* 81 E1 TRAN TX Alarm/Diagnostic Ctl */ + VINT32 e1_tran_intctl; /* 82 E1 TRAN International Ctl */ + VINT32 e1_tran_extrab; /* 83 E1 TRAN Extra Bits Ctl */ + VINT32 e1_tran_ien; /* 84 E1 TRAN Intr Enable */ + VINT32 e1_tran_ists; /* 85 E1 TRAN Intr Sts */ + VINT32 e1_tran_nats; /* 86 E1 TRAN National Bit Codeword + * Select */ + VINT32 e1_tran_nat; /* 87 E1 TRAN National Bit Codeword */ + VINT32 __res88; /* 88 Reserved */ + VINT32 __res89; /* 89 Reserved */ + VINT32 __res8A; /* 8A Reserved */ + VINT32 __res8B; /* 8B Reserved */ - VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */ - VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */ - VINT32 __res8E; /* 8E Reserved */ - VINT32 __res8F; /* 8F Reserved */ + VINT32 _t1_frmr_res8C; /* 8C T1 FRMR Reserved */ + VINT32 _t1_frmr_res8D; /* 8D T1 FRMR Reserved */ + VINT32 __res8E; /* 8E Reserved */ + VINT32 __res8F; /* 8F Reserved */ - VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */ - VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */ - VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */ - VINT32 e1_frmr_mien; /* 93 E1 FRMR Maintenance/Alarm Sts Intr Enable */ - VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */ - VINT32 e1_frmr_mists; /* 95 E1 FRMR Maintenance/Alarm Sts Indication Enable */ - VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */ - VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */ - VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */ - VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */ - VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */ - VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR National Bit Codeword Intr Enables */ - VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR National Bit Codeword Intr/Sts */ - VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */ - VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR Frame Pulse/Alarm Intr Enables */ - VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */ + VINT32 e1_frmr_aopts; /* 90 E1 FRMR Frame Alignment Options */ + VINT32 e1_frmr_mopts; /* 91 E1 FRMR Maintenance Mode Options */ + VINT32 e1_frmr_ien; /* 92 E1 FRMR Framing Sts Intr Enable */ + VINT32 e1_frmr_mien; /* 93 E1 FRMR + * Maintenance/Alarm Sts Intr Enable */ + VINT32 e1_frmr_ists; /* 94 E1 FRMR Framing Sts Intr Indication */ + VINT32 e1_frmr_mists; /* 95 E1 FRMR + * Maintenance/Alarm Sts Indication Enable */ + VINT32 e1_frmr_sts; /* 96 E1 FRMR Framing Sts */ + VINT32 e1_frmr_masts; /* 97 E1 FRMR Maintenance/Alarm Sts */ + VINT32 e1_frmr_nat_bits; /* 98 E1 FRMR International/National Bits */ + VINT32 e1_frmr_crc_lsb; /* 99 E1 FRMR CRC Err Cnt - LSB */ + VINT32 e1_frmr_crc_msb; /* 9A E1 FRMR CRC Err Cnt - MSB */ + VINT32 e1_frmr_nat_ien; /* 9B E1 FRMR + * National Bit Codeword Intr Enables */ + VINT32 e1_frmr_nat_ists; /* 9C E1 FRMR + * National Bit Codeword Intr/Sts */ + VINT32 e1_frmr_nat; /* 9D E1 FRMR National Bit Codewords */ + VINT32 e1_frmr_fp_ien; /* 9E E1 FRMR + * Frame Pulse/Alarm Intr Enables */ + VINT32 e1_frmr_fp_ists; /* 9F E1 FRMR Frame Pulse/Alarm Intr/Sts */ - VINT32 __resA0; /* A0 Reserved */ - VINT32 __resA1; /* A1 Reserved */ - VINT32 __resA2; /* A2 Reserved */ - VINT32 __resA3; /* A3 Reserved */ - VINT32 __resA4; /* A4 Reserved */ - VINT32 __resA5; /* A5 Reserved */ - VINT32 __resA6; /* A6 Reserved */ - VINT32 __resA7; /* A7 Reserved */ + VINT32 __resA0; /* A0 Reserved */ + VINT32 __resA1; /* A1 Reserved */ + VINT32 __resA2; /* A2 Reserved */ + VINT32 __resA3; /* A3 Reserved */ + VINT32 __resA4; /* A4 Reserved */ + VINT32 __resA5; /* A5 Reserved */ + VINT32 __resA6; /* A6 Reserved */ + VINT32 __resA7; /* A7 Reserved */ - VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */ - VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */ - VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */ - VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */ - VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */ - VINT32 tdpr1_data; /* AD TDPR #1 TX Data */ - VINT32 __resAE; /* AE Reserved */ - VINT32 __resAF; /* AF Reserved */ - VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */ - VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */ - VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */ - VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */ - VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */ - VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */ - VINT32 __resB6; /* B6 Reserved */ - VINT32 __resB7; /* B7 Reserved1 */ - VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */ - VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */ - VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */ - VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */ - VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */ - VINT32 tdpr3_data; /* BD TDPR #3 TX Data */ - VINT32 __resBE; /* BE Reserved */ - VINT32 __resBF; /* BF Reserved */ + VINT32 tdpr1_cfg; /* A8 TDPR #1 Cfg */ + VINT32 tdpr1_utl; /* A9 TDPR #1 Upper TX Threshold */ + VINT32 tdpr1_ltl; /* AA TDPR #1 Lower TX Threshold */ + VINT32 tdpr1_ien; /* AB TDPR #1 Intr Enable */ + VINT32 tdpr1_ists; /* AC TDPR #1 Intr Sts/UDR Clear */ + VINT32 tdpr1_data; /* AD TDPR #1 TX Data */ + VINT32 __resAE; /* AE Reserved */ + VINT32 __resAF; /* AF Reserved */ + VINT32 tdpr2_cfg; /* B0 TDPR #2 Cfg */ + VINT32 tdpr2_utl; /* B1 TDPR #2 Upper TX Threshold */ + VINT32 tdpr2_ltl; /* B2 TDPR #2 Lower TX Threshold */ + VINT32 tdpr2_ien; /* B3 TDPR #2 Intr Enable */ + VINT32 tdpr2_ists; /* B4 TDPR #2 Intr Sts/UDR Clear */ + VINT32 tdpr2_data; /* B5 TDPR #2 TX Data */ + VINT32 __resB6; /* B6 Reserved */ + VINT32 __resB7; /* B7 Reserved1 */ + VINT32 tdpr3_cfg; /* B8 TDPR #3 Cfg */ + VINT32 tdpr3_utl; /* B9 TDPR #3 Upper TX Threshold */ + VINT32 tdpr3_ltl; /* BA TDPR #3 Lower TX Threshold */ + VINT32 tdpr3_ien; /* BB TDPR #3 Intr Enable */ + VINT32 tdpr3_ists; /* BC TDPR #3 Intr Sts/UDR Clear */ + VINT32 tdpr3_data; /* BD TDPR #3 TX Data */ + VINT32 __resBE; /* BE Reserved */ + VINT32 __resBF; /* BF Reserved */ - VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */ - VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */ - VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */ - VINT32 rdlc1_data; /* C3 RDLC #1 Data */ - VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */ - VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */ - VINT32 __resC6; /* C6 Reserved */ - VINT32 __resC7; /* C7 Reserved */ - VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */ - VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */ - VINT32 rdlc2_sts; /* CA RDLC #2 Sts */ - VINT32 rdlc2_data; /* CB RDLC #2 Data */ - VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */ - VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */ - VINT32 __resCE; /* CE Reserved */ - VINT32 __resCF; /* CF Reserved */ - VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */ - VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */ - VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */ - VINT32 rdlc3_data; /* D3 RDLC #3 Data */ - VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */ - VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */ + VINT32 rdlc1_cfg; /* C0 RDLC #1 Cfg */ + VINT32 rdlc1_intctl; /* C1 RDLC #1 Intr Ctl */ + VINT32 rdlc1_sts; /* C2 RDLC #1 Sts */ + VINT32 rdlc1_data; /* C3 RDLC #1 Data */ + VINT32 rdlc1_paddr; /* C4 RDLC #1 Primary Addr Match */ + VINT32 rdlc1_saddr; /* C5 RDLC #1 Secondary Addr Match */ + VINT32 __resC6; /* C6 Reserved */ + VINT32 __resC7; /* C7 Reserved */ + VINT32 rdlc2_cfg; /* C8 RDLC #2 Cfg */ + VINT32 rdlc2_intctl; /* C9 RDLC #2 Intr Ctl */ + VINT32 rdlc2_sts; /* CA RDLC #2 Sts */ + VINT32 rdlc2_data; /* CB RDLC #2 Data */ + VINT32 rdlc2_paddr; /* CC RDLC #2 Primary Addr Match */ + VINT32 rdlc2_saddr; /* CD RDLC #2 Secondary Addr Match */ + VINT32 __resCE; /* CE Reserved */ + VINT32 __resCF; /* CF Reserved */ + VINT32 rdlc3_cfg; /* D0 RDLC #3 Cfg */ + VINT32 rdlc3_intctl; /* D1 RDLC #3 Intr Ctl */ + VINT32 rdlc3_sts; /* D2 RDLC #3 Sts */ + VINT32 rdlc3_data; /* D3 RDLC #3 Data */ + VINT32 rdlc3_paddr; /* D4 RDLC #3 Primary Addr Match */ + VINT32 rdlc3_saddr; /* D5 RDLC #3 Secondary Addr Match */ - VINT32 csu_cfg; /* D6 CSU Cfg */ - VINT32 _csu_resD7; /* D7 CSU Reserved */ + VINT32 csu_cfg; /* D6 CSU Cfg */ + VINT32 _csu_resD7; /* D7 CSU Reserved */ - VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */ - VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */ - VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */ - VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */ - VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference - * (E1 missing) */ - VINT32 _rlps_resDD; /* DD RLPS Reserved */ - VINT32 _rlps_resDE; /* DE RLPS Reserved */ - VINT32 _rlps_resDF; /* DF RLPS Reserved */ + VINT32 rlps_idata3; /* D8 RLPS Indirect Data, 24-31 */ + VINT32 rlps_idata2; /* D9 RLPS Indirect Data, 16-23 */ + VINT32 rlps_idata1; /* DA RLPS Indirect Data, 8-15 */ + VINT32 rlps_idata0; /* DB RLPS Indirect Data, 0-7 */ + VINT32 rlps_eqvr; /* DC RLPS Equalizer Voltage Reference + * (E1 missing) */ + VINT32 _rlps_resDD; /* DD RLPS Reserved */ + VINT32 _rlps_resDE; /* DE RLPS Reserved */ + VINT32 _rlps_resDF; /* DF RLPS Reserved */ - VINT32 prgd_ctl; /* E0 PRGD Ctl */ - VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */ - VINT32 prgd_shift_len; /* E2 PRGD Shift Length */ - VINT32 prgd_tap; /* E3 PRGD Tap */ - VINT32 prgd_errin; /* E4 PRGD Err Insertion */ - VINT32 _prgd_resE5; /* E5 PRGD Reserved */ - VINT32 _prgd_resE6; /* E6 PRGD Reserved */ - VINT32 _prgd_resE7; /* E7 PRGD Reserved */ - VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */ - VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */ - VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */ - VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */ - VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */ - VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */ - VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */ - VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */ + VINT32 prgd_ctl; /* E0 PRGD Ctl */ + VINT32 prgd_ies; /* E1 PRGD Intr Enable/Sts */ + VINT32 prgd_shift_len; /* E2 PRGD Shift Length */ + VINT32 prgd_tap; /* E3 PRGD Tap */ + VINT32 prgd_errin; /* E4 PRGD Err Insertion */ + VINT32 _prgd_resE5; /* E5 PRGD Reserved */ + VINT32 _prgd_resE6; /* E6 PRGD Reserved */ + VINT32 _prgd_resE7; /* E7 PRGD Reserved */ + VINT32 prgd_patin1; /* E8 PRGD Pattern Insertion #1 */ + VINT32 prgd_patin2; /* E9 PRGD Pattern Insertion #2 */ + VINT32 prgd_patin3; /* EA PRGD Pattern Insertion #3 */ + VINT32 prgd_patin4; /* EB PRGD Pattern Insertion #4 */ + VINT32 prgd_patdet1; /* EC PRGD Pattern Detector #1 */ + VINT32 prgd_patdet2; /* ED PRGD Pattern Detector #2 */ + VINT32 prgd_patdet3; /* EE PRGD Pattern Detector #3 */ + VINT32 prgd_patdet4; /* EF PRGD Pattern Detector #4 */ - VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */ - VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */ - VINT32 xlpg_pwave_addr; /* F2 XLPG Pulse Waveform Storage Write Addr */ - VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */ - VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */ - VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */ - VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */ - VINT32 _xlpg_resF7; /* F7 XLPG Reserved */ + VINT32 xlpg_cfg; /* F0 XLPG Line Driver Cfg */ + VINT32 xlpg_ctlsts; /* F1 XLPG Ctl/Sts */ + VINT32 xlpg_pwave_addr; /* F2 XLPG + * Pulse Waveform Storage Write Addr */ + VINT32 xlpg_pwave_data; /* F3 XLPG Pulse Waveform Storage Data */ + VINT32 xlpg_atest_pctl; /* F4 XLPG Analog Test Positive Ctl */ + VINT32 xlpg_atest_nctl; /* F5 XLPG Analog Test Negative Ctl */ + VINT32 xlpg_fdata_sel; /* F6 XLPG Fuse Data Select */ + VINT32 _xlpg_resF7; /* F7 XLPG Reserved */ - VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */ - VINT32 rlps_alos_thresh; /* F9 RLPS ALOS Detection/Clearance Threshold */ - VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */ - VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */ - VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */ - VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */ - VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */ - VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */ + VINT32 rlps_cfgsts; /* F8 RLPS Cfg & Sts */ + VINT32 rlps_alos_thresh; /* F9 RLPS + * ALOS Detection/Clearance Threshold */ + VINT32 rlps_alos_dper; /* FA RLPS ALOS Detection Period */ + VINT32 rlps_alos_cper; /* FB RLPS ALOS Clearance Period */ + VINT32 rlps_eq_iaddr; /* FC RLPS Equalization Indirect Addr */ + VINT32 rlps_eq_rwsel; /* FD RLPS Equalization Read/WriteB Select */ + VINT32 rlps_eq_ctlsts; /* FE RLPS Equalizer Loop Sts & Ctl */ + VINT32 rlps_eq_cfg; /* FF RLPS Equalizer Cfg */ }; -typedef struct s_comet_reg comet_t; - /* 00AH: MDIAG Register bit definitions */ #define COMET_MDIAG_ID5 0x40 #define COMET_MDIAG_LBMASK 0x3F @@ -338,7 +347,7 @@ typedef struct s_comet_reg comet_t; #ifdef __KERNEL__ extern void -init_comet(void *, comet_t *, u_int32_t, int, u_int8_t); +init_comet(void *, struct s_comet_reg *, u_int32_t, int, u_int8_t); #endif #endif /* _INC_COMET_H_ */ diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c index d021b312ffa2..95218e283966 100644 --- a/drivers/staging/cxt1e1/functions.c +++ b/drivers/staging/cxt1e1/functions.c @@ -274,7 +274,7 @@ VMETRO_TRACE (void *x) void VMETRO_TRIGGER (ci_t *ci, int x) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t data; comet = ci->port[0].cometbase; /* default to COMET # 0 */ diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index 0ba8c3ae673b..7a3a30cd0f7f 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -1,5 +1,5 @@ -unsigned int max_intcnt = 0; -unsigned int max_bh = 0; +static unsigned int max_intcnt = 0; +static unsigned int max_bh = 0; /*----------------------------------------------------------------------------- * musycc.c - diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index 4028ea11c442..a9d95753be20 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -194,7 +194,7 @@ checkPorts (ci_t *ci) * alarms conflicts with NCOMM's interrupt servicing implementation. */ - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t value; u_int32_t copyVal, LEDval; @@ -507,7 +507,7 @@ c4_cleanup (void) int c4_get_portcfg (ci_t *ci) { - comet_t *comet; + struct s_comet_reg *comet; int portnum, mask; u_int32_t wdata, rdata; @@ -561,7 +561,7 @@ c4_init (ci_t *ci, u_char *func0, u_char *func1) for (portnum = 0; portnum < MUSYCC_NPORTS; portnum++) { pi = &ci->port[portnum]; - pi->cometbase = (comet_t *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum))); + pi->cometbase = (struct s_comet_reg *) ((u_int32_t *) (func1 + COMET_OFFSET (portnum))); pi->reg = (struct musycc_globalr *) ((u_char *) ci->reg + (portnum * 0x800)); pi->portnum = portnum; pi->p.portnum = portnum; @@ -693,7 +693,7 @@ c4_init2 (ci_t *ci) int c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t loopValue; comet = ci->port[portnum].cometbase; @@ -752,7 +752,7 @@ c4_loop_port (ci_t *ci, int portnum, u_int8_t cmd) status_t c4_frame_rw (ci_t *ci, struct sbecom_port_param *pp) { - comet_t *comet; + struct s_comet_reg *comet; volatile u_int32_t data; if (pp->portnum >= ci->max_port)/* sanity check */ diff --git a/drivers/staging/cxt1e1/pmcc4_private.h b/drivers/staging/cxt1e1/pmcc4_private.h index b2b6e3702630..7edbd4e492e3 100644 --- a/drivers/staging/cxt1e1/pmcc4_private.h +++ b/drivers/staging/cxt1e1/pmcc4_private.h @@ -133,7 +133,7 @@ struct c4_port_info void *regram_saved; /* Original malloc value may have non-2KB * boundary. Need to save for use when * freeing. */ - comet_t *cometbase; + struct s_comet_reg *cometbase; struct sbe_card_info *up; /* diff --git a/drivers/staging/cxt1e1/sbeid.c b/drivers/staging/cxt1e1/sbeid.c index 6ec51bccceb1..97c5c6e7e299 100644 --- a/drivers/staging/cxt1e1/sbeid.c +++ b/drivers/staging/cxt1e1/sbeid.c @@ -20,190 +20,185 @@ #include "sbe_bid.h" char * -sbeid_get_bdname (ci_t *ci) +sbeid_get_bdname(ci_t *ci) { - char *np = NULL; + char *np = NULL; - switch (ci->brd_id) - { - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): - np = "wanPTMC-256T3 "; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): - np = "wanPTMC-256T3 "; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): - np = "wanPMC-C4T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): - np = "wanPMC-C2T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): - np = "wanPMC-C1T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): - np = "wanPCI-C4T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): - np = "wanPCI-C2T1E1"; - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): - np = "wanPCI-C1T1E1"; - break; - default: - /*** np = ""; ***/ - np = "wanPCI-CxT1E1"; - break; - } + switch (ci->brd_id) { + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + np = "wanPTMC-256T3 "; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + np = "wanPTMC-256T3 "; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + np = "wanPMC-C4T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + np = "wanPMC-C2T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + np = "wanPMC-C1T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + np = "wanPCI-C4T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + np = "wanPCI-C2T1E1"; + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + np = "wanPCI-C1T1E1"; + break; + default: + /*** np = ""; ***/ + np = "wanPCI-CxT1E1"; + break; + } - return np; + return np; } /* given the presetting of brd_id, set the corresponding hdw_id */ void -sbeid_set_hdwbid (ci_t *ci) +sbeid_set_hdwbid(ci_t *ci) { - /* - * set SBE's unique hardware identification (for legacy boards might not - * have this register implemented) - */ + /* + * set SBE's unique hardware identification (for legacy boards might not + * have this register implemented) + */ - switch (ci->brd_id) - { - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): - ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1 - * Version) */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): - ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1 - * Version) */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): - /* - * This Board ID is a generic identification. Use the found number - * of ports to further define this hardware. - */ - switch (ci->max_port) - { - default: /* shouldn't need a default, but have one - * anyway */ - case 4: - ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */ - break; - case 2: - ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); - break; - case 1: - ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); - break; - } - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): - ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): - ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ - break; + switch (ci->brd_id) { + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1): + ci->hdw_bid = SBE_BID_256T3_E1; /* 0x46 - SBE wanPTMC-256T3 (E1 + * Version) */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1): + ci->hdw_bid = SBE_BID_256T3_T1; /* 0x42 - SBE wanPTMC-256T3 (T1 + * Version) */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L): + /* + * This Board ID is a generic identification. Use the found number + * of ports to further define this hardware. + */ + switch (ci->max_port) { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0xC4 - SBE wanPMC-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + } + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C2T1E1; /* 0xC2 - SBE wanPMC-C2T1E1 */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1): + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L): + ci->hdw_bid = SBE_BID_PMC_C1T1E1; /* 0xC1 - SBE wanPMC-C1T1E1 */ + break; #ifdef SBE_PMCC4_ENABLE - /* - * This case is entered as a result of the inability to obtain the - * from the board's EEPROM. Assume a PCI board and set - * according to the number ofr found ports. - */ - case 0: - /* start by assuming 4-port for ZERO casing */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */ + /* + * This case is entered as a result of the inability to obtain the + * from the board's EEPROM. Assume a PCI board and set + * according to the number ofr found ports. + */ + case 0: + /* start by assuming 4-port for ZERO casing */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + /* drop thru to set hdw_bid and alternate PCI CxT1E1 settings */ #endif - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): - /* - * This Board ID is a generic identification. Use the number of - * found ports to further define this hardware. - */ - switch (ci->max_port) - { - default: /* shouldn't need a default, but have one - * anyway */ - case 4: - ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */ - break; - case 2: - ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); - break; - case 1: - ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); - break; - } - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): - ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ - break; - case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): - ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ - break; - default: - /*** bid = ""; ***/ - ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */ - break; - } + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1): + /* + * This Board ID is a generic identification. Use the number of + * found ports to further define this hardware. + */ + switch (ci->max_port) { + default: /* shouldn't need a default, but have one + * anyway */ + case 4: + ci->hdw_bid = SBE_BID_PCI_C4T1E1; /* 0x04 - SBE wanPCI-C4T1E1 */ + break; + case 2: + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case 1: + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; + } + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1): + ci->hdw_bid = SBE_BID_PCI_C2T1E1; /* 0x02 - SBE wanPCI-C2T1E1 */ + break; + case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1): + ci->hdw_bid = SBE_BID_PCI_C1T1E1; /* 0x01 - SBE wanPCI-C1T1E1 */ + break; + default: + /*** bid = ""; ***/ + ci->hdw_bid = SBE_BID_PMC_C4T1E1; /* 0x41 - SBE wanPTMC-C4T1E1 */ + break; + } } /* given the presetting of hdw_bid, set the corresponding brd_id */ void -sbeid_set_bdtype (ci_t *ci) +sbeid_set_bdtype(ci_t *ci) { - /* set SBE's unique PCI VENDOR/DEVID */ - switch (ci->hdw_bid) - { - case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3); - break; - case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1); - break; - case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1); - break; - case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1); - break; - case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1); - break; - case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); - break; - case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); - break; - case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - break; - case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); - break; - case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); - break; + /* set SBE's unique PCI VENDOR/DEVID */ + switch (ci->hdw_bid) { + case SBE_BID_C1T3: /* SBE wanPMC-C1T3 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3); + break; + case SBE_BID_C24TE1: /* SBE wanPTMC-C24TE1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1); + break; + case SBE_BID_256T3_E1: /* SBE wanPTMC-256T3 E1 Version */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1); + break; + case SBE_BID_256T3_T1: /* SBE wanPTMC-256T3 T1 Version */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1); + break; + case SBE_BID_PMC_C4T1E1: /* 0xC4 - SBE wanPMC-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1); + break; + case SBE_BID_PMC_C2T1E1: /* 0xC2 - SBE wanPMC-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1); + break; + case SBE_BID_PMC_C1T1E1: /* 0xC1 - SBE wanPMC-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1); + break; + case SBE_BID_PCI_C4T1E1: /* 0x04 - SBE wanPCI-C4T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + case SBE_BID_PCI_C2T1E1: /* 0x02 - SBE wanPCI-C2T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1); + break; + case SBE_BID_PCI_C1T1E1: /* 0x01 - SBE wanPCI-C1T1E1 */ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1); + break; - default: - /*** hdw_bid = ""; ***/ - ci->brd_id = SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); - break; - } + default: + /*** hdw_bid = ""; ***/ + ci->brd_id = SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1); + break; + } } diff --git a/drivers/staging/dgap/dgap_conf.h b/drivers/staging/dgap/dgap_conf.h index 88097013ed04..484ed726a4d6 100644 --- a/drivers/staging/dgap/dgap_conf.h +++ b/drivers/staging/dgap/dgap_conf.h @@ -138,7 +138,7 @@ #define CU 91 #define PRINT 92 #define XPRINT 93 -#define CMAJOR 94 +#define CMAJOR 94 #define ALTPIN 95 #define STARTO 96 #define USEINTR 97 @@ -262,9 +262,9 @@ struct cnode { } module; char *ttyname; - + char *cuname; - + char *printname; int majornumber; diff --git a/drivers/staging/dgap/dgap_driver.c b/drivers/staging/dgap/dgap_driver.c index 4c1515ee56e5..089d017fc291 100644 --- a/drivers/staging/dgap/dgap_driver.c +++ b/drivers/staging/dgap/dgap_driver.c @@ -506,7 +506,7 @@ static int dgap_found_board(struct pci_dev *pdev, int id) /* get the board structure and prep it */ brd = dgap_Board[dgap_NumBoards] = - (struct board_t *) dgap_driver_kzmalloc(sizeof(struct board_t), GFP_KERNEL); + (struct board_t *) kzalloc(sizeof(struct board_t), GFP_KERNEL); if (!brd) { APR(("memory allocation for board structure failed\n")); return(-ENOMEM); @@ -514,7 +514,7 @@ static int dgap_found_board(struct pci_dev *pdev, int id) /* make a temporary message buffer for the boot messages */ brd->msgbuf = brd->msgbuf_head = - (char *) dgap_driver_kzmalloc(sizeof(char) * 8192, GFP_KERNEL); + (char *) kzalloc(sizeof(char) * 8192, GFP_KERNEL); if(!brd->msgbuf) { kfree(brd); APR(("memory allocation for board msgbuf failed\n")); @@ -924,20 +924,6 @@ static void dgap_init_globals(void) ************************************************************************/ -/* - * dgap_driver_kzmalloc() - * - * Malloc and clear memory, - */ -void *dgap_driver_kzmalloc(size_t size, int priority) -{ - void *p = kmalloc(size, priority); - if(p) - memset(p, 0, size); - return(p); -} - - /* * dgap_mbuf() * diff --git a/drivers/staging/dgap/dgap_driver.h b/drivers/staging/dgap/dgap_driver.h index 7d631e80c00e..2f7a55a7e40d 100644 --- a/drivers/staging/dgap/dgap_driver.h +++ b/drivers/staging/dgap/dgap_driver.h @@ -578,7 +578,6 @@ struct channel_t { *************************************************************************/ extern int dgap_ms_sleep(ulong ms); -extern void *dgap_driver_kzmalloc(size_t size, int priority); extern char *dgap_ioctl_name(int cmd); extern void dgap_do_bios_load(struct board_t *brd, uchar __user *ubios, int len); extern void dgap_do_fep_load(struct board_t *brd, uchar __user *ufep, int len); diff --git a/drivers/staging/dgap/dgap_fep5.c b/drivers/staging/dgap/dgap_fep5.c index 794cf9db8b83..f75831a422e8 100644 --- a/drivers/staging/dgap/dgap_fep5.c +++ b/drivers/staging/dgap/dgap_fep5.c @@ -6,16 +6,6 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * * * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! * @@ -39,6 +29,7 @@ #include /* For copy_from_user/copy_to_user */ #include #include /* For tty_schedule_flip */ +#include #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) #include @@ -75,7 +66,7 @@ void dgap_do_config_load(uchar __user *uaddr, int len) char buf[U2BSIZE]; int n; - to_addr = dgap_config_buf = dgap_driver_kzmalloc(len + 1, GFP_ATOMIC); + to_addr = dgap_config_buf = kzalloc(len + 1, GFP_ATOMIC); if (!dgap_config_buf) { DPR_INIT(("dgap_do_config_load - unable to allocate memory for file\n")); dgap_driver_state = DRIVER_NEED_CONFIG_LOAD; @@ -99,7 +90,7 @@ void dgap_do_config_load(uchar __user *uaddr, int len) to_addr += n; from_addr += n; n = U2BSIZE; - } + } dgap_config_buf[orig_len] = '\0'; @@ -130,8 +121,8 @@ int dgap_after_config_loaded(void) /* * allocate flip buffer for board. */ - dgap_Board[i]->flipbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC); - dgap_Board[i]->flipflagbuf = dgap_driver_kzmalloc(MYFLIPLEN, GFP_ATOMIC); + dgap_Board[i]->flipbuf = kzalloc(MYFLIPLEN, GFP_ATOMIC); + dgap_Board[i]->flipflagbuf = kzalloc(MYFLIPLEN, GFP_ATOMIC); } return rc; @@ -166,9 +157,9 @@ static int dgap_usertoboard(struct board_t *brd, char *to_addr, char __user *fro /* increment counts */ len -= n; to_addr += n; - from_addr += n; + from_addr += n; n = U2BSIZE; - } + } return 0; } @@ -195,7 +186,7 @@ void dgap_do_bios_load(struct board_t *brd, uchar __user *ubios, int len) */ for (i = 0; i < 16; i++) writeb(0, addr + POSTAREA + i); - + /* * Download bios */ @@ -364,7 +355,7 @@ static void dgap_do_reset_board(struct board_t *brd) int i = 0; if (!brd || (brd->magic != DGAP_BOARD_MAGIC) || !brd->re_map_membase || !brd->re_map_port) { - DPR_INIT(("dgap_do_reset_board() start. bad values. brd: %p mem: %p io: %p\n", + DPR_INIT(("dgap_do_reset_board() start. bad values. brd: %p mem: %p io: %p\n", brd, brd ? brd->re_map_membase : 0, brd ? brd->re_map_port : 0)); return; } @@ -470,7 +461,7 @@ static void dgap_get_vpd(struct board_t *brd) /* * To get to the OTPROM memory, we have to send the boards base - * address or'ed with 1 into the PCI Rom Address location. + * address or'ed with 1 into the PCI Rom Address location. */ magic = brd->membase | 0x01; pci_write_config_dword(brd->pdev, PCI_ROM_ADDRESS, magic); @@ -492,7 +483,7 @@ static void dgap_get_vpd(struct board_t *brd) * for the VPD offset. */ while (base_offset <= EXPANSION_ROM_SIZE) { - + /* * Lots of magic numbers here. * @@ -551,7 +542,7 @@ static void dgap_get_vpd(struct board_t *brd) */ void dgap_poll_tasklet(unsigned long data) { - struct board_t *bd = (struct board_t *) data; + struct board_t *bd = (struct board_t *) data; ulong lock_flags; ulong lock_flags2; char *vaddr; @@ -816,13 +807,13 @@ out: * *=======================================================================*/ void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint ncmds) -{ +{ char *vaddr = NULL; struct cm_t *cm_addr = NULL; uint count; uint n; u16 head; - u16 tail; + u16 tail; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -833,7 +824,7 @@ void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint n if (ch->ch_bd->state == BOARD_FAILED) { DPR_CORE(("%s:%d board is in failed state.\n", __FILE__, __LINE__)); return; - } + } /* * Make sure the pointers are in range before @@ -847,13 +838,13 @@ void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint n cm_addr = (struct cm_t *) (vaddr + CMDBUF); head = readw(&(cm_addr->cm_head)); - /* + /* * Forget it if pointers out of range. */ if (head >= (CMDMAX - CMDSTART) || (head & 03)) { DPR_CORE(("%s:%d pointers out of range, failing board!\n", __FILE__, __LINE__)); ch->ch_bd->state = BOARD_FAILED; - return; + return; } /* @@ -869,7 +860,7 @@ void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint n writew(head, &(cm_addr->cm_head)); /* - * Wait if necessary before updating the head + * Wait if necessary before updating the head * pointer to limit the number of outstanding * commands to the FEP. If the time spent waiting * is outlandish, declare the FEP dead. @@ -890,14 +881,14 @@ void dgap_cmdb(struct channel_t *ch, uchar cmd, uchar byte1, uchar byte2, uint n return; } udelay(10); - } + } } /*======================================================================= * * dgap_cmdw - Sends a 1 word command to the FEP. - * + * * ch - Pointer to channel structure. * cmd - Command to be sent. * word - Integer containing word to be sent. @@ -936,7 +927,7 @@ void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds) cm_addr = (struct cm_t *) (vaddr + CMDBUF); head = readw(&(cm_addr->cm_head)); - /* + /* * Forget it if pointers out of range. */ if (head >= (CMDMAX - CMDSTART) || (head & 03)) { @@ -958,7 +949,7 @@ void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds) /* * Wait if necessary before updating the head - * pointer to limit the number of outstanding + * pointer to limit the number of outstanding * commands to the FEP. If the time spent waiting * is outlandish, declare the FEP dead. */ @@ -978,7 +969,7 @@ void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds) return; } udelay(10); - } + } } @@ -986,7 +977,7 @@ void dgap_cmdw(struct channel_t *ch, uchar cmd, u16 word, uint ncmds) /*======================================================================= * * dgap_cmdw_ext - Sends a extended word command to the FEP. - * + * * ch - Pointer to channel structure. * cmd - Command to be sent. * word - Integer containing word to be sent. @@ -1025,7 +1016,7 @@ static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) cm_addr = (struct cm_t *) (vaddr + CMDBUF); head = readw(&(cm_addr->cm_head)); - /* + /* * Forget it if pointers out of range. */ if (head >= (CMDMAX - CMDSTART) || (head & 03)) { @@ -1060,7 +1051,7 @@ static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) /* * Wait if necessary before updating the head - * pointer to limit the number of outstanding + * pointer to limit the number of outstanding * commands to the FEP. If the time spent waiting * is outlandish, declare the FEP dead. */ @@ -1080,7 +1071,7 @@ static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds) return; } udelay(10); - } + } } @@ -1102,7 +1093,7 @@ void dgap_wmove(struct channel_t *ch, char *buf, uint cnt) if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; - + /* * Check parameters. */ @@ -1172,9 +1163,9 @@ uint dgap_get_custom_baud(struct channel_t *ch) /* * Go get from fep mem, what the fep - * believes the custom baud rate is. + * believes the custom baud rate is. */ - offset = ((((*(unsigned short *)(vaddr + ECS_SEG)) << 4) + + offset = ((((*(unsigned short *)(vaddr + ECS_SEG)) << 4) + (ch->ch_portnum * 0x28) + LINE_SPEED)); value = readw(vaddr + offset); @@ -1210,7 +1201,7 @@ void dgap_firmware_reset_port(struct channel_t *ch) /*======================================================================= - * + * * dgap_param - Set Digi parameters. * * struct tty_struct * - TTY for port. @@ -1244,7 +1235,7 @@ int dgap_param(struct tty_struct *tty) if (!bd || bd->magic != DGAP_BOARD_MAGIC) return -ENXIO; - bs = ch->ch_bs; + bs = ch->ch_bs; if (!bs) return -ENXIO; @@ -1284,13 +1275,13 @@ int dgap_param(struct tty_struct *tty) /* * Now go get from fep mem, what the fep - * believes the custom baud rate is. + * believes the custom baud rate is. */ ch->ch_baud_info = ch->ch_custom_speed = dgap_get_custom_baud(ch); DPR_PARAM(("param: Got %d speed\n", ch->ch_custom_speed)); - /* Handle transition from B0 */ + /* Handle transition from B0 */ if (ch->ch_flags & CH_BAUD0) { ch->ch_flags &= ~(CH_BAUD0); ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); @@ -1352,7 +1343,7 @@ int dgap_param(struct tty_struct *tty) baud = 0; } - if (baud == 0) + if (baud == 0) baud = 9600; ch->ch_baud_info = baud; @@ -1425,7 +1416,7 @@ int dgap_param(struct tty_struct *tty) dgap_cmdw(ch, SCFLAG, (u16) cflag, 0); } - /* Handle transition from B0 */ + /* Handle transition from B0 */ if (ch->ch_flags & CH_BAUD0) { ch->ch_flags &= ~(CH_BAUD0); ch->ch_mval |= (D_RTS(ch)|D_DTR(ch)); @@ -1475,7 +1466,7 @@ int dgap_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & RTSPACE) hflow |= D_RTS(ch); if (ch->ch_digi.digi_flags & DTRPACE) - hflow |= D_DTR(ch); + hflow |= D_DTR(ch); if (ch->ch_digi.digi_flags & CTSPACE) hflow |= D_CTS(ch); if (ch->ch_digi.digi_flags & DSRPACE) @@ -1488,7 +1479,7 @@ int dgap_param(struct tty_struct *tty) /* Okay to have channel and board locks held calling this */ dgap_cmdb(ch, SHFLOW, (uchar) hflow, 0xff, 0); - } + } /* @@ -1507,7 +1498,7 @@ int dgap_param(struct tty_struct *tty) } /* - * Set modem control lines. + * Set modem control lines. */ mval ^= ch->ch_mforce & (mval ^ ch->ch_mval); @@ -1524,12 +1515,12 @@ int dgap_param(struct tty_struct *tty) } /* - * Read modem signals, and then call carrier function. + * Read modem signals, and then call carrier function. */ ch->ch_mistat = readb(&(bs->m_stat)); dgap_carrier(ch); - /* + /* * Set the start and stop characters. */ if (ch->ch_startc != ch->ch_fepstartc || ch->ch_stopc != ch->ch_fepstopc) { @@ -1542,7 +1533,7 @@ int dgap_param(struct tty_struct *tty) /* * Set the Auxiliary start and stop characters. - */ + */ if (ch->ch_astartc != ch->ch_fepastartc || ch->ch_astopc != ch->ch_fepastopc) { ch->ch_fepastartc = ch->ch_astartc; ch->ch_fepastopc = ch->ch_astopc; @@ -1609,7 +1600,7 @@ void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, unsigned char * } else { /* save value examination in next state */ ch->pscan_savechar = c; - ch->pscan_state = 2; + ch->pscan_state = 2; } break; @@ -1637,7 +1628,7 @@ void dgap_parity_scan(struct channel_t *ch, unsigned char *cbuf, unsigned char * count += 1; ch->pscan_state = 0; - } + } } *len = count; DPR_PSCAN(("dgap_parity_scan finish\n")); @@ -1721,9 +1712,8 @@ static int dgap_event(struct board_t *bd) /* * Make sure the interrupt is valid. */ - if ( port >= bd->nasync) { + if (port >= bd->nasync) goto next; - } if (!(reason & (IFMODEM | IFBREAK | IFTLW | IFTEM | IFDATA))) { goto next; @@ -1779,7 +1769,7 @@ static int dgap_event(struct board_t *bd) } /* - * Process Modem change signals. + * Process Modem change signals. */ if (reason & IFMODEM) { ch->ch_mistat = modem; @@ -1813,7 +1803,7 @@ static int dgap_event(struct board_t *bd) ch->ch_tun.un_flags &= ~UN_LOW; if (ch->ch_tun.un_flags & UN_ISOPEN) { - if ((ch->ch_tun.un_tty->flags & + if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) ch->ch_tun.un_tty->ldisc->ops->write_wakeup) @@ -1841,7 +1831,7 @@ static int dgap_event(struct board_t *bd) if (ch->ch_pun.un_flags & UN_LOW) { ch->ch_pun.un_flags &= ~UN_LOW; if (ch->ch_pun.un_flags & UN_ISOPEN) { - if ((ch->ch_pun.un_tty->flags & + if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) ch->ch_pun.un_tty->ldisc->ops->write_wakeup) @@ -1879,7 +1869,7 @@ static int dgap_event(struct board_t *bd) if (ch->ch_tun.un_flags & UN_EMPTY) { ch->ch_tun.un_flags &= ~UN_EMPTY; if (ch->ch_tun.un_flags & UN_ISOPEN) { - if ((ch->ch_tun.un_tty->flags & + if ((ch->ch_tun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) ch->ch_tun.un_tty->ldisc->ops->write_wakeup) @@ -1905,7 +1895,7 @@ static int dgap_event(struct board_t *bd) if (ch->ch_pun.un_flags & UN_EMPTY) { ch->ch_pun.un_flags &= ~UN_EMPTY; if (ch->ch_pun.un_flags & UN_ISOPEN) { - if ((ch->ch_pun.un_tty->flags & + if ((ch->ch_pun.un_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) ch->ch_pun.un_tty->ldisc->ops->write_wakeup) @@ -1945,4 +1935,4 @@ next: DGAP_UNLOCK(bd->bd_lock, lock_flags); return 0; -} +} diff --git a/drivers/staging/dgap/dgap_parse.c b/drivers/staging/dgap/dgap_parse.c index ff9d19449b43..36fd93d3f5f6 100644 --- a/drivers/staging/dgap/dgap_parse.c +++ b/drivers/staging/dgap/dgap_parse.c @@ -42,6 +42,7 @@ #include "dgap_types.h" #include "dgap_fep5.h" #include "dgap_driver.h" +#include "dgap_parse.h" #include "dgap_conf.h" diff --git a/drivers/staging/dgap/dgap_trace.c b/drivers/staging/dgap/dgap_trace.c index 0f9a9569ea27..a53db9e0a577 100644 --- a/drivers/staging/dgap/dgap_trace.c +++ b/drivers/staging/dgap/dgap_trace.c @@ -17,15 +17,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * - * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! + * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! * * This is shared code between Digi's CVS archive and the * Linux Kernel sources. * Changing the source just for reformatting needlessly breaks * our CVS diff history. * - * Send any bug fixes/changes to: Eng.Linux at digi dot com. - * Thank you. + * Send any bug fixes/changes to: Eng.Linux at digi dot com. + * Thank you. * */ @@ -37,6 +37,7 @@ #include #include "dgap_driver.h" +#include "dgap_trace.h" #define TRC_TO_CONSOLE 1 @@ -107,16 +108,16 @@ void dgap_tracef(const char *fmt, ...) dgap_trcbufi = 0; initd++; - printk("dgap: tracing enabled - " TRC_DTRC + printk("dgap: tracing enabled - " TRC_DTRC " 0x%lx 0x%x\n", - (unsigned long)dgap_trcbuf, + (unsigned long)dgap_trcbuf, dgap_trcbuf_size); } # if defined(TRC_ON_OVERFLOW_WRAP_AROUND) /* * This is the less CPU-intensive way to do things. We simply - * wrap around before we fall off the end of the buffer. A + * wrap around before we fall off the end of the buffer. A * tilde (~) demarcates the current end of the trace. * * This method should be used if you are concerned about race @@ -131,14 +132,14 @@ void dgap_tracef(const char *fmt, ...) dgap_trcbufi = 0; } - strcpy(&dgap_trcbuf[dgap_trcbufi], buf); + strcpy(&dgap_trcbuf[dgap_trcbufi], buf); dgap_trcbufi += lenbuf; dgap_trcbuf[dgap_trcbufi] = '~'; # elif defined(TRC_ON_OVERFLOW_SHIFT_BUFFER) /* * This is the more CPU-intensive way to do things. If we - * venture into the last 1/8 of the buffer, we shift the + * venture into the last 1/8 of the buffer, we shift the * last 7/8 of the buffer forward, wiping out the first 1/8. * Advantage: No wrap-around, only truncation from the * beginning. diff --git a/drivers/staging/dgap/dgap_tty.c b/drivers/staging/dgap/dgap_tty.c index 2a7a37298da4..39fb4dfb8b7e 100644 --- a/drivers/staging/dgap/dgap_tty.c +++ b/drivers/staging/dgap/dgap_tty.c @@ -17,22 +17,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * - * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! + * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! * * This is shared code between Digi's CVS archive and the * Linux Kernel sources. * Changing the source just for reformatting needlessly breaks * our CVS diff history. * - * Send any bug fixes/changes to: Eng.Linux at digi dot com. - * Thank you. + * Send any bug fixes/changes to: Eng.Linux at digi dot com. + * Thank you. */ /************************************************************************ - * + * * This file implements the tty driver functionality for the * FEP5 based product lines. - * + * ************************************************************************ * * $Id: dgap_tty.c,v 1.3 2011/06/23 12:11:31 markh Exp $ @@ -155,7 +155,7 @@ static const struct tty_operations dgap_tty_ops = { .flush_chars = dgap_tty_flush_chars, .ioctl = dgap_tty_ioctl, .set_termios = dgap_tty_set_termios, - .stop = dgap_tty_stop, + .stop = dgap_tty_stop, .start = dgap_tty_start, .throttle = dgap_tty_throttle, .unthrottle = dgap_tty_unthrottle, @@ -173,11 +173,11 @@ static const struct tty_operations dgap_tty_ops = { /************************************************************************ - * + * * TTY Initialization/Cleanup Functions - * + * ************************************************************************/ - + /* * dgap_tty_preinit() * @@ -187,7 +187,7 @@ int dgap_tty_preinit(void) { unsigned long flags; - DGAP_LOCK(dgap_global_lock, flags); + DGAP_LOCK(dgap_global_lock, flags); /* * Allocate a buffer for doing the copy from user space to @@ -202,7 +202,7 @@ int dgap_tty_preinit(void) DPR_INIT(("unable to allocate tmp write buf")); return (-ENOMEM); } - + DGAP_UNLOCK(dgap_global_lock, flags); return(0); } @@ -226,14 +226,14 @@ int dgap_tty_register(struct board_t *brd) brd->SerialDriver->name_base = 0; brd->SerialDriver->major = 0; brd->SerialDriver->minor_start = 0; - brd->SerialDriver->type = TTY_DRIVER_TYPE_SERIAL; - brd->SerialDriver->subtype = SERIAL_TYPE_NORMAL; + brd->SerialDriver->type = TTY_DRIVER_TYPE_SERIAL; + brd->SerialDriver->subtype = SERIAL_TYPE_NORMAL; brd->SerialDriver->init_termios = DgapDefaultTermios; brd->SerialDriver->driver_name = DRVSTR; brd->SerialDriver->flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); /* The kernel wants space to store pointers to tty_structs */ - brd->SerialDriver->ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); + brd->SerialDriver->ttys = kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); if (!brd->SerialDriver->ttys) return(-ENOMEM); @@ -259,14 +259,14 @@ int dgap_tty_register(struct board_t *brd) brd->PrintDriver->name_base = 0; brd->PrintDriver->major = 0; brd->PrintDriver->minor_start = 0; - brd->PrintDriver->type = TTY_DRIVER_TYPE_SERIAL; + brd->PrintDriver->type = TTY_DRIVER_TYPE_SERIAL; brd->PrintDriver->subtype = SERIAL_TYPE_NORMAL; brd->PrintDriver->init_termios = DgapDefaultTermios; brd->PrintDriver->driver_name = DRVSTR; brd->PrintDriver->flags = (TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK); /* The kernel wants space to store pointers to tty_structs */ - brd->PrintDriver->ttys = dgap_driver_kzmalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); + brd->PrintDriver->ttys = kzalloc(MAXPORTS * sizeof(struct tty_struct *), GFP_KERNEL); if (!brd->PrintDriver->ttys) return(-ENOMEM); @@ -380,7 +380,7 @@ int dgap_tty_init(struct board_t *brd) */ for (i = 0; i < brd->nasync; i++) { if (!brd->channels[i]) { - brd->channels[i] = dgap_driver_kzmalloc(sizeof(struct channel_t), GFP_ATOMIC); + brd->channels[i] = kzalloc(sizeof(struct channel_t), GFP_ATOMIC); if (!brd->channels[i]) { DPR_CORE(("%s:%d Unable to allocate memory for channel struct\n", __FILE__, __LINE__)); @@ -450,7 +450,7 @@ int dgap_tty_init(struct board_t *brd) /* * Set queue water marks, interrupt mask, - * and general tty parameters. + * and general tty parameters. */ ch->ch_tlw = tlw = ch->ch_tsize >= 2000 ? ((ch->ch_tsize * 5) / 8) : ch->ch_tsize / 2; @@ -479,7 +479,7 @@ int dgap_tty_init(struct board_t *brd) writew(0, &(ch->ch_bs->edelay)); else writew(100, &(ch->ch_bs->edelay)); - + writeb(1, &(ch->ch_bs->idata)); } @@ -506,7 +506,7 @@ void dgap_tty_post_uninit(void) * dgap_tty_uninit() * * Uninitialize the TTY portion of this driver. Free all memory and - * resources. + * resources. */ void dgap_tty_uninit(struct board_t *brd) { @@ -611,7 +611,7 @@ static void dgap_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *b if (n == 0) { return; } - + /* * Copy as much data as will fit. */ @@ -661,9 +661,9 @@ static void dgap_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *b /*======================================================================= * * dgap_input - Process received data. - * + * * ch - Pointer to channel structure. - * + * *=======================================================================*/ void dgap_input(struct channel_t *ch) @@ -704,8 +704,8 @@ void dgap_input(struct channel_t *ch) DGAP_LOCK(bd->bd_lock, lock_flags); DGAP_LOCK(ch->ch_lock, lock_flags2); - /* - * Figure the number of characters in the buffer. + /* + * Figure the number of characters in the buffer. * Exit immediately if none. */ @@ -775,13 +775,13 @@ void dgap_input(struct channel_t *ch) len = min(len, (N_TTY_BUF_SIZE - 1)); ld = tty_ldisc_ref(tp); - + #ifdef TTY_DONT_FLIP /* * If the DONT_FLIP flag is on, don't flush our buffer, and act - * like the ld doesn't have any space to put the data right now. + * like the ld doesn't have any space to put the data right now. */ - if (test_bit(TTY_DONT_FLIP, &tp->flags)) + if (test_bit(TTY_DONT_FLIP, &tp->flags)) len = 0; #endif @@ -879,9 +879,9 @@ void dgap_input(struct channel_t *ch) } -/************************************************************************ +/************************************************************************ * Determines when CARRIER changes state and takes appropriate - * action. + * action. ************************************************************************/ void dgap_carrier(struct channel_t *ch) { @@ -889,7 +889,7 @@ void dgap_carrier(struct channel_t *ch) int virt_carrier = 0; int phys_carrier = 0; - + DPR_CARR(("dgap_carrier called...\n")); if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) @@ -917,11 +917,11 @@ void dgap_carrier(struct channel_t *ch) if (ch->ch_digi.digi_flags & DIGI_FORCEDCD) { virt_carrier = 1; - } + } if (ch->ch_c_cflag & CLOCAL) { virt_carrier = 1; - } + } DPR_CARR(("DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier)); @@ -968,7 +968,7 @@ void dgap_carrier(struct channel_t *ch) * "make pretend that carrier is there". */ if ((virt_carrier == 0) && ((ch->ch_flags & CH_CD) != 0) && - (phys_carrier == 0)) + (phys_carrier == 0)) { /* @@ -991,7 +991,7 @@ void dgap_carrier(struct channel_t *ch) tty_hangup(ch->ch_tun.un_tty); } - if (ch->ch_pun.un_open_count > 0) { + if (ch->ch_pun.un_open_count > 0) { DPR_CARR(("Sending pr hangup\n")); tty_hangup(ch->ch_pun.un_tty); } @@ -1002,7 +1002,7 @@ void dgap_carrier(struct channel_t *ch) */ if (virt_carrier == 1) ch->ch_flags |= CH_FCAR; - else + else ch->ch_flags &= ~CH_FCAR; if (phys_carrier == 1) @@ -1013,9 +1013,9 @@ void dgap_carrier(struct channel_t *ch) /************************************************************************ - * + * * TTY Entry points and helper functions - * + * ************************************************************************/ /* @@ -1165,7 +1165,7 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file) */ dgap_param(tty); - /* + /* * follow protocol for opening port */ @@ -1195,13 +1195,13 @@ static int dgap_tty_open(struct tty_struct *tty, struct file *file) } -/* +/* * dgap_block_til_ready() * * Wait for DCD, if needed. */ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, struct channel_t *ch) -{ +{ int retval = 0; struct un_t *un = NULL; ulong lock_flags; @@ -1246,7 +1246,7 @@ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, struc * If either unit is in the middle of the fragile part of close, * we just cannot touch the channel safely. * Go back to sleep, knowing that when the channel can be - * touched safely, the close routine will signal the + * touched safely, the close routine will signal the * ch_wait_flags to wake us back up. */ if (!((ch->ch_tun.un_flags | ch->ch_pun.un_flags) & UN_CLOSING)) { @@ -1354,7 +1354,7 @@ static int dgap_block_til_ready(struct tty_struct *tty, struct file *file, struc * dgap_tty_hangup() * * Hangup the port. Like a close, but don't wait for output to drain. - */ + */ static void dgap_tty_hangup(struct tty_struct *tty) { struct board_t *bd; @@ -1436,7 +1436,7 @@ static void dgap_tty_close(struct tty_struct *tty, struct file *file) */ APR(("tty->count is 1, un open count is %d\n", un->un_open_count)); un->un_open_count = 1; - } + } if (--un->un_open_count < 0) { APR(("bad serial port open count of %d\n", un->un_open_count)); @@ -1497,7 +1497,7 @@ static void dgap_tty_close(struct tty_struct *tty, struct file *file) dgap_cmdb( ch, SMODEM, 0, D_DTR(ch)|D_RTS(ch), 0 ); /* - * Go to sleep to ensure RTS/DTR + * Go to sleep to ensure RTS/DTR * have been dropped for modems to see it. */ if (ch->ch_close_delay) { @@ -1535,7 +1535,7 @@ static void dgap_tty_close(struct tty_struct *tty, struct file *file) wake_up_interruptible(&un->un_flags_wait); DGAP_UNLOCK(ch->ch_lock, lock_flags); - + DPR_BASIC(("dgap_tty_close - complete\n")); } @@ -1637,7 +1637,7 @@ static int dgap_tty_chars_in_buffer(struct tty_struct *tty) } } - DPR_WRITE(("dgap_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d tsize: %d)\n", + DPR_WRITE(("dgap_tty_chars_in_buffer. Port: %x - %d (head: %d tail: %d tsize: %d)\n", ch->ch_portnum, chars, thead, ttail, ch->ch_tsize)); return(chars); } @@ -1702,14 +1702,14 @@ static int dgap_wait_for_drain(struct tty_struct *tty) } -/* +/* * dgap_maxcps_room * * Reduces bytes_available to the max number of characters * that can be sent currently given the maxcps value, and * returns the new bytes_available. This only affects printer * output. - */ + */ static int dgap_maxcps_room(struct tty_struct *tty, int bytes_available) { struct channel_t *ch = NULL; @@ -1750,7 +1750,7 @@ static int dgap_maxcps_room(struct tty_struct *tty, int bytes_available) } else { /* no room in the buffer */ - cps_limit = 0; + cps_limit = 0; } bytes_available = min(cps_limit, bytes_available); @@ -1793,7 +1793,7 @@ static inline void dgap_set_firmware_event(struct un_t *un, unsigned int event) * dgap_tty_write_room() * * Return space available in Tx buffer - */ + */ static int dgap_tty_write_room(struct tty_struct *tty) { struct channel_t *ch = NULL; @@ -1831,7 +1831,7 @@ static int dgap_tty_write_room(struct tty_struct *tty) ret = dgap_maxcps_room(tty, ret); /* - * If we are printer device, leave space for + * If we are printer device, leave space for * possibly both the on and off strings. */ if (un->un_type == DGAP_PRINT) { @@ -1856,7 +1856,7 @@ static int dgap_tty_write_room(struct tty_struct *tty) */ dgap_set_firmware_event(un, UN_LOW | UN_EMPTY); DGAP_UNLOCK(ch->ch_lock, lock_flags); - + DPR_WRITE(("dgap_tty_write_room - %d tail: %d head: %d\n", ret, tail, head)); return(ret); @@ -1867,7 +1867,7 @@ static int dgap_tty_write_room(struct tty_struct *tty) * dgap_tty_put_char() * * Put a character into ch->ch_buf - * + * * - used by the line discipline for OPOST processing */ static int dgap_tty_put_char(struct tty_struct *tty, unsigned char c) @@ -2094,7 +2094,7 @@ static int dgap_tty_write(struct tty_struct *tty, const unsigned char *buf, int if (from_user) { DGAP_UNLOCK(ch->ch_lock, lock_flags); up(&dgap_TmpWriteSem); - } + } else { DGAP_UNLOCK(ch->ch_lock, lock_flags); } @@ -2206,12 +2206,12 @@ static int dgap_tty_tiocmset(struct tty_struct *tty, struct file *file, if (set & TIOCM_RTS) { ch->ch_mforce |= D_RTS(ch); ch->ch_mval |= D_RTS(ch); - } + } if (set & TIOCM_DTR) { ch->ch_mforce |= D_DTR(ch); ch->ch_mval |= D_DTR(ch); - } + } if (clear & TIOCM_RTS) { ch->ch_mforce |= D_RTS(ch); @@ -2316,7 +2316,7 @@ static void dgap_tty_wait_until_sent(struct tty_struct *tty, int timeout) /* * dgap_send_xchar() - * + * * send a high priority character, called by ld. */ static void dgap_tty_send_xchar(struct tty_struct *tty, char c) @@ -2529,7 +2529,7 @@ static int dgap_set_modem_info(struct tty_struct *tty, unsigned int command, uns /* - * dgap_tty_digigeta() + * dgap_tty_digigeta() * * Ioctl to get the information for ditty. * @@ -2571,7 +2571,7 @@ static int dgap_tty_digigeta(struct tty_struct *tty, struct digi_t __user *retin /* - * dgap_tty_digiseta() + * dgap_tty_digiseta() * * Ioctl to set the information for ditty. * @@ -2614,10 +2614,10 @@ static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i memcpy(&ch->ch_digi, &new_digi, sizeof(struct digi_t)); - if (ch->ch_digi.digi_maxcps < 1) + if (ch->ch_digi.digi_maxcps < 1) ch->ch_digi.digi_maxcps = 1; - if (ch->ch_digi.digi_maxcps > 10000) + if (ch->ch_digi.digi_maxcps > 10000) ch->ch_digi.digi_maxcps = 10000; if (ch->ch_digi.digi_bufsize < 10) @@ -2647,7 +2647,7 @@ static int dgap_tty_digiseta(struct tty_struct *tty, struct digi_t __user *new_i /* - * dgap_tty_digigetedelay() + * dgap_tty_digigetedelay() * * Ioctl to get the current edelay setting. * @@ -2689,7 +2689,7 @@ static int dgap_tty_digigetedelay(struct tty_struct *tty, int __user *retinfo) /* - * dgap_tty_digisetedelay() + * dgap_tty_digisetedelay() * * Ioctl to set the EDELAY setting * @@ -2783,7 +2783,7 @@ static int dgap_tty_digigetcustombaud(struct tty_struct *tty, int __user *retinf /* - * dgap_tty_digisetcustombaud() + * dgap_tty_digisetcustombaud() * * Ioctl to set the custom baud rate setting */ @@ -2898,7 +2898,7 @@ static void dgap_tty_throttle(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -2938,7 +2938,7 @@ static void dgap_tty_unthrottle(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -2979,7 +2979,7 @@ static void dgap_tty_start(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -3016,7 +3016,7 @@ static void dgap_tty_stop(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -3039,7 +3039,7 @@ static void dgap_tty_stop(struct tty_struct *tty) } -/* +/* * dgap_tty_flush_chars() * * Flush the cook buffer @@ -3066,7 +3066,7 @@ static void dgap_tty_flush_chars(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -3092,7 +3092,7 @@ static void dgap_tty_flush_chars(struct tty_struct *tty) /* * dgap_tty_flush_buffer() - * + * * Flush Tx buffer (make in == out) */ static void dgap_tty_flush_buffer(struct tty_struct *tty) @@ -3110,7 +3110,7 @@ static void dgap_tty_flush_buffer(struct tty_struct *tty) un = tty->driver_data; if (!un || un->magic != DGAP_UNIT_MAGIC) return; - + ch = un->un_ch; if (!ch || ch->magic != DGAP_CHANNEL_MAGIC) return; @@ -3153,7 +3153,7 @@ static void dgap_tty_flush_buffer(struct tty_struct *tty) * The IOCTL function and all of its helpers * *****************************************************************************/ - + /* * dgap_tty_ioctl() * @@ -3186,7 +3186,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, if (!bd || bd->magic != DGAP_BOARD_MAGIC) return (-ENODEV); - DPR_IOCTL(("dgap_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl start on port %d - cmd %s (%x), arg %lx\n", ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); DGAP_LOCK(bd->bd_lock, lock_flags); @@ -3205,7 +3205,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, case TCSBRK: /* - * TCSBRK is SVID version: non-zero arg --> no break + * TCSBRK is SVID version: non-zero arg --> no break * this behaviour is exploited by tcdrain(). * * According to POSIX.1 spec (7.2.2.1.2) breaks should be @@ -3236,7 +3236,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, DGAP_UNLOCK(ch->ch_lock, lock_flags2); DGAP_UNLOCK(bd->bd_lock, lock_flags); - DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); return(0); @@ -3270,7 +3270,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, DGAP_UNLOCK(ch->ch_lock, lock_flags2); DGAP_UNLOCK(bd->bd_lock, lock_flags); - DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); return(0); @@ -3303,11 +3303,11 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, DGAP_UNLOCK(ch->ch_lock, lock_flags2); DGAP_UNLOCK(bd->bd_lock, lock_flags); - DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); return 0; - + case TIOCCBRK: /* * FEP5 doesn't support turning off a break unconditionally. @@ -3343,7 +3343,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, DGAP_UNLOCK(bd->bd_lock, lock_flags); return(0); - + case TIOCMGET: DGAP_UNLOCK(ch->ch_lock, lock_flags2); DGAP_UNLOCK(bd->bd_lock, lock_flags); @@ -3359,8 +3359,8 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, /* * Here are any additional ioctl's that we want to implement */ - - case TCFLSH: + + case TCFLSH: /* * The linux tty driver doesn't have a flush * input routine for the driver, assuming all backed @@ -3369,7 +3369,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, * act on the ioctl, but then lie and say we didn't * so the line discipline will process the flush * also. - */ + */ rc = tty_check_change(tty); if (rc) { DGAP_UNLOCK(ch->ch_lock, lock_flags2); @@ -3407,13 +3407,13 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, tty_wakeup(tty); DGAP_LOCK(bd->bd_lock, lock_flags); DGAP_LOCK(ch->ch_lock, lock_flags2); - } + } - /* pretend we didn't recognize this IOCTL */ + /* pretend we didn't recognize this IOCTL */ DGAP_UNLOCK(ch->ch_lock, lock_flags2); DGAP_UNLOCK(bd->bd_lock, lock_flags); - DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl (LINE:%d) finish on port %d - cmd %s (%x), arg %lx\n", __LINE__, ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); return(-ENOIOCTLCMD); @@ -3445,7 +3445,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, return(-EINTR); } - DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl finish on port %d - cmd %s (%x), arg %lx\n", ch->ch_portnum, dgap_ioctl_name(cmd), cmd, arg)); /* pretend we didn't recognize this */ @@ -3462,7 +3462,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, } /* pretend we didn't recognize this */ - return(-ENOIOCTLCMD); + return(-ENOIOCTLCMD); case TCXONC: /* @@ -3572,7 +3572,7 @@ static int dgap_tty_ioctl(struct tty_struct *tty, unsigned int cmd, DGAP_UNLOCK(bd->bd_lock, lock_flags); DPR_IOCTL(("dgap_tty_ioctl - in default\n")); - DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n", + DPR_IOCTL(("dgap_tty_ioctl end - cmd %s (%x), arg %lx\n", dgap_ioctl_name(cmd), cmd, arg)); return(-ENOIOCTLCMD); diff --git a/drivers/staging/dgap/downld.c b/drivers/staging/dgap/downld.c index 638c5da43c85..1f4aa2eca437 100644 --- a/drivers/staging/dgap/downld.c +++ b/drivers/staging/dgap/downld.c @@ -24,7 +24,7 @@ ** ** This is the daemon that sends the fep, bios, and concentrator images ** from user space to the driver. -** BUGS: +** BUGS: ** If the file changes in the middle of the download, you probably ** will get what you deserve. ** @@ -121,7 +121,7 @@ struct downld_t *dp; /* conc. download */ /* - * The same for either the FEP or the BIOS. + * The same for either the FEP or the BIOS. * Append the downldio header, issue the ioctl, then free * the buffer. Not horribly CPU efficient, but quite RAM efficient. */ @@ -136,7 +136,7 @@ void squirt(int req_type, int bdid, struct image_info *ii) /* * If this binary comes from a file, stat it to see how * large it is. Yes, we intentionally do this each - * time for the binary may change between loads. + * time for the binary may change between loads. */ if (ii->pathname) { @@ -144,7 +144,7 @@ void squirt(int req_type, int bdid, struct image_info *ii) if (sfd < 0 ) { myperror(ii->pathname); - goto squirt_end; + goto squirt_end; } if (fstat(sfd, &sb) == -1 ) { @@ -152,7 +152,7 @@ void squirt(int req_type, int bdid, struct image_info *ii) goto squirt_end; } - ii->len = sb.st_size ; + ii->len = sb.st_size; } size_buf = ii->len + sizeof(struct downldio); @@ -165,7 +165,7 @@ void squirt(int req_type, int bdid, struct image_info *ii) dliop = (struct downldio *) malloc(size_buf); if (dliop == NULL) { - fprintf(stderr,"%s: can't get %d bytes of memory; aborting\n", + fprintf(stderr,"%s: can't get %d bytes of memory; aborting\n", pgm, size_buf); exit (1); } @@ -185,7 +185,7 @@ void squirt(int req_type, int bdid, struct image_info *ii) if (debugflag) printf("sending %d bytes of %s %s from %s\n", - ii->len, + ii->len, (ii->type == IFEP) ? "FEP" : (ii->type == IBIOS) ? "BIOS" : "CONFIG", ii->name ? ii->name : "", (ii->pathname) ? ii->pathname : "internal image" ); @@ -209,13 +209,13 @@ squirt_end: /* - * See if we need to reload the download image in core - * + * See if we need to reload the download image in core + * */ void consider_file_rescan(struct image_info *ii) { - int sfd ; - int len ; + int sfd; + int len; struct stat sb; /* This operation only makes sense when we're working from a file */ @@ -232,14 +232,14 @@ void consider_file_rescan(struct image_info *ii) myperror(ii->pathname); exit(1); } - - /* If the file hasn't changed since we last did this, - * and we have not done a free() on the image, bail + + /* If the file hasn't changed since we last did this, + * and we have not done a free() on the image, bail */ if (ii->image && (sb.st_mtime == ii->mtime)) goto end_rescan; - ii->len = len = sb.st_size ; + ii->len = len = sb.st_size; /* Record the timestamp of the file */ ii->mtime = sb.st_mtime; @@ -249,12 +249,12 @@ void consider_file_rescan(struct image_info *ii) * have a memory leak. */ if ( ii->image ) { - free( ii->image ); + free( ii->image ); /* ii->image = NULL; */ /* not necessary */ } - /* This image will be kept only long enough for the - * download to happen. After sending the last block, + /* This image will be kept only long enough for the + * download to happen. After sending the last block, * it will be freed */ ii->image = malloc(len) ; @@ -267,14 +267,14 @@ void consider_file_rescan(struct image_info *ii) } if (read(sfd, ii->image, len) < len) { - fprintf(stderr,"%s: read error on %s; aborting\n", + fprintf(stderr,"%s: read error on %s; aborting\n", pgm, ii->pathname); exit (1); } end_rescan: close(sfd); - + } } @@ -284,12 +284,12 @@ end_rescan: struct image_info * find_conc_image() { - int x ; - struct image_info *i = NULL ; + int x; + struct image_info *i = NULL; for ( x = 0; x < nimages; x++ ) { i=&image_list[x]; - + if(i->type != ICONC) continue; @@ -305,8 +305,8 @@ struct image_info * find_conc_image() */ if ((dp->dl_type != 'P' ) && ( ip->dl_srev == dp->dl_srev )) return i; - } - return NULL ; + } + return NULL; } @@ -378,7 +378,7 @@ int main(int argc, char **argv) ** the list before built in images so that the command line images ** can override the built in ones. */ - + /* allocate space for the list */ nimages = argc - 2; @@ -390,15 +390,15 @@ int main(int argc, char **argv) nimages += count; /* Really should just remove the variable "image_list".... robertl */ - image_list = images ; - + image_list = images; + /* get the images from the command line */ for(x = 2; x < argc; x++) { - int xx; + int xx; /* - * strip off any leading path information for - * determining file type + * strip off any leading path information for + * determining file type */ if( (fname = strrchr(argv[x],'/')) == NULL) fname = argv[x]; @@ -406,18 +406,18 @@ int main(int argc, char **argv) fname++; /* skip the slash */ for (xx = 0; xx < count; xx++) { - if (strcmp(fname, images[xx].fname) == 0 ) { + if (strcmp(fname, images[xx].fname) == 0 ) { images[xx].pathname = argv[x]; /* image should be NULL until */ /* space is malloced */ - images[xx].image = NULL ; + images[xx].image = NULL; } } } sleep(3); - + /* ** Endless loop: get a request from the fep, and service that request. */ @@ -425,7 +425,7 @@ int main(int argc, char **argv) /* get the request */ if (debugflag) printf("b4 get ioctl..."); - + if (ioctl(fd,DIGI_DLREQ_GET, &dlio) == -1 ) { if (errorprint) { fprintf(stderr, @@ -438,7 +438,7 @@ int main(int argc, char **argv) if (debugflag) printf("dlio.req_type is %d bd %d\n", dlio.req_type,dlio.bdid); - + switch(dlio.req_type) { case DLREQ_BIOS: /* @@ -447,18 +447,18 @@ int main(int argc, char **argv) for ( x = 0; x < nimages; x++ ) { if(image_list[x].type != IBIOS) continue; - - if ((dlio.image.fi.type & FAMILY) == + + if ((dlio.image.fi.type & FAMILY) == image_list[x].family) { - - if ( image_list[x].family == T_CX ) { - if ((dlio.image.fi.type & BUSTYPE) + + if ( image_list[x].family == T_CX ) { + if ((dlio.image.fi.type & BUSTYPE) == T_PCIBUS ) { - if ( image_list[x].subtype + if ( image_list[x].subtype == T_PCIBUS ) break; } - else { + else { break; } } @@ -466,15 +466,15 @@ int main(int argc, char **argv) /* If subtype of image is T_PCIBUS, it is */ /* a PCI EPC image, so the board must */ /* have bus type T_PCIBUS to match */ - if ((dlio.image.fi.type & BUSTYPE) + if ((dlio.image.fi.type & BUSTYPE) == T_PCIBUS ) { - if ( image_list[x].subtype + if ( image_list[x].subtype == T_PCIBUS ) break; } - else { + else { /* NON PCI EPC doesn't use PCI image */ - if ( image_list[x].subtype + if ( image_list[x].subtype != T_PCIBUS ) break; } @@ -484,12 +484,12 @@ int main(int argc, char **argv) } else if ((dlio.image.fi.type & SUBTYPE) == image_list[x].subtype) { /* PCXR board will break out of the loop here */ - if ( image_list[x].subtype == T_PCXR ) { + if ( image_list[x].subtype == T_PCXR ) { break; } } } - + if ( x >= nimages) { /* ** no valid images exist @@ -514,7 +514,7 @@ int main(int argc, char **argv) } squirt(dlio.req_type, dlio.bdid, &image_list[x]); break ; - + case DLREQ_FEP: /* ** find the fep image for this type @@ -522,17 +522,17 @@ int main(int argc, char **argv) for ( x = 0; x < nimages; x++ ) { if(image_list[x].type != IFEP) continue; - if( (dlio.image.fi.type & FAMILY) == + if( (dlio.image.fi.type & FAMILY) == image_list[x].family ) { - if ( image_list[x].family == T_CX ) { + if ( image_list[x].family == T_CX ) { /* C/X PCI board */ - if ((dlio.image.fi.type & BUSTYPE) + if ((dlio.image.fi.type & BUSTYPE) == T_PCIBUS ) { if ( image_list[x].subtype == T_PCIBUS ) break; } - else { + else { /* Regular CX */ break; } @@ -541,15 +541,15 @@ int main(int argc, char **argv) /* If subtype of image is T_PCIBUS, it is */ /* a PCI EPC image, so the board must */ /* have bus type T_PCIBUS to match */ - if ((dlio.image.fi.type & BUSTYPE) + if ((dlio.image.fi.type & BUSTYPE) == T_PCIBUS ) { - if ( image_list[x].subtype + if ( image_list[x].subtype == T_PCIBUS ) break; } - else { + else { /* NON PCI EPC doesn't use PCI image */ - if ( image_list[x].subtype + if ( image_list[x].subtype != T_PCIBUS ) break; } @@ -559,12 +559,12 @@ int main(int argc, char **argv) } else if ((dlio.image.fi.type & SUBTYPE) == image_list[x].subtype) { /* PCXR board will break out of the loop here */ - if ( image_list[x].subtype == T_PCXR ) { + if ( image_list[x].subtype == T_PCXR ) { break; } } } - + if ( x >= nimages) { /* ** no valid images exist @@ -613,7 +613,7 @@ int main(int argc, char **argv) } break; - + case DLREQ_CONFIG: for ( x = 0; x < nimages; x++ ) { if(image_list[x].type != ICONFIG) @@ -658,15 +658,15 @@ int main(int argc, char **argv) */ for ( x = 0; x < nimages; x++ ) { ii=&image_list[x]; - + if(image_list[x].type != ICONC) continue; - + consider_file_rescan(ii) ; - + ip = (struct downld_t *) image_list[x].image; if (ip == NULL) continue; - + /* * When I removed Clusterport, I kept only the * code that I was SURE wasn't ClusterPort. @@ -674,11 +674,11 @@ int main(int argc, char **argv) */ if ((dp->dl_type != 'P' ) && - (ip->dl_lrev <= dp->dl_lrev ) && + (ip->dl_lrev <= dp->dl_lrev ) && ( dp->dl_lrev <= ip->dl_hrev)) break; } - + if ( x >= nimages ) { /* ** No valid images exist @@ -691,7 +691,7 @@ int main(int argc, char **argv) } continue; } - + } else { /* ** find image version required @@ -706,40 +706,40 @@ int main(int argc, char **argv) continue; } } - + /* ** download block of image */ - + offset = 1024 * dp->dl_seq; - + /* ** test if block requested within image */ - if ( offset < ii->len ) { - + if ( offset < ii->len ) { + /* ** if it is, determine block size, set segment, ** set size, set pointers, and copy block */ if (( bsize = ii->len - offset ) > 1024 ) bsize = 1024; - + /* ** copy image version info to download area */ dp->dl_srev = ip->dl_srev; dp->dl_lrev = ip->dl_lrev; dp->dl_hrev = ip->dl_hrev; - + dp->dl_seg = (64 * dp->dl_seq) + ip->dl_seg; dp->dl_size = bsize; - + down = (char *)&dp->dl_data[0]; image = (char *)((char *)ip + offset); - + memcpy(down, image, bsize); - } + } else { /* ** Image has been downloaded, set segment and @@ -747,24 +747,24 @@ int main(int argc, char **argv) */ dp->dl_seg = ip->dl_seg; dp->dl_size = 0; - + /* Now, we can release the concentrator */ /* image from memory if we're running */ /* from filesystem images */ - + if (ii->pathname) if (ii->image) { free(ii->image); - ii->image = NULL ; - } + ii->image = NULL; + } } - + if (debugflag) printf( "sending conc dl section %d to %s from %s\n", dp->dl_seq, ii->name, ii->pathname ? ii->pathname : "Internal Image"); - + if (ioctl(fd, DIGI_DLREQ_SET, &dlio) == -1 ) { if (errorprint) { fprintf(stderr, diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index fdc1aabc7fde..708adbbcedbd 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -119,7 +119,10 @@ static inline void cls_set_cts_flow_control(struct channel_t *ch) /* Write old LCR value back out, which turns enhanced access off */ writeb(lcrb, &ch->ch_cls_uart->lcr); - /* Enable interrupts for CTS flow, turn off interrupts for received XOFF chars */ + /* + * Enable interrupts for CTS flow, turn off interrupts for + * received XOFF chars + */ ier |= (UART_EXAR654_IER_CTSDSR); ier &= ~(UART_EXAR654_IER_XOFF); writeb(ier, &ch->ch_cls_uart->ier); @@ -167,7 +170,10 @@ static inline void cls_set_ixon_flow_control(struct channel_t *ch) /* Write old LCR value back out, which turns enhanced access off */ writeb(lcrb, &ch->ch_cls_uart->lcr); - /* Disable interrupts for CTS flow, turn on interrupts for received XOFF chars */ + /* + * Disable interrupts for CTS flow, turn on interrupts for + * received XOFF chars + */ ier &= ~(UART_EXAR654_IER_CTSDSR); ier |= (UART_EXAR654_IER_XOFF); writeb(ier, &ch->ch_cls_uart->ier); @@ -207,7 +213,10 @@ static inline void cls_set_no_output_flow_control(struct channel_t *ch) /* Write old LCR value back out, which turns enhanced access off */ writeb(lcrb, &ch->ch_cls_uart->lcr); - /* Disable interrupts for CTS flow, turn off interrupts for received XOFF chars */ + /* + * Disable interrupts for CTS flow, turn off interrupts for + * received XOFF chars + */ ier &= ~(UART_EXAR654_IER_CTSDSR); ier &= ~(UART_EXAR654_IER_XOFF); writeb(ier, &ch->ch_cls_uart->ier); @@ -220,8 +229,8 @@ static inline void cls_set_no_output_flow_control(struct channel_t *ch) &ch->ch_cls_uart->isr_fcr); ch->ch_r_watermark = 0; - ch->ch_t_tlevel = 16; - ch->ch_r_tlevel = 16; + ch->ch_t_tlevel = 16; + ch->ch_r_tlevel = 16; } @@ -350,8 +359,8 @@ static inline void cls_set_no_input_flow_control(struct channel_t *ch) UART_16654_FCR_TXTRIGGER_16 | UART_FCR_CLEAR_RCVR), &ch->ch_cls_uart->isr_fcr); - ch->ch_t_tlevel = 16; - ch->ch_r_tlevel = 16; + ch->ch_t_tlevel = 16; + ch->ch_r_tlevel = 16; } @@ -380,12 +389,13 @@ static inline void cls_clear_break(struct channel_t *ch, int force) /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { - if ((jiffies >= ch->ch_stop_sending_break) || force) { + if (time_after(jiffies, ch->ch_stop_sending_break) || force) { uchar temp = readb(&ch->ch_cls_uart->lcr); - writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); + writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags &= ~(CH_BREAK_SENDING); ch->ch_stop_sending_break = 0; - DPR_IOCTL(("Finishing UART_LCR_SBC! finished: %lx\n", jiffies)); + DPR_IOCTL(("Finishing UART_LCR_SBC! finished: %lx\n", + jiffies)); } } DGNC_UNLOCK(ch->ch_lock, lock_flags); @@ -420,7 +430,8 @@ static inline void cls_parse_isr(struct dgnc_board *brd, uint port) if (isr & UART_IIR_NO_INT) break; - DPR_INTR(("%s:%d port: %x isr: %x\n", __FILE__, __LINE__, port, isr)); + DPR_INTR(("%s:%d port: %x isr: %x\n", __FILE__, __LINE__, + port, isr)); /* Receive Interrupt pending */ if (isr & (UART_IIR_RDI | UART_IIR_RDI_TIMEOUT)) { @@ -473,11 +484,11 @@ static void cls_param(struct tty_struct *tty) uchar uart_lcr = 0; uchar ier = 0; uchar uart_ier = 0; - uint baud = 9600; + uint baud = 9600; int quot = 0; - struct dgnc_board *bd; + struct dgnc_board *bd; struct channel_t *ch; - struct un_t *un; + struct un_t *un; if (!tty || tty->magic != TTY_MAGIC) return; @@ -495,7 +506,8 @@ static void cls_param(struct tty_struct *tty) return; DPR_PARAM(("param start: tdev: %x cflags: %x oflags: %x iflags: %x\n", - ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, ch->ch_c_iflag)); + ch->ch_tun.un_dev, ch->ch_c_cflag, ch->ch_c_oflag, + ch->ch_c_iflag)); /* * If baud rate is zero, flush queues, and set mval to drop DTR. @@ -506,7 +518,7 @@ static void cls_param(struct tty_struct *tty) ch->ch_w_head = ch->ch_w_tail = 0; cls_flush_uart_write(ch); - cls_flush_uart_read(ch); + cls_flush_uart_read(ch); /* The baudrate is B0 so all modem lines are to be dropped. */ ch->ch_flags |= (CH_BAUD0); @@ -558,8 +570,12 @@ static void cls_param(struct tty_struct *tty) 4800, 9600, 19200, 38400 } }; - /* Only use the TXPrint baud rate if the terminal unit is NOT open */ - if (!(ch->ch_tun.un_flags & UN_ISOPEN) && (un->un_type == DGNC_PRINT)) + /* + * Only use the TXPrint baud rate if the terminal + * unit is NOT open + */ + if (!(ch->ch_tun.un_flags & UN_ISOPEN) && + (un->un_type == DGNC_PRINT)) baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; else baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; @@ -572,7 +588,8 @@ static void cls_param(struct tty_struct *tty) jindex = baud; - if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && (jindex < 16)) { + if ((iindex >= 0) && (iindex < 4) && (jindex >= 0) && + (jindex < 16)) { baud = bauds[iindex][jindex]; } else { DPR_IOCTL(("baud indices were out of range (%d)(%d)", @@ -598,13 +615,11 @@ static void cls_param(struct tty_struct *tty) } } - if (ch->ch_c_cflag & PARENB) { + if (ch->ch_c_cflag & PARENB) lcr |= UART_LCR_PARITY; - } - if (!(ch->ch_c_cflag & PARODD)) { + if (!(ch->ch_c_cflag & PARODD)) lcr |= UART_LCR_EPAR; - } /* * Not all platforms support mark/space parity, @@ -648,31 +663,28 @@ static void cls_param(struct tty_struct *tty) writeb((quot & 0xff), &ch->ch_cls_uart->txrx); writeb((quot >> 8), &ch->ch_cls_uart->ier); writeb(lcr, &ch->ch_cls_uart->lcr); - } + } if (uart_lcr != lcr) writeb(lcr, &ch->ch_cls_uart->lcr); - if (ch->ch_c_cflag & CREAD) { + if (ch->ch_c_cflag & CREAD) ier |= (UART_IER_RDI | UART_IER_RLSI); - } - else { + else ier &= ~(UART_IER_RDI | UART_IER_RLSI); - } /* * Have the UART interrupt on modem signal changes ONLY when * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set. */ - if ((ch->ch_digi.digi_flags & CTSPACE) || (ch->ch_digi.digi_flags & RTSPACE) || - (ch->ch_c_cflag & CRTSCTS) || !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) || + if ((ch->ch_digi.digi_flags & CTSPACE) || + (ch->ch_digi.digi_flags & RTSPACE) || + (ch->ch_c_cflag & CRTSCTS) || + !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) || !(ch->ch_c_cflag & CLOCAL)) - { - ier |= UART_IER_MSI; - } - else { - ier &= ~UART_IER_MSI; - } + ier |= UART_IER_MSI; + else + ier &= ~UART_IER_MSI; ier |= UART_IER_THRI; @@ -681,29 +693,33 @@ static void cls_param(struct tty_struct *tty) if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) { cls_set_cts_flow_control(ch); - } - else if (ch->ch_c_iflag & IXON) { - /* If start/stop is set to disable, then we should disable flow control */ - if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) + } else if (ch->ch_c_iflag & IXON) { + /* + * If start/stop is set to disable, then we should + * disable flow control + */ + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) cls_set_no_output_flow_control(ch); else cls_set_ixon_flow_control(ch); - } - else { + } else { cls_set_no_output_flow_control(ch); } if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) { cls_set_rts_flow_control(ch); - } - else if (ch->ch_c_iflag & IXOFF) { - /* If start/stop is set to disable, then we should disable flow control */ - if ((ch->ch_startc == _POSIX_VDISABLE) || (ch->ch_stopc == _POSIX_VDISABLE)) + } else if (ch->ch_c_iflag & IXOFF) { + /* + * If start/stop is set to disable, then we should disable + * flow control + */ + if ((ch->ch_startc == _POSIX_VDISABLE) || + (ch->ch_stopc == _POSIX_VDISABLE)) cls_set_no_input_flow_control(ch); else cls_set_ixoff_flow_control(ch); - } - else { + } else { cls_set_no_input_flow_control(ch); } @@ -719,7 +735,7 @@ static void cls_param(struct tty_struct *tty) */ static void cls_tasklet(unsigned long data) { - struct dgnc_board *bd = (struct dgnc_board *) data; + struct dgnc_board *bd = (struct dgnc_board *) data; struct channel_t *ch; ulong lock_flags; int i; @@ -802,7 +818,8 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) unsigned long lock_flags; if (!brd) { - APR(("Received interrupt (%d) with null board associated\n", irq)); + APR(("Received interrupt (%d) with null board associated\n", + irq)); return IRQ_NONE; } @@ -810,7 +827,9 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) * Check to make sure its for us. */ if (brd->magic != DGNC_BOARD_MAGIC) { - APR(("Received interrupt (%d) with a board pointer that wasn't ours!\n", irq)); + APR(( + "Received interrupt (%d) with a board pointer " + "that wasn't ours!\n", irq)); return IRQ_NONE; } @@ -826,7 +845,9 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) /* If 0, no interrupts pending */ if (!poll_reg) { - DPR_INTR(("Kernel interrupted to me, but no pending interrupts...\n")); + DPR_INTR(( + "Kernel interrupted to me, but no pending " + "interrupts...\n")); DGNC_UNLOCK(brd->bd_intr_lock, lock_flags); return IRQ_NONE; } @@ -834,9 +855,8 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) DPR_INTR(("%s:%d poll_reg: %x\n", __FILE__, __LINE__, poll_reg)); /* Parse each port to find out what caused the interrupt */ - for (i = 0; i < brd->nasync; i++) { + for (i = 0; i < brd->nasync; i++) cls_parse_isr(brd, i); - } /* * Schedule tasklet to more in-depth servicing at a better time. @@ -868,8 +888,8 @@ static void cls_enable_receiver(struct channel_t *ch) static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) { - int qleft = 0; - uchar linestatus = 0; + int qleft = 0; + uchar linestatus = 0; uchar error_mask = 0; ushort head; ushort tail; @@ -885,7 +905,8 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) tail = ch->ch_r_tail; /* Store how much space we have left in the queue */ - if ((qleft = tail - head - 1) < 0) + qleft = (tail - head - 1); + if (qleft < 0) qleft += RQUEUEMASK + 1; /* @@ -912,9 +933,9 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) } /* - * If our queue is full, we have no choice but to drop some data. - * The assumption is that HWFLOW or SWFLOW should have stopped - * things way way before we got to this point. + * If our queue is full, we have no choice but to drop some + * data. The assumption is that HWFLOW or SWFLOW should have + * stopped things way way before we got to this point. * * I decided that I wanted to ditch the oldest data first, * I hope thats okay with everyone? Yes? Good. @@ -928,13 +949,16 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) qleft++; } - ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE | UART_LSR_FE); + ch->ch_equeue[head] = linestatus & (UART_LSR_BI | UART_LSR_PE + | UART_LSR_FE); ch->ch_rqueue[head] = readb(&ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART READ", ch->ch_rqueue + head, 1); + dgnc_sniff_nowait_nolock(ch, "UART READ", + ch->ch_rqueue + head, 1); qleft--; - DPR_READ(("DATA/LSR pair: %x %x\n", ch->ch_rqueue[head], ch->ch_equeue[head])); + DPR_READ(("DATA/LSR pair: %x %x\n", ch->ch_rqueue[head], + ch->ch_equeue[head])); if (ch->ch_equeue[head] & UART_LSR_PE) ch->ch_err_parity++; @@ -966,22 +990,19 @@ static int cls_drain(struct tty_struct *tty, uint seconds) { ulong lock_flags; struct channel_t *ch; - struct un_t *un; + struct un_t *un; int rc = 0; - if (!tty || tty->magic != TTY_MAGIC) { + if (!tty || tty->magic != TTY_MAGIC) return -ENXIO; - } un = (struct un_t *) tty->driver_data; - if (!un || un->magic != DGNC_UNIT_MAGIC) { + if (!un || un->magic != DGNC_UNIT_MAGIC) return -ENXIO; - } ch = un->un_ch; - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) { + if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return -ENXIO; - } DGNC_LOCK(ch->ch_lock, lock_flags); un->un_flags |= UN_EMPTY; @@ -990,24 +1011,25 @@ static int cls_drain(struct tty_struct *tty, uint seconds) /* * NOTE: Do something with time passed in. */ - rc = wait_event_interruptible(un->un_flags_wait, ((un->un_flags & UN_EMPTY) == 0)); + rc = wait_event_interruptible(un->un_flags_wait, + ((un->un_flags & UN_EMPTY) == 0)); /* If ret is non-zero, user ctrl-c'ed us */ if (rc) DPR_IOCTL(("%d Drain - User ctrl c'ed\n", __LINE__)); - return rc; + return rc; } /* Channel lock MUST be held before calling this function! */ static void cls_flush_uart_write(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) { + if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - } - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), &ch->ch_cls_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), + &ch->ch_cls_uart->isr_fcr); udelay(10); ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); @@ -1017,9 +1039,8 @@ static void cls_flush_uart_write(struct channel_t *ch) /* Channel lock MUST be held before calling this function! */ static void cls_flush_uart_read(struct channel_t *ch) { - if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) { + if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - } /* * For complete POSIX compatibility, we should be purging the @@ -1032,7 +1053,8 @@ static void cls_flush_uart_read(struct channel_t *ch) * So for now, we will leave the code #ifdef'ed out... */ #if 0 - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), &ch->ch_cls_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR), + &ch->ch_cls_uart->isr_fcr); #endif udelay(10); } @@ -1059,7 +1081,8 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) } /* If port is "stopped", don't send any data to the UART */ - if ((ch->ch_flags & CH_FORCED_STOP) || (ch->ch_flags & CH_BREAK_SENDING)) { + if ((ch->ch_flags & CH_FORCED_STOP) || + (ch->ch_flags & CH_BREAK_SENDING)) { DGNC_UNLOCK(ch->ch_lock, lock_flags); return; } @@ -1071,10 +1094,10 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) n = 32; - /* cache head and tail of queue */ - head = ch->ch_w_head & WQUEUEMASK; - tail = ch->ch_w_tail & WQUEUEMASK; - qlen = (head - tail) & WQUEUEMASK; + /* cache head and tail of queue */ + head = ch->ch_w_head & WQUEUEMASK; + tail = ch->ch_w_tail & WQUEUEMASK; + qlen = (head - tail) & WQUEUEMASK; /* Find minimum of the FIFO space, versus queue length */ n = min(n, qlen); @@ -1083,7 +1106,8 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) /* * If RTS Toggle mode is on, turn on RTS now if not already set, - * and make sure we get an event when the data transfer has completed. + * and make sure we get an event when the data transfer has + * completed. */ if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) { if (!(ch->ch_mostat & UART_MCR_RTS)) { @@ -1095,7 +1119,8 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) /* * If DTR Toggle mode is on, turn on DTR now if not already set, - * and make sure we get an event when the data transfer has completed. + * and make sure we get an event when the data transfer has + * completed. */ if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) { if (!(ch->ch_mostat & UART_MCR_DTR)) { @@ -1105,7 +1130,8 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_tun.un_flags |= (UN_EMPTY); } writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_cls_uart->txrx); - dgnc_sniff_nowait_nolock(ch, "UART WRITE", ch->ch_wqueue + ch->ch_w_tail, 1); + dgnc_sniff_nowait_nolock(ch, "UART WRITE", + ch->ch_wqueue + ch->ch_w_tail, 1); DPR_WRITE(("Tx data: %x\n", ch->ch_wqueue[ch->ch_w_tail])); ch->ch_w_tail++; ch->ch_w_tail &= WQUEUEMASK; @@ -1125,17 +1151,20 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) static void cls_parse_modem(struct channel_t *ch, uchar signals) { - volatile uchar msignals = signals; + uchar msignals = signals; + ulong lock_flags; if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; - DPR_MSIGS(("cls_parse_modem: port: %d signals: %d\n", ch->ch_portnum, msignals)); + DPR_MSIGS(("cls_parse_modem: port: %d signals: %d\n", + ch->ch_portnum, msignals)); /* * Do altpin switching. Altpin switches DCD and DSR. * This prolly breaks DSRPACE, so we should be more clever here. */ + DGNC_LOCK(ch->ch_lock, lock_flags); if (ch->ch_digi.digi_flags & DIGI_ALTPIN) { uchar mswap = signals; if (mswap & UART_MSR_DDCD) { @@ -1155,10 +1184,15 @@ static void cls_parse_modem(struct channel_t *ch, uchar signals) msignals |= UART_MSR_DCD; } } + DGNC_UNLOCK(ch->ch_lock, lock_flags); - /* Scrub off lower bits. They signify delta's, which I don't care about */ + /* + * Scrub off lower bits. They signify delta's, which I don't + * care about + */ signals &= 0xf0; + DGNC_LOCK(ch->ch_lock, lock_flags); if (msignals & UART_MSR_DCD) ch->ch_mistat |= UART_MSR_DCD; else @@ -1178,9 +1212,11 @@ static void cls_parse_modem(struct channel_t *ch, uchar signals) ch->ch_mistat |= UART_MSR_CTS; else ch->ch_mistat &= ~UART_MSR_CTS; + DGNC_UNLOCK(ch->ch_lock, lock_flags); - DPR_MSIGS(("Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", + DPR_MSIGS(( + "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", ch->ch_portnum, !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), @@ -1204,7 +1240,7 @@ static void cls_assert_modem_signals(struct channel_t *ch) if (ch->ch_flags & CH_LOOPBACK) out |= UART_MCR_LOOP; - writeb(out, &ch->ch_cls_uart->mcr); + writeb(out, &ch->ch_cls_uart->mcr); /* Give time for the UART to actually drop the signals */ udelay(10); @@ -1219,7 +1255,7 @@ static void cls_send_start_character(struct channel_t *ch) if (ch->ch_startc != _POSIX_VDISABLE) { ch->ch_xon_sends++; writeb(ch->ch_startc, &ch->ch_cls_uart->txrx); - } + } } @@ -1231,7 +1267,7 @@ static void cls_send_stop_character(struct channel_t *ch) if (ch->ch_stopc != _POSIX_VDISABLE) { ch->ch_xoff_sends++; writeb(ch->ch_stopc, &ch->ch_cls_uart->txrx); - } + } } @@ -1259,10 +1295,11 @@ static void cls_uart_init(struct channel_t *ch) /* Write old LCR value back out, which turns enhanced access off */ writeb(lcrb, &ch->ch_cls_uart->lcr); - /* Clear out UART and FIFO */ + /* Clear out UART and FIFO */ readb(&ch->ch_cls_uart->txrx); - writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), &ch->ch_cls_uart->isr_fcr); + writeb((UART_FCR_ENABLE_FIFO|UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT), + &ch->ch_cls_uart->isr_fcr); udelay(10); ch->ch_flags |= (CH_FIFO_ENABLED | CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); @@ -1302,8 +1339,7 @@ static uint cls_get_uart_bytes_left(struct channel_t *ch) if (ch->ch_flags & CH_TX_FIFO_EMPTY) tasklet_schedule(&ch->ch_bd->helper_tasklet); left = 1; - } - else { + } else { ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); left = 0; } @@ -1333,10 +1369,11 @@ static void cls_send_break(struct channel_t *ch, int msecs) writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags &= ~(CH_BREAK_SENDING); ch->ch_stop_sending_break = 0; - DPR_IOCTL(("Finishing UART_LCR_SBC! finished: %lx\n", jiffies)); + DPR_IOCTL(("Finishing UART_LCR_SBC! finished: %lx\n", + jiffies)); } return; - } + } /* * Set the time we should stop sending the break. @@ -1350,7 +1387,9 @@ static void cls_send_break(struct channel_t *ch, int msecs) uchar temp = readb(&ch->ch_cls_uart->lcr); writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags |= (CH_BREAK_SENDING); - DPR_IOCTL(("Port %d. Starting UART_LCR_SBC! start: %lx should end: %lx\n", + DPR_IOCTL(( + "Port %d. Starting UART_LCR_SBC! start: %lx " + "should end: %lx\n", ch->ch_portnum, jiffies, ch->ch_stop_sending_break)); } } @@ -1373,8 +1412,8 @@ static void cls_send_immediate_char(struct channel_t *ch, unsigned char c) static void cls_vpd(struct dgnc_board *brd) { - ulong vpdbase; /* Start of io base of the card */ - u8 __iomem *re_map_vpdbase;/* Remapped memory of the card */ + ulong vpdbase; /* Start of io base of the card */ + u8 __iomem *re_map_vpdbase;/* Remapped memory of the card */ int i = 0; @@ -1389,12 +1428,12 @@ static void cls_vpd(struct dgnc_board *brd) if (!re_map_vpdbase) return; - /* Store the VPD into our buffer */ - for (i = 0; i < 0x40; i++) { + /* Store the VPD into our buffer */ + for (i = 0; i < 0x40; i++) { brd->vpd[i] = readb(re_map_vpdbase + i); - printk("%x ", brd->vpd[i]); - } - printk("\n"); + pr_info("%x ", brd->vpd[i]); + } + pr_info("\n"); if (re_map_vpdbase) iounmap(re_map_vpdbase); diff --git a/drivers/staging/dgnc/dgnc_trace.c b/drivers/staging/dgnc/dgnc_trace.c index a98b7d4255c8..2f62f2a43542 100644 --- a/drivers/staging/dgnc/dgnc_trace.c +++ b/drivers/staging/dgnc/dgnc_trace.c @@ -35,6 +35,7 @@ #include #include "dgnc_driver.h" +#include "dgnc_trace.h" #define TRC_TO_CONSOLE 1 @@ -63,16 +64,16 @@ void dgnc_tracef(const char *fmt, ...) void dgnc_tracef(const char *fmt, ...) { - va_list ap; - char buf[TRC_MAXMSG+1]; - size_t lenbuf; - int i; - static int failed = FALSE; + va_list ap; + char buf[TRC_MAXMSG+1]; + size_t lenbuf; + int i; + static int failed = FALSE; # if defined(TRC_TO_KMEM) unsigned long flags; #endif - if(failed) + if (failed) return; # if defined(TRC_TO_KMEM) DGNC_LOCK(dgnc_tracef_lock, flags); @@ -86,7 +87,7 @@ void dgnc_tracef(const char *fmt, ...) # if defined(TRC_TO_KMEM) { - static int initd=0; + static int initd = 0; /* * Now, in addition to (or instead of) printing this stuff out @@ -95,7 +96,7 @@ void dgnc_tracef(const char *fmt, ...) */ if (!initd) { dgnc_trcbuf = (char *) vmalloc(dgnc_trcbuf_size); - if(!dgnc_trcbuf) { + if (!dgnc_trcbuf) { failed = TRUE; printk("dgnc: tracing init failed!\n"); return; @@ -179,6 +180,6 @@ void dgnc_tracef(const char *fmt, ...) */ void dgnc_tracer_free(void) { - if(dgnc_trcbuf) + if (dgnc_trcbuf) vfree(dgnc_trcbuf); } diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c index 08eedf0867e6..b60a8da6350a 100644 --- a/drivers/staging/dgrp/dgrp_driver.c +++ b/drivers/staging/dgrp/dgrp_driver.c @@ -23,7 +23,6 @@ #include #include #include -#include /* * PortServer includes diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 33ac7fb88cbd..1f61b89eca44 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -2232,6 +2232,177 @@ done: return rtn; } +/* + * Common Packet Handling code + */ + +static void handle_data_in_packet(struct nd_struct *nd, struct ch_struct *ch, + long dlen, long plen, int n1, u8 *dbuf) +{ + char *error; + long n; + long remain; + u8 *buf; + u8 *b; + + remain = nd->nd_remain; + nd->nd_tx_work = 1; + + /* + * Otherwise data should appear only when we are + * in the CS_READY state. + */ + + if (ch->ch_state < CS_READY) { + error = "Data received before RWIN established"; + nd->nd_remain = 0; + nd->nd_state = NS_SEND_ERROR; + nd->nd_error = error; + } + + /* + * Assure that the data received is within the + * allowable window. + */ + + n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; + + if (dlen > n) { + error = "Receive data overrun"; + nd->nd_remain = 0; + nd->nd_state = NS_SEND_ERROR; + nd->nd_error = error; + } + + /* + * If we received 3 or less characters, + * assume it is a human typing, and set RTIME + * to 10 milliseconds. + * + * If we receive 10 or more characters, + * assume its not a human typing, and set RTIME + * to 100 milliseconds. + */ + + if (ch->ch_edelay != DGRP_RTIME) { + if (ch->ch_rtime != ch->ch_edelay) { + ch->ch_rtime = ch->ch_edelay; + ch->ch_flag |= CH_PARAM; + } + } else if (dlen <= 3) { + if (ch->ch_rtime != 10) { + ch->ch_rtime = 10; + ch->ch_flag |= CH_PARAM; + } + } else { + if (ch->ch_rtime != DGRP_RTIME) { + ch->ch_rtime = DGRP_RTIME; + ch->ch_flag |= CH_PARAM; + } + } + + /* + * If a portion of the packet is outside the + * buffer, shorten the effective length of the + * data packet to be the amount of data received. + */ + + if (remain < plen) + dlen -= plen - remain; + + /* + * Detect if receive flush is now complete. + */ + + if ((ch->ch_flag & CH_RX_FLUSH) != 0 && + ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= + ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { + ch->ch_flag &= ~CH_RX_FLUSH; + } + + /* + * If we are ready to receive, move the data into + * the receive buffer. + */ + + ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; + + if (ch->ch_state == CS_READY && + (ch->ch_tun.un_open_count != 0) && + (ch->ch_tun.un_flag & UN_CLOSING) == 0 && + (ch->ch_cflag & CF_CREAD) != 0 && + (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && + (ch->ch_send & RR_RX_FLUSH) == 0) { + + if (ch->ch_rin + dlen >= RBUF_MAX) { + n = RBUF_MAX - ch->ch_rin; + + memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); + + ch->ch_rin = 0; + dbuf += n; + dlen -= n; + } + + memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); + + ch->ch_rin += dlen; + + + /* + * If we are not in fastcook mode, or + * if there is a fastcook thread + * waiting for data, send the data to + * the line discipline. + */ + + if ((ch->ch_flag & CH_FAST_READ) == 0 || + ch->ch_inwait != 0) { + dgrp_input(ch); + } + + /* + * If there is a read thread waiting + * in select, and we are in fastcook + * mode, wake him up. + */ + + if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && + (ch->ch_flag & CH_FAST_READ) != 0) + wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); + + /* + * Wake any thread waiting in the + * fastcook loop. + */ + + if ((ch->ch_flag & CH_INPUT) != 0) { + ch->ch_flag &= ~CH_INPUT; + wake_up_interruptible(&ch->ch_flag_wait); + } + } + + /* + * Fabricate and insert a data packet header to + * preced the remaining data when it comes in. + */ + + if (remain < plen) { + dlen = plen - remain; + b = buf; + + b[0] = 0x90 + n1; + put_unaligned_be16(dlen, b + 1); + + remain = 3; + if (remain > 0 && b != buf) + memcpy(buf, b, remain); + + nd->nd_remain = remain; + return; + } +} + /** * dgrp_receive() -- decode data packets received from the remote PortServer. * @nd: pointer to a node structure @@ -2306,7 +2477,8 @@ static void dgrp_receive(struct nd_struct *nd) plen = dlen + 1; dbuf = b + 1; - goto data; + handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); + break; /* * Process 2-byte header data packet. @@ -2320,7 +2492,8 @@ static void dgrp_receive(struct nd_struct *nd) plen = dlen + 2; dbuf = b + 2; - goto data; + handle_data_in_packet(nd, ch, dlen, plen, n1, dbuf); + break; /* * Process 3-byte header data packet. @@ -2335,159 +2508,6 @@ static void dgrp_receive(struct nd_struct *nd) dbuf = b + 3; - /* - * Common packet handling code. - */ - -data: - nd->nd_tx_work = 1; - - /* - * Otherwise data should appear only when we are - * in the CS_READY state. - */ - - if (ch->ch_state < CS_READY) { - error = "Data received before RWIN established"; - goto prot_error; - } - - /* - * Assure that the data received is within the - * allowable window. - */ - - n = (ch->ch_s_rwin - ch->ch_s_rin) & 0xffff; - - if (dlen > n) { - error = "Receive data overrun"; - goto prot_error; - } - - /* - * If we received 3 or less characters, - * assume it is a human typing, and set RTIME - * to 10 milliseconds. - * - * If we receive 10 or more characters, - * assume its not a human typing, and set RTIME - * to 100 milliseconds. - */ - - if (ch->ch_edelay != DGRP_RTIME) { - if (ch->ch_rtime != ch->ch_edelay) { - ch->ch_rtime = ch->ch_edelay; - ch->ch_flag |= CH_PARAM; - } - } else if (dlen <= 3) { - if (ch->ch_rtime != 10) { - ch->ch_rtime = 10; - ch->ch_flag |= CH_PARAM; - } - } else { - if (ch->ch_rtime != DGRP_RTIME) { - ch->ch_rtime = DGRP_RTIME; - ch->ch_flag |= CH_PARAM; - } - } - - /* - * If a portion of the packet is outside the - * buffer, shorten the effective length of the - * data packet to be the amount of data received. - */ - - if (remain < plen) - dlen -= plen - remain; - - /* - * Detect if receive flush is now complete. - */ - - if ((ch->ch_flag & CH_RX_FLUSH) != 0 && - ((ch->ch_flush_seq - nd->nd_seq_out) & SEQ_MASK) >= - ((nd->nd_seq_in - nd->nd_seq_out) & SEQ_MASK)) { - ch->ch_flag &= ~CH_RX_FLUSH; - } - - /* - * If we are ready to receive, move the data into - * the receive buffer. - */ - - ch->ch_s_rin = (ch->ch_s_rin + dlen) & 0xffff; - - if (ch->ch_state == CS_READY && - (ch->ch_tun.un_open_count != 0) && - (ch->ch_tun.un_flag & UN_CLOSING) == 0 && - (ch->ch_cflag & CF_CREAD) != 0 && - (ch->ch_flag & (CH_BAUD0 | CH_RX_FLUSH)) == 0 && - (ch->ch_send & RR_RX_FLUSH) == 0) { - - if (ch->ch_rin + dlen >= RBUF_MAX) { - n = RBUF_MAX - ch->ch_rin; - - memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, n); - - ch->ch_rin = 0; - dbuf += n; - dlen -= n; - } - - memcpy(ch->ch_rbuf + ch->ch_rin, dbuf, dlen); - - ch->ch_rin += dlen; - - - /* - * If we are not in fastcook mode, or - * if there is a fastcook thread - * waiting for data, send the data to - * the line discipline. - */ - - if ((ch->ch_flag & CH_FAST_READ) == 0 || - ch->ch_inwait != 0) { - dgrp_input(ch); - } - - /* - * If there is a read thread waiting - * in select, and we are in fastcook - * mode, wake him up. - */ - - if (waitqueue_active(&ch->ch_tun.un_tty->read_wait) && - (ch->ch_flag & CH_FAST_READ) != 0) - wake_up_interruptible(&ch->ch_tun.un_tty->read_wait); - - /* - * Wake any thread waiting in the - * fastcook loop. - */ - - if ((ch->ch_flag & CH_INPUT) != 0) { - ch->ch_flag &= ~CH_INPUT; - - wake_up_interruptible(&ch->ch_flag_wait); - } - } - - /* - * Fabricate and insert a data packet header to - * preced the remaining data when it comes in. - */ - - if (remain < plen) { - dlen = plen - remain; - b = buf; - - b[0] = 0x90 + n1; - put_unaligned_be16(dlen, b + 1); - - remain = 3; - goto done; - } break; /* diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index 0d52de3729c6..7a9694c1d9c4 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c @@ -371,7 +371,7 @@ static void drp_param(struct ch_struct *ch) ch->ch_flag |= CH_BAUD0; } } else if (ch->ch_custom_speed) { - ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed ; + ch->ch_brate = PORTSERVER_DIVIDEND / ch->ch_custom_speed; if (ch->ch_flag & CH_BAUD0) { ch->ch_mout |= DM_DTR | DM_RTS; @@ -752,7 +752,7 @@ static int dgrp_tty_open(struct tty_struct *tty, struct file *file) if (ch->ch_open_error != 0 && otype == ch->ch_otype) { retval = (ch->ch_open_error <= 2) ? - delay_error : -ENXIO ; + delay_error : -ENXIO; goto unlock; } diff --git a/drivers/staging/dwc2/TODO b/drivers/staging/dwc2/TODO deleted file mode 100644 index 282470d55315..000000000000 --- a/drivers/staging/dwc2/TODO +++ /dev/null @@ -1,33 +0,0 @@ -TODO: - - Dan Carpenter would like to see some cleanups to the microframe - scheduler code: - http://www.mail-archive.com/linux-usb@vger.kernel.org/msg26650.html - - - Should merge the NAK holdoff patch from Raspberry Pi - (http://marc.info/?l=linux-usb&m=137625067103833). But as it stands - that patch is incomplete, it needs more investigation to see if it - can be made to work for non-Raspberry Pi platforms that lack the - special FIQ interrupt that the Pi has. Without this patch, the driver - has a high interrupt rate (8K/sec). - - - The Raspberry Pi platform needs to have support for its FIQ interrupt - added, to get the same level of functionality as the downstream - driver. The raspberrypi.org developers have indicated they are - willing to help with that. - - - Some of the default driver parameters (see 'struct dwc2_core_params' - in core.h) won't work for many platforms. So DT attributes will need - to be added for some of these. But that can be done as-needed as new - platforms are added. - - - Eventually the driver should be merged with the s3c-hsotg peripheral - mode driver, so that both modes of operation can be supported with a - single driver. But I think that can wait till after the driver has - been moved to mainline. - - - After that, OTG support can be added. I'm not sure how much demand - there is for that, though, so I have that as a low priority. - -Please send any patches for this driver to Paul Zimmerman -and Greg Kroah-Hartman . And please CC linux-usb - too. diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README index 8da96a6d2c92..3befc45fab8a 100644 --- a/drivers/staging/et131x/README +++ b/drivers/staging/et131x/README @@ -13,10 +13,6 @@ TODO: - Implement NAPI support - In et131x_tx(), don't return NETDEV_TX_BUSY, just drop the packet with kfree_skb(). - Reduce the number of split lines by careful consideration of variable names etc. - - Do this in et131x.c: - struct fbr_lookup *fbr; - fbr = rx_local->fbr[id]; - Then replace all the instances of "rx_local->fbr[id]" with fbr. Please send patches to: Greg Kroah-Hartman diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index ab8b29d2cb26..e516bb69f3b4 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -54,7 +54,6 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include #include #include @@ -813,20 +812,21 @@ static void et131x_rx_dma_enable(struct et131x_adapter *adapter) { /* Setup the receive dma configuration register for normal operation */ u32 csr = ET_RXDMA_CSR_FBR1_ENABLE; + struct rx_ring *rx_ring = &adapter->rx_ring; - if (adapter->rx_ring.fbr[1]->buffsize == 4096) + if (rx_ring->fbr[1]->buffsize == 4096) csr |= ET_RXDMA_CSR_FBR1_SIZE_LO; - else if (adapter->rx_ring.fbr[1]->buffsize == 8192) + else if (rx_ring->fbr[1]->buffsize == 8192) csr |= ET_RXDMA_CSR_FBR1_SIZE_HI; - else if (adapter->rx_ring.fbr[1]->buffsize == 16384) + else if (rx_ring->fbr[1]->buffsize == 16384) csr |= ET_RXDMA_CSR_FBR1_SIZE_LO | ET_RXDMA_CSR_FBR1_SIZE_HI; csr |= ET_RXDMA_CSR_FBR0_ENABLE; - if (adapter->rx_ring.fbr[0]->buffsize == 256) + if (rx_ring->fbr[0]->buffsize == 256) csr |= ET_RXDMA_CSR_FBR0_SIZE_LO; - else if (adapter->rx_ring.fbr[0]->buffsize == 512) + else if (rx_ring->fbr[0]->buffsize == 512) csr |= ET_RXDMA_CSR_FBR0_SIZE_HI; - else if (adapter->rx_ring.fbr[0]->buffsize == 1024) + else if (rx_ring->fbr[0]->buffsize == 1024) csr |= ET_RXDMA_CSR_FBR0_SIZE_LO | ET_RXDMA_CSR_FBR0_SIZE_HI; writel(csr, &adapter->regs->rxdma.csr); @@ -968,7 +968,7 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) /* Set up the if mode bits */ cfg2 &= ~ET_MAC_CFG2_IFMODE_MASK; - if (phydev && phydev->speed == SPEED_1000) { + if (phydev->speed == SPEED_1000) { cfg2 |= ET_MAC_CFG2_IFMODE_1000; /* Phy mode bit */ ifctrl &= ~ET_MAC_IFCTRL_PHYMODE; @@ -999,11 +999,11 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) cfg2 &= ~ET_MAC_CFG2_IFMODE_FULL_DPLX; /* Turn on duplex if needed */ - if (phydev && phydev->duplex == DUPLEX_FULL) + if (phydev->duplex == DUPLEX_FULL) cfg2 |= ET_MAC_CFG2_IFMODE_FULL_DPLX; ifctrl &= ~ET_MAC_IFCTRL_GHDMODE; - if (phydev && phydev->duplex == DUPLEX_HALF) + if (phydev->duplex == DUPLEX_HALF) ifctrl |= ET_MAC_IFCTRL_GHDMODE; writel(ifctrl, &mac->if_ctrl); @@ -1039,9 +1039,7 @@ static void et1310_config_mac_regs2(struct et131x_adapter *adapter) */ static int et1310_in_phy_coma(struct et131x_adapter *adapter) { - u32 pmcsr; - - pmcsr = readl(&adapter->regs->global.pm_csr); + u32 pmcsr = readl(&adapter->regs->global.pm_csr); return ET_PM_PHY_SW_COMA & pmcsr ? 1 : 0; } @@ -1351,8 +1349,6 @@ static void et1310_config_macstat_regs(struct et131x_adapter *adapter) * @addr: the address of the transceiver * @reg: the register to read * @value: pointer to a 16-bit value in which the value will be stored - * - * Returns 0 on success, errno on failure (as defined in errno.h) */ static int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 addr, u8 reg, u16 *value) @@ -1425,10 +1421,6 @@ static int et131x_mii_read(struct et131x_adapter *adapter, u8 reg, u16 *value) * @adapter: pointer to our private adapter structure * @reg: the register to read * @value: 16-bit value to write - * - * FIXME: one caller in netdev still - * - * Return 0 on success, errno on failure (as defined in errno.h) */ static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) { @@ -1494,10 +1486,10 @@ static int et131x_mii_write(struct et131x_adapter *adapter, u8 reg, u16 value) return status; } -/* Still used from _mac for BIT_READ */ -static void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, - u16 action, u16 regnum, u16 bitnum, - u8 *value) +static void et1310_phy_read_mii_bit(struct et131x_adapter *adapter, + u16 regnum, + u16 bitnum, + u8 *value) { u16 reg; u16 mask = 1 << bitnum; @@ -1505,22 +1497,7 @@ static void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, /* Read the requested register */ et131x_mii_read(adapter, regnum, ®); - switch (action) { - case TRUEPHY_BIT_READ: - *value = (reg & mask) >> bitnum; - break; - - case TRUEPHY_BIT_SET: - et131x_mii_write(adapter, regnum, reg | mask); - break; - - case TRUEPHY_BIT_CLEAR: - et131x_mii_write(adapter, regnum, reg & ~mask); - break; - - default: - break; - } + *value = (reg & mask) >> bitnum; } static void et1310_config_flow_control(struct et131x_adapter *adapter) @@ -1532,27 +1509,19 @@ static void et1310_config_flow_control(struct et131x_adapter *adapter) } else { char remote_pause, remote_async_pause; - et1310_phy_access_mii_bit(adapter, - TRUEPHY_BIT_READ, 5, 10, &remote_pause); - et1310_phy_access_mii_bit(adapter, - TRUEPHY_BIT_READ, 5, 11, - &remote_async_pause); + et1310_phy_read_mii_bit(adapter, 5, 10, &remote_pause); + et1310_phy_read_mii_bit(adapter, 5, 11, &remote_async_pause); - if ((remote_pause == TRUEPHY_BIT_SET) && - (remote_async_pause == TRUEPHY_BIT_SET)) { + if (remote_pause && remote_async_pause) { adapter->flowcontrol = adapter->wanted_flow; - } else if ((remote_pause == TRUEPHY_BIT_SET) && - (remote_async_pause == TRUEPHY_BIT_CLEAR)) { + } else if (remote_pause && !remote_async_pause) { if (adapter->wanted_flow == FLOW_BOTH) adapter->flowcontrol = FLOW_BOTH; else adapter->flowcontrol = FLOW_NONE; - } else if ((remote_pause == TRUEPHY_BIT_CLEAR) && - (remote_async_pause == TRUEPHY_BIT_CLEAR)) { + } else if (!remote_pause && !remote_async_pause) { adapter->flowcontrol = FLOW_NONE; - } else {/* if (remote_pause == TRUEPHY_CLEAR_BIT && - * remote_async_pause == TRUEPHY_SET_BIT) - */ + } else { if (adapter->wanted_flow == FLOW_BOTH) adapter->flowcontrol = FLOW_RXONLY; else @@ -1561,9 +1530,7 @@ static void et1310_config_flow_control(struct et131x_adapter *adapter) } } -/* et1310_update_macstat_host_counters - Update the local copy of the statistics - * @adapter: pointer to the adapter structure - */ +/* et1310_update_macstat_host_counters - Update local copy of the statistics */ static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) { struct ce_stats *stats = &adapter->stats; @@ -1589,7 +1556,6 @@ static void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) } /* et1310_handle_macstat_interrupt - * @adapter: pointer to the adapter structure * * One of the MACSTAT counters has wrapped. Update the local copy of * the statistics held in the adapter structure, checking the "wrap" @@ -1679,7 +1645,7 @@ static int et131x_mdio_reset(struct mii_bus *bus) return 0; } -/* et1310_phy_power_down - PHY power control +/* et1310_phy_power_switch - PHY power control * @adapter: device to control * @down: true for off/false for back on * @@ -1688,7 +1654,7 @@ static int et131x_mdio_reset(struct mii_bus *bus) * Can't you see that this code processed * Phy power, phy power.. */ -static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) +static void et1310_phy_power_switch(struct et131x_adapter *adapter, bool down) { u16 data; @@ -1699,10 +1665,7 @@ static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) et131x_mii_write(adapter, MII_BMCR, data); } -/* et131x_xcvr_init - Init the phy if we are setting it into force mode - * @adapter: pointer to our private adapter structure - * - */ +/* et131x_xcvr_init - Init the phy if we are setting it into force mode */ static void et131x_xcvr_init(struct et131x_adapter *adapter) { u16 lcr2; @@ -1731,7 +1694,6 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) } /* et131x_configure_global_regs - configure JAGCore global regs - * @adapter: pointer to our adapter structure * * Used to configure the global registers on the JAGCore */ @@ -1776,9 +1738,7 @@ static void et131x_configure_global_regs(struct et131x_adapter *adapter) writel(0, ®s->watchdog_timer); } -/* et131x_config_rx_dma_regs - Start of Rx_DMA init sequence - * @adapter: pointer to our adapter structure - */ +/* et131x_config_rx_dma_regs - Start of Rx_DMA init sequence */ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) { struct rxdma_regs __iomem *rx_dma = &adapter->regs->rxdma; @@ -1821,6 +1781,7 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) u32 __iomem *min_des; u32 __iomem *base_hi; u32 __iomem *base_lo; + struct fbr_lookup *fbr = rx_local->fbr[id]; if (id == 0) { num_des = &rx_dma->fbr0_num_des; @@ -1837,12 +1798,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) } /* Now's the best time to initialize FBR contents */ - fbr_entry = - (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr; - for (entry = 0; - entry < rx_local->fbr[id]->num_entries; entry++) { - fbr_entry->addr_hi = rx_local->fbr[id]->bus_high[entry]; - fbr_entry->addr_lo = rx_local->fbr[id]->bus_low[entry]; + fbr_entry = fbr->ring_virtaddr; + for (entry = 0; entry < fbr->num_entries; entry++) { + fbr_entry->addr_hi = fbr->bus_high[entry]; + fbr_entry->addr_lo = fbr->bus_low[entry]; fbr_entry->word2 = entry; fbr_entry++; } @@ -1850,19 +1809,16 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Set the address and parameters of Free buffer ring 1 and 0 * into the 1310's registers */ - writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr), - base_hi); - writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr), - base_lo); - writel(rx_local->fbr[id]->num_entries - 1, num_des); + writel(upper_32_bits(fbr->ring_physaddr), base_hi); + writel(lower_32_bits(fbr->ring_physaddr), base_lo); + writel(fbr->num_entries - 1, num_des); writel(ET_DMA10_WRAP, full_offset); /* This variable tracks the free buffer ring 1 full position, * so it has to match the above. */ - rx_local->fbr[id]->local_full = ET_DMA10_WRAP; - writel(((rx_local->fbr[id]->num_entries * - LO_MARK_PERCENT_FOR_RX) / 100) - 1, + fbr->local_full = ET_DMA10_WRAP; + writel(((fbr->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, min_des); } @@ -1884,7 +1840,6 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) } /* et131x_config_tx_dma_regs - Set up the tx dma section of the JAGCore. - * @adapter: pointer to our private adapter structure * * Configure the transmit engine with the ring buffers we have created * and prepare it for use. @@ -1892,33 +1847,26 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter) { struct txdma_regs __iomem *txdma = &adapter->regs->txdma; + struct tx_ring *tx_ring = &adapter->tx_ring; /* Load the hardware with the start of the transmit descriptor ring. */ - writel(upper_32_bits(adapter->tx_ring.tx_desc_ring_pa), - &txdma->pr_base_hi); - writel(lower_32_bits(adapter->tx_ring.tx_desc_ring_pa), - &txdma->pr_base_lo); + writel(upper_32_bits(tx_ring->tx_desc_ring_pa), &txdma->pr_base_hi); + writel(lower_32_bits(tx_ring->tx_desc_ring_pa), &txdma->pr_base_lo); /* Initialise the transmit DMA engine */ writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des); /* Load the completion writeback physical address */ - writel(upper_32_bits(adapter->tx_ring.tx_status_pa), - &txdma->dma_wb_base_hi); - writel(lower_32_bits(adapter->tx_ring.tx_status_pa), - &txdma->dma_wb_base_lo); + writel(upper_32_bits(tx_ring->tx_status_pa), &txdma->dma_wb_base_hi); + writel(lower_32_bits(tx_ring->tx_status_pa), &txdma->dma_wb_base_lo); - *adapter->tx_ring.tx_status = 0; + *tx_ring->tx_status = 0; writel(0, &txdma->service_request); - adapter->tx_ring.send_idx = 0; + tx_ring->send_idx = 0; } -/* et131x_adapter_setup - Set the adapter up as per cassini+ documentation - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_adapter_setup - Set the adapter up as per cassini+ documentation */ static void et131x_adapter_setup(struct et131x_adapter *adapter) { /* Configure the JAGCore */ @@ -1938,13 +1886,11 @@ static void et131x_adapter_setup(struct et131x_adapter *adapter) et1310_config_macstat_regs(adapter); - et1310_phy_power_down(adapter, 0); + et1310_phy_power_switch(adapter, 0); et131x_xcvr_init(adapter); } -/* et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310 - * @adapter: pointer to our private adapter structure - */ +/* et131x_soft_reset - Issue soft reset to the hardware, complete for ET1310 */ static void et131x_soft_reset(struct et131x_adapter *adapter) { u32 reg; @@ -1965,7 +1911,6 @@ static void et131x_soft_reset(struct et131x_adapter *adapter) } /* et131x_enable_interrupts - enable interrupt - * @adapter: et131x device * * Enable the appropriate interrupts on the ET131x according to our * configuration @@ -1976,7 +1921,7 @@ static void et131x_enable_interrupts(struct et131x_adapter *adapter) /* Enable all global interrupts */ if (adapter->flowcontrol == FLOW_TXONLY || - adapter->flowcontrol == FLOW_BOTH) + adapter->flowcontrol == FLOW_BOTH) mask = INT_MASK_ENABLE; else mask = INT_MASK_ENABLE_NO_FLOW; @@ -1985,7 +1930,6 @@ static void et131x_enable_interrupts(struct et131x_adapter *adapter) } /* et131x_disable_interrupts - interrupt disable - * @adapter: et131x device * * Block all interrupts from the et131x device at the device itself */ @@ -1995,9 +1939,7 @@ static void et131x_disable_interrupts(struct et131x_adapter *adapter) writel(INT_MASK_DISABLE, &adapter->regs->global.int_mask); } -/* et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 - * @adapter: pointer to our adapter structure - */ +/* et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 */ static void et131x_tx_dma_disable(struct et131x_adapter *adapter) { /* Setup the tramsmit dma configuration register */ @@ -2005,9 +1947,7 @@ static void et131x_tx_dma_disable(struct et131x_adapter *adapter) &adapter->regs->txdma.csr); } -/* et131x_enable_txrx - Enable tx/rx queues - * @netdev: device to be enabled - */ +/* et131x_enable_txrx - Enable tx/rx queues */ static void et131x_enable_txrx(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -2024,9 +1964,7 @@ static void et131x_enable_txrx(struct net_device *netdev) netif_start_queue(netdev); } -/* et131x_disable_txrx - Disable tx/rx queues - * @netdev: device to be disabled - */ +/* et131x_disable_txrx - Disable tx/rx queues */ static void et131x_disable_txrx(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -2042,18 +1980,12 @@ static void et131x_disable_txrx(struct net_device *netdev) et131x_disable_interrupts(adapter); } -/* et131x_init_send - Initialize send data structures - * @adapter: pointer to our private adapter structure - */ +/* et131x_init_send - Initialize send data structures */ static void et131x_init_send(struct et131x_adapter *adapter) { - struct tcb *tcb; u32 ct; - struct tx_ring *tx_ring; - - /* Setup some convenience pointers */ - tx_ring = &adapter->tx_ring; - tcb = adapter->tx_ring.tcb_ring; + struct tx_ring *tx_ring = &adapter->tx_ring; + struct tcb *tcb = tx_ring->tcb_ring; tx_ring->tcb_qhead = tcb; @@ -2076,7 +2008,6 @@ static void et131x_init_send(struct et131x_adapter *adapter) } /* et1310_enable_phy_coma - called when network cable is unplugged - * @adapter: pointer to our adapter structure * * driver receive an phy status change interrupt while in D0 and check that * phy_status is down. @@ -2104,11 +2035,6 @@ static void et1310_enable_phy_coma(struct et131x_adapter *adapter) /* Save the GbE PHY speed and duplex modes. Need to restore this * when cable is plugged back in */ - /* TODO - when PM is re-enabled, check if we need to - * perform a similar task as this - - * adapter->pdown_speed = adapter->ai_force_speed; - * adapter->pdown_duplex = adapter->ai_force_duplex; - */ /* Stop sending packets. */ spin_lock_irqsave(&adapter->send_hw_lock, flags); @@ -2128,9 +2054,7 @@ static void et1310_enable_phy_coma(struct et131x_adapter *adapter) writel(pmcsr, &adapter->regs->global.pm_csr); } -/* et1310_disable_phy_coma - Disable the Phy Coma Mode - * @adapter: pointer to our adapter structure - */ +/* et1310_disable_phy_coma - Disable the Phy Coma Mode */ static void et1310_disable_phy_coma(struct et131x_adapter *adapter) { u32 pmcsr; @@ -2145,11 +2069,6 @@ static void et1310_disable_phy_coma(struct et131x_adapter *adapter) /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY */ - /* TODO - when PM is re-enabled, check if we need to - * perform a similar task as this - - * adapter->ai_force_speed = adapter->pdown_speed; - * adapter->ai_force_duplex = adapter->pdown_duplex; - */ /* Re-initialize the send structures */ et131x_init_send(adapter); @@ -2183,15 +2102,12 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) tmp_free_buff_ring ^= ET_DMA10_WRAP; } /* For the 1023 case */ - tmp_free_buff_ring &= (ET_DMA10_MASK|ET_DMA10_WRAP); + tmp_free_buff_ring &= (ET_DMA10_MASK | ET_DMA10_WRAP); *free_buff_ring = tmp_free_buff_ring; return tmp_free_buff_ring; } /* et131x_rx_dma_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h) * * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required, * and the Packet Status Ring. @@ -2203,10 +2119,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) u32 bufsize; u32 pktstat_ringsize; u32 fbr_chunksize; - struct rx_ring *rx_ring; - - /* Setup some convenience pointers */ - rx_ring = &adapter->rx_ring; + struct rx_ring *rx_ring = &adapter->rx_ring; + struct fbr_lookup *fbr; /* Alloc memory for the lookup table */ rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); @@ -2247,20 +2161,18 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->fbr[1]->num_entries = 128; } - adapter->rx_ring.psr_num_entries = - adapter->rx_ring.fbr[0]->num_entries + - adapter->rx_ring.fbr[1]->num_entries; + rx_ring->psr_num_entries = rx_ring->fbr[0]->num_entries + + rx_ring->fbr[1]->num_entries; for (id = 0; id < NUM_FBRS; id++) { + fbr = rx_ring->fbr[id]; /* Allocate an area of memory for Free Buffer Ring */ - bufsize = - (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries); - rx_ring->fbr[id]->ring_virtaddr = - dma_alloc_coherent(&adapter->pdev->dev, - bufsize, - &rx_ring->fbr[id]->ring_physaddr, - GFP_KERNEL); - if (!rx_ring->fbr[id]->ring_virtaddr) { + bufsize = sizeof(struct fbr_desc) * fbr->num_entries; + fbr->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, + bufsize, + &fbr->ring_physaddr, + GFP_KERNEL); + if (!fbr->ring_virtaddr) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Free Buffer Ring %d\n", id); return -ENOMEM; @@ -2268,25 +2180,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) } for (id = 0; id < NUM_FBRS; id++) { - fbr_chunksize = (FBR_CHUNKS * rx_ring->fbr[id]->buffsize); + fbr = rx_ring->fbr[id]; + fbr_chunksize = (FBR_CHUNKS * fbr->buffsize); - for (i = 0; - i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { + for (i = 0; i < fbr->num_entries / FBR_CHUNKS; i++) { dma_addr_t fbr_tmp_physaddr; - rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( + fbr->mem_virtaddrs[i] = dma_alloc_coherent( &adapter->pdev->dev, fbr_chunksize, - &rx_ring->fbr[id]->mem_physaddrs[i], + &fbr->mem_physaddrs[i], GFP_KERNEL); - if (!rx_ring->fbr[id]->mem_virtaddrs[i]) { + if (!fbr->mem_virtaddrs[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - fbr_tmp_physaddr = rx_ring->fbr[id]->mem_physaddrs[i]; + fbr_tmp_physaddr = fbr->mem_physaddrs[i]; for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; @@ -2294,26 +2206,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* Save the Virtual address of this index for * quick access later */ - rx_ring->fbr[id]->virt[index] = - (u8 *) rx_ring->fbr[id]->mem_virtaddrs[i] + - (j * rx_ring->fbr[id]->buffsize); + fbr->virt[index] = (u8 *)fbr->mem_virtaddrs[i] + + (j * fbr->buffsize); /* now store the physical address in the * descriptor so the device can access it */ - rx_ring->fbr[id]->bus_high[index] = + fbr->bus_high[index] = upper_32_bits(fbr_tmp_physaddr); - rx_ring->fbr[id]->bus_low[index] = + fbr->bus_low[index] = lower_32_bits(fbr_tmp_physaddr); - fbr_tmp_physaddr += rx_ring->fbr[id]->buffsize; + fbr_tmp_physaddr += fbr->buffsize; } } } /* Allocate an area of memory for FIFO of Packet Status ring entries */ pktstat_ringsize = - sizeof(struct pkt_stat_desc) * adapter->rx_ring.psr_num_entries; + sizeof(struct pkt_stat_desc) * rx_ring->psr_num_entries; rx_ring->ps_ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, pktstat_ringsize, @@ -2325,8 +2236,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Packet Status Ring\n"); return -ENOMEM; } - pr_info("Packet Status Ring %llx\n", - (unsigned long long) rx_ring->ps_ring_physaddr); /* NOTE : dma_alloc_coherent(), used above to alloc DMA regions, * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses @@ -2345,7 +2254,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } rx_ring->num_rfd = NIC_DEFAULT_NUM_RFD; - pr_info("PRS %llx\n", (unsigned long long)rx_ring->rx_status_bus); /* The RFDs are going to be put on lists later on, so initialize the * lists now. @@ -2354,9 +2262,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return 0; } -/* et131x_rx_dma_memory_free - Free all memory allocated within this module. - * @adapter: pointer to our private adapter structure - */ +/* et131x_rx_dma_memory_free - Free all memory allocated within this module */ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { u8 id; @@ -2364,17 +2270,15 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) u32 bufsize; u32 pktstat_ringsize; struct rfd *rfd; - struct rx_ring *rx_ring; - - /* Setup some convenience pointers */ - rx_ring = &adapter->rx_ring; + struct rx_ring *rx_ring = &adapter->rx_ring; + struct fbr_lookup *fbr; /* Free RFDs and associated packet descriptors */ WARN_ON(rx_ring->num_ready_recv != rx_ring->num_rfd); while (!list_empty(&rx_ring->recv_list)) { - rfd = (struct rfd *) list_entry(rx_ring->recv_list.next, - struct rfd, list_node); + rfd = list_entry(rx_ring->recv_list.next, + struct rfd, list_node); list_del(&rfd->list_node); rfd->skb = NULL; @@ -2383,40 +2287,41 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Free Buffer Rings */ for (id = 0; id < NUM_FBRS; id++) { - if (!rx_ring->fbr[id]->ring_virtaddr) + fbr = rx_ring->fbr[id]; + + if (!fbr->ring_virtaddr) continue; /* First the packet memory */ for (index = 0; - index < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); + index < fbr->num_entries / FBR_CHUNKS; index++) { - if (rx_ring->fbr[id]->mem_virtaddrs[index]) { - bufsize = - rx_ring->fbr[id]->buffsize * FBR_CHUNKS; + if (fbr->mem_virtaddrs[index]) { + bufsize = fbr->buffsize * FBR_CHUNKS; dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[id]->mem_virtaddrs[index], - rx_ring->fbr[id]->mem_physaddrs[index]); + bufsize, + fbr->mem_virtaddrs[index], + fbr->mem_physaddrs[index]); - rx_ring->fbr[id]->mem_virtaddrs[index] = NULL; + fbr->mem_virtaddrs[index] = NULL; } } - bufsize = - sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries; + bufsize = sizeof(struct fbr_desc) * fbr->num_entries; - dma_free_coherent(&adapter->pdev->dev, bufsize, - rx_ring->fbr[id]->ring_virtaddr, - rx_ring->fbr[id]->ring_physaddr); + dma_free_coherent(&adapter->pdev->dev, + bufsize, + fbr->ring_virtaddr, + fbr->ring_physaddr); - rx_ring->fbr[id]->ring_virtaddr = NULL; + fbr->ring_virtaddr = NULL; } /* Free Packet Status Ring */ if (rx_ring->ps_ring_virtaddr) { pktstat_ringsize = sizeof(struct pkt_stat_desc) * - adapter->rx_ring.psr_num_entries; + rx_ring->psr_num_entries; dma_free_coherent(&adapter->pdev->dev, pktstat_ringsize, rx_ring->ps_ring_virtaddr, @@ -2441,20 +2346,12 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->num_ready_recv = 0; } -/* et131x_init_recv - Initialize receive data structures. - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h) - */ +/* et131x_init_recv - Initialize receive data structures */ static int et131x_init_recv(struct et131x_adapter *adapter) { struct rfd *rfd; u32 rfdct; - u32 numrfd = 0; - struct rx_ring *rx_ring; - - /* Setup some convenience pointers */ - rx_ring = &adapter->rx_ring; + struct rx_ring *rx_ring = &adapter->rx_ring; /* Setup each RFD */ for (rfdct = 0; rfdct < rx_ring->num_rfd; rfdct++) { @@ -2467,24 +2364,18 @@ static int et131x_init_recv(struct et131x_adapter *adapter) /* Add this RFD to the recv_list */ list_add_tail(&rfd->list_node, &rx_ring->recv_list); - /* Increment both the available RFD's, and the total RFD's. */ + /* Increment the available RFD's */ rx_ring->num_ready_recv++; - numrfd++; } return 0; } -/* et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate. - * @adapter: pointer to our adapter structure - */ +/* et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate */ static void et131x_set_rx_dma_timer(struct et131x_adapter *adapter) { struct phy_device *phydev = adapter->phydev; - if (!phydev) - return; - /* For version B silicon, we do not use the RxDMA timer for 10 and 100 * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. */ @@ -2505,11 +2396,13 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) u16 buff_index = rfd->bufferindex; u8 ring_index = rfd->ringindex; unsigned long flags; + struct fbr_lookup *fbr = rx_local->fbr[ring_index]; /* We don't use any of the OOB data besides status. Otherwise, we * need to clean up OOB data */ - if (buff_index < rx_local->fbr[ring_index]->num_entries) { + if (buff_index < fbr->num_entries) { + u32 free_buff_ring; u32 __iomem *offset; struct fbr_desc *next; @@ -2520,22 +2413,20 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) else offset = &rx_dma->fbr1_full_offset; - next = (struct fbr_desc *) - (rx_local->fbr[ring_index]->ring_virtaddr) + - INDEX10(rx_local->fbr[ring_index]->local_full); + next = (struct fbr_desc *)(fbr->ring_virtaddr) + + INDEX10(fbr->local_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - next->addr_hi = rx_local->fbr[ring_index]->bus_high[buff_index]; - next->addr_lo = rx_local->fbr[ring_index]->bus_low[buff_index]; + next->addr_hi = fbr->bus_high[buff_index]; + next->addr_lo = fbr->bus_low[buff_index]; next->word2 = buff_index; - writel(bump_free_buff_ring( - &rx_local->fbr[ring_index]->local_full, - rx_local->fbr[ring_index]->num_entries - 1), - offset); + free_buff_ring = bump_free_buff_ring(&fbr->local_full, + fbr->num_entries - 1); + writel(free_buff_ring, offset); spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { @@ -2555,7 +2446,6 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) } /* nic_rx_pkts - Checks the hardware for available packets - * @adapter: pointer to our adapter * * Returns rfd, a pointer to our MPRFD. * @@ -2580,6 +2470,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) u32 word0; u32 word1; struct sk_buff *skb; + struct fbr_lookup *fbr; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet @@ -2601,6 +2492,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) */ len = psr->word1 & 0xFFFF; ring_index = (psr->word1 >> 26) & 0x03; + fbr = rx_local->fbr[ring_index]; buff_index = (psr->word1 >> 16) & 0x3FF; word0 = psr->word0; @@ -2616,8 +2508,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset); - if (ring_index > 1 || - buff_index > rx_local->fbr[ring_index]->num_entries - 1) { + if (ring_index > 1 || buff_index > fbr->num_entries - 1) { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates length of %d and/or bad bi(%d)\n", @@ -2629,7 +2520,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) spin_lock_irqsave(&adapter->rcv_lock, flags); element = rx_local->recv_list.next; - rfd = (struct rfd *) list_entry(element, struct rfd, list_node); + rfd = list_entry(element, struct rfd, list_node); if (!rfd) { spin_unlock_irqrestore(&adapter->rcv_lock, flags); @@ -2670,7 +2561,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) && !(adapter->packet_filter & ET131X_PACKET_TYPE_PROMISCUOUS) && !(adapter->packet_filter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - buf = rx_local->fbr[ring_index]->virt[buff_index]; + buf = fbr->virt[buff_index]; /* Loop through our list to see if the destination * address of this packet matches one in our list. @@ -2708,7 +2599,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) adapter->stats.unicast_pkts_rcvd++; } - if (len == 0) { + if (!len) { rfd->len = 0; goto out; } @@ -2723,9 +2614,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) adapter->net_stats.rx_bytes += rfd->len; - memcpy(skb_put(skb, rfd->len), - rx_local->fbr[ring_index]->virt[buff_index], - rfd->len); + memcpy(skb_put(skb, rfd->len), fbr->virt[buff_index], rfd->len); skb->protocol = eth_type_trans(skb, adapter->netdev); skb->ip_summed = CHECKSUM_NONE; @@ -2737,7 +2626,6 @@ out: } /* et131x_handle_recv_interrupt - Interrupt handler for receive processing - * @adapter: pointer to our adapter * * Assumption, Rcv spinlock has been acquired. */ @@ -2746,11 +2634,12 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter) struct rfd *rfd = NULL; u32 count = 0; bool done = true; + struct rx_ring *rx_ring = &adapter->rx_ring; /* Process up to available RFD's */ while (count < NUM_PACKETS_HANDLED) { - if (list_empty(&adapter->rx_ring.recv_list)) { - WARN_ON(adapter->rx_ring.num_ready_recv != 0); + if (list_empty(&rx_ring->recv_list)) { + WARN_ON(rx_ring->num_ready_recv != 0); done = false; break; } @@ -2774,25 +2663,22 @@ static void et131x_handle_recv_interrupt(struct et131x_adapter *adapter) adapter->net_stats.rx_packets++; /* Set the status on the packet, either resources or success */ - if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK) + if (rx_ring->num_ready_recv < RFD_LOW_WATER_MARK) dev_warn(&adapter->pdev->dev, "RFD's are running out\n"); count++; } if (count == NUM_PACKETS_HANDLED || !done) { - adapter->rx_ring.unfinished_receives = true; + rx_ring->unfinished_receives = true; writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, &adapter->regs->global.watchdog_timer); } else /* Watchdog timer will disable itself if appropriate. */ - adapter->rx_ring.unfinished_receives = false; + rx_ring->unfinished_receives = false; } /* et131x_tx_dma_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h). * * Allocates memory that will be visible both to the device and to the CPU. * The OS will pass us packets, pointers to which we will insert in the Tx @@ -2806,18 +2692,17 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) struct tx_ring *tx_ring = &adapter->tx_ring; /* Allocate memory for the TCB's (Transmit Control Block) */ - adapter->tx_ring.tcb_ring = kcalloc(NUM_TCB, sizeof(struct tcb), - GFP_ATOMIC | GFP_DMA); - if (!adapter->tx_ring.tcb_ring) + tx_ring->tcb_ring = kcalloc(NUM_TCB, sizeof(struct tcb), + GFP_ATOMIC | GFP_DMA); + if (!tx_ring->tcb_ring) return -ENOMEM; desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); - tx_ring->tx_desc_ring = - (struct tx_desc *) dma_alloc_coherent(&adapter->pdev->dev, - desc_size, - &tx_ring->tx_desc_ring_pa, - GFP_KERNEL); - if (!adapter->tx_ring.tx_desc_ring) { + tx_ring->tx_desc_ring = dma_alloc_coherent(&adapter->pdev->dev, + desc_size, + &tx_ring->tx_desc_ring_pa, + GFP_KERNEL); + if (!tx_ring->tx_desc_ring) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Tx Ring\n"); return -ENOMEM; @@ -2835,51 +2720,46 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) sizeof(u32), &tx_ring->tx_status_pa, GFP_KERNEL); - if (!adapter->tx_ring.tx_status_pa) { + if (!tx_ring->tx_status_pa) { dev_err(&adapter->pdev->dev, - "Cannot alloc memory for Tx status block\n"); + "Cannot alloc memory for Tx status block\n"); return -ENOMEM; } return 0; } -/* et131x_tx_dma_memory_free - Free all memory allocated within this module - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success and errno on failure (as defined in errno.h). - */ +/* et131x_tx_dma_memory_free - Free all memory allocated within this module */ static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) { int desc_size = 0; + struct tx_ring *tx_ring = &adapter->tx_ring; - if (adapter->tx_ring.tx_desc_ring) { + if (tx_ring->tx_desc_ring) { /* Free memory relating to Tx rings here */ desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); dma_free_coherent(&adapter->pdev->dev, - desc_size, - adapter->tx_ring.tx_desc_ring, - adapter->tx_ring.tx_desc_ring_pa); - adapter->tx_ring.tx_desc_ring = NULL; + desc_size, + tx_ring->tx_desc_ring, + tx_ring->tx_desc_ring_pa); + tx_ring->tx_desc_ring = NULL; } /* Free memory for the Tx status block */ - if (adapter->tx_ring.tx_status) { + if (tx_ring->tx_status) { dma_free_coherent(&adapter->pdev->dev, - sizeof(u32), - adapter->tx_ring.tx_status, - adapter->tx_ring.tx_status_pa); + sizeof(u32), + tx_ring->tx_status, + tx_ring->tx_status_pa); - adapter->tx_ring.tx_status = NULL; + tx_ring->tx_status = NULL; } /* Free the memory for the tcb structures */ - kfree(adapter->tx_ring.tcb_ring); + kfree(tx_ring->tcb_ring); } /* nic_send_packet - NIC specific send handler for version B silicon. * @adapter: pointer to our adapter * @tcb: pointer to struct tcb - * - * Returns 0 or errno. */ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { @@ -2893,6 +2773,7 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) unsigned long flags; struct phy_device *phydev = adapter->phydev; dma_addr_t dma_addr; + struct tx_ring *tx_ring = &adapter->tx_ring; /* Part of the optimizations of this send routine restrict us to * sending 24 fragments at a pass. In practice we should never see @@ -2968,11 +2849,11 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) } if (phydev && phydev->speed == SPEED_1000) { - if (++adapter->tx_ring.since_irq == PARM_TX_NUM_BUFS_DEF) { + if (++tx_ring->since_irq == PARM_TX_NUM_BUFS_DEF) { /* Last element & Interrupt flag */ desc[frag - 1].flags = TXDESC_FLAG_INTPROC | TXDESC_FLAG_LASTPKT; - adapter->tx_ring.since_irq = 0; + tx_ring->since_irq = 0; } else { /* Last element */ desc[frag - 1].flags = TXDESC_FLAG_LASTPKT; } @@ -2982,12 +2863,12 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) desc[0].flags |= TXDESC_FLAG_FIRSTPKT; - tcb->index_start = adapter->tx_ring.send_idx; + tcb->index_start = tx_ring->send_idx; tcb->stale = 0; spin_lock_irqsave(&adapter->send_hw_lock, flags); - thiscopy = NUM_DESC_PER_RING_TX - INDEX10(adapter->tx_ring.send_idx); + thiscopy = NUM_DESC_PER_RING_TX - INDEX10(tx_ring->send_idx); if (thiscopy >= frag) { remainder = 0; @@ -2996,52 +2877,51 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) remainder = frag - thiscopy; } - memcpy(adapter->tx_ring.tx_desc_ring + - INDEX10(adapter->tx_ring.send_idx), desc, + memcpy(tx_ring->tx_desc_ring + INDEX10(tx_ring->send_idx), + desc, sizeof(struct tx_desc) * thiscopy); - add_10bit(&adapter->tx_ring.send_idx, thiscopy); + add_10bit(&tx_ring->send_idx, thiscopy); - if (INDEX10(adapter->tx_ring.send_idx) == 0 || - INDEX10(adapter->tx_ring.send_idx) == NUM_DESC_PER_RING_TX) { - adapter->tx_ring.send_idx &= ~ET_DMA10_MASK; - adapter->tx_ring.send_idx ^= ET_DMA10_WRAP; + if (INDEX10(tx_ring->send_idx) == 0 || + INDEX10(tx_ring->send_idx) == NUM_DESC_PER_RING_TX) { + tx_ring->send_idx &= ~ET_DMA10_MASK; + tx_ring->send_idx ^= ET_DMA10_WRAP; } if (remainder) { - memcpy(adapter->tx_ring.tx_desc_ring, + memcpy(tx_ring->tx_desc_ring, desc + thiscopy, sizeof(struct tx_desc) * remainder); - add_10bit(&adapter->tx_ring.send_idx, remainder); + add_10bit(&tx_ring->send_idx, remainder); } - if (INDEX10(adapter->tx_ring.send_idx) == 0) { - if (adapter->tx_ring.send_idx) + if (INDEX10(tx_ring->send_idx) == 0) { + if (tx_ring->send_idx) tcb->index = NUM_DESC_PER_RING_TX - 1; else tcb->index = ET_DMA10_WRAP|(NUM_DESC_PER_RING_TX - 1); } else - tcb->index = adapter->tx_ring.send_idx - 1; + tcb->index = tx_ring->send_idx - 1; spin_lock(&adapter->tcb_send_qlock); - if (adapter->tx_ring.send_tail) - adapter->tx_ring.send_tail->next = tcb; + if (tx_ring->send_tail) + tx_ring->send_tail->next = tcb; else - adapter->tx_ring.send_head = tcb; + tx_ring->send_head = tcb; - adapter->tx_ring.send_tail = tcb; + tx_ring->send_tail = tcb; WARN_ON(tcb->next != NULL); - adapter->tx_ring.used++; + tx_ring->used++; spin_unlock(&adapter->tcb_send_qlock); /* Write the new write pointer back to the device. */ - writel(adapter->tx_ring.send_idx, - &adapter->regs->txdma.service_request); + writel(tx_ring->send_idx, &adapter->regs->txdma.service_request); /* For Gig only, we use Tx Interrupt coalescing. Enable the software * timer to wake us up if this packet isn't followed by N more. @@ -3056,19 +2936,16 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) } /* send_packet - Do the work to send a packet - * @skb: the packet(s) to send - * @adapter: a pointer to the device's private adapter structure - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only. * * Assumption: Send spinlock has been acquired */ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) { int status; - struct tcb *tcb = NULL; + struct tcb *tcb; u16 *shbufva; unsigned long flags; + struct tx_ring *tx_ring = &adapter->tx_ring; /* All packets must have at least a MAC address and a protocol type */ if (skb->len < ETH_HLEN) @@ -3077,17 +2954,17 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) /* Get a TCB for this packet */ spin_lock_irqsave(&adapter->tcb_ready_qlock, flags); - tcb = adapter->tx_ring.tcb_qhead; + tcb = tx_ring->tcb_qhead; if (tcb == NULL) { spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); return -ENOMEM; } - adapter->tx_ring.tcb_qhead = tcb->next; + tx_ring->tcb_qhead = tcb->next; - if (adapter->tx_ring.tcb_qhead == NULL) - adapter->tx_ring.tcb_qtail = NULL; + if (tx_ring->tcb_qhead == NULL) + tx_ring->tcb_qtail = NULL; spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); @@ -3111,30 +2988,26 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) if (status != 0) { spin_lock_irqsave(&adapter->tcb_ready_qlock, flags); - if (adapter->tx_ring.tcb_qtail) - adapter->tx_ring.tcb_qtail->next = tcb; + if (tx_ring->tcb_qtail) + tx_ring->tcb_qtail->next = tcb; else /* Apparently ready Q is empty. */ - adapter->tx_ring.tcb_qhead = tcb; + tx_ring->tcb_qhead = tcb; - adapter->tx_ring.tcb_qtail = tcb; + tx_ring->tcb_qtail = tcb; spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); return status; } - WARN_ON(adapter->tx_ring.used > NUM_TCB); + WARN_ON(tx_ring->used > NUM_TCB); return 0; } -/* et131x_send_packets - This function is called by the OS to send packets - * @skb: the packet(s) to send - * @netdev:device on which to TX the above packet(s) - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only - */ +/* et131x_send_packets - This function is called by the OS to send packets */ static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) { int status = 0; struct et131x_adapter *adapter = netdev_priv(netdev); + struct tx_ring *tx_ring = &adapter->tx_ring; /* Send these packets * @@ -3143,7 +3016,7 @@ static int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) */ /* TCB is not available */ - if (adapter->tx_ring.used >= NUM_TCB) { + if (tx_ring->used >= NUM_TCB) { /* NOTE: If there's an error on send, no need to queue the * packet under Linux; if we just send an error up to the * netif layer, it will resend the skb to us. @@ -3187,6 +3060,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter, unsigned long flags; struct tx_desc *desc = NULL; struct net_device_stats *stats = &adapter->net_stats; + struct tx_ring *tx_ring = &adapter->tx_ring; u64 dma_addr; if (tcb->flags & FMP_DEST_BROAD) @@ -3204,9 +3078,8 @@ static inline void free_send_packet(struct et131x_adapter *adapter, * they point to */ do { - desc = (struct tx_desc *) - (adapter->tx_ring.tx_desc_ring + - INDEX10(tcb->index_start)); + desc = tx_ring->tx_desc_ring + + INDEX10(tcb->index_start); dma_addr = desc->addr_lo; dma_addr |= (u64)desc->addr_hi << 32; @@ -3221,8 +3094,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter, tcb->index_start &= ~ET_DMA10_MASK; tcb->index_start ^= ET_DMA10_WRAP; } - } while (desc != (adapter->tx_ring.tx_desc_ring + - INDEX10(tcb->index))); + } while (desc != tx_ring->tx_desc_ring + INDEX10(tcb->index)); dev_kfree_skb_any(tcb->skb); } @@ -3234,20 +3106,19 @@ static inline void free_send_packet(struct et131x_adapter *adapter, adapter->net_stats.tx_packets++; - if (adapter->tx_ring.tcb_qtail) - adapter->tx_ring.tcb_qtail->next = tcb; + if (tx_ring->tcb_qtail) + tx_ring->tcb_qtail->next = tcb; else /* Apparently ready Q is empty. */ - adapter->tx_ring.tcb_qhead = tcb; + tx_ring->tcb_qhead = tcb; - adapter->tx_ring.tcb_qtail = tcb; + tx_ring->tcb_qtail = tcb; spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); - WARN_ON(adapter->tx_ring.used < 0); + WARN_ON(tx_ring->used < 0); } /* et131x_free_busy_send_packets - Free and complete the stopped active sends - * @adapter: pointer to our adapter * * Assumption - Send spinlock has been acquired */ @@ -3256,21 +3127,22 @@ static void et131x_free_busy_send_packets(struct et131x_adapter *adapter) struct tcb *tcb; unsigned long flags; u32 freed = 0; + struct tx_ring *tx_ring = &adapter->tx_ring; /* Any packets being sent? Check the first TCB on the send list */ spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; while (tcb != NULL && freed < NUM_TCB) { struct tcb *next = tcb->next; - adapter->tx_ring.send_head = next; + tx_ring->send_head = next; if (next == NULL) - adapter->tx_ring.send_tail = NULL; + tx_ring->send_tail = NULL; - adapter->tx_ring.used--; + tx_ring->used--; spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); @@ -3279,18 +3151,17 @@ static void et131x_free_busy_send_packets(struct et131x_adapter *adapter) spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; } WARN_ON(freed == NUM_TCB); spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); - adapter->tx_ring.used = 0; + tx_ring->used = 0; } /* et131x_handle_send_interrupt - Interrupt handler for sending processing - * @adapter: pointer to our adapter * * Re-claim the send resources, complete sends and get more to send from * the send wait queue. @@ -3303,6 +3174,7 @@ static void et131x_handle_send_interrupt(struct et131x_adapter *adapter) u32 serviced; struct tcb *tcb; u32 index; + struct tx_ring *tx_ring = &adapter->tx_ring; serviced = readl(&adapter->regs->txdma.new_service_complete); index = INDEX10(serviced); @@ -3312,41 +3184,41 @@ static void et131x_handle_send_interrupt(struct et131x_adapter *adapter) */ spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; while (tcb && ((serviced ^ tcb->index) & ET_DMA10_WRAP) && index < INDEX10(tcb->index)) { - adapter->tx_ring.used--; - adapter->tx_ring.send_head = tcb->next; + tx_ring->used--; + tx_ring->send_head = tcb->next; if (tcb->next == NULL) - adapter->tx_ring.send_tail = NULL; + tx_ring->send_tail = NULL; spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); free_send_packet(adapter, tcb); spin_lock_irqsave(&adapter->tcb_send_qlock, flags); /* Goto the next packet */ - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; } while (tcb && !((serviced ^ tcb->index) & ET_DMA10_WRAP) && index > (tcb->index & ET_DMA10_MASK)) { - adapter->tx_ring.used--; - adapter->tx_ring.send_head = tcb->next; + tx_ring->used--; + tx_ring->send_head = tcb->next; if (tcb->next == NULL) - adapter->tx_ring.send_tail = NULL; + tx_ring->send_tail = NULL; spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); free_send_packet(adapter, tcb); spin_lock_irqsave(&adapter->tcb_send_qlock, flags); /* Goto the next packet */ - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; } /* Wake up the queue when we hit a low-water mark */ - if (adapter->tx_ring.used <= NUM_TCB / 3) + if (tx_ring->used <= NUM_TCB / 3) netif_wake_queue(adapter->netdev); spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); @@ -3548,9 +3420,7 @@ static struct ethtool_ops et131x_ethtool_ops = { .get_link = ethtool_op_get_link, }; -/* et131x_hwaddr_init - set up the MAC Address on the ET1310 - * @adapter: pointer to our private adapter structure - */ +/* et131x_hwaddr_init - set up the MAC Address on the ET1310 */ static void et131x_hwaddr_init(struct et131x_adapter *adapter) { /* If have our default mac from init and no mac address from @@ -3580,14 +3450,12 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter) } /* et131x_pci_init - initial PCI setup - * @adapter: pointer to our private adapter structure - * @pdev: our PCI device * * Perform the initial setup of PCI registers and if possible initialise * the MAC address. At this point the I/O registers have yet to be mapped */ static int et131x_pci_init(struct et131x_adapter *adapter, - struct pci_dev *pdev) + struct pci_dev *pdev) { u16 max_payload; int i, rc; @@ -3704,21 +3572,14 @@ static void et131x_error_timer_handler(unsigned long data) mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000); } -/* et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx - * @adapter: pointer to our private adapter structure - */ +/* et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx */ static void et131x_adapter_memory_free(struct et131x_adapter *adapter) { - /* Free DMA memory */ et131x_tx_dma_memory_free(adapter); et131x_rx_dma_memory_free(adapter); } /* et131x_adapter_memory_alloc - * @adapter: pointer to our private adapter structure - * - * Returns 0 on success, errno on failure (as defined in errno.h). - * * Allocate all the memory blocks for send, receive and others. */ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) @@ -3727,14 +3588,14 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) /* Allocate memory for the Tx Ring */ status = et131x_tx_dma_memory_alloc(adapter); - if (status != 0) { + if (status) { dev_err(&adapter->pdev->dev, "et131x_tx_dma_memory_alloc FAILED\n"); return status; } /* Receive buffer memory allocation */ status = et131x_rx_dma_memory_alloc(adapter); - if (status != 0) { + if (status) { dev_err(&adapter->pdev->dev, "et131x_rx_dma_memory_alloc FAILED\n"); et131x_tx_dma_memory_free(adapter); @@ -3744,8 +3605,7 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) /* Init receive data structures */ status = et131x_init_recv(adapter); if (status) { - dev_err(&adapter->pdev->dev, - "et131x_init_recv FAILED\n"); + dev_err(&adapter->pdev->dev, "et131x_init_recv FAILED\n"); et131x_adapter_memory_free(adapter); } return status; @@ -3756,97 +3616,89 @@ static void et131x_adjust_link(struct net_device *netdev) struct et131x_adapter *adapter = netdev_priv(netdev); struct phy_device *phydev = adapter->phydev; - if (phydev && phydev->link != adapter->link) { - /* Check to see if we are in coma mode and if - * so, disable it because we will not be able - * to read PHY values until we are out. - */ - if (et1310_in_phy_coma(adapter)) - et1310_disable_phy_coma(adapter); + if (!phydev) + return; + if (phydev->link == adapter->link) + return; - adapter->link = phydev->link; - phy_print_status(phydev); + /* Check to see if we are in coma mode and if + * so, disable it because we will not be able + * to read PHY values until we are out. + */ + if (et1310_in_phy_coma(adapter)) + et1310_disable_phy_coma(adapter); - if (phydev->link) { - adapter->boot_coma = 20; - if (phydev && phydev->speed == SPEED_10) { - /* NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(adapter->hTruePhy, 0)== - * EMI_TRUEPHY_A13O) { - */ - u16 register18; + adapter->link = phydev->link; + phy_print_status(phydev); - et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, - ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, - register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, - register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); - } + if (phydev->link) { + adapter->boot_coma = 20; + if (phydev->speed == SPEED_10) { + u16 register18; - et1310_config_flow_control(adapter); - - if (phydev && phydev->speed == SPEED_1000 && - adapter->registry_jumbo_packet > 2048) { - u16 reg; - - et131x_mii_read(adapter, PHY_CONFIG, ®); - reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; - reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; - et131x_mii_write(adapter, PHY_CONFIG, reg); - } - - et131x_set_rx_dma_timer(adapter); - et1310_config_mac_regs2(adapter); - } else { - adapter->boot_coma = 0; - - if (phydev->speed == SPEED_10) { - /* NOTE - Is there a way to query this without - * TruePHY? - * && TRU_QueryCoreType(adapter->hTruePhy, 0) == - * EMI_TRUEPHY_A13O) - */ - u16 register18; - - et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, - ®ister18); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18 | 0x4); - et131x_mii_write(adapter, PHY_INDEX_REG, - register18 | 0x8402); - et131x_mii_write(adapter, PHY_DATA_REG, - register18 | 511); - et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, - register18); - } - - /* Free the packets being actively sent & stopped */ - et131x_free_busy_send_packets(adapter); - - /* Re-initialize the send structures */ - et131x_init_send(adapter); - - /* Bring the device back to the state it was during - * init prior to autonegotiation being complete. This - * way, when we get the auto-neg complete interrupt, - * we can complete init by calling config_mac_regs2. - */ - et131x_soft_reset(adapter); - - /* Setup ET1310 as per the documentation */ - et131x_adapter_setup(adapter); - - /* perform reset of tx/rx */ - et131x_disable_txrx(netdev); - et131x_enable_txrx(netdev); + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, + ®ister18); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18 | 0x4); + et131x_mii_write(adapter, PHY_INDEX_REG, + register18 | 0x8402); + et131x_mii_write(adapter, PHY_DATA_REG, + register18 | 511); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18); } + et1310_config_flow_control(adapter); + + if (phydev->speed == SPEED_1000 && + adapter->registry_jumbo_packet > 2048) { + u16 reg; + + et131x_mii_read(adapter, PHY_CONFIG, ®); + reg &= ~ET_PHY_CONFIG_TX_FIFO_DEPTH; + reg |= ET_PHY_CONFIG_FIFO_DEPTH_32; + et131x_mii_write(adapter, PHY_CONFIG, reg); + } + + et131x_set_rx_dma_timer(adapter); + et1310_config_mac_regs2(adapter); + } else { + adapter->boot_coma = 0; + + if (phydev->speed == SPEED_10) { + u16 register18; + + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, + ®ister18); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18 | 0x4); + et131x_mii_write(adapter, PHY_INDEX_REG, + register18 | 0x8402); + et131x_mii_write(adapter, PHY_DATA_REG, + register18 | 511); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, + register18); + } + + /* Free the packets being actively sent & stopped */ + et131x_free_busy_send_packets(adapter); + + /* Re-initialize the send structures */ + et131x_init_send(adapter); + + /* Bring the device back to the state it was during + * init prior to autonegotiation being complete. This + * way, when we get the auto-neg complete interrupt, + * we can complete init by calling config_mac_regs2. + */ + et131x_soft_reset(adapter); + + /* Setup ET1310 as per the documentation */ + et131x_adapter_setup(adapter); + + /* perform reset of tx/rx */ + et131x_disable_txrx(netdev); + et131x_enable_txrx(netdev); } } @@ -3883,21 +3735,20 @@ static int et131x_mii_probe(struct net_device *netdev) phydev->advertising = phydev->supported; adapter->phydev = phydev; - dev_info(&adapter->pdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", + dev_info(&adapter->pdev->dev, + "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", phydev->drv->name, dev_name(&phydev->dev)); return 0; } /* et131x_adapter_init - * @adapter: pointer to the private adapter struct - * @pdev: pointer to the PCI device * * Initialize the data structures for the et131x_adapter object and link * them together with the platform provided device structures. */ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, - struct pci_dev *pdev) + struct pci_dev *pdev) { static const u8 default_mac[] = { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }; @@ -3925,7 +3776,6 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, } /* et131x_pci_remove - * @pdev: a pointer to the device's pci_dev structure * * Registered in the pci_driver structure, this function is called when the * PCI subsystem detects that a PCI device which matches the information @@ -3952,9 +3802,7 @@ static void et131x_pci_remove(struct pci_dev *pdev) pci_disable_device(pdev); } -/* et131x_up - Bring up a device for use. - * @netdev: device to be opened - */ +/* et131x_up - Bring up a device for use. */ static void et131x_up(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -3963,9 +3811,7 @@ static void et131x_up(struct net_device *netdev) phy_start(adapter->phydev); } -/* et131x_down - Bring down the device - * @netdev: device to be brought down - */ +/* et131x_down - Bring down the device */ static void et131x_down(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4022,7 +3868,9 @@ static irqreturn_t et131x_isr(int irq, void *dev_id) { bool handled = true; struct net_device *netdev = (struct net_device *)dev_id; - struct et131x_adapter *adapter = NULL; + struct et131x_adapter *adapter = netdev_priv(netdev); + struct rx_ring *rx_ring = &adapter->rx_ring; + struct tx_ring *tx_ring = &adapter->tx_ring; u32 status; if (!netif_device_present(netdev)) { @@ -4030,8 +3878,6 @@ static irqreturn_t et131x_isr(int irq, void *dev_id) goto out; } - adapter = netdev_priv(netdev); - /* If the adapter is in low power state, then it should not * recognize any interrupt */ @@ -4061,13 +3907,13 @@ static irqreturn_t et131x_isr(int irq, void *dev_id) /* This is our interrupt, so process accordingly */ if (status & ET_INTR_WATCHDOG) { - struct tcb *tcb = adapter->tx_ring.send_head; + struct tcb *tcb = tx_ring->send_head; if (tcb) if (++tcb->stale > 1) status |= ET_INTR_TXDMA_ISR; - if (adapter->rx_ring.unfinished_receives) + if (rx_ring->unfinished_receives) status |= ET_INTR_RXDMA_XFR_DONE; else if (tcb == NULL) writel(0, &adapter->regs->global.watchdog_timer); @@ -4075,7 +3921,7 @@ static irqreturn_t et131x_isr(int irq, void *dev_id) status &= ~ET_INTR_WATCHDOG; } - if (status == 0) { + if (!status) { /* This interrupt has in some way been "handled" by * the ISR. Either it was a spurious Rx interrupt, or * it was a Tx interrupt that has been filtered by @@ -4101,7 +3947,6 @@ out: } /* et131x_isr_handler - The ISR handler - * @p_adapter, a pointer to the device's private adapter structure * * scheduled to run in a deferred context by the ISR. This is where the ISR's * work actually gets done. @@ -4125,17 +3970,15 @@ static void et131x_isr_handler(struct work_struct *work) if (status & ET_INTR_RXDMA_XFR_DONE) et131x_handle_recv_interrupt(adapter); - status &= 0xffffffd7; + status &= ~(ET_INTR_TXDMA_ERR | ET_INTR_RXDMA_XFR_DONE); if (!status) goto out; /* Handle the TXDMA Error interrupt */ if (status & ET_INTR_TXDMA_ERR) { - u32 txdma_err; - /* Following read also clears the register (COR) */ - txdma_err = readl(&iomem->txdma.tx_dma_error); + u32 txdma_err = readl(&iomem->txdma.tx_dma_error); dev_warn(&adapter->pdev->dev, "TXDMA_ERR interrupt, error = %d\n", @@ -4281,11 +4124,7 @@ out: et131x_enable_interrupts(adapter); } -/* et131x_stats - Return the current device statistics. - * @netdev: device whose stats are being queried - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_stats - Return the current device statistics */ static struct net_device_stats *et131x_stats(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4327,11 +4166,7 @@ static struct net_device_stats *et131x_stats(struct net_device *netdev) return stats; } -/* et131x_open - Open the device for use. - * @netdev: device to be opened - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_open - Open the device for use. */ static int et131x_open(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4360,11 +4195,7 @@ static int et131x_open(struct net_device *netdev) return result; } -/* et131x_close - Close the device - * @netdev: device to be closed - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_close - Close the device */ static int et131x_close(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4382,8 +4213,6 @@ static int et131x_close(struct net_device *netdev) * @netdev: device on which the control request is being made * @reqbuf: a pointer to the IOCTL request buffer * @cmd: the IOCTL command code - * - * Returns 0 on success, errno on failure (as defined in errno.h) */ static int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd) @@ -4400,8 +4229,6 @@ static int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, * @adapter: pointer to our private adapter structure * * FIXME: lot of dups with MAC code - * - * Returns 0 on success, errno on failure */ static int et131x_set_packet_filter(struct et131x_adapter *adapter) { @@ -4460,9 +4287,7 @@ static int et131x_set_packet_filter(struct et131x_adapter *adapter) return status; } -/* et131x_multicast - The handler to configure multicasting on the interface - * @netdev: a pointer to a net_device struct representing the device - */ +/* et131x_multicast - The handler to configure multicasting on the interface */ static void et131x_multicast(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); @@ -4522,27 +4347,21 @@ static void et131x_multicast(struct net_device *netdev) * NOTE - This block will always update the multicast_list with the * hardware, even if the addresses aren't the same. */ - if (packet_filter != adapter->packet_filter) { - /* Call the device's filter function */ + if (packet_filter != adapter->packet_filter) et131x_set_packet_filter(adapter); - } + spin_unlock_irqrestore(&adapter->lock, flags); } -/* et131x_tx - The handler to tx a packet on the device - * @skb: data to be Tx'd - * @netdev: device on which data is to be Tx'd - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_tx - The handler to tx a packet on the device */ static int et131x_tx(struct sk_buff *skb, struct net_device *netdev) { int status = 0; struct et131x_adapter *adapter = netdev_priv(netdev); + struct tx_ring *tx_ring = &adapter->tx_ring; /* stop the queue if it's getting full */ - if (adapter->tx_ring.used >= NUM_TCB - 1 && - !netif_queue_stopped(netdev)) + if (tx_ring->used >= NUM_TCB - 1 && !netif_queue_stopped(netdev)) netif_stop_queue(netdev); /* Save the timestamp for the TX timeout watchdog */ @@ -4562,7 +4381,6 @@ static int et131x_tx(struct sk_buff *skb, struct net_device *netdev) } /* et131x_tx_timeout - Timeout handler - * @netdev: a pointer to a net_device struct representing the device * * The handler called when a Tx request times out. The timeout period is * specified by the 'tx_timeo" element in the net_device structure (see @@ -4571,6 +4389,7 @@ static int et131x_tx(struct sk_buff *skb, struct net_device *netdev) static void et131x_tx_timeout(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); + struct tx_ring *tx_ring = &adapter->tx_ring; struct tcb *tcb; unsigned long flags; @@ -4593,7 +4412,7 @@ static void et131x_tx_timeout(struct net_device *netdev) /* Is send stuck? */ spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = adapter->tx_ring.send_head; + tcb = tx_ring->send_head; if (tcb != NULL) { tcb->count++; @@ -4619,12 +4438,7 @@ static void et131x_tx_timeout(struct net_device *netdev) spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); } -/* et131x_change_mtu - The handler called to change the MTU for the device - * @netdev: device whose MTU is to be changed - * @new_mtu: the desired MTU - * - * Returns 0 on success, errno on failure (as defined in errno.h) - */ +/* et131x_change_mtu - The handler called to change the MTU for the device */ static int et131x_change_mtu(struct net_device *netdev, int new_mtu) { int result = 0; @@ -4669,22 +4483,13 @@ static int et131x_change_mtu(struct net_device *netdev, int new_mtu) return result; } -/* et131x_set_mac_addr - handler to change the MAC address for the device - * @netdev: device whose MAC is to be changed - * @new_mac: the desired MAC address - * - * Returns 0 on success, errno on failure (as defined in errno.h) - * - * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 - */ +/* et131x_set_mac_addr - handler to change the MAC address for the device */ static int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) { int result = 0; struct et131x_adapter *adapter = netdev_priv(netdev); struct sockaddr *address = new_mac; - /* begin blux */ - if (adapter == NULL) return -ENODEV; @@ -4746,15 +4551,13 @@ static const struct net_device_ops et131x_netdev_ops = { * @pdev: a pointer to the device's pci_dev structure * @ent: this device's entry in the pci_device_id table * - * Returns 0 on success, errno on failure (as defined in errno.h) - * * Registered in the pci_driver structure, this function is called when the * PCI subsystem finds a new PCI device which matches the information * contained in the pci_device_id table. This routine is the equivalent to * a device insertion routine. */ static int et131x_pci_setup(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct net_device *netdev; struct et131x_adapter *adapter; @@ -4930,7 +4733,7 @@ err_disable: goto out; } -static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = { +static const struct pci_device_id et131x_pci_table[] = { { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL}, { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, {0,} diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index bbe78a703a23..2ac6e9980117 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -1668,43 +1668,3 @@ struct address_map { #define LED_100TX_SHIFT 4 /* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */ - -/* Defines for PHY access routines */ - -/* Define bit operation flags */ -#define TRUEPHY_BIT_CLEAR 0 -#define TRUEPHY_BIT_SET 1 -#define TRUEPHY_BIT_READ 2 - -/* Define read/write operation flags */ -#ifndef TRUEPHY_READ -#define TRUEPHY_READ 0 -#define TRUEPHY_WRITE 1 -#define TRUEPHY_MASK 2 -#endif - -/* Define master/slave configuration values */ -#define TRUEPHY_CFG_SLAVE 0 -#define TRUEPHY_CFG_MASTER 1 - -/* Define MDI/MDI-X settings */ -#define TRUEPHY_MDI 0 -#define TRUEPHY_MDIX 1 -#define TRUEPHY_AUTO_MDI_MDIX 2 - -/* Define 10Base-T link polarities */ -#define TRUEPHY_POLARITY_NORMAL 0 -#define TRUEPHY_POLARITY_INVERTED 1 - -/* Define auto-negotiation results */ -#define TRUEPHY_ANEG_NOT_COMPLETE 0 -#define TRUEPHY_ANEG_COMPLETE 1 -#define TRUEPHY_ANEG_DISABLED 2 - -/* Define duplex advertisement flags */ -#define TRUEPHY_ADV_DUPLEX_NONE 0x00 -#define TRUEPHY_ADV_DUPLEX_FULL 0x01 -#define TRUEPHY_ADV_DUPLEX_HALF 0x02 -#define TRUEPHY_ADV_DUPLEX_BOTH \ - (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) - diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index 817f837b240d..edd5cef300d0 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c index 074b0e5bcc68..0e499ce5f0d7 100644 --- a/drivers/staging/frontier/tranzport.c +++ b/drivers/staging/frontier/tranzport.c @@ -34,7 +34,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/ft1000/ft1000-pcmcia/boot.h b/drivers/staging/ft1000/ft1000-pcmcia/boot.h index 9dce54eae1cf..60c015c1c28a 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/boot.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/boot.h @@ -1,158 +1,158 @@ -//--------------------------------------------------------------------------- -// FT1000 driver for Flarion Flash OFDM NIC Device -// -// Copyright (C) 2002 Flarion Technologies, All rights reserved. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 of the License, or (at your option) any -// later version. This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. You should have received a copy of the GNU General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - -// Suite 330, Boston, MA 02111-1307, USA. -//--------------------------------------------------------------------------- -// -// File: boot.h -// -// Description: boatloader -// -// History: -// 1/11/05 Whc Ported to Linux. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + FT1000 driver for Flarion Flash OFDM NIC Device + + Copyright (C) 2002 Flarion Technologies, All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - + Suite 330, Boston, MA 02111-1307, USA. + --------------------------------------------------------------------------- + + File: boot.h + + Description: boatloader + + History: + 1/11/05 Whc Ported to Linux. + +---------------------------------------------------------------------------*/ #ifndef _BOOTH_ #define _BOOTH_ -// Official bootloader -static unsigned char bootimage [] = { -0x00,0x00,0x01,0x5E,0x00,0x00 -,0x00,0x00,0x00,0x00,0x02,0xD7 -,0x00,0x00,0x01,0x5E,0x46,0xB3 -,0xE6,0x02,0x00,0x98,0xE6,0x8C -,0x00,0x98,0xFB,0x92,0xFF,0xFF -,0x98,0xFB,0x94,0xFF,0xFF,0x98 -,0xFB,0x06,0x08,0x00,0x98,0xFB -,0x96,0x84,0x00,0x98,0xFB,0x08 -,0x1C,0x00,0x98,0xFB,0x51,0x25 -,0x10,0x1C,0x00,0xE6,0x51,0x01 -,0x07,0xFD,0x4C,0xFF,0x20,0xF5 -,0x51,0x02,0x20,0x08,0x00,0x4C -,0xFF,0x20,0x3C,0x00,0xC0,0x64 -,0x98,0xC0,0x66,0x98,0xC0,0x68 -,0x98,0xC0,0x6A,0x98,0xC0,0x6C -,0x98,0x90,0x08,0x90,0x09,0x90 -,0x0A,0x90,0x0B,0x90,0x0C,0x90 -,0x0D,0x90,0x0E,0x90,0x0F,0x90 -,0x04,0x90,0x06,0xFB,0x51,0x22 -,0x16,0x08,0x03,0xFB,0x51,0x52 -,0x16,0x08,0x04,0xFB,0x51,0x24 -,0x2B,0x08,0x06,0xFB,0x51,0x54 -,0x2B,0x08,0x07,0xFB,0x51,0x24 -,0x2B,0x08,0x09,0xFB,0x51,0x54 -,0x2B,0x08,0x0A,0xFB,0x51,0x12 -,0x16,0x08,0x0C,0xFB,0x51,0x52 -,0x16,0x08,0x0D,0x78,0x00,0x00 -,0x00,0x16,0x00,0x00,0xEC,0x31 -,0xAE,0x00,0x00,0x81,0x4C,0x0F -,0xE6,0x43,0xFF,0xEC,0x31,0x4E -,0x00,0x00,0x91,0xEC,0x31,0xAE -,0x00,0x00,0x91,0x4C,0x0F,0xE6 -,0x43,0xFF,0xEC,0x31,0x5E,0x00 -,0x00,0xA1,0xEB,0x31,0x08,0x00 -,0x00,0xA6,0xEB,0x31,0x08,0x00 -,0x00,0xAC,0x3C,0x00,0xEB,0x31 -,0x08,0x00,0x00,0xA8,0x76,0xFE -,0xFE,0x08,0xEB,0x31,0x08,0x20 -,0x00,0x00,0x76,0xFF,0xFF,0x18 -,0xED,0x31,0x08,0x20,0x00,0x00 -,0x26,0x10,0x04,0x10,0xF5,0x3C -,0x01,0x3C,0x00,0x08,0x01,0x12 -,0x3C,0x11,0x3C,0x00,0x08,0x01 -,0x0B,0x08,0x00,0x6D,0xEC,0x31 -,0xAE,0x20,0x00,0x06,0xED,0x4D -,0x08,0x00,0x00,0x67,0x80,0x6F -,0x00,0x01,0x0B,0x6F,0x00,0x02 -,0x2E,0x76,0xEE,0x01,0x48,0x06 -,0x01,0x39,0xED,0x4D,0x18,0x00 -,0x02,0xED,0x4D,0x08,0x00,0x04 -,0x14,0x06,0xA4,0xED,0x31,0x22 -,0x00,0x00,0xAC,0x76,0xEE,0x07 -,0x48,0x6D,0x22,0x01,0x1E,0x08 -,0x01,0x58,0xEB,0x31,0x08,0x00 -,0x00,0xAC,0x06,0xFF,0xBA,0x3C -,0x00,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x30,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x00 -,0x00,0xA2,0x91,0x00,0x9C,0x3C -,0x80,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x20,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x20 -,0x00,0x04,0x42,0x10,0x90,0x08 -,0xEC,0x31,0xAE,0x20,0x00,0x06 -,0xA4,0x41,0x08,0x00,0xB6,0xED -,0x41,0x28,0x7D,0xFF,0xFF,0x22 -,0xB3,0x40,0x98,0x2A,0x32,0xEB -,0x41,0x28,0xB4,0x43,0xFC,0x05 -,0xFF,0xE6,0xA0,0x31,0x20,0x00 -,0x06,0xEB,0x31,0x08,0x20,0x00 -,0x04,0x3C,0x20,0xEB,0x31,0x08 -,0x20,0x00,0x02,0x3C,0x10,0xEB -,0x31,0x08,0x20,0x00,0x00,0xED -,0x31,0x08,0x20,0x00,0x00,0x04 -,0x10,0xF7,0xED,0x31,0x08,0x20 -,0x00,0x04,0x42,0x10,0x90,0x08 -,0xEC,0x31,0xAE,0x20,0x00,0x06 -,0xA4,0x41,0x08,0x00,0x68,0xED -,0x41,0x28,0x7D,0xFF,0xFF,0x22 -,0xB3,0x40,0x98,0x2A,0x32,0xEB -,0x41,0x28,0xB4,0x43,0xFC,0x05 -,0xFF,0xE6,0x48,0x04,0xEB,0x31 -,0x08,0x20,0x00,0x04,0xEB,0x31 -,0x18,0x20,0x00,0x02,0x3C,0x11 -,0xEB,0x31,0x18,0x20,0x00,0x00 -,0xED,0x31,0x08,0x20,0x00,0x00 -,0x04,0x10,0xF7,0xED,0x31,0x08 -,0x20,0x00,0x02,0x66,0x00,0x6F -,0x00,0x01,0x16,0x76,0xEE,0x06 -,0x48,0x4A,0x1E,0x48,0x04,0xED -,0x31,0x08,0x20,0x00,0x04,0xEB -,0x31,0x08,0x00,0x00,0xA4,0x48 -,0x04,0xED,0x31,0x08,0x20,0x00 -,0x04,0xEB,0x31,0x08,0x00,0x00 -,0xA2,0x48,0x04,0x20,0x20,0x4A -,0x7C,0x46,0x82,0x50,0x05,0x50 -,0x15,0xB5,0x1E,0x98,0xED,0x31 -,0x08,0x00,0x00,0xA8,0x10,0x47 -,0x3B,0x2C,0x01,0xDB,0x40,0x11 -,0x98,0xC1,0x1E,0x98,0x10,0x07 -,0x30,0xF9,0x40,0x07,0x18,0x98 -,0x2A,0x10,0xEB,0x31,0x08,0x00 -,0x00,0xA8,0xA4,0x1E,0x98,0xBB -,0x1E,0x98,0x50,0x14,0x50,0x04 -,0x46,0x83,0x48,0x04,0x02,0x01 -,0x00,0x50,0x05,0x50,0x15,0x10 -,0x87,0x3F,0x90,0x2B,0x18,0x01 -,0x00,0xC0,0x31,0x00,0x00,0xAE -,0xDF,0x41,0x00,0x08,0x00,0x1A -,0x42,0x11,0x67,0x01,0xDF,0x41 -,0x02,0x08,0x00,0x10,0x42,0x11 -,0x62,0x01,0xB4,0x43,0x4A,0x68 -,0x50,0x14,0x50,0x04,0x24,0x10 -,0x48,0x04,0xF2,0x31,0x00,0x01 -,0x00,0x00,0xAE,0xF6,0x31,0x00 -,0x01,0x00,0x00,0xAE,0x62,0xE4 -,0xE5,0x61,0x04,0x48,0x04,0xE5 -,0x63,0x05,0x48,0x04,0x20,0x20 -,0x00,0x00,0x00,0x00 +/* Official bootloader */ +static unsigned char bootimage[] = { + 0x00, 0x00, 0x01, 0x5E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0xD7, + 0x00, 0x00, 0x01, 0x5E, 0x46, 0xB3, + 0xE6, 0x02, 0x00, 0x98, 0xE6, 0x8C, + 0x00, 0x98, 0xFB, 0x92, 0xFF, 0xFF, + 0x98, 0xFB, 0x94, 0xFF, 0xFF, 0x98, + 0xFB, 0x06, 0x08, 0x00, 0x98, 0xFB, + 0x96, 0x84, 0x00, 0x98, 0xFB, 0x08, + 0x1C, 0x00, 0x98, 0xFB, 0x51, 0x25, + 0x10, 0x1C, 0x00, 0xE6, 0x51, 0x01, + 0x07, 0xFD, 0x4C, 0xFF, 0x20, 0xF5, + 0x51, 0x02, 0x20, 0x08, 0x00, 0x4C, + 0xFF, 0x20, 0x3C, 0x00, 0xC0, 0x64, + 0x98, 0xC0, 0x66, 0x98, 0xC0, 0x68, + 0x98, 0xC0, 0x6A, 0x98, 0xC0, 0x6C, + 0x98, 0x90, 0x08, 0x90, 0x09, 0x90, + 0x0A, 0x90, 0x0B, 0x90, 0x0C, 0x90, + 0x0D, 0x90, 0x0E, 0x90, 0x0F, 0x90, + 0x04, 0x90, 0x06, 0xFB, 0x51, 0x22, + 0x16, 0x08, 0x03, 0xFB, 0x51, 0x52, + 0x16, 0x08, 0x04, 0xFB, 0x51, 0x24, + 0x2B, 0x08, 0x06, 0xFB, 0x51, 0x54, + 0x2B, 0x08, 0x07, 0xFB, 0x51, 0x24, + 0x2B, 0x08, 0x09, 0xFB, 0x51, 0x54, + 0x2B, 0x08, 0x0A, 0xFB, 0x51, 0x12, + 0x16, 0x08, 0x0C, 0xFB, 0x51, 0x52, + 0x16, 0x08, 0x0D, 0x78, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0xEC, 0x31, + 0xAE, 0x00, 0x00, 0x81, 0x4C, 0x0F, + 0xE6, 0x43, 0xFF, 0xEC, 0x31, 0x4E, + 0x00, 0x00, 0x91, 0xEC, 0x31, 0xAE, + 0x00, 0x00, 0x91, 0x4C, 0x0F, 0xE6, + 0x43, 0xFF, 0xEC, 0x31, 0x5E, 0x00, + 0x00, 0xA1, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xA6, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xAC, 0x3C, 0x00, 0xEB, 0x31, + 0x08, 0x00, 0x00, 0xA8, 0x76, 0xFE, + 0xFE, 0x08, 0xEB, 0x31, 0x08, 0x20, + 0x00, 0x00, 0x76, 0xFF, 0xFF, 0x18, + 0xED, 0x31, 0x08, 0x20, 0x00, 0x00, + 0x26, 0x10, 0x04, 0x10, 0xF5, 0x3C, + 0x01, 0x3C, 0x00, 0x08, 0x01, 0x12, + 0x3C, 0x11, 0x3C, 0x00, 0x08, 0x01, + 0x0B, 0x08, 0x00, 0x6D, 0xEC, 0x31, + 0xAE, 0x20, 0x00, 0x06, 0xED, 0x4D, + 0x08, 0x00, 0x00, 0x67, 0x80, 0x6F, + 0x00, 0x01, 0x0B, 0x6F, 0x00, 0x02, + 0x2E, 0x76, 0xEE, 0x01, 0x48, 0x06, + 0x01, 0x39, 0xED, 0x4D, 0x18, 0x00, + 0x02, 0xED, 0x4D, 0x08, 0x00, 0x04, + 0x14, 0x06, 0xA4, 0xED, 0x31, 0x22, + 0x00, 0x00, 0xAC, 0x76, 0xEE, 0x07, + 0x48, 0x6D, 0x22, 0x01, 0x1E, 0x08, + 0x01, 0x58, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xAC, 0x06, 0xFF, 0xBA, 0x3C, + 0x00, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x30, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x00, + 0x00, 0xA2, 0x91, 0x00, 0x9C, 0x3C, + 0x80, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x20, + 0x00, 0x04, 0x42, 0x10, 0x90, 0x08, + 0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06, + 0xA4, 0x41, 0x08, 0x00, 0xB6, 0xED, + 0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22, + 0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB, + 0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05, + 0xFF, 0xE6, 0xA0, 0x31, 0x20, 0x00, + 0x06, 0xEB, 0x31, 0x08, 0x20, 0x00, + 0x04, 0x3C, 0x20, 0xEB, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x3C, 0x10, 0xEB, + 0x31, 0x08, 0x20, 0x00, 0x00, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x00, 0x04, + 0x10, 0xF7, 0xED, 0x31, 0x08, 0x20, + 0x00, 0x04, 0x42, 0x10, 0x90, 0x08, + 0xEC, 0x31, 0xAE, 0x20, 0x00, 0x06, + 0xA4, 0x41, 0x08, 0x00, 0x68, 0xED, + 0x41, 0x28, 0x7D, 0xFF, 0xFF, 0x22, + 0xB3, 0x40, 0x98, 0x2A, 0x32, 0xEB, + 0x41, 0x28, 0xB4, 0x43, 0xFC, 0x05, + 0xFF, 0xE6, 0x48, 0x04, 0xEB, 0x31, + 0x08, 0x20, 0x00, 0x04, 0xEB, 0x31, + 0x18, 0x20, 0x00, 0x02, 0x3C, 0x11, + 0xEB, 0x31, 0x18, 0x20, 0x00, 0x00, + 0xED, 0x31, 0x08, 0x20, 0x00, 0x00, + 0x04, 0x10, 0xF7, 0xED, 0x31, 0x08, + 0x20, 0x00, 0x02, 0x66, 0x00, 0x6F, + 0x00, 0x01, 0x16, 0x76, 0xEE, 0x06, + 0x48, 0x4A, 0x1E, 0x48, 0x04, 0xED, + 0x31, 0x08, 0x20, 0x00, 0x04, 0xEB, + 0x31, 0x08, 0x00, 0x00, 0xA4, 0x48, + 0x04, 0xED, 0x31, 0x08, 0x20, 0x00, + 0x04, 0xEB, 0x31, 0x08, 0x00, 0x00, + 0xA2, 0x48, 0x04, 0x20, 0x20, 0x4A, + 0x7C, 0x46, 0x82, 0x50, 0x05, 0x50, + 0x15, 0xB5, 0x1E, 0x98, 0xED, 0x31, + 0x08, 0x00, 0x00, 0xA8, 0x10, 0x47, + 0x3B, 0x2C, 0x01, 0xDB, 0x40, 0x11, + 0x98, 0xC1, 0x1E, 0x98, 0x10, 0x07, + 0x30, 0xF9, 0x40, 0x07, 0x18, 0x98, + 0x2A, 0x10, 0xEB, 0x31, 0x08, 0x00, + 0x00, 0xA8, 0xA4, 0x1E, 0x98, 0xBB, + 0x1E, 0x98, 0x50, 0x14, 0x50, 0x04, + 0x46, 0x83, 0x48, 0x04, 0x02, 0x01, + 0x00, 0x50, 0x05, 0x50, 0x15, 0x10, + 0x87, 0x3F, 0x90, 0x2B, 0x18, 0x01, + 0x00, 0xC0, 0x31, 0x00, 0x00, 0xAE, + 0xDF, 0x41, 0x00, 0x08, 0x00, 0x1A, + 0x42, 0x11, 0x67, 0x01, 0xDF, 0x41, + 0x02, 0x08, 0x00, 0x10, 0x42, 0x11, + 0x62, 0x01, 0xB4, 0x43, 0x4A, 0x68, + 0x50, 0x14, 0x50, 0x04, 0x24, 0x10, + 0x48, 0x04, 0xF2, 0x31, 0x00, 0x01, + 0x00, 0x00, 0xAE, 0xF6, 0x31, 0x00, + 0x01, 0x00, 0x00, 0xAE, 0x62, 0xE4, + 0xE5, 0x61, 0x04, 0x48, 0x04, 0xE5, + 0x63, 0x05, 0x48, 0x04, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x00 }; #endif diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 29d0a72f0d65..d6421b9b5981 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -15,7 +15,7 @@ License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ------------------------------------------------------------------------------*/ + -------------------------------------------------------------------------*/ #include #include @@ -80,19 +80,19 @@ MODULE_SUPPORTED_DEVICE("FT1000"); #define MAX_RCV_LOOP 100 -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_fifo_len -// Description: This function will read the ASIC Uplink FIFO status register -// which will return the number of bytes remaining in the Uplink FIFO. -// Sixteen bytes are subtracted to make sure that the ASIC does not -// reach its threshold. -// Input: -// dev - network device structure -// Output: -// value - number of bytes available in the ASIC Uplink FIFO. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_fifo_len + Description: This function will read the ASIC Uplink FIFO status register + which will return the number of bytes remaining in the Uplink FIFO. + Sixteen bytes are subtracted to make sure that the ASIC does not + reach its threshold. + Input: + dev - network device structure + Output: + value - number of bytes available in the ASIC Uplink FIFO. + + -------------------------------------------------------------------------*/ static inline u16 ft1000_read_fifo_len(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -103,25 +103,25 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) return (ft1000_read_reg(dev, FT1000_REG_MAG_UFSR) - 16); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram -// Description: This function will read the specific area of dpram -// (Electrabuzz ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram + Description: This function will read the specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u16 ft1000_read_dpram(struct net_device *dev, int offset) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); data = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA); @@ -130,54 +130,54 @@ u16 ft1000_read_dpram(struct net_device *dev, int offset) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram -// Description: This function will write to a specific area of dpram -// (Electrabuzz ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram + Description: This function will write to a specific area of dpram + (Electrabuzz ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram(struct net_device *dev, int offset, u16 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, value); spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram_mag_16 -// Description: This function will read the specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram_mag_16 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u16 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); - // check if we want to read upper or lower 32-bit word + /* check if we want to read upper or lower 32-bit word */ if (Index) { data = ft1000_read_reg(dev, FT1000_REG_MAG_DPDATAL); } else { @@ -188,26 +188,26 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram_mag_16 -// Description: This function will write to a specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram_mag_16 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, int offset, u16 value, int Index) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); if (Index) { @@ -218,25 +218,25 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_read_dpram_mag_32 -// Description: This function will read the specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// Output: -// value - value of dpram -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_read_dpram_mag_32 + Description: This function will read the specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + Output: + value - value of dpram + + -------------------------------------------------------------------------*/ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; u32 data; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); data = inl(dev->base_addr + FT1000_REG_MAG_DPDATAL); @@ -245,41 +245,41 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) return (data); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_write_dpram_mag_32 -// Description: This function will write to a specific area of dpram -// (Magnemite ASIC only) -// Input: -// dev - device structure -// offset - index of dpram -// value - value to write -// Output: -// none. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_write_dpram_mag_32 + Description: This function will write to a specific area of dpram + (Magnemite ASIC only) + Input: + dev - device structure + offset - index of dpram + value - value to write + Output: + none. + + -------------------------------------------------------------------------*/ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) { struct ft1000_info *info = netdev_priv(dev); unsigned long flags; - // Provide mutual exclusive access while reading ASIC registers. + /* Provide mutual exclusive access while reading ASIC registers. */ spin_lock_irqsave(&info->dpram_lock, flags); ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, offset); outl(value, dev->base_addr + FT1000_REG_MAG_DPDATAL); spin_unlock_irqrestore(&info->dpram_lock, flags); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_enable_interrupts -// Description: This function will enable interrupts base on the current interrupt mask. -// Input: -// dev - device structure -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_enable_interrupts + Description: This function will enable interrupts base on the current interrupt mask. + Input: + dev - device structure + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_enable_interrupts(struct net_device *dev) { u16 tempword; @@ -292,16 +292,16 @@ static void ft1000_enable_interrupts(struct net_device *dev) tempword); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_disable_interrupts -// Description: This function will disable all interrupts. -// Input: -// dev - device structure -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_disable_interrupts + Description: This function will disable all interrupts. + Input: + dev - device structure + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_disable_interrupts(struct net_device *dev) { u16 tempword; @@ -314,17 +314,17 @@ static void ft1000_disable_interrupts(struct net_device *dev) tempword); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_asic -// Description: This function will call the Card Service function to reset the -// ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_reset_asic + Description: This function will call the Card Service function to reset the + ASIC. + Input: + dev - device structure + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_reset_asic(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -335,21 +335,23 @@ static void ft1000_reset_asic(struct net_device *dev) (*info->ft1000_reset) (pcmcia->link); - // Let's use the register provided by the Magnemite ASIC to reset the - // ASIC and DSP. + /* + * Let's use the register provided by the Magnemite ASIC to reset the + * ASIC and DSP. + */ if (info->AsicID == MAGNEMITE_ID) { ft1000_write_reg(dev, FT1000_REG_RESET, (DSP_RESET_BIT | ASIC_RESET_BIT)); } mdelay(1); if (info->AsicID == ELECTRABUZZ_ID) { - // set watermark to -1 in order to not generate an interrupt + /* set watermark to -1 in order to not generate an interrupt */ ft1000_write_reg(dev, FT1000_REG_WATERMARK, 0xffff); } else { - // set watermark to -1 in order to not generate an interrupt + /* set watermark to -1 in order to not generate an interrupt */ ft1000_write_reg(dev, FT1000_REG_MAG_WATERMARK, 0xffff); } - // clear interrupts + /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); @@ -358,17 +360,17 @@ static void ft1000_reset_asic(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_card -// Description: This function will reset the card -// Input: -// dev - device structure -// Output: -// status - false (card reset fail) -// true (card reset successful) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_reset_card + Description: This function will reset the card + Input: + dev - device structure + Output: + status - false (card reset fail) + true (card reset successful) + + -------------------------------------------------------------------------*/ static int ft1000_reset_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -384,9 +386,9 @@ static int ft1000_reset_card(struct net_device *dev) info->squeseqnum = 0; ft1000_disable_interrupts(dev); -// del_timer(&poll_timer); + /* del_timer(&poll_timer); */ - // Make sure we free any memory reserve for provisioning + /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { DEBUG(0, "ft1000_hw:ft1000_reset_card:deleting provisioning record\n"); @@ -406,7 +408,7 @@ static int ft1000_reset_card(struct net_device *dev) (DSP_RESET_BIT | ASIC_RESET_BIT)); } - // Copy DSP session record into info block if this is not a coldstart + /* Copy DSP session record into info block if this is not a coldstart */ if (ft1000_card_present == 1) { spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { @@ -430,29 +432,29 @@ static int ft1000_reset_card(struct net_device *dev) DEBUG(1, "ft1000_hw:ft1000_reset_card:resetting ASIC\n"); mdelay(10); - //reset ASIC + /* reset ASIC */ ft1000_reset_asic(dev); DEBUG(1, "ft1000_hw:ft1000_reset_card:downloading dsp image\n"); if (info->AsicID == MAGNEMITE_ID) { - // Put dsp in reset and take ASIC out of reset + /* Put dsp in reset and take ASIC out of reset */ DEBUG(0, "ft1000_hw:ft1000_reset_card:Put DSP in reset and take ASIC out of reset\n"); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); - // Setting MAGNEMITE ASIC to big endian mode + /* Setting MAGNEMITE ASIC to big endian mode */ ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE); - // Download bootloader + /* Download bootloader */ card_bootload(dev); - // Take DSP out of reset + /* Take DSP out of reset */ ft1000_write_reg(dev, FT1000_REG_RESET, 0); - // FLARION_DSP_ACTIVE; + /* FLARION_DSP_ACTIVE; */ mdelay(10); DEBUG(0, "ft1000_hw:ft1000_reset_card:Take DSP out of reset\n"); - // Wait for 0xfefe indicating dsp ready before starting download + /* Wait for 0xfefe indicating dsp ready before starting download */ for (i = 0; i < 50; i++) { tempword = ft1000_read_dpram_mag_16(dev, FT1000_MAG_DPRAM_FEFE, @@ -470,7 +472,7 @@ static int ft1000_reset_card(struct net_device *dev) } } else { - // Take DSP out of reset + /* Take DSP out of reset */ ft1000_write_reg(dev, FT1000_REG_RESET, ~DSP_RESET_BIT); mdelay(10); } @@ -485,17 +487,19 @@ static int ft1000_reset_card(struct net_device *dev) mdelay(10); if (info->AsicID == ELECTRABUZZ_ID) { - // Need to initialize the FIFO length counter to zero in order to sync up - // with the DSP + /* + * Need to initialize the FIFO length counter to zero in order to sync up + * with the DSP + */ info->fifo_cnt = 0; ft1000_write_dpram(dev, FT1000_FIFO_LEN, info->fifo_cnt); - // Initialize DSP heartbeat area to ho + /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram(dev, FT1000_HI_HO, ho); tempword = ft1000_read_dpram(dev, FT1000_HI_HO); DEBUG(1, "ft1000_hw:ft1000_reset_asic:hi_ho value = 0x%x\n", tempword); } else { - // Initialize DSP heartbeat area to ho + /* Initialize DSP heartbeat area to ho */ ft1000_write_dpram_mag_16(dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); tempword = @@ -509,40 +513,44 @@ static int ft1000_reset_card(struct net_device *dev) ft1000_enable_interrupts(dev); /* Schedule heartbeat process to run every 2 seconds */ -// poll_timer.expires = jiffies + (2*HZ); -// poll_timer.data = (u_long)dev; -// add_timer(&poll_timer); + /* poll_timer.expires = jiffies + (2*HZ); */ + /* poll_timer.data = (u_long)dev; */ + /* add_timer(&poll_timer); */ return true; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_chkcard -// Description: This function will check if the device is presently available on -// the system. -// Input: -// dev - device structure -// Output: -// status - false (device is not present) -// true (device is present) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_chkcard + Description: This function will check if the device is presently available on + the system. + Input: + dev - device structure + Output: + status - false (device is not present) + true (device is present) + + -------------------------------------------------------------------------*/ static int ft1000_chkcard(struct net_device *dev) { u16 tempword; - // Mask register is used to check for device presence since it is never - // set to zero. + /* + * Mask register is used to check for device presence since it is never + * set to zero. + */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_IMASK); if (tempword == 0) { DEBUG(1, "ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); return false; } - // The system will return the value of 0xffff for the version register - // if the device is not present. + /* + * The system will return the value of 0xffff for the version register + * if the device is not present. + */ tempword = ft1000_read_reg(dev, FT1000_REG_ASIC_ID); if (tempword == 0xffff) { DEBUG(1, @@ -553,17 +561,17 @@ static int ft1000_chkcard(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_hbchk -// Description: This function will perform the heart beat check of the DSP as -// well as the ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_hbchk + Description: This function will perform the heart beat check of the DSP as + well as the ASIC. + Input: + dev - device structure + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_hbchk(u_long data) { struct net_device *dev = (struct net_device *)data; @@ -574,7 +582,7 @@ static void ft1000_hbchk(u_long data) info = netdev_priv(dev); if (info->CardReady == 1) { - // Perform dsp heartbeat check + /* Perform dsp heartbeat check */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_dpram(dev, FT1000_HI_HO); } else { @@ -585,7 +593,7 @@ static void ft1000_hbchk(u_long data) } DEBUG(1, "ft1000_hw:ft1000_hbchk:hi_ho value = 0x%x\n", tempword); - // Let's perform another check if ho is not detected + /* Let's perform another check if ho is not detected */ if (tempword != ho) { if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_dpram(dev, FT1000_HI_HO); @@ -639,7 +647,7 @@ static void ft1000_hbchk(u_long data) } tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); - // Let's check doorbell again if fail + /* Let's check doorbell again if fail */ if (tempword & FT1000_DB_HB) { tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); } @@ -686,8 +694,10 @@ static void ft1000_hbchk(u_long data) add_timer(&poll_timer); return; } - // Set dedicated area to hi and ring appropriate doorbell according - // to hi/ho heartbeat protocol + /* + * Set dedicated area to hi and ring appropriate doorbell according + * to hi/ho heartbeat protocol + */ if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_dpram(dev, FT1000_HI_HO, hi); } else { @@ -703,7 +713,7 @@ static void ft1000_hbchk(u_long data) (dev, FT1000_MAG_HI_HO, FT1000_MAG_HI_HO_INDX)); } - // Let's write hi again if fail + /* Let's write hi again if fail */ if (tempword != hi) { if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_dpram(dev, FT1000_HI_HO, hi); @@ -774,14 +784,14 @@ static void ft1000_hbchk(u_long data) add_timer(&poll_timer); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_send_cmd -// Description: -// Input: -// Output: -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_send_cmd + Description: + Input: + Output: + + -------------------------------------------------------------------------*/ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { struct ft1000_info *info = netdev_priv(dev); @@ -790,17 +800,19 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, unsigned long flags; size += sizeof(struct pseudo_hdr); - // check for odd byte and increment to 16-bit word align value + /* check for odd byte and increment to 16-bit word align value */ if ((size & 0x0001)) { size++; } DEBUG(1, "FT1000:ft1000_send_cmd:total length = %d\n", size); DEBUG(1, "FT1000:ft1000_send_cmd:length = %d\n", ntohs(*ptempbuffer)); - // put message into slow queue area - // All messages are in the form total_len + pseudo header + message body + /* + * put message into slow queue area + * All messages are in the form total_len + pseudo header + message body + */ spin_lock_irqsave(&info->dpram_lock, flags); - // Make sure SLOWQ doorbell is clear + /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); i=0; while (tempword & FT1000_DB_DPRAM_TX) { @@ -816,9 +828,9 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_TX_BASE); - // Write total length to dpram + /* Write total length to dpram */ ft1000_write_reg(dev, FT1000_REG_DPRAM_DATA, size); - // Write pseudo header and messgae body + /* Write pseudo header and messgae body */ for (i = 0; i < (size >> 1); i++) { DEBUG(1, "FT1000:ft1000_send_cmd:data %d = 0x%x\n", i, *ptempbuffer); @@ -828,9 +840,9 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, } else { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE); - // Write total length to dpram + /* Write total length to dpram */ ft1000_write_reg(dev, FT1000_REG_MAG_DPDATAH, htons(size)); - // Write pseudo header and messgae body + /* Write pseudo header and messgae body */ ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, FT1000_DPRAM_MAG_TX_BASE + 1); for (i = 0; i < (size >> 2); i++) { @@ -850,23 +862,23 @@ static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, } spin_unlock_irqrestore(&info->dpram_lock, flags); - // ring doorbell to notify DSP that we have a message ready + /* ring doorbell to notify DSP that we have a message ready */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_DPRAM_TX); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_receive_cmd -// Description: This function will read a message from the dpram area. -// Input: -// dev - network device structure -// pbuffer - caller supply address to buffer -// pnxtph - pointer to next pseudo header -// Output: -// Status = 0 (unsuccessful) -// = 1 (successful) -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_receive_cmd + Description: This function will read a message from the dpram area. + Input: + dev - network device structure + pbuffer - caller supply address to buffer + pnxtph - pointer to next pseudo header + Output: + Status = 0 (unsuccessful) + = 1 (successful) + + -------------------------------------------------------------------------*/ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) { @@ -919,7 +931,7 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, FT1000_REG_MAG_DPDATAH); pbuffer++; } - //copy odd aligned word + /* copy odd aligned word */ *pbuffer = inw(dev->base_addr + FT1000_REG_MAG_DPDATAL); DEBUG(1, "ft1000_hw:received data = 0x%x\n", *pbuffer); pbuffer++; @@ -928,14 +940,16 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, pbuffer++; } if (size & 0x0001) { - //copy odd byte from fifo + /* copy odd byte from fifo */ tempword = ft1000_read_reg(dev, FT1000_REG_DPRAM_DATA); *pbuffer = ntohs(tempword); } spin_unlock_irqrestore(&info->dpram_lock, flags); - // Check if pseudo header checksum is good - // Calculate pseudo header checksum + /* + * Check if pseudo header checksum is good + * Calculate pseudo header checksum + */ tempword = *ppseudohdr++; for (i = 1; i < 7; i++) { tempword ^= *ppseudohdr++; @@ -943,24 +957,24 @@ static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, if ((tempword != *ppseudohdr)) { DEBUG(1, "FT1000:ft1000_receive_cmd:Pseudo header checksum mismatch\n"); - // Drop this message + /* Drop this message */ return false; } return true; } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_proc_drvmsg -// Description: This function will process the various driver messages. -// Input: -// dev - device structure -// pnxtph - pointer to next pseudo header -// Output: -// none -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_proc_drvmsg + Description: This function will process the various driver messages. + Input: + dev - device structure + pnxtph - pointer to next pseudo header + Output: + none + + -------------------------------------------------------------------------*/ static void ft1000_proc_drvmsg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -988,7 +1002,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ( ft1000_receive_cmd(dev, &cmdbuffer[0], MAX_CMD_SQSIZE, &tempword) ) { - // Get the message type which is total_len + PSEUDO header + msgtype + message body + /* Get the message type which is total_len + PSEUDO header + msgtype + message body */ pdrvmsg = (struct drv_msg *) & cmdbuffer[0]; msgtype = ntohs(pdrvmsg->type); DEBUG(1, "Command message type = 0x%x\n", msgtype); @@ -999,7 +1013,7 @@ static void ft1000_proc_drvmsg(struct net_device *dev) mdelay(25); while (list_empty(&info->prov_list) == 0) { DEBUG(0, "Sending a provisioning message\n"); - // Make sure SLOWQ doorbell is clear + /* Make sure SLOWQ doorbell is clear */ tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); i = 0; @@ -1018,10 +1032,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) pmsg = (u16 *) ptr->pprov_data; ppseudo_hdr = (struct pseudo_hdr *) pmsg; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; DEBUG(1, "checksum = 0x%x\n", ppseudo_hdr->checksum); @@ -1036,8 +1050,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) kfree(ptr->pprov_data); kfree(ptr); } - // Indicate adapter is ready to take application messages after all - // provisioning messages are sent + /* + * Indicate adapter is ready to take application messages after all + * provisioning messages are sent + */ info->CardReady = 1; break; case MEDIA_STATE: @@ -1118,8 +1134,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) break; case DSP_GET_INFO: DEBUG(1, "FT1000:drivermsg:Got DSP_GET_INFO\n"); - // copy dsp info block to dsp - // allow any outstanding ioctl to finish + /* + * copy dsp info block to dsp + * allow any outstanding ioctl to finish + */ mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { @@ -1132,8 +1150,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - // Put message into Slow Queue - // Form Pseudo header + /* + * Put message into Slow Queue + * Form Pseudo header + */ pmsg = (u16 *) info->DSPInfoBlk; ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = @@ -1147,11 +1167,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ppseudo_hdr->rsvd1 = 0; ppseudo_hdr->rsvd2 = 0; ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id + /* Insert application id */ ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; for (i = 1; i < 7; i++) { ppseudo_hdr->checksum ^= *pmsg++; @@ -1165,8 +1185,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) break; case GET_DRV_ERR_RPT_MSG: DEBUG(1, "FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); - // copy driver error message to dsp - // allow any outstanding ioctl to finish + /* + * copy driver error message to dsp + * allow any outstanding ioctl to finish + */ mdelay(10); tempword = ft1000_read_reg(dev, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { @@ -1179,8 +1201,10 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - // Put message into Slow Queue - // Form Pseudo header + /* + * Put message into Slow Queue + * Form Pseudo header + */ pmsg = (u16 *) & tempbuffer[0]; ppseudo_hdr = (struct pseudo_hdr *) pmsg; ppseudo_hdr->length = htons(0x0012); @@ -1193,11 +1217,11 @@ static void ft1000_proc_drvmsg(struct net_device *dev) ppseudo_hdr->rsvd1 = 0; ppseudo_hdr->rsvd2 = 0; ppseudo_hdr->qos_class = 0; - // Insert slow queue sequence number + /* Insert slow queue sequence number */ ppseudo_hdr->seq_num = info->squeseqnum++; - // Insert application id + /* Insert application id */ ppseudo_hdr->portsrc = 0; - // Calculate new checksum + /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; for (i=1; i<7; i++) { ppseudo_hdr->checksum ^= *pmsg++; @@ -1228,18 +1252,18 @@ static void ft1000_proc_drvmsg(struct net_device *dev) } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_parse_dpram_msg -// Description: This function will parse the message received from the DSP -// via the DPRAM interface. -// Input: -// dev - device structure -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_parse_dpram_msg + Description: This function will parse the message received from the DSP + via the DPRAM interface. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_parse_dpram_msg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -1255,7 +1279,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) DEBUG(1, "Doorbell = 0x%x\n", doorbell); if (doorbell & FT1000_ASIC_RESET_REQ) { - // Copy DSP session record from info block + /* Copy DSP session record from info block */ spin_lock_irqsave(&info->dpram_lock, flags); if (info->AsicID == ELECTRABUZZ_ID) { ft1000_write_reg(dev, FT1000_REG_DPRAM_ADDR, @@ -1274,7 +1298,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } spin_unlock_irqrestore(&info->dpram_lock, flags); - // clear ASIC RESET request + /* clear ASIC RESET request */ ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_ASIC_RESET_REQ); DEBUG(1, "Got an ASIC RESET Request\n"); @@ -1282,7 +1306,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) FT1000_ASIC_RESET_DSP); if (info->AsicID == MAGNEMITE_ID) { - // Setting MAGNEMITE ASIC to big endian mode + /* Setting MAGNEMITE ASIC to big endian mode */ ft1000_write_reg(dev, FT1000_REG_SUP_CTRL, HOST_INTF_BE); } @@ -1315,8 +1339,10 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) if ((total_len < MAX_CMD_SQSIZE) && (total_len > sizeof(struct pseudo_hdr))) { total_len += nxtph; cnt = 0; - // ft1000_read_reg will return a value that needs to be byteswap - // in order to get DSP_QID_OFFSET. + /* + * ft1000_read_reg will return a value that needs to be byteswap + * in order to get DSP_QID_OFFSET. + */ if (info->AsicID == ELECTRABUZZ_ID) { portid = (ft1000_read_dpram @@ -1332,7 +1358,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) DEBUG(1, "DSP_QID = 0x%x\n", portid); if (portid == DRIVERID) { - // We are assumming one driver message from the DSP at a time. + /* We are assumming one driver message from the DSP at a time. */ ft1000_proc_drvmsg(dev); } } @@ -1340,7 +1366,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } if (doorbell & FT1000_DB_COND_RESET) { - // Reset ASIC and DSP + /* Reset ASIC and DSP */ if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = ft1000_read_dpram(dev, FT1000_DSP_TIMER0); @@ -1370,7 +1396,7 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) ft1000_write_reg(dev, FT1000_REG_DOORBELL, FT1000_DB_COND_RESET); } - // let's clear any unexpected doorbells from DSP + /* let's clear any unexpected doorbells from DSP */ doorbell = doorbell & ~(FT1000_DB_DPRAM_RX | FT1000_ASIC_RESET_REQ | FT1000_DB_COND_RESET | 0xff00); @@ -1383,18 +1409,18 @@ static int ft1000_parse_dpram_msg(struct net_device *dev) } -//--------------------------------------------------------------------------- -// -// Function: ft1000_flush_fifo -// Description: This function will flush one packet from the downlink -// FIFO. -// Input: -// dev - device structure -// drv_err - driver error causing the flush fifo -// Output: -// None. -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_flush_fifo + Description: This function will flush one packet from the downlink + FIFO. + Input: + dev - device structure + drv_err - driver error causing the flush fifo + Output: + None. + + -------------------------------------------------------------------------*/ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) { struct ft1000_info *info = netdev_priv(dev); @@ -1432,7 +1458,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) ft1000_reset_card(dev); return; } else { - // Flush corrupted pkt from FIFO + /* Flush corrupted pkt from FIFO */ i = 0; do { if (info->AsicID == ELECTRABUZZ_ID) { @@ -1447,8 +1473,10 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) inw(dev->base_addr + FT1000_REG_MAG_DFSR); } i++; - // This should never happen unless the ASIC is broken. - // We must reset to recover. + /* + * This should never happen unless the ASIC is broken. + * We must reset to recover. + */ if ((i > 2048) || (tempword == 0)) { if (info->AsicID == ELECTRABUZZ_ID) { info->DSP_TIME[0] = @@ -1482,17 +1510,19 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) FT1000_MAG_DSP_TIMER3_INDX); } if (tempword == 0) { - // Let's check if ASIC reads are still ok by reading the Mask register - // which is never zero at this point of the code. + /* + * Let's check if ASIC reads are still ok by reading the Mask register + * which is never zero at this point of the code. + */ tempword = inw(dev->base_addr + FT1000_REG_SUP_IMASK); if (tempword == 0) { - // This indicates that we can not communicate with the ASIC + /* This indicates that we can not communicate with the ASIC */ info->DrvErrNum = FIFO_FLUSH_BADCNT; } else { - // Let's assume that we really flush the FIFO + /* Let's assume that we really flush the FIFO */ pcmcia->PktIntfErr++; return; } @@ -1506,9 +1536,9 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) if (info->AsicID == ELECTRABUZZ_ID) { i++; DEBUG(0, "Flushing FIFO complete = %x\n", tempword); - // Flush last word in FIFO. + /* Flush last word in FIFO. */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); - // Update FIFO counter for DSP + /* Update FIFO counter for DSP */ i = i * 2; DEBUG(0, "Flush Data byte count to dsp = %d\n", i); info->fifo_cnt += i; @@ -1516,7 +1546,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) info->fifo_cnt); } else { DEBUG(0, "Flushing FIFO complete = %x\n", tempword); - // Flush last word in FIFO + /* Flush last word in FIFO */ templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); tempword = inw(dev->base_addr + FT1000_REG_SUP_STAT); DEBUG(0, "FT1000_REG_SUP_STAT = 0x%x\n", tempword); @@ -1529,19 +1559,19 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) } } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_up_pkt -// Description: This function will pull Flarion packets out of the Downlink -// FIFO and convert it to an ethernet packet. The ethernet packet will -// then be deliver to the TCP/IP stack. -// Input: -// dev - device structure -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_copy_up_pkt + Description: This function will pull Flarion packets out of the Downlink + FIFO and convert it to an ethernet packet. The ethernet packet will + then be deliver to the TCP/IP stack. + Input: + dev - device structure + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_copy_up_pkt(struct net_device *dev) { u16 tempword; @@ -1556,7 +1586,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) u32 templong; DEBUG(1, "ft1000_copy_up_pkt\n"); - // Read length + /* Read length */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); len = tempword; @@ -1570,7 +1600,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) if (len > ENET_MAX_SIZE) { DEBUG(0, "size of ethernet packet invalid\n"); if (info->AsicID == MAGNEMITE_ID) { - // Read High word to complete 32 bit access + /* Read High word to complete 32 bit access */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); } ft1000_flush_fifo(dev, DSP_PKTLEN_INFO); @@ -1582,7 +1612,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) if (skb == NULL) { DEBUG(0, "No Network buffers available\n"); - // Read High word to complete 32 bit access + /* Read High word to complete 32 bit access */ if (info->AsicID == MAGNEMITE_ID) { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); } @@ -1592,13 +1622,13 @@ static int ft1000_copy_up_pkt(struct net_device *dev) } pbuffer = (u8 *) skb_put(skb, len + 12); - // Pseudo header + /* Pseudo header */ if (info->AsicID == ELECTRABUZZ_ID) { for (i = 1; i < 7; i++) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); chksum ^= tempword; } - // read checksum value + /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); } else { tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); @@ -1625,7 +1655,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) DEBUG(1, "Pseudo = 0x%x\n", tempword); chksum ^= tempword; - // read checksum value + /* read checksum value */ tempword = ft1000_read_reg(dev, FT1000_REG_MAG_DFRH); DEBUG(1, "Pseudo = 0x%x\n", tempword); } @@ -1638,10 +1668,10 @@ static int ft1000_copy_up_pkt(struct net_device *dev) kfree_skb(skb); return FAILURE; } - //subtract the number of bytes read already + /* subtract the number of bytes read already */ ptemp = pbuffer; - // fake MAC address + /* fake MAC address */ *pbuffer++ = dev->dev_addr[0]; *pbuffer++ = dev->dev_addr[1]; *pbuffer++ = dev->dev_addr[2]; @@ -1666,7 +1696,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) } } - // Need to read one more word if odd byte + /* Need to read one more word if odd byte */ if (len & 0x0001) { tempword = ft1000_read_reg(dev, FT1000_REG_DFIFO); *pbuffer++ = (u8) (tempword >> 8); @@ -1679,7 +1709,7 @@ static int ft1000_copy_up_pkt(struct net_device *dev) *ptemplong++ = templong; } - // Need to read one more word if odd align. + /* Need to read one more word if odd align. */ if (len & 0x0003) { templong = inl(dev->base_addr + FT1000_REG_MAG_DFR); DEBUG(1, "Data = 0x%8x\n", templong); @@ -1699,11 +1729,11 @@ static int ft1000_copy_up_pkt(struct net_device *dev) netif_rx(skb); info->stats.rx_packets++; - // Add on 12 bytes for MAC address which was removed + /* Add on 12 bytes for MAC address which was removed */ info->stats.rx_bytes += (len + 12); if (info->AsicID == ELECTRABUZZ_ID) { - // track how many bytes have been read from FIFO - round up to 16 bit word + /* track how many bytes have been read from FIFO - round up to 16 bit word */ tempword = len + 16; if (tempword & 0x01) tempword++; @@ -1715,21 +1745,21 @@ static int ft1000_copy_up_pkt(struct net_device *dev) return SUCCESS; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_down_pkt -// Description: This function will take an ethernet packet and convert it to -// a Flarion packet prior to sending it to the ASIC Downlink -// FIFO. -// Input: -// dev - device structure -// packet - address of ethernet packet -// len - length of IP packet -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/*--------------------------------------------------------------------------- + + Function: ft1000_copy_down_pkt + Description: This function will take an ethernet packet and convert it to + a Flarion packet prior to sending it to the ASIC Downlink + FIFO. + Input: + dev - device structure + packet - address of ethernet packet + len - length of IP packet + Output: + status - FAILURE + SUCCESS + + -------------------------------------------------------------------------*/ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) { struct ft1000_info *info = netdev_priv(dev); @@ -1744,7 +1774,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) DEBUG(1, "ft1000_hw: copy_down_pkt()\n"); - // Check if there is room on the FIFO + /* Check if there is room on the FIFO */ if (len > ft1000_read_fifo_len(dev)) { udelay(10); if (len > ft1000_read_fifo_len(dev)) { @@ -1769,15 +1799,15 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) return SUCCESS; } } - // Create pseudo header and send pseudo/ip to hardware + /* Create pseudo header and send pseudo/ip to hardware */ if (info->AsicID == ELECTRABUZZ_ID) { pseudo.blk.length = len; } else { pseudo.blk.length = ntohs(len); } - pseudo.blk.source = DSPID; // Need to swap to get in correct order + pseudo.blk.source = DSPID; /* Need to swap to get in correct order */ pseudo.blk.destination = HOSTID; - pseudo.blk.portdest = NETWORKID; // Need to swap to get in correct order + pseudo.blk.portdest = NETWORKID; /* Need to swap to get in correct order */ pseudo.blk.portsrc = DSPAIRID; pseudo.blk.sh_str_id = 0; pseudo.blk.control = 0; @@ -1791,14 +1821,14 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) pseudo.blk.checksum ^= pseudo.buff[i]; } - // Production Mode + /* Production Mode */ if (info->AsicID == ELECTRABUZZ_ID) { - // copy first word to UFIFO_BEG reg + /* copy first word to UFIFO_BEG reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_BEG, pseudo.buff[0]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 0 BEG = 0x%04x\n", pseudo.buff[0]); - // copy subsequent words to UFIFO_MID reg + /* copy subsequent words to UFIFO_MID reg */ ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, pseudo.buff[1]); DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 1 MID = 0x%04x\n", pseudo.buff[1]); @@ -1821,7 +1851,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data 7 MID = 0x%04x\n", pseudo.buff[7]); - // Write PPP type + IP Packet into Downlink FIFO + /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 1) - 1; i++) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); @@ -1831,7 +1861,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) packet++; } - // Check for odd byte + /* Check for odd byte */ if (len & 0x0001) { ft1000_write_reg(dev, FT1000_REG_UFIFO_MID, htons(*packet)); @@ -1870,12 +1900,12 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) *(u32 *) & pseudo.buff[6]); plong = (u32 *) packet; - // Write PPP type + IP Packet into Downlink FIFO + /* Write PPP type + IP Packet into Downlink FIFO */ for (i = 0; i < (len >> 2); i++) { outl(*plong++, dev->base_addr + FT1000_REG_MAG_UFDR); } - // Check for odd alignment + /* Check for odd alignment */ if (len & 0x0003) { DEBUG(1, "ft1000_hw:ft1000_copy_down_pkt:data = 0x%8x\n", @@ -1886,7 +1916,7 @@ static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) } info->stats.tx_packets++; - // Add 14 bytes for MAC address plus ethernet type + /* Add 14 bytes for MAC address plus ethernet type */ info->stats.tx_bytes += (len + 14); return SUCCESS; } @@ -1931,7 +1961,7 @@ static int ft1000_close(struct net_device *dev) ft1000_disable_interrupts(dev); ft1000_write_reg(dev, FT1000_REG_RESET, DSP_RESET_BIT); - //reset ASIC + /* reset ASIC */ ft1000_reset_asic(dev); } return 0; @@ -1995,10 +2025,10 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) ft1000_disable_interrupts(dev); - // Read interrupt type + /* Read interrupt type */ inttype = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); - // Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type + /* Make sure we process all interrupt before leaving the ISR due to the edge trigger interrupt type */ while (inttype) { if (inttype & ISR_DOORBELL_PEND) ft1000_parse_dpram_msg(dev); @@ -2008,7 +2038,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) cnt = 0; do { - // Check if we have packets in the Downlink FIFO + /* Check if we have packets in the Downlink FIFO */ if (info->AsicID == ELECTRABUZZ_ID) { tempword = ft1000_read_reg(dev, @@ -2027,12 +2057,12 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) } while (cnt < MAX_RCV_LOOP); } - // clear interrupts + /* clear interrupts */ tempword = ft1000_read_reg(dev, FT1000_REG_SUP_ISR); DEBUG(1, "ft1000_hw: interrupt status register = 0x%x\n", tempword); ft1000_write_reg(dev, FT1000_REG_SUP_ISR, tempword); - // Read interrupt type + /* Read interrupt type */ inttype = ft1000_read_reg (dev, FT1000_REG_SUP_ISR); DEBUG(1,"ft1000_hw: interrupt status register after clear = 0x%x\n",inttype); } @@ -2044,7 +2074,7 @@ void stop_ft1000_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); struct prov_record *ptr; -// int cnt; + /* int cnt; */ DEBUG(0, "ft1000_hw: stop_ft1000_card()\n"); @@ -2053,7 +2083,7 @@ void stop_ft1000_card(struct net_device *dev) netif_stop_queue(dev); ft1000_disable_interrupts(dev); - // Make sure we free any memory reserve for provisioning + /* Make sure we free any memory reserve for provisioning */ while (list_empty(&info->prov_list) == 0) { ptr = list_entry(info->prov_list.next, struct prov_record, list); list_del(&ptr->list); @@ -2109,7 +2139,7 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, struct ft1000_pcmcia *pcmcia; struct net_device *dev; - static const struct net_device_ops ft1000ops = // Slavius 21.10.2009 due to kernel changes + static const struct net_device_ops ft1000ops = /* Slavius 21.10.2009 due to kernel changes */ { .ndo_open = &ft1000_open, .ndo_stop = &ft1000_close, @@ -2169,12 +2199,12 @@ struct net_device *init_ft1000_card(struct pcmcia_device *link, info->squeseqnum = 0; -// dev->hard_start_xmit = &ft1000_start_xmit; -// dev->get_stats = &ft1000_stats; -// dev->open = &ft1000_open; -// dev->stop = &ft1000_close; + /* dev->hard_start_xmit = &ft1000_start_xmit; */ + /* dev->get_stats = &ft1000_stats; */ + /* dev->open = &ft1000_open; */ + /* dev->stop = &ft1000_close; */ - dev->netdev_ops = &ft1000ops; // Slavius 21.10.2009 due to kernel changes + dev->netdev_ops = &ft1000ops; /* Slavius 21.10.2009 due to kernel changes */ DEBUG(0, "device name = %s\n", dev->name); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index 68a55ce69200..ffdc7f597a96 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -560,6 +560,8 @@ static long ft1000_ioctl(struct file *file, unsigned int command, /* Get the length field to see how many bytes to copy */ result = get_user(msgsz, (__u16 __user *)argp); + if (result) + break; msgsz = ntohs(msgsz); /* DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); */ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 12f333fa59b5..cab9cdf6273e 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -4,7 +4,6 @@ * This file is part of Express Card USB Driver */ -#include #include #include #include @@ -55,7 +54,7 @@ #define MAX_LENGTH 0x7f0 -// Temporary download mechanism for Magnemite +/* Temporary download mechanism for Magnemite */ #define DWNLD_MAG_TYPE_LOC 0x00 #define DWNLD_MAG_LEN_LOC 0x01 #define DWNLD_MAG_ADDR_LOC 0x02 @@ -74,36 +73,36 @@ #define HANDSHAKE_MAG_TIMEOUT_VALUE 0xF1F1 -// New Magnemite downloader +/* New Magnemite downloader */ #define DWNLD_MAG1_HANDSHAKE_LOC 0x00 #define DWNLD_MAG1_TYPE_LOC 0x01 #define DWNLD_MAG1_SIZE_LOC 0x02 #define DWNLD_MAG1_PS_HDR_LOC 0x03 struct dsp_file_hdr { - long version_id; // Version ID of this image format. - long package_id; // Package ID of code release. - long build_date; // Date/time stamp when file was built. - long commands_offset; // Offset to attached commands in Pseudo Hdr format. - long loader_offset; // Offset to bootloader code. - long loader_code_address; // Start address of bootloader. - long loader_code_end; // Where bootloader code ends. - long loader_code_size; - long version_data_offset; // Offset were scrambled version data begins. - long version_data_size; // Size, in words, of scrambled version data. - long nDspImages; // Number of DSP images in file. + long version_id; /* Version ID of this image format. */ + long package_id; /* Package ID of code release. */ + long build_date; /* Date/time stamp when file was built. */ + long commands_offset; /* Offset to attached commands in Pseudo Hdr format. */ + long loader_offset; /* Offset to bootloader code. */ + long loader_code_address; /* Start address of bootloader. */ + long loader_code_end; /* Where bootloader code ends. */ + long loader_code_size; + long version_data_offset; /* Offset were scrambled version data begins. */ + long version_data_size; /* Size, in words, of scrambled version data. */ + long nDspImages; /* Number of DSP images in file. */ }; #pragma pack(1) struct dsp_image_info { - long coff_date; // Date/time when DSP Coff image was built. - long begin_offset; // Offset in file where image begins. - long end_offset; // Offset in file where image begins. - long run_address; // On chip Start address of DSP code. - long image_size; // Size of image. - long version; // Embedded version # of DSP code. - unsigned short checksum; // DSP File checksum - unsigned short pad1; + long coff_date; /* Date/time when DSP Coff image was built. */ + long begin_offset; /* Offset in file where image begins. */ + long end_offset; /* Offset in file where image begins. */ + long run_address; /* On chip Start address of DSP code. */ + long image_size; /* Size of image. */ + long version; /* Embedded version # of DSP code. */ + unsigned short checksum; /* DSP File checksum */ + unsigned short pad1; }; @@ -151,7 +150,7 @@ static int check_usb_db(struct ft1000_usb *ft1000dev) } } - return HANDSHAKE_MAG_TIMEOUT_VALUE; + return -1; } /* gets the handshake and compares it with the expected value */ @@ -172,9 +171,8 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) ft1000dev->fcodeldr); ft1000dev->fcodeldr = 0; status = check_usb_db(ft1000dev); - if (status != STATUS_SUCCESS) { + if (status != 0) { DEBUG("get_handshake: check_usb_db failed\n"); - status = STATUS_FAILURE; break; } status = ft1000_write_register(ft1000dev, @@ -202,7 +200,7 @@ static u16 get_handshake(struct ft1000_usb *ft1000dev, u16 expected_value) } /* write the handshake value to the handshake location */ -static void put_handshake(struct ft1000_usb *ft1000dev,u16 handshake_value) +static void put_handshake(struct ft1000_usb *ft1000dev, u16 handshake_value) { u32 tempx; u16 tempword; @@ -268,11 +266,12 @@ static u16 get_handshake_usb(struct ft1000_usb *ft1000dev, u16 expected_value) return HANDSHAKE_TIMEOUT_VALUE; } -static void put_handshake_usb(struct ft1000_usb *ft1000dev,u16 handshake_value) +static void put_handshake_usb(struct ft1000_usb *ft1000dev, u16 handshake_value) { int i; - for (i=0; i<1000; i++); + for (i = 0; i < 1000; i++) + ; } static u16 get_request_type(struct ft1000_usb *ft1000dev) @@ -450,7 +449,7 @@ static int write_dpram32_and_check(struct ft1000_usb *ft1000dev, static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - int status = STATUS_SUCCESS; + int status = 0; u16 dpram; int loopcnt, i; u16 tempword; @@ -499,7 +498,7 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, } else { status = write_dpram32_and_check(ft1000dev, tempbuffer, dpram); - if (status != STATUS_SUCCESS) { + if (status != 0) { DEBUG("FT1000:download:Write failed tempbuffer[31] = 0x%x\n", tempbuffer[31]); break; } @@ -509,9 +508,9 @@ static int write_blk(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, return status; } -static void usb_dnld_complete (struct urb *urb) +static void usb_dnld_complete(struct urb *urb) { - //DEBUG("****** usb_dnld_complete\n"); + /* DEBUG("****** usb_dnld_complete\n"); */ } /* writes a block of DSP image to DPRAM @@ -523,7 +522,7 @@ static void usb_dnld_complete (struct urb *urb) static int write_blk_fifo(struct ft1000_usb *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - int Status = STATUS_SUCCESS; + int Status = 0; int byte_length; byte_length = word_length * 4; @@ -586,12 +585,12 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, /*NdisMSleep (100); */ if (word_length > MAX_LENGTH) { DEBUG("FT1000:download:Download error: Max length exceeded\n"); - return STATUS_FAILURE; + return -1; } if ((word_length * 2 + (long)c_file) > (long)endpoint) { /* Error, beyond boot code range.*/ DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundary.\n", (int)word_length); - return STATUS_FAILURE; + return -1; } if (word_length & 0x1) word_length++; @@ -601,11 +600,11 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, status = write_blk(ft1000dev, s_file, c_file, word_length); /*DEBUG("write_blk returned %d\n", status); */ } else { - write_blk_fifo(ft1000dev, s_file, c_file, word_length); + status = write_blk_fifo(ft1000dev, s_file, c_file, word_length); if (ft1000dev->usbboot == 0) ft1000dev->usbboot++; if (ft1000dev->usbboot == 1) - ft1000_write_dpram16(ft1000dev, + status |= ft1000_write_dpram16(ft1000dev, DWNLD_MAG1_PS_HDR_LOC, 0, 0); } return status; @@ -615,7 +614,7 @@ static int request_code_segment(struct ft1000_usb *ft1000dev, u16 **s_file, int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, u32 FileLength) { - int status = STATUS_SUCCESS; + int status = 0; u32 state; u16 handshake; struct pseudo_hdr *pseudo_header; @@ -651,9 +650,9 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, ft1000dev->usbboot = 0; ft1000dev->dspalive = 0xffff; - // - // Get version id of file, at first 4 bytes of file, for newer files. - // + /* + * Get version id of file, at first 4 bytes of file, for newer files. + */ state = STATE_START_DWNLD; @@ -670,7 +669,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, loader_code_size = file_hdr->loader_code_size; correct_version = false; - while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) { + while ((status == 0) && (state != STATE_DONE_FILE)) { switch (state) { case STATE_START_DWNLD: status = scram_start_dwnld(ft1000dev, &handshake, @@ -702,8 +701,8 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, /* Reposition ptrs to beginning of code section */ s_file = (u16 *) (boot_end); c_file = (u8 *) (boot_end); - //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); - //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); + /* DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); */ + /* DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); */ state = STATE_CODE_DWNLD; ft1000dev->fcodeldr = 1; break; @@ -717,7 +716,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n", request); - status = STATUS_FAILURE; + status = -1; break; } if (ft1000dev->usbboot) @@ -729,13 +728,13 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; + status = -1; } break; case STATE_CODE_DWNLD: - //DEBUG("FT1000:STATE_CODE_DWNLD\n"); + /* DEBUG("FT1000:STATE_CODE_DWNLD\n"); */ ft1000dev->bootmode = 0; if (ft1000dev->usbboot) handshake = @@ -773,7 +772,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Got Run address request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -789,7 +788,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Got Size request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -805,11 +804,11 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: - //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); + /* DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); */ if (!correct_version) { DEBUG ("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); - status = STATUS_FAILURE; + status = -1; break; } @@ -823,7 +822,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, case REQUEST_MAILBOX_DATA: DEBUG ("FT1000:download: REQUEST_MAILBOX_DATA\n"); - // Convert length from byte count to word count. Make sure we round up. + /* Convert length from byte count to word count. Make sure we round up. */ word_length = (long)(pft1000info->DSPInfoBlklen + 1) / 2; @@ -836,7 +835,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, * Position ASIC DPRAM auto-increment pointer. */ - data = (u16 *) & mailbox_data->data[0]; + data = (u16 *) &mailbox_data->data[0]; dpram = (u16) DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -850,7 +849,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, - (u8 *) & templong); + (u8 *) &templong); } break; @@ -939,7 +938,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } dsp_img_info++; - } //end of for + } /* end of for */ if (!correct_version) { /* @@ -948,7 +947,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad Version Request = 0x%x.\n", (int)requested_version); - status = STATUS_FAILURE; + status = -1; break; } break; @@ -957,7 +956,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, DEBUG ("FT1000:download:Download error: Bad request type=%d in CODE download state.\n", request); - status = STATUS_FAILURE; + status = -1; break; } if (ft1000dev->usbboot) @@ -969,7 +968,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } else { DEBUG ("FT1000:download:Download error: Handshake failed\n"); - status = STATUS_FAILURE; + status = -1; } break; @@ -1002,7 +1001,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, (u32) (pseudo_header_len + sizeof(struct pseudo_hdr))); - // link provisioning data + /* link provisioning data */ pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC); @@ -1013,7 +1012,7 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, list, &pft1000info-> prov_list); - // Move to next entry if available + /* Move to next entry if available */ c_file = (u8 *) ((unsigned long) c_file + @@ -1026,14 +1025,14 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, } } else { kfree(pbuffer); - status = STATUS_FAILURE; + status = -1; } } else { - status = STATUS_FAILURE; + status = -1; } } else { /* Checksum did not compute */ - status = STATUS_FAILURE; + status = -1; } DEBUG ("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", @@ -1046,23 +1045,23 @@ int scram_dnldr(struct ft1000_usb *ft1000dev, void *pFileStart, break; default: - status = STATUS_FAILURE; + status = -1; break; } /* End Switch */ - if (status != STATUS_SUCCESS) + if (status != 0) break; /**** // Check if Card is present status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { - break; + break; } status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { - break; + break; } ****/ diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 0d4931b2c2e2..a433e33049b5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1,12 +1,9 @@ -//===================================================== -// CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. -// -// -// This file is part of Express Card USB Driver -// -// $Id: -//==================================================== -#include +/* CopyRight (C) 2007 Qualcomm Inc. All Rights Reserved. +* +* +* This file is part of Express Card USB Driver +*/ + #include #include #include @@ -27,7 +24,9 @@ #define HARLEY_READ_OPERATION 0xc1 #define HARLEY_WRITE_OPERATION 0x41 -//#define JDEBUG +#if 0 +#define JDEBUG +#endif static int ft1000_submit_rx_urb(struct ft1000_info *info); @@ -35,32 +34,22 @@ static u8 tempbuffer[1600]; #define MAX_RCV_LOOP 100 -//--------------------------------------------------------------------------- -// Function: ft1000_control -// -// Parameters: ft1000_usb - device structure -// pipe - usb control message pipe -// request - control request -// requesttype - control message request type -// value - value to be written or 0 -// index - register index -// data - data buffer to hold the read/write values -// size - data size -// timeout - control message time out value -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function sends a control message via USB interface synchronously -// -// Notes: -// -//--------------------------------------------------------------------------- +/* send a control message via USB interface synchronously +* Parameters: ft1000_usb - device structure +* pipe - usb control message pipe +* request - control request +* requesttype - control message request type +* value - value to be written or 0 +* index - register index +* data - data buffer to hold the read/write values +* size - data size +* timeout - control message time out value +*/ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, u8 request, u8 requesttype, u16 value, u16 index, void *data, u16 size, int timeout) { - u16 ret; + int ret; if ((ft1000dev == NULL) || (ft1000dev->dev == NULL)) { DEBUG("ft1000dev or ft1000dev->dev == NULL, failure\n"); @@ -76,26 +65,11 @@ static int ft1000_control(struct ft1000_usb *ft1000dev, unsigned int pipe, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_register -// -// Parameters: ft1000_usb - device structure -// Data - data buffer to hold the value read -// nRegIndex - register index -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function returns the value in a register -// -// Notes: -// -//--------------------------------------------------------------------------- - -int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data, +/* returns the value in a register */ +int ft1000_read_register(struct ft1000_usb *ft1000dev, u16 *Data, u16 nRegIndx) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_rcvctrlpipe(ft1000dev->dev, 0), @@ -110,25 +84,11 @@ int ft1000_read_register(struct ft1000_usb *ft1000dev, u16* Data, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_register -// -// Parameters: ft1000_usb - device structure -// value - value to write into a register -// nRegIndex - register index -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes the value in a register -// -// Notes: -// -//--------------------------------------------------------------------------- +/* writes the value in a register */ int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value, u16 nRegIndx) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_sndctrlpipe(ft1000dev->dev, 0), @@ -143,27 +103,11 @@ int ft1000_write_register(struct ft1000_usb *ft1000dev, u16 value, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// cnt - number of byte read from DPRAM -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read a number of bytes from DPRAM -// -// Notes: -// -//--------------------------------------------------------------------------- - +/* read a number of bytes from DPRAM */ int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - int ret = STATUS_SUCCESS; + int ret = 0; ret = ft1000_control(ft1000dev, usb_rcvctrlpipe(ft1000dev->dev, 0), @@ -178,26 +122,11 @@ int ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write the data -// buffer - data buffer to write into DPRAM -// cnt - number of bytes to write -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes into DPRAM a number of bytes -// -// Notes: -// -//--------------------------------------------------------------------------- +/* writes into DPRAM a number of bytes */ int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { - int ret = STATUS_SUCCESS; + int ret = 0; if (cnt % 4) cnt += cnt - (cnt % 4); @@ -215,26 +144,11 @@ int ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_read_dpram16 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// hightlow - high or low 16 bit word -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read 16 bits from DPRAM -// -// Notes: -// -//--------------------------------------------------------------------------- +/* read 16 bits from DPRAM */ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u8 highlow) { - int ret = STATUS_SUCCESS; + int ret = 0; u8 request; if (highlow == 0) @@ -255,25 +169,11 @@ int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, return ret; } -//--------------------------------------------------------------------------- -// Function: ft1000_write_dpram16 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write the data -// value - 16bits value to write -// hightlow - high or low 16 bit word -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function writes into DPRAM a number of bytes -// -// Notes: -// -//--------------------------------------------------------------------------- -int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 highlow) +/* write into DPRAM a number of bytes */ +int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, + u8 highlow) { - int ret = STATUS_SUCCESS; + int ret = 0; u8 request; if (highlow == 0) @@ -294,33 +194,18 @@ int ft1000_write_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u16 value, u8 h return ret; } -//--------------------------------------------------------------------------- -// Function: fix_ft1000_read_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to read -// buffer - data buffer to hold the data read -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function read DPRAM 4 words at a time -// -// Notes: -// -//--------------------------------------------------------------------------- +/* read DPRAM 4 words at a time */ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) { u8 buf[16]; u16 pos; - int ret = STATUS_SUCCESS; + int ret = 0; pos = (indx / 4) * 4; ret = ft1000_read_dpram32(ft1000dev, pos, buf, 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { pos = (indx % 4) * 4; *buffer++ = buf[pos++]; *buffer++ = buf[pos++]; @@ -338,22 +223,7 @@ int fix_ft1000_read_dpram32(struct ft1000_usb *ft1000dev, u16 indx, } -//--------------------------------------------------------------------------- -// Function: fix_ft1000_write_dpram32 -// -// Parameters: ft1000_usb - device structure -// indx - starting address to write -// buffer - data buffer to write -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function write to DPRAM 4 words at a time -// -// Notes: -// -//--------------------------------------------------------------------------- +/* Description: This function write to DPRAM 4 words at a time */ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) { u16 pos1; @@ -362,13 +232,13 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) u8 buf[32]; u8 resultbuffer[32]; u8 *pdata; - int ret = STATUS_SUCCESS; + int ret = 0; pos1 = (indx / 4) * 4; pdata = buffer; ret = ft1000_read_dpram32(ft1000dev, pos1, buf, 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { pos2 = (indx % 4)*4; buf[pos2++] = *buffer++; buf[pos2++] = *buffer++; @@ -382,24 +252,24 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { buffer = pdata; for (i = 0; i < 16; i++) { if (buf[i] != resultbuffer[i]) - ret = STATUS_FAILURE; + ret = -1; } } - if (ret == STATUS_FAILURE) { + if (ret == -1) { ret = ft1000_write_dpram32(ft1000dev, pos1, (u8 *)&tempbuffer[0], 16); ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); - if (ret == STATUS_SUCCESS) { + if (ret == 0) { buffer = pdata; for (i = 0; i < 16; i++) { if (tempbuffer[i] != resultbuffer[i]) { - ret = STATUS_FAILURE; + ret = -1; DEBUG("%s Failed to write\n", __func__); } @@ -410,20 +280,10 @@ int fix_ft1000_write_dpram32(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer) return ret; } - -//------------------------------------------------------------------------ -// -// Function: card_reset_dsp -// -// Synopsis: This function is called to reset or activate the DSP -// -// Arguments: value - reset or activate -// -// Returns: None -//----------------------------------------------------------------------- +/* reset or activate the DSP */ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) { - u16 status = STATUS_SUCCESS; + int status = 0; u16 tempword; status = ft1000_write_register(ft1000dev, HOST_INTF_BE, @@ -457,21 +317,11 @@ static void card_reset_dsp(struct ft1000_usb *ft1000dev, bool value) } } -//--------------------------------------------------------------------------- -// Function: card_send_command -// -// Parameters: ft1000_usb - device structure -// ptempbuffer - command buffer -// size - command buffer size -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function sends a command to ASIC -// -// Notes: -// -//--------------------------------------------------------------------------- +/* send a command to ASIC +* Parameters: ft1000_usb - device structure +* ptempbuffer - command buffer +* size - command buffer size +*/ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, int size) { @@ -486,7 +336,7 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); if (temp & 0x0100) - msleep(10); + usleep_range(900, 1100); /* check for odd word */ size = size + 2; @@ -496,29 +346,21 @@ void card_send_command(struct ft1000_usb *ft1000dev, void *ptempbuffer, size += 4 - (size % 4); ft1000_write_dpram32(ft1000dev, 0, commandbuf, size); - msleep(1); + usleep_range(900, 1100); ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); - msleep(1); + usleep_range(900, 1100); ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); - if ((temp & 0x0100) == 0) { - //DEBUG("card_send_command: Message sent\n"); - } +#if 0 + if ((temp & 0x0100) == 0) + DEBUG("card_send_command: Message sent\n"); +#endif } -//-------------------------------------------------------------------------- -// -// Function: dsp_reload -// -// Synopsis: This function is called to load or reload the DSP -// -// Arguments: ft1000dev - device structure -// -// Returns: None -//----------------------------------------------------------------------- +/* load or reload the DSP */ int dsp_reload(struct ft1000_usb *ft1000dev) { int status; @@ -559,7 +401,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) /* call codeloader */ status = scram_dnldr(ft1000dev, pFileStart, FileLength); - if (status != STATUS_SUCCESS) + if (status != 0) return -EIO; msleep(1000); @@ -569,17 +411,7 @@ int dsp_reload(struct ft1000_usb *ft1000dev) return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_asic -// Description: This function will call the Card Service function to reset the -// ASIC. -// Input: -// dev - device structure -// Output: -// none -// -//--------------------------------------------------------------------------- +/* call the Card Service function to reset the ASIC. */ static void ft1000_reset_asic(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -607,18 +439,6 @@ static void ft1000_reset_asic(struct net_device *dev) DEBUG("ft1000_hw: interrupt status register = 0x%x\n", tempword); } - -//--------------------------------------------------------------------------- -// -// Function: ft1000_reset_card -// Description: This function will reset the card -// Input: -// dev - device structure -// Output: -// status - FALSE (card reset fail) -// TRUE (card reset successful) -// -//--------------------------------------------------------------------------- static int ft1000_reset_card(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); @@ -666,19 +486,7 @@ static int ft1000_reset_card(struct net_device *dev) return TRUE; } -//--------------------------------------------------------------------------- -// Function: ft1000_usb_transmit_complete -// -// Parameters: urb - transmitted usb urb -// -// -// Returns: none -// -// Description: This is the callback function when a urb is transmitted -// -// Notes: -// -//--------------------------------------------------------------------------- +/* callback function when a urb is transmitted */ static void ft1000_usb_transmit_complete(struct urb *urb) { @@ -690,22 +498,10 @@ static void ft1000_usb_transmit_complete(struct urb *urb) netif_wake_queue(ft1000dev->net); } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_down_pkt -// Description: This function will take an ethernet packet and convert it to -// a Flarion packet prior to sending it to the ASIC Downlink -// FIFO. -// Input: -// dev - device structure -// packet - address of ethernet packet -// len - length of IP packet -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- -static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) +/* take an ethernet packet and convert it to a Flarion +* packet prior to sending it to the ASIC Downlink FIFO. +*/ +static int ft1000_copy_down_pkt(struct net_device *netdev, u8 *packet, u16 len) { struct ft1000_info *pInfo = netdev_priv(netdev); struct ft1000_usb *pFt1000Dev = pInfo->priv; @@ -769,20 +565,10 @@ static int ft1000_copy_down_pkt(struct net_device *netdev, u8 * packet, u16 len) return 0; } -//--------------------------------------------------------------------------- -// Function: ft1000_start_xmit -// -// Parameters: skb - socket buffer to be sent -// dev - network device -// -// -// Returns: none -// -// Description: transmit a ethernet packet -// -// Notes: -// -//--------------------------------------------------------------------------- +/* transmit an ethernet packet +* Parameters: skb - socket buffer to be sent +* dev - network device +*/ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -827,20 +613,7 @@ err: return NETDEV_TX_OK; } -//--------------------------------------------------------------------------- -// Function: ft1000_open -// -// Parameters: -// dev - network device -// -// -// Returns: none -// -// Description: open the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* open the network driver */ static int ft1000_open(struct net_device *dev) { struct ft1000_info *pInfo = netdev_priv(dev); @@ -871,29 +644,14 @@ static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev) return &(info->stats); } -static const struct net_device_ops ftnet_ops = -{ +static const struct net_device_ops ftnet_ops = { .ndo_open = &ft1000_open, .ndo_stop = &ft1000_close, .ndo_start_xmit = &ft1000_start_xmit, .ndo_get_stats = &ft1000_netdev_stats, }; -//--------------------------------------------------------------------------- -// Function: init_ft1000_netdev -// -// Parameters: ft1000dev - device structure -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function initialize the network device -// -// Notes: -// -//--------------------------------------------------------------------------- - +/* initialize the network device */ static int ft1000_reset(void *dev) { ft1000_reset_card(dev); @@ -931,14 +689,14 @@ int init_ft1000_netdev(struct ft1000_usb *ft1000dev) card_nr[1] = '\0'; ret_val = kstrtou8(card_nr, 10, &gCardIndex); if (ret_val) { - printk(KERN_ERR "Can't parse netdev\n"); + netdev_err(ft1000dev->net, "Can't parse netdev\n"); goto err_net; } ft1000dev->CardNumber = gCardIndex; DEBUG("card number = %d\n", ft1000dev->CardNumber); } else { - printk(KERN_ERR "ft1000: Invalid device name\n"); + netdev_err(ft1000dev->net, "ft1000: Invalid device name\n"); ret_val = -ENXIO; goto err_net; } @@ -1014,20 +772,7 @@ err_net: return ret_val; } -//--------------------------------------------------------------------------- -// Function: reg_ft1000_netdev -// -// Parameters: ft1000dev - device structure -// -// -// Returns: STATUS_SUCCESS - success -// STATUS_FAILURE - failure -// -// Description: This function register the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* register the network driver */ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, struct usb_interface *intf) { @@ -1060,19 +805,9 @@ int reg_ft1000_netdev(struct ft1000_usb *ft1000dev, return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_copy_up_pkt -// Description: This function will take a packet from the FIFO up link and -// convert it into an ethernet packet and deliver it to the IP stack -// Input: -// urb - the receiving usb urb -// -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/* take a packet from the FIFO up link and +* convert it into an ethernet packet and deliver it to the IP stack +*/ static int ft1000_copy_up_pkt(struct urb *urb) { struct ft1000_info *info = urb->context; @@ -1090,9 +825,9 @@ static int ft1000_copy_up_pkt(struct urb *urb) if (ft1000dev->status & FT1000_STATUS_CLOSING) { DEBUG("network driver is closed, return\n"); - return STATUS_SUCCESS; + return 0; } - // Read length + /* Read length */ len = urb->transfer_buffer_length; lena = urb->actual_length; @@ -1105,7 +840,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) if (tempword != *chksum) { info->stats.rx_errors++; ft1000_submit_rx_urb(info); - return STATUS_FAILURE; + return -1; } skb = dev_alloc_skb(len + 12 + 2); @@ -1114,7 +849,7 @@ static int ft1000_copy_up_pkt(struct urb *urb) DEBUG("ft1000_copy_up_pkt: No Network buffers available\n"); info->stats.rx_errors++; ft1000_submit_rx_urb(info); - return STATUS_FAILURE; + return -1; } pbuffer = (u8 *) skb_put(skb, len + 12); @@ -1151,23 +886,11 @@ static int ft1000_copy_up_pkt(struct urb *urb) ft1000_submit_rx_urb(info); - return SUCCESS; + return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_submit_rx_urb -// Description: the receiving function of the network driver -// -// Input: -// info - a private structure contains the device information -// -// Output: -// status - FAILURE -// SUCCESS -// -//--------------------------------------------------------------------------- +/* the receiving function of the network driver */ static int ft1000_submit_rx_urb(struct ft1000_info *info) { int result; @@ -1196,20 +919,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) return 0; } -//--------------------------------------------------------------------------- -// Function: ft1000_close -// -// Parameters: -// net - network device -// -// -// Returns: none -// -// Description: close the network driver -// -// Notes: -// -//--------------------------------------------------------------------------- +/* close the network driver */ int ft1000_close(struct net_device *net) { struct ft1000_info *pInfo = netdev_priv(net); @@ -1227,26 +937,14 @@ int ft1000_close(struct net_device *net) return 0; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_chkcard -// Description: This function will check if the device is presently available on -// the system. -// Input: -// dev - device structure -// Output: -// status - FALSE (device is not present) -// TRUE (device is present) -// -//--------------------------------------------------------------------------- +/* check if the device is presently available on the system. */ static int ft1000_chkcard(struct ft1000_usb *dev) { u16 tempword; - u16 status; + int status; if (dev->fCondResetPend) { - DEBUG - ("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); + DEBUG("ft1000_hw:ft1000_chkcard:Card is being reset, return FALSE\n"); return TRUE; } /* Mask register is used to check for device presence since it is never @@ -1254,8 +952,7 @@ static int ft1000_chkcard(struct ft1000_usb *dev) */ status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK); if (tempword == 0) { - DEBUG - ("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); + DEBUG("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n"); return FALSE; } /* The system will return the value of 0xffff for the version register @@ -1264,30 +961,22 @@ static int ft1000_chkcard(struct ft1000_usb *dev) status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID); if (tempword != 0x1b01) { dev->status |= FT1000_STATUS_CLOSING; - DEBUG - ("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); + DEBUG("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n"); return FALSE; } return TRUE; } -//--------------------------------------------------------------------------- -// -// Function: ft1000_receive_cmd -// Description: This function will read a message from the dpram area. -// Input: -// dev - network device structure -// pbuffer - caller supply address to buffer -// pnxtph - pointer to next pseudo header -// Output: -// Status = 0 (unsuccessful) -// = 1 (successful) -// -//--------------------------------------------------------------------------- +/* read a message from the dpram area. +* Input: +* dev - network device structure +* pbuffer - caller supply address to buffer +*/ static bool ft1000_receive_cmd(struct ft1000_usb *dev, u16 *pbuffer, - int maxsz, u16 *pnxtph) + int maxsz) { - u16 size, ret; + u16 size; + int ret; u16 *ppseudohdr; int i; u16 tempword; @@ -1359,7 +1048,7 @@ static int ft1000_dsp_prov(void *arg) struct prov_record *ptr; struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; - u16 status; + int status; u16 TempShortBuf[256]; DEBUG("*** DspProv Entered\n"); @@ -1381,7 +1070,7 @@ static int ft1000_dsp_prov(void *arg) i++; if (i == 10) { DEBUG("FT1000:ft1000_dsp_prov:message drop\n"); - return STATUS_FAILURE; + return -1; } ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); @@ -1405,9 +1094,8 @@ static int ft1000_dsp_prov(void *arg) ppseudo_hdr->portsrc = 0; /* Calculate new checksum */ ppseudo_hdr->checksum = *pmsg++; - for (i = 1; i < 7; i++) { + for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - } TempShortBuf[0] = 0; TempShortBuf[1] = htons(len); @@ -1425,7 +1113,7 @@ static int ft1000_dsp_prov(void *arg) kfree(ptr->pprov_data); kfree(ptr); } - msleep(10); + usleep_range(9000, 11000); } DEBUG("DSP Provisioning List Entry finished\n"); @@ -1435,7 +1123,7 @@ static int ft1000_dsp_prov(void *arg) dev->fProvComplete = true; info->CardReady = 1; - return STATUS_SUCCESS; + return 0; } static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) @@ -1449,7 +1137,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) u16 i; struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; - u16 status; + int status; union { u8 byte[2]; u16 wrd; @@ -1457,7 +1145,7 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) char *cmdbuffer = kmalloc(1600, GFP_KERNEL); if (!cmdbuffer) - return STATUS_FAILURE; + return -1; status = ft1000_read_dpram32(dev, 0x200, cmdbuffer, size); @@ -1481,154 +1169,179 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) DEBUG("ft1000_proc_drvmsg:Command message type = 0x%x\n", msgtype); switch (msgtype) { case MEDIA_STATE:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); - - pmediamsg = (struct media_msg *)&cmdbuffer[0]; - if (info->ProgConStat != 0xFF) { - if (pmediamsg->state) { - DEBUG("Media is up\n"); - if (info->mediastate == 0) { - if (dev->NetDevRegDone) { - netif_wake_queue(dev-> - net); - } - info->mediastate = 1; - } - } else { - DEBUG("Media is down\n"); - if (info->mediastate == 1) { - info->mediastate = 0; - if (dev->NetDevRegDone) { - } - info->ConTm = 0; - } + DEBUG("ft1000_proc_drvmsg:Command message type = MEDIA_STATE"); + pmediamsg = (struct media_msg *)&cmdbuffer[0]; + if (info->ProgConStat != 0xFF) { + if (pmediamsg->state) { + DEBUG("Media is up\n"); + if (info->mediastate == 0) { + if (dev->NetDevRegDone) + netif_wake_queue(dev->net); + info->mediastate = 1; } } else { DEBUG("Media is down\n"); if (info->mediastate == 1) { info->mediastate = 0; - info->ConTm = 0; + if (dev->NetDevRegDone) + info->ConTm = 0; } } - break; + } else { + DEBUG("Media is down\n"); + if (info->mediastate == 1) { + info->mediastate = 0; + info->ConTm = 0; + } } + break; + } case DSP_INIT_MSG:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_INIT_MSG"); + pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; + memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); + DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", + info->DspVer[0], info->DspVer[1], info->DspVer[2], + info->DspVer[3]); + memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, + HWSERNUMSZ); + memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); + memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); + DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", + info->eui64[0], info->eui64[1], info->eui64[2], + info->eui64[3], info->eui64[4], info->eui64[5], + info->eui64[6], info->eui64[7]); + dev->net->dev_addr[0] = info->eui64[0]; + dev->net->dev_addr[1] = info->eui64[1]; + dev->net->dev_addr[2] = info->eui64[2]; + dev->net->dev_addr[3] = info->eui64[5]; + dev->net->dev_addr[4] = info->eui64[6]; + dev->net->dev_addr[5] = info->eui64[7]; - pdspinitmsg = (struct dsp_init_msg *)&cmdbuffer[2]; - memcpy(info->DspVer, pdspinitmsg->DspVer, DSPVERSZ); - DEBUG("DSPVER = 0x%2x 0x%2x 0x%2x 0x%2x\n", - info->DspVer[0], info->DspVer[1], info->DspVer[2], - info->DspVer[3]); - memcpy(info->HwSerNum, pdspinitmsg->HwSerNum, - HWSERNUMSZ); - memcpy(info->Sku, pdspinitmsg->Sku, SKUSZ); - memcpy(info->eui64, pdspinitmsg->eui64, EUISZ); - DEBUG("EUI64=%2x.%2x.%2x.%2x.%2x.%2x.%2x.%2x\n", - info->eui64[0], info->eui64[1], info->eui64[2], - info->eui64[3], info->eui64[4], info->eui64[5], - info->eui64[6], info->eui64[7]); - dev->net->dev_addr[0] = info->eui64[0]; - dev->net->dev_addr[1] = info->eui64[1]; - dev->net->dev_addr[2] = info->eui64[2]; - dev->net->dev_addr[3] = info->eui64[5]; - dev->net->dev_addr[4] = info->eui64[6]; - dev->net->dev_addr[5] = info->eui64[7]; - - if (ntohs(pdspinitmsg->length) == - (sizeof(struct dsp_init_msg) - 20)) { - memcpy(info->ProductMode, - pdspinitmsg->ProductMode, MODESZ); - memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, - CALVERSZ); - memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, - CALDATESZ); - DEBUG("RFCalVer = 0x%2x 0x%2x\n", - info->RfCalVer[0], info->RfCalVer[1]); - } - break; + if (ntohs(pdspinitmsg->length) == + (sizeof(struct dsp_init_msg) - 20)) { + memcpy(info->ProductMode, pdspinitmsg->ProductMode, + MODESZ); + memcpy(info->RfCalVer, pdspinitmsg->RfCalVer, CALVERSZ); + memcpy(info->RfCalDate, pdspinitmsg->RfCalDate, + CALDATESZ); + DEBUG("RFCalVer = 0x%2x 0x%2x\n", info->RfCalVer[0], + info->RfCalVer[1]); } + break; + } case DSP_PROVISION:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_PROVISION\n"); - /* kick off dspprov routine to start provisioning - * Send provisioning data to DSP - */ - if (list_empty(&info->prov_list) == 0) { - dev->fProvComplete = false; - status = ft1000_dsp_prov(dev); - if (status != STATUS_SUCCESS) - goto out; - } else { - dev->fProvComplete = true; - status = - ft1000_write_register(dev, FT1000_DB_HB, - FT1000_REG_DOORBELL); - DEBUG - ("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); - } - DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); - break; + /* kick off dspprov routine to start provisioning + * Send provisioning data to DSP + */ + if (list_empty(&info->prov_list) == 0) { + dev->fProvComplete = false; + status = ft1000_dsp_prov(dev); + if (status != 0) + goto out; + } else { + dev->fProvComplete = true; + status = ft1000_write_register(dev, FT1000_DB_HB, + FT1000_REG_DOORBELL); + DEBUG("FT1000:drivermsg:No more DSP provisioning data in dsp image\n"); } + DEBUG("ft1000_proc_drvmsg:DSP PROVISION is done\n"); + break; + } case DSP_STORE_INFO:{ - DEBUG - ("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); - - DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); - tempword = ntohs(pdrvmsg->length); - info->DSPInfoBlklen = tempword; - if (tempword < (MAX_DSP_SESS_REC - 4)) { - pmsg = (u16 *) &pdrvmsg->data[0]; - for (i = 0; i < ((tempword + 1) / 2); i++) { - DEBUG - ("FT1000:drivermsg:dsp info data = 0x%x\n", - *pmsg); - info->DSPInfoBlk[i + 10] = *pmsg++; - } - } else { - info->DSPInfoBlklen = 0; + DEBUG("ft1000_proc_drvmsg:Command message type = DSP_STORE_INFO"); + DEBUG("FT1000:drivermsg:Got DSP_STORE_INFO\n"); + tempword = ntohs(pdrvmsg->length); + info->DSPInfoBlklen = tempword; + if (tempword < (MAX_DSP_SESS_REC - 4)) { + pmsg = (u16 *) &pdrvmsg->data[0]; + for (i = 0; i < ((tempword + 1) / 2); i++) { + DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); + info->DSPInfoBlk[i + 10] = *pmsg++; } - break; + } else { + info->DSPInfoBlklen = 0; } + break; + } case DSP_GET_INFO:{ - DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); - /* copy dsp info block to dsp */ - dev->DrvMsgPend = 1; - /* allow any outstanding ioctl to finish */ + DEBUG("FT1000:drivermsg:Got DSP_GET_INFO\n"); + /* copy dsp info block to dsp */ + dev->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) - break; - } + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + break; } - /* Put message into Slow Queue - * Form Pseudo header - */ - pmsg = (u16 *) info->DSPInfoBlk; - *pmsg++ = 0; - *pmsg++ = - htons(info->DSPInfoBlklen + 20 + - info->DSPInfoBlklen); - ppseudo_hdr = - (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; - ppseudo_hdr->length = - htons(info->DSPInfoBlklen + 4 + - info->DSPInfoBlklen); + } + /* Put message into Slow Queue Form Pseudo header */ + pmsg = (u16 *) info->DSPInfoBlk; + *pmsg++ = 0; + *pmsg++ = htons(info->DSPInfoBlklen + 20 + info->DSPInfoBlklen); + ppseudo_hdr = + (struct pseudo_hdr *)(u16 *) &info->DSPInfoBlk[2]; + ppseudo_hdr->length = htons(info->DSPInfoBlklen + 4 + + info->DSPInfoBlklen); + ppseudo_hdr->source = 0x10; + ppseudo_hdr->destination = 0x20; + ppseudo_hdr->portdest = 0; + ppseudo_hdr->portsrc = 0; + ppseudo_hdr->sh_str_id = 0; + ppseudo_hdr->control = 0; + ppseudo_hdr->rsvd1 = 0; + ppseudo_hdr->rsvd2 = 0; + ppseudo_hdr->qos_class = 0; + /* Insert slow queue sequence number */ + ppseudo_hdr->seq_num = info->squeseqnum++; + /* Insert application id */ + ppseudo_hdr->portsrc = 0; + /* Calculate new checksum */ + ppseudo_hdr->checksum = *pmsg++; + for (i = 1; i < 7; i++) + ppseudo_hdr->checksum ^= *pmsg++; + + info->DSPInfoBlk[10] = 0x7200; + info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); + status = ft1000_write_dpram32(dev, 0, + (u8 *)&info->DSPInfoBlk[0], + (unsigned short)(info->DSPInfoBlklen + 22)); + status = ft1000_write_register(dev, FT1000_DB_DPRAM_TX, + FT1000_REG_DOORBELL); + dev->DrvMsgPend = 0; + break; + } + case GET_DRV_ERR_RPT_MSG:{ + DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); + /* copy driver error message to dsp */ + dev->DrvMsgPend = 1; + /* allow any outstanding ioctl to finish */ + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + mdelay(10); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) + mdelay(10); + } + if ((tempword & FT1000_DB_DPRAM_TX) == 0) { + /* Put message into Slow Queue Form Pseudo header */ + pmsg = (u16 *) &tempbuffer[0]; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; ppseudo_hdr->portdest = 0; @@ -1647,293 +1360,245 @@ static int ft1000_proc_drvmsg(struct ft1000_usb *dev, u16 size) for (i = 1; i < 7; i++) ppseudo_hdr->checksum ^= *pmsg++; - info->DSPInfoBlk[10] = 0x7200; - info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); - status = - ft1000_write_dpram32(dev, 0, - (u8 *) &info->DSPInfoBlk[0], - (unsigned short)(info-> - DSPInfoBlklen - + 22)); - status = - ft1000_write_register(dev, FT1000_DB_DPRAM_TX, - FT1000_REG_DOORBELL); - dev->DrvMsgPend = 0; + pmsg = (u16 *) &tempbuffer[16]; + *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); + *pmsg++ = htons(0x000e); + *pmsg++ = htons(info->DSP_TIME[0]); + *pmsg++ = htons(info->DSP_TIME[1]); + *pmsg++ = htons(info->DSP_TIME[2]); + *pmsg++ = htons(info->DSP_TIME[3]); + convert.byte[0] = info->DspVer[0]; + convert.byte[1] = info->DspVer[1]; + *pmsg++ = convert.wrd; + convert.byte[0] = info->DspVer[2]; + convert.byte[1] = info->DspVer[3]; + *pmsg++ = convert.wrd; + *pmsg++ = htons(info->DrvErrNum); - break; + card_send_command(dev, (unsigned char *)&tempbuffer[0], + (u16)(0x0012 + PSEUDOSZ)); + info->DrvErrNum = 0; } - - case GET_DRV_ERR_RPT_MSG:{ - DEBUG("FT1000:drivermsg:Got GET_DRV_ERR_RPT_MSG\n"); - /* copy driver error message to dsp */ - dev->DrvMsgPend = 1; - /* allow any outstanding ioctl to finish */ - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - mdelay(10); - status = - ft1000_read_register(dev, &tempword, - FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) - mdelay(10); - } - - if ((tempword & FT1000_DB_DPRAM_TX) == 0) { - /* Put message into Slow Queue - * Form Pseudo header - */ - pmsg = (u16 *) &tempbuffer[0]; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - ppseudo_hdr->length = htons(0x0012); - ppseudo_hdr->source = 0x10; - ppseudo_hdr->destination = 0x20; - ppseudo_hdr->portdest = 0; - ppseudo_hdr->portsrc = 0; - ppseudo_hdr->sh_str_id = 0; - ppseudo_hdr->control = 0; - ppseudo_hdr->rsvd1 = 0; - ppseudo_hdr->rsvd2 = 0; - ppseudo_hdr->qos_class = 0; - /* Insert slow queue sequence number */ - ppseudo_hdr->seq_num = info->squeseqnum++; - /* Insert application id */ - ppseudo_hdr->portsrc = 0; - /* Calculate new checksum */ - ppseudo_hdr->checksum = *pmsg++; - for (i = 1; i < 7; i++) - ppseudo_hdr->checksum ^= *pmsg++; - - pmsg = (u16 *) &tempbuffer[16]; - *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); - *pmsg++ = htons(0x000e); - *pmsg++ = htons(info->DSP_TIME[0]); - *pmsg++ = htons(info->DSP_TIME[1]); - *pmsg++ = htons(info->DSP_TIME[2]); - *pmsg++ = htons(info->DSP_TIME[3]); - convert.byte[0] = info->DspVer[0]; - convert.byte[1] = info->DspVer[1]; - *pmsg++ = convert.wrd; - convert.byte[0] = info->DspVer[2]; - convert.byte[1] = info->DspVer[3]; - *pmsg++ = convert.wrd; - *pmsg++ = htons(info->DrvErrNum); - - card_send_command(dev, - (unsigned char *)&tempbuffer[0], - (u16) (0x0012 + PSEUDOSZ)); - info->DrvErrNum = 0; - } - dev->DrvMsgPend = 0; - - break; - } - + dev->DrvMsgPend = 0; + break; + } default: break; } - status = STATUS_SUCCESS; + status = 0; out: kfree(cmdbuffer); DEBUG("return from ft1000_proc_drvmsg\n"); return status; } -int ft1000_poll(void* dev_id) +/* Check which application has registered for dsp broadcast messages */ +static int dsp_broadcast_msg_id(struct ft1000_usb *dev) { - struct ft1000_usb *dev = (struct ft1000_usb *)dev_id; - struct ft1000_info *info = netdev_priv(dev->net); - - u16 tempword; - u16 status; - u16 size; - int i; - u16 data; - u16 modulo; - u16 portid; - u16 nxtph; struct dpram_blk *pdpram_blk; - struct pseudo_hdr *ppseudo_hdr; - unsigned long flags; - - if (ft1000_chkcard(dev) == FALSE) { - DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); - return STATUS_FAILURE; - } - - status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL); - - if ( !status ) - { - - if (tempword & FT1000_DB_DPRAM_RX) { - - status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0); - size = ntohs(data) + 16 + 2; - if (size % 4) { - modulo = 4 - (size % 4); - size = size + modulo; - } - status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1); - portid &= 0xff; - - if (size < MAX_CMD_SQSIZE) { - switch (portid) - { - case DRIVERID: - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); - - status = ft1000_proc_drvmsg (dev, size); - if (status != STATUS_SUCCESS ) - return status; - break; - case DSPBCMSGID: - // This is a dsp broadcast message - // Check which application has registered for dsp broadcast messages - - for (i=0; iapp_info[i].DspBCMsgFlag) && (dev->app_info[i].fileobject) && - (dev->app_info[i].NumOfMsg < MAX_MSG_LIMIT) ) - { - nxtph = FT1000_DPRAM_RX_BASE + 2; - pdpram_blk = ft1000_get_buffer (&freercvpool); - if (pdpram_blk != NULL) { - if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) { - ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer; - // Put message into the appropriate application block - dev->app_info[i].nRxMsg++; - spin_lock_irqsave(&free_buff_lock, flags); - list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); - dev->app_info[i].NumOfMsg++; - spin_unlock_irqrestore(&free_buff_lock, flags); - wake_up_interruptible(&dev->app_info[i].wait_dpram_msg); - } - else { - dev->app_info[i].nRxMsgMiss++; - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); - } - } - else { - DEBUG("Out of memory in free receive command pool\n"); - dev->app_info[i].nRxMsgMiss++; - } - } - } - break; - default: - pdpram_blk = ft1000_get_buffer (&freercvpool); - - if (pdpram_blk != NULL) { - if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) { - ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer; - // Search for correct application block - for (i=0; iapp_info[i].app_id == ppseudo_hdr->portdest) { - break; - } - } - - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ppseudo_hdr->portdest); - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - else { - if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - else { - dev->app_info[i].nRxMsg++; - // Put message into the appropriate application block - list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); - dev->app_info[i].NumOfMsg++; - } - } - } - else { - // Put memory back to free pool - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - } - else { - DEBUG("Out of memory in free receive command pool\n"); - } - break; - } - } - else { - DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); - } - status = ft1000_write_register (dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL); - } - else if (tempword & FT1000_DSP_ASIC_RESET) { - - // Let's reset the ASIC from the Host side as well - status = ft1000_write_register (dev, ASIC_RESET_BIT, FT1000_REG_RESET); - status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET); - i = 0; - while (tempword & ASIC_RESET_BIT) { - status = ft1000_read_register (dev, &tempword, FT1000_REG_RESET); - msleep(10); - i++; - if (i==100) - break; - } - if (i==100) { - DEBUG("Unable to reset ASIC\n"); - return STATUS_SUCCESS; - } - msleep(10); - // Program WMARK register - status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK); - // clear ASIC reset doorbell - status = ft1000_write_register (dev, FT1000_DSP_ASIC_RESET, FT1000_REG_DOORBELL); - msleep(10); - } - else if (tempword & FT1000_ASIC_RESET_REQ) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); - - // clear ASIC reset request from DSP - status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL); - status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); - // copy dsp session record from Adapter block - status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024); - // Program WMARK register - status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK); - // ring doorbell to tell DSP that ASIC is out of reset - status = ft1000_write_register (dev, FT1000_ASIC_RESET_DSP, FT1000_REG_DOORBELL); - } - else if (tempword & FT1000_DB_COND_RESET) { - DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); - - if (!dev->fAppMsgPend) { - // Reset ASIC and DSP - - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX); - info->CardReady = 0; - info->DrvErrNum = DSP_CONDRESET_INFO; - DEBUG("ft1000_hw:DSP conditional reset requested\n"); - info->ft1000_reset(dev->net); - } - else { - dev->fProvComplete = false; - dev->fCondResetPend = true; - } - - ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL); - } - - } - - return STATUS_SUCCESS; + unsigned long flags; + int i; + for (i = 0; i < MAX_NUM_APP; i++) { + if ((dev->app_info[i].DspBCMsgFlag) + && (dev->app_info[i].fileobject) + && (dev->app_info[i].NumOfMsg + < MAX_MSG_LIMIT)) { + pdpram_blk = ft1000_get_buffer(&freercvpool); + if (pdpram_blk == NULL) { + DEBUG("Out of memory in free receive command pool\n"); + dev->app_info[i].nRxMsgMiss++; + return -1; + } + if (ft1000_receive_cmd(dev, pdpram_blk->pbuffer, + MAX_CMD_SQSIZE)) { + /* Put message into the + * appropriate application block + */ + dev->app_info[i].nRxMsg++; + spin_lock_irqsave(&free_buff_lock, flags); + list_add_tail(&pdpram_blk->list, + &dev->app_info[i] .app_sqlist); + dev->app_info[i].NumOfMsg++; + spin_unlock_irqrestore(&free_buff_lock, flags); + wake_up_interruptible(&dev->app_info[i] + .wait_dpram_msg); + } else { + dev->app_info[i].nRxMsgMiss++; + ft1000_free_buffer(pdpram_blk, &freercvpool); + DEBUG("pdpram_blk::ft1000_get_buffer NULL\n"); + return -1; + } + } + } + return 0; +} + +static int handle_misc_portid(struct ft1000_usb *dev) +{ + struct dpram_blk *pdpram_blk; + int i; + + pdpram_blk = ft1000_get_buffer(&freercvpool); + if (pdpram_blk == NULL) { + DEBUG("Out of memory in free receive command pool\n"); + return -1; + } + if (!ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE)) + goto exit_failure; + + /* Search for correct application block */ + for (i = 0; i < MAX_NUM_APP; i++) { + if (dev->app_info[i].app_id == ((struct pseudo_hdr *) + pdpram_blk->pbuffer)->portdest) + break; + } + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_parse_dpram_msg: No application matching id = %d\n", ((struct pseudo_hdr *)pdpram_blk->pbuffer)->portdest); + goto exit_failure; + } else if (dev->app_info[i].NumOfMsg > MAX_MSG_LIMIT) { + goto exit_failure; + } else { + dev->app_info[i].nRxMsg++; + /* Put message into the appropriate application block */ + list_add_tail(&pdpram_blk->list, &dev->app_info[i].app_sqlist); + dev->app_info[i].NumOfMsg++; + } + return 0; + +exit_failure: + ft1000_free_buffer(pdpram_blk, &freercvpool); + return -1; +} + +int ft1000_poll(void *dev_id) +{ + struct ft1000_usb *dev = (struct ft1000_usb *)dev_id; + struct ft1000_info *info = netdev_priv(dev->net); + u16 tempword; + int status; + u16 size; + int i; + u16 data; + u16 modulo; + u16 portid; + + if (ft1000_chkcard(dev) == FALSE) { + DEBUG("ft1000_poll::ft1000_chkcard: failed\n"); + return -1; + } + status = ft1000_read_register(dev, &tempword, FT1000_REG_DOORBELL); + if (!status) { + if (tempword & FT1000_DB_DPRAM_RX) { + status = ft1000_read_dpram16(dev, + 0x200, (u8 *)&data, 0); + size = ntohs(data) + 16 + 2; + if (size % 4) { + modulo = 4 - (size % 4); + size = size + modulo; + } + status = ft1000_read_dpram16(dev, 0x201, + (u8 *)&portid, 1); + portid &= 0xff; + if (size < MAX_CMD_SQSIZE) { + switch (portid) { + case DRIVERID: + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DRIVERID\n"); + status = ft1000_proc_drvmsg(dev, size); + if (status != 0) + return status; + break; + case DSPBCMSGID: + status = dsp_broadcast_msg_id(dev); + break; + default: + status = handle_misc_portid(dev); + break; + } + } else + DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size); + status = ft1000_write_register(dev, + FT1000_DB_DPRAM_RX, + FT1000_REG_DOORBELL); + } else if (tempword & FT1000_DSP_ASIC_RESET) { + /* Let's reset the ASIC from the Host side as well */ + status = ft1000_write_register(dev, ASIC_RESET_BIT, + FT1000_REG_RESET); + status = ft1000_read_register(dev, &tempword, + FT1000_REG_RESET); + i = 0; + while (tempword & ASIC_RESET_BIT) { + status = ft1000_read_register(dev, &tempword, + FT1000_REG_RESET); + usleep_range(9000, 11000); + i++; + if (i == 100) + break; + } + if (i == 100) { + DEBUG("Unable to reset ASIC\n"); + return 0; + } + usleep_range(9000, 11000); + /* Program WMARK register */ + status = ft1000_write_register(dev, 0x600, + FT1000_REG_MAG_WATERMARK); + /* clear ASIC reset doorbell */ + status = ft1000_write_register(dev, + FT1000_DSP_ASIC_RESET, + FT1000_REG_DOORBELL); + usleep_range(9000, 11000); + } else if (tempword & FT1000_ASIC_RESET_REQ) { + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_ASIC_RESET_REQ\n"); + /* clear ASIC reset request from DSP */ + status = ft1000_write_register(dev, + FT1000_ASIC_RESET_REQ, + FT1000_REG_DOORBELL); + status = ft1000_write_register(dev, HOST_INTF_BE, + FT1000_REG_SUP_CTRL); + /* copy dsp session record from Adapter block */ + status = ft1000_write_dpram32(dev, 0, + (u8 *)&info->DSPSess.Rec[0], 1024); + status = ft1000_write_register(dev, 0x600, + FT1000_REG_MAG_WATERMARK); + /* ring doorbell to tell DSP that + * ASIC is out of reset + * */ + status = ft1000_write_register(dev, + FT1000_ASIC_RESET_DSP, + FT1000_REG_DOORBELL); + } else if (tempword & FT1000_DB_COND_RESET) { + DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_COND_RESET\n"); + if (!dev->fAppMsgPend) { + /* Reset ASIC and DSP */ + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER0, + (u8 *)&(info->DSP_TIME[0]), + FT1000_MAG_DSP_TIMER0_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER1, + (u8 *)&(info->DSP_TIME[1]), + FT1000_MAG_DSP_TIMER1_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER2, + (u8 *)&(info->DSP_TIME[2]), + FT1000_MAG_DSP_TIMER2_INDX); + status = ft1000_read_dpram16(dev, + FT1000_MAG_DSP_TIMER3, + (u8 *)&(info->DSP_TIME[3]), + FT1000_MAG_DSP_TIMER3_INDX); + info->CardReady = 0; + info->DrvErrNum = DSP_CONDRESET_INFO; + DEBUG("ft1000_hw:DSP conditional reset requested\n"); + info->ft1000_reset(dev->net); + } else { + dev->fProvComplete = false; + dev->fCondResetPend = true; + } + ft1000_write_register(dev, FT1000_DB_COND_RESET, + FT1000_REG_DOORBELL); + } + } + return 0; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 5ead942be680..2575d0d6bff3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -33,13 +33,13 @@ #define seq_putx(m, message, size, var) \ seq_printf(m, message); \ - for(i = 0; i < (size - 1); i++) \ + for (i = 0; i < (size - 1); i++) \ seq_printf(m, "%02x:", var[i]); \ seq_printf(m, "%02x\n", var[i]) #define seq_putd(m, message, size, var) \ seq_printf(m, message); \ - for(i = 0; i < (size - 1); i++) \ + for (i = 0; i < (size - 1); i++) \ seq_printf(m, "%d.", var[i]); \ seq_printf(m, "%d\n", var[i]) @@ -47,14 +47,14 @@ #define FTNET_PROC init_net.proc_net -int ft1000_read_dpram16 (struct ft1000_usb *ft1000dev, u16 indx, +int ft1000_read_dpram16(struct ft1000_usb *ft1000dev, u16 indx, u8 *buffer, u8 highlow); static int ft1000ReadProc(struct seq_file *m, void *v) { - static const char *status[] = { - "Idle (Disconnect)", + static const char *status[] = { + "Idle (Disconnect)", "Searching", "Active (Connected)", "Waiting for L2", @@ -127,10 +127,10 @@ static int ft1000ReadProc(struct seq_file *m, void *v) } seq_printf(m, "Connection Time: %02ld:%02ld:%02ld\n", - ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); + ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); seq_printf(m, "Connection Time[s]: %ld\n", delta); seq_printf(m, "Asic ID: %s\n", - (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); + (info->AsicID) == ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); seq_putx(m, "SKU: ", SKUSZ, info->Sku); seq_putx(m, "EUI64: ", EUISZ, info->eui64); seq_putd(m, "DSP version number: ", DSPVERSZ, info->DspVer); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index a8dd1e54878c..e40763e60dbd 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -7,7 +7,6 @@ * $Id: *==================================================== */ -#include #include #include #include @@ -45,13 +44,13 @@ static int ft1000_poll_thread(void *arg) msleep(10); if (!gPollingfailed) { ret = ft1000_poll(arg); - if (ret != STATUS_SUCCESS) { + if (ret != 0) { DEBUG("ft1000_poll_thread: polling failed\n"); gPollingfailed = true; } } } - return STATUS_SUCCESS; + return 0; } static int ft1000_probe(struct usb_interface *interface, diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index e8d00a930dc6..a6fdd524ee6f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -11,8 +11,6 @@ #define PSEUDOSZ 16 -#define SUCCESS 0x00 - struct app_info_block { u32 nTxMsg; /* DPRAM msg sent to DSP with app_id */ u32 nRxMsg; /* DPRAM msg rcv from dsp with app_id */ @@ -31,9 +29,6 @@ struct app_info_block { #define FALSE 0 #define TRUE 1 -#define STATUS_SUCCESS 0 -#define STATUS_FAILURE 0x1001 - #define FT1000_STATUS_CLOSING 0x01 #define DSPBCMSGID 0x10 diff --git a/drivers/staging/gdm724x/gdm_lte.c b/drivers/staging/gdm724x/gdm_lte.c index c57a6ba5d010..74a03608b2dd 100644 --- a/drivers/staging/gdm724x/gdm_lte.c +++ b/drivers/staging/gdm724x/gdm_lte.c @@ -44,18 +44,6 @@ */ #define DEFAULT_MTU_SIZE 1500 -#define gdm_dev_endian(n) (\ - n->phy_dev->get_endian(n->phy_dev->priv_dev)) - -#define gdm_lte_hci_send(n, d, l) (\ - n->phy_dev->send_hci_func(n->phy_dev->priv_dev, d, l, NULL, NULL)) - -#define gdm_lte_sdu_send(n, d, l, c, b, i, t) (\ - n->phy_dev->send_sdu_func(n->phy_dev->priv_dev, d, l, n->pdn_table.dft_eps_id, 0, c, b, i, t)) - -#define gdm_lte_rcv_with_cb(n, c, b, e) (\ - n->rcv_func(n->priv_dev, c, b, e)) - #define IP_VERSION_4 4 #define IP_VERSION_6 6 @@ -458,13 +446,11 @@ static int gdm_lte_tx(struct sk_buff *skb, struct net_device *dev) sscanf(dev->name, "lte%d", &idx); - ret = gdm_lte_sdu_send(nic, - data_buf, - data_len, - tx_complete, - nic, - idx, - nic_type); + ret = nic->phy_dev->send_sdu_func(nic->phy_dev->priv_dev, + data_buf, data_len, + nic->pdn_table.dft_eps_id, 0, + tx_complete, nic, idx, + nic_type); if (ret == TX_NO_BUFFER || ret == TX_NO_SPC) { netif_stop_queue(dev); @@ -503,14 +489,18 @@ static int gdm_lte_event_send(struct net_device *dev, char *buf, int len) sscanf(dev->name, "lte%d", &idx); return netlink_send(lte_event.sock, idx, 0, buf, - gdm_dev16_to_cpu(gdm_dev_endian(nic), hci->len) + HCI_HEADER_SIZE); + gdm_dev16_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), hci->len) + + HCI_HEADER_SIZE); } static void gdm_lte_event_rcv(struct net_device *dev, u16 type, void *msg, int len) { struct nic *nic = netdev_priv(dev); - gdm_lte_hci_send(nic, msg, len); + nic->phy_dev->send_hci_func(nic->phy_dev->priv_dev, msg, len, NULL, + NULL); } int gdm_lte_event_init(void) @@ -688,8 +678,14 @@ static void gdm_lte_pdn_table(struct net_device *dev, char *buf, int len) if (pdn_table->activate) { nic->pdn_table.activate = pdn_table->activate; - nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->dft_eps_id); - nic->pdn_table.nic_type = gdm_dev32_to_cpu(gdm_dev_endian(nic), pdn_table->nic_type); + nic->pdn_table.dft_eps_id = gdm_dev32_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), + pdn_table->dft_eps_id); + nic->pdn_table.nic_type = gdm_dev32_to_cpu( + nic->phy_dev->get_endian( + nic->phy_dev->priv_dev), + pdn_table->nic_type); netdev_info(dev, "pdn activated, nic_type=0x%x\n", nic->pdn_table.nic_type); @@ -762,7 +758,7 @@ void start_rx_proc(struct phy_dev *phy_dev) int i; for (i = 0; i < MAX_RX_SUBMIT_COUNT; i++) - gdm_lte_rcv_with_cb(phy_dev, rx_complete, phy_dev, USB_COMPLETE); + phy_dev->rcv_func(phy_dev->priv_dev, rx_complete, phy_dev, USB_COMPLETE); } static struct net_device_ops gdm_netdev_ops = { diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 62163673976c..2fa3a5a6580f 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c @@ -158,7 +158,6 @@ static int up_to_host(struct mux_rx *r) unsigned int start_flag; unsigned int payload_size; unsigned short packet_type; - int remain; int dummy_cnt; u32 packet_size_sum = r->offset; int index; @@ -176,8 +175,7 @@ static int up_to_host(struct mux_rx *r) break; } - remain = (MUX_HEADER_SIZE + payload_size) % 4; - dummy_cnt = remain ? (4-remain) : 0; + dummy_cnt = ALIGN(MUX_HEADER_SIZE + payload_size, 4); if (len - packet_size_sum < MUX_HEADER_SIZE + payload_size + dummy_cnt) { @@ -361,7 +359,6 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, struct mux_pkt_header *mux_header; struct mux_tx *t = NULL; static u32 seq_num = 1; - int remain; int dummy_cnt; int total_len; int ret; @@ -375,8 +372,7 @@ static int gdm_mux_send(void *priv_dev, void *data, int len, int tty_index, spin_lock_irqsave(&mux_dev->write_lock, flags); - remain = (MUX_HEADER_SIZE + len) % 4; - dummy_cnt = remain ? (4 - remain) : 0; + dummy_cnt = ALIGN(MUX_HEADER_SIZE + len, 4); total_len = len + MUX_HEADER_SIZE + dummy_cnt; diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index c0f7cd75116b..fe47cd3eb2ed 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/gdm724x/gdm_usb.c b/drivers/staging/gdm724x/gdm_usb.c index 781134af69d1..33458a583142 100644 --- a/drivers/staging/gdm724x/gdm_usb.c +++ b/drivers/staging/gdm724x/gdm_usb.c @@ -830,24 +830,19 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id if (bInterfaceNumber > NETWORK_INTERFACE) { pr_info("not a network device\n"); - return -1; + return -ENODEV; } - phy_dev = kmalloc(sizeof(struct phy_dev), GFP_ATOMIC); - if (!phy_dev) { - ret = -ENOMEM; - goto out; - } + phy_dev = kzalloc(sizeof(struct phy_dev), GFP_KERNEL); + if (!phy_dev) + return -ENOMEM; - udev = kmalloc(sizeof(struct lte_udev), GFP_ATOMIC); + udev = kzalloc(sizeof(struct lte_udev), GFP_KERNEL); if (!udev) { ret = -ENOMEM; - goto out; + goto err_udev; } - memset(phy_dev, 0, sizeof(struct phy_dev)); - memset(udev, 0, sizeof(struct lte_udev)); - phy_dev->priv_dev = (void *)udev; phy_dev->send_hci_func = gdm_usb_hci_send; phy_dev->send_sdu_func = gdm_usb_sdu_send; @@ -858,7 +853,7 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = init_usb(udev); if (ret < 0) { pr_err("init_usb func failed\n"); - goto out; + goto err_init_usb; } udev->intf = intf; @@ -875,23 +870,22 @@ static int gdm_usb_probe(struct usb_interface *intf, const struct usb_device_id ret = request_mac_address(udev); if (ret < 0) { pr_err("request Mac address failed\n"); - goto out; + goto err_mac_address; } start_rx_proc(phy_dev); -out: - - if (ret < 0) { - kfree(phy_dev); - if (udev) { - release_usb(udev); - kfree(udev); - } - } - usb_get_dev(usbdev); usb_set_intfdata(intf, phy_dev); + return 0; + +err_mac_address: + release_usb(udev); +err_init_usb: + kfree(udev); +err_udev: + kfree(phy_dev); + return ret; } diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index cc3692439a5c..50d43ada0936 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -97,7 +97,7 @@ void gdm_qos_init(void *nic_ptr) struct qos_cb_s *qcb = &nic->qos; int i; - for (i = 0 ; i < QOS_MAX; i++) { + for (i = 0; i < QOS_MAX; i++) { INIT_LIST_HEAD(&qcb->qos_list[i]); qcb->csr[i].qos_buf_count = 0; qcb->csr[i].enabled = 0; diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index e0cb2ffb41be..f8788bf0a7d3 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -780,9 +780,10 @@ static int k_mode_thread(void *arg) spin_lock_irqsave(&k_lock, flags2); } + wait_event_interruptible_lock_irq(k_wait, + !list_empty(&k_list) || k_mode_stop, + k_lock); spin_unlock_irqrestore(&k_lock, flags2); - - interruptible_sleep_on(&k_wait); } return 0; } diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c index 4302fcbdfdc3..cbe5dcfc2ac9 100644 --- a/drivers/staging/gdm72xx/sdio_boot.c +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/drivers/staging/goldfish/goldfish_nand.c b/drivers/staging/goldfish/goldfish_nand.c index 81e2ad4038fe..eca0873098cd 100644 --- a/drivers/staging/goldfish/goldfish_nand.c +++ b/drivers/staging/goldfish/goldfish_nand.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 4c9364b63c77..6f38ca95f9bb 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -439,13 +439,13 @@ static int adis16220_probe(struct spi_device *spi) indio_dev->channels = adis16220_channels; indio_dev->num_channels = ARRAY_SIZE(adis16220_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &accel_bin); if (ret) - goto error_unregister_dev; + return ret; ret = sysfs_create_bin_file(&indio_dev->dev.kobj, &adc1_bin); if (ret) @@ -470,8 +470,6 @@ error_rm_adc1_bin: sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); error_rm_accel_bin: sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); -error_unregister_dev: - iio_device_unregister(indio_dev); return ret; } @@ -482,7 +480,6 @@ static int adis16220_remove(struct spi_device *spi) sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc2_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &adc1_bin); sysfs_remove_bin_file(&indio_dev->dev.kobj, &accel_bin); - iio_device_unregister(indio_dev); return 0; } diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 735c0a34fa93..898653c09279 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -676,10 +676,10 @@ static const struct attribute_group lis3l02dq_attribute_group = { static const struct iio_info lis3l02dq_info = { .read_raw = &lis3l02dq_read_raw, .write_raw = &lis3l02dq_write_raw, - .read_event_value_new = &lis3l02dq_read_thresh, - .write_event_value_new = &lis3l02dq_write_thresh, - .write_event_config_new = &lis3l02dq_write_event_config, - .read_event_config_new = &lis3l02dq_read_event_config, + .read_event_value = &lis3l02dq_read_thresh, + .write_event_value = &lis3l02dq_write_thresh, + .write_event_config = &lis3l02dq_write_event_config, + .read_event_config = &lis3l02dq_read_event_config, .driver_module = THIS_MODULE, .attrs = &lis3l02dq_attribute_group, }; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index c49e6ef9d05f..7f6ccdfaf168 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -1126,20 +1126,20 @@ static const struct iio_info sca3000_info = { .attrs = &sca3000_attribute_group, .read_raw = &sca3000_read_raw, .event_attrs = &sca3000_event_attribute_group, - .read_event_value_new = &sca3000_read_thresh, - .write_event_value_new = &sca3000_write_thresh, - .read_event_config_new = &sca3000_read_event_config, - .write_event_config_new = &sca3000_write_event_config, + .read_event_value = &sca3000_read_thresh, + .write_event_value = &sca3000_write_thresh, + .read_event_config = &sca3000_read_event_config, + .write_event_config = &sca3000_write_event_config, .driver_module = THIS_MODULE, }; static const struct iio_info sca3000_info_with_temp = { .attrs = &sca3000_attribute_group_with_temp, .read_raw = &sca3000_read_raw, - .read_event_value_new = &sca3000_read_thresh, - .write_event_value_new = &sca3000_write_thresh, - .read_event_config_new = &sca3000_read_event_config, - .write_event_config_new = &sca3000_write_event_config, + .read_event_value = &sca3000_read_thresh, + .write_event_value = &sca3000_write_thresh, + .read_event_config = &sca3000_read_event_config, + .write_event_config = &sca3000_write_event_config, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index 8209fa542a8a..1ac11f64827c 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -134,6 +134,8 @@ struct ad7280_state { unsigned char aux_threshhigh; unsigned char aux_threshlow; unsigned char cb_mask[AD7280A_MAX_CHAIN]; + + __be32 buf[2] ____cacheline_aligned; }; static void ad7280_crc8_build_table(unsigned char *crc_tab) @@ -189,22 +191,22 @@ static void ad7280_delay(struct ad7280_state *st) msleep(1); } -static int __ad7280_read32(struct spi_device *spi, unsigned *val) +static int __ad7280_read32(struct ad7280_state *st, unsigned *val) { - unsigned rx_buf, tx_buf = cpu_to_be32(AD7280A_READ_TXVAL); int ret; - struct spi_transfer t = { - .tx_buf = &tx_buf, - .rx_buf = &rx_buf, + .tx_buf = &st->buf[0], + .rx_buf = &st->buf[1], .len = 4, }; - ret = spi_sync_transfer(spi, &t, 1); + st->buf[0] = cpu_to_be32(AD7280A_READ_TXVAL); + + ret = spi_sync_transfer(st->spi, &t, 1); if (ret) return ret; - *val = be32_to_cpu(rx_buf); + *val = be32_to_cpu(st->buf[1]); return 0; } @@ -216,9 +218,9 @@ static int ad7280_write(struct ad7280_state *st, unsigned devaddr, (val & 0xFF) << 13 | all << 12); reg |= ad7280_calc_crc8(st->crc_tab, reg >> 11) << 3 | 0x2; - reg = cpu_to_be32(reg); + st->buf[0] = cpu_to_be32(reg); - return spi_write(st->spi, ®, 4); + return spi_write(st->spi, &st->buf[0], 4); } static int ad7280_read(struct ad7280_state *st, unsigned devaddr, @@ -248,7 +250,7 @@ static int ad7280_read(struct ad7280_state *st, unsigned devaddr, if (ret) return ret; - __ad7280_read32(st->spi, &tmp); + __ad7280_read32(st, &tmp); if (ad7280_check_crc(st, tmp)) return -EIO; @@ -286,7 +288,7 @@ static int ad7280_read_channel(struct ad7280_state *st, unsigned devaddr, ad7280_delay(st); - __ad7280_read32(st->spi, &tmp); + __ad7280_read32(st, &tmp); if (ad7280_check_crc(st, tmp)) return -EIO; @@ -319,7 +321,7 @@ static int ad7280_read_all_channels(struct ad7280_state *st, unsigned cnt, ad7280_delay(st); for (i = 0; i < cnt; i++) { - __ad7280_read32(st->spi, &tmp); + __ad7280_read32(st, &tmp); if (ad7280_check_crc(st, tmp)) return -EIO; @@ -362,7 +364,7 @@ static int ad7280_chain_setup(struct ad7280_state *st) return ret; for (n = 0; n <= AD7280A_MAX_CHAIN; n++) { - __ad7280_read32(st->spi, &val); + __ad7280_read32(st, &val); if (val == 0) return n - 1; diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index d13f8aeeb62f..357cef2a6f4c 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -452,10 +452,10 @@ static const struct iio_chan_spec ad7291_channels[] = { static const struct iio_info ad7291_info = { .read_raw = &ad7291_read_raw, - .read_event_config_new = &ad7291_read_event_config, - .write_event_config_new = &ad7291_write_event_config, - .read_event_value_new = &ad7291_read_event_value, - .write_event_value_new = &ad7291_write_event_value, + .read_event_config = &ad7291_read_event_config, + .write_event_config = &ad7291_write_event_config, + .read_event_value = &ad7291_read_event_value, + .write_event_value = &ad7291_write_event_value, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 2083673a79ca..f0f05f195d2c 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -239,7 +239,12 @@ static const struct attribute_group ad7606_attribute_group_range = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\ .scan_index = num, \ - .scan_type = IIO_ST('s', 16, 16, 0), \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_CPU, \ + }, \ } static const struct iio_chan_spec ad7606_8_channels[] = { diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 9f48e5c74eed..2369cf28412e 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -412,7 +412,7 @@ static int ad7816_probe(struct spi_device *spi_dev) return ret; } - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi_dev->dev, indio_dev); if (ret) return ret; @@ -422,15 +422,6 @@ static int ad7816_probe(struct spi_device *spi_dev) return 0; } -static int ad7816_remove(struct spi_device *spi_dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); - - iio_device_unregister(indio_dev); - - return 0; -} - static const struct spi_device_id ad7816_id[] = { { "ad7816", 0 }, { "ad7817", 0 }, @@ -446,7 +437,6 @@ static struct spi_driver ad7816_driver = { .owner = THIS_MODULE, }, .probe = ad7816_probe, - .remove = ad7816_remove, .id_table = ad7816_id, }; module_spi_driver(ad7816_driver); diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 9428be82b655..5ea36410f716 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -377,9 +377,9 @@ static const struct iio_info ad7991_info = { static const struct iio_info ad7993_4_7_8_info = { .read_raw = &ad799x_read_raw, .event_attrs = &ad799x_event_attrs_group, - .read_event_config_new = &ad799x_read_event_config, - .read_event_value_new = &ad799x_read_event_value, - .write_event_value_new = &ad799x_write_event_value, + .read_event_config = &ad799x_read_event_config, + .read_event_value = &ad799x_read_event_value, + .write_event_value = &ad799x_write_event_value, .driver_module = THIS_MODULE, .update_scan_mode = ad7997_8_update_scan_mode, }; diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index ef0a21d8ce15..a876ce755351 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -183,7 +183,7 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) iodev->channels = lpc32xx_adc_iio_channels; iodev->num_channels = ARRAY_SIZE(lpc32xx_adc_iio_channels); - retval = iio_device_register(iodev); + retval = devm_iio_device_register(&pdev->dev, iodev); if (retval) return retval; @@ -192,15 +192,6 @@ static int lpc32xx_adc_probe(struct platform_device *pdev) return 0; } -static int lpc32xx_adc_remove(struct platform_device *pdev) -{ - struct iio_dev *iodev = platform_get_drvdata(pdev); - - iio_device_unregister(iodev); - - return 0; -} - #ifdef CONFIG_OF static const struct of_device_id lpc32xx_adc_match[] = { { .compatible = "nxp,lpc3220-adc" }, @@ -211,7 +202,6 @@ MODULE_DEVICE_TABLE(of, lpc32xx_adc_match); static struct platform_driver lpc32xx_adc_driver = { .probe = lpc32xx_adc_probe, - .remove = lpc32xx_adc_remove, .driver = { .name = MOD_NAME, .owner = THIS_MODULE, diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index e2dd7830b320..df71669bb60e 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -111,16 +112,59 @@ static const char * const mx28_lradc_irq_names[] = { struct mxs_lradc_of_config { const int irq_count; const char * const *irq_name; + const uint32_t *vref_mv; +}; + +#define VREF_MV_BASE 1850 + +static const uint32_t mx23_vref_mv[LRADC_MAX_TOTAL_CHANS] = { + VREF_MV_BASE, /* CH0 */ + VREF_MV_BASE, /* CH1 */ + VREF_MV_BASE, /* CH2 */ + VREF_MV_BASE, /* CH3 */ + VREF_MV_BASE, /* CH4 */ + VREF_MV_BASE, /* CH5 */ + VREF_MV_BASE * 2, /* CH6 VDDIO */ + VREF_MV_BASE * 4, /* CH7 VBATT */ + VREF_MV_BASE, /* CH8 Temp sense 0 */ + VREF_MV_BASE, /* CH9 Temp sense 1 */ + VREF_MV_BASE, /* CH10 */ + VREF_MV_BASE, /* CH11 */ + VREF_MV_BASE, /* CH12 USB_DP */ + VREF_MV_BASE, /* CH13 USB_DN */ + VREF_MV_BASE, /* CH14 VBG */ + VREF_MV_BASE * 4, /* CH15 VDD5V */ +}; + +static const uint32_t mx28_vref_mv[LRADC_MAX_TOTAL_CHANS] = { + VREF_MV_BASE, /* CH0 */ + VREF_MV_BASE, /* CH1 */ + VREF_MV_BASE, /* CH2 */ + VREF_MV_BASE, /* CH3 */ + VREF_MV_BASE, /* CH4 */ + VREF_MV_BASE, /* CH5 */ + VREF_MV_BASE, /* CH6 */ + VREF_MV_BASE * 4, /* CH7 VBATT */ + VREF_MV_BASE, /* CH8 Temp sense 0 */ + VREF_MV_BASE, /* CH9 Temp sense 1 */ + VREF_MV_BASE * 2, /* CH10 VDDIO */ + VREF_MV_BASE, /* CH11 VTH */ + VREF_MV_BASE * 2, /* CH12 VDDA */ + VREF_MV_BASE, /* CH13 VDDD */ + VREF_MV_BASE, /* CH14 VBG */ + VREF_MV_BASE * 4, /* CH15 VDD5V */ }; static const struct mxs_lradc_of_config mxs_lradc_of_config[] = { [IMX23_LRADC] = { .irq_count = ARRAY_SIZE(mx23_lradc_irq_names), .irq_name = mx23_lradc_irq_names, + .vref_mv = mx23_vref_mv, }, [IMX28_LRADC] = { .irq_count = ARRAY_SIZE(mx28_lradc_irq_names), .irq_name = mx28_lradc_irq_names, + .vref_mv = mx28_vref_mv, }, }; @@ -141,6 +185,16 @@ enum lradc_ts_plate { LRADC_SAMPLE_VALID, }; +enum mxs_lradc_divbytwo { + MXS_LRADC_DIV_DISABLED = 0, + MXS_LRADC_DIV_ENABLED, +}; + +struct mxs_lradc_scale { + unsigned int integer; + unsigned int nano; +}; + struct mxs_lradc { struct device *dev; void __iomem *base; @@ -155,6 +209,10 @@ struct mxs_lradc { struct completion completion; + const uint32_t *vref_mv; + struct mxs_lradc_scale scale_avail[LRADC_MAX_TOTAL_CHANS][2]; + unsigned long is_divided; + /* * Touchscreen LRADC channels receives a private slot in the CTRL4 * register, the slot #7. Therefore only 7 slots instead of 8 in the @@ -243,6 +301,7 @@ struct mxs_lradc { #define LRADC_CTRL1_LRADC_IRQ_OFFSET 0 #define LRADC_CTRL2 0x20 +#define LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET 24 #define LRADC_CTRL2_TEMPSENSE_PWD (1 << 15) #define LRADC_STATUS 0x40 @@ -759,20 +818,11 @@ static void mxs_lradc_handle_touch(struct mxs_lradc *lradc) /* * Raw I/O operations */ -static int mxs_lradc_read_raw(struct iio_dev *iio_dev, - const struct iio_chan_spec *chan, - int *val, int *val2, long m) +static int mxs_lradc_read_single(struct iio_dev *iio_dev, int chan, int *val) { struct mxs_lradc *lradc = iio_priv(iio_dev); int ret; - if (m != IIO_CHAN_INFO_RAW) - return -EINVAL; - - /* Check for invalid channel */ - if (chan->channel > LRADC_MAX_TOTAL_CHANS) - return -EINVAL; - /* * See if there is no buffered operation in progess. If there is, simply * bail out. This can be improved to support both buffered and raw IO at @@ -797,7 +847,7 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev, /* Clean the slot's previous content, then set new one. */ mxs_lradc_reg_clear(lradc, LRADC_CTRL4_LRADCSELECT_MASK(0), LRADC_CTRL4); - mxs_lradc_reg_set(lradc, chan->channel, LRADC_CTRL4); + mxs_lradc_reg_set(lradc, chan, LRADC_CTRL4); mxs_lradc_reg_wrt(lradc, 0, LRADC_CH(0)); @@ -824,9 +874,206 @@ err: return ret; } +static int mxs_lradc_read_temp(struct iio_dev *iio_dev, int *val) +{ + int ret, min, max; + + ret = mxs_lradc_read_single(iio_dev, 8, &min); + if (ret != IIO_VAL_INT) + return ret; + + ret = mxs_lradc_read_single(iio_dev, 9, &max); + if (ret != IIO_VAL_INT) + return ret; + + *val = max - min; + + return IIO_VAL_INT; +} + +static int mxs_lradc_read_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int *val, int *val2, long m) +{ + struct mxs_lradc *lradc = iio_priv(iio_dev); + + /* Check for invalid channel */ + if (chan->channel > LRADC_MAX_TOTAL_CHANS) + return -EINVAL; + + switch (m) { + case IIO_CHAN_INFO_RAW: + if (chan->type == IIO_TEMP) + return mxs_lradc_read_temp(iio_dev, val); + + return mxs_lradc_read_single(iio_dev, chan->channel, val); + + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_TEMP) { + /* From the datasheet, we have to multiply by 1.012 and + * divide by 4 + */ + *val = 0; + *val2 = 253000; + return IIO_VAL_INT_PLUS_MICRO; + } + + *val = lradc->vref_mv[chan->channel]; + *val2 = chan->scan_type.realbits - + test_bit(chan->channel, &lradc->is_divided); + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_OFFSET: + if (chan->type == IIO_TEMP) { + /* The calculated value from the ADC is in Kelvin, we + * want Celsius for hwmon so the offset is + * -272.15 * scale + */ + *val = -1075; + *val2 = 691699; + + return IIO_VAL_INT_PLUS_MICRO; + } + + return -EINVAL; + + default: + break; + } + + return -EINVAL; +} + +static int mxs_lradc_write_raw(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + int val, int val2, long m) +{ + struct mxs_lradc *lradc = iio_priv(iio_dev); + struct mxs_lradc_scale *scale_avail = + lradc->scale_avail[chan->channel]; + int ret; + + ret = mutex_trylock(&lradc->lock); + if (!ret) + return -EBUSY; + + switch (m) { + case IIO_CHAN_INFO_SCALE: + ret = -EINVAL; + if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer && + val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) { + /* divider by two disabled */ + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR); + clear_bit(chan->channel, &lradc->is_divided); + ret = 0; + } else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer && + val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) { + /* divider by two enabled */ + writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET, + lradc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET); + set_bit(chan->channel, &lradc->is_divided); + ret = 0; + } + + break; + default: + ret = -EINVAL; + break; + } + + mutex_unlock(&lradc->lock); + + return ret; +} + +static int mxs_lradc_write_raw_get_fmt(struct iio_dev *iio_dev, + const struct iio_chan_spec *chan, + long m) +{ + return IIO_VAL_INT_PLUS_NANO; +} + +static ssize_t mxs_lradc_show_scale_available_ch(struct device *dev, + struct device_attribute *attr, + char *buf, + int ch) +{ + struct iio_dev *iio = dev_to_iio_dev(dev); + struct mxs_lradc *lradc = iio_priv(iio); + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(lradc->scale_avail[ch]); i++) + len += sprintf(buf + len, "%d.%09u ", + lradc->scale_avail[ch][i].integer, + lradc->scale_avail[ch][i].nano); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static ssize_t mxs_lradc_show_scale_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr); + + return mxs_lradc_show_scale_available_ch(dev, attr, buf, + iio_attr->address); +} + +#define SHOW_SCALE_AVAILABLE_ATTR(ch) \ +static IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, S_IRUGO, \ + mxs_lradc_show_scale_available, NULL, ch) + +SHOW_SCALE_AVAILABLE_ATTR(0); +SHOW_SCALE_AVAILABLE_ATTR(1); +SHOW_SCALE_AVAILABLE_ATTR(2); +SHOW_SCALE_AVAILABLE_ATTR(3); +SHOW_SCALE_AVAILABLE_ATTR(4); +SHOW_SCALE_AVAILABLE_ATTR(5); +SHOW_SCALE_AVAILABLE_ATTR(6); +SHOW_SCALE_AVAILABLE_ATTR(7); +SHOW_SCALE_AVAILABLE_ATTR(8); +SHOW_SCALE_AVAILABLE_ATTR(9); +SHOW_SCALE_AVAILABLE_ATTR(10); +SHOW_SCALE_AVAILABLE_ATTR(11); +SHOW_SCALE_AVAILABLE_ATTR(12); +SHOW_SCALE_AVAILABLE_ATTR(13); +SHOW_SCALE_AVAILABLE_ATTR(14); +SHOW_SCALE_AVAILABLE_ATTR(15); + +static struct attribute *mxs_lradc_attributes[] = { + &iio_dev_attr_in_voltage0_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage1_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage2_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage3_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage4_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage5_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage6_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage7_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage8_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage9_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage10_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage11_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage12_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage13_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage14_scale_available.dev_attr.attr, + &iio_dev_attr_in_voltage15_scale_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group mxs_lradc_attribute_group = { + .attrs = mxs_lradc_attributes, +}; + static const struct iio_info mxs_lradc_iio_info = { .driver_module = THIS_MODULE, .read_raw = mxs_lradc_read_raw, + .write_raw = mxs_lradc_write_raw, + .write_raw_get_fmt = mxs_lradc_write_raw_get_fmt, + .attrs = &mxs_lradc_attribute_group, }; static int mxs_lradc_ts_open(struct input_dev *dev) @@ -1133,8 +1380,10 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = { .type = (chan_type), \ .indexed = 1, \ .scan_index = (idx), \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE), \ .channel = (idx), \ + .address = (idx), \ .scan_type = { \ .sign = 'u', \ .realbits = LRADC_RESOLUTION, \ @@ -1151,8 +1400,17 @@ static const struct iio_chan_spec mxs_lradc_chan_spec[] = { MXS_ADC_CHAN(5, IIO_VOLTAGE), MXS_ADC_CHAN(6, IIO_VOLTAGE), MXS_ADC_CHAN(7, IIO_VOLTAGE), /* VBATT */ - MXS_ADC_CHAN(8, IIO_TEMP), /* Temp sense 0 */ - MXS_ADC_CHAN(9, IIO_TEMP), /* Temp sense 1 */ + /* Combined Temperature sensors */ + { + .type = IIO_TEMP, + .indexed = 1, + .scan_index = 8, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET) | + BIT(IIO_CHAN_INFO_SCALE), + .channel = 8, + .scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,}, + }, MXS_ADC_CHAN(10, IIO_VOLTAGE), /* VDDIO */ MXS_ADC_CHAN(11, IIO_VOLTAGE), /* VTH */ MXS_ADC_CHAN(12, IIO_VOLTAGE), /* VDDA */ @@ -1271,7 +1529,8 @@ static int mxs_lradc_probe(struct platform_device *pdev) struct iio_dev *iio; struct resource *iores; int ret = 0, touch_ret; - int i; + int i, s; + unsigned int scale_uv; /* Allocate the IIO device. */ iio = devm_iio_device_alloc(dev, sizeof(*lradc)); @@ -1316,6 +1575,8 @@ static int mxs_lradc_probe(struct platform_device *pdev) return ret; } + lradc->vref_mv = of_cfg->vref_mv; + platform_set_drvdata(pdev, iio); init_completion(&lradc->completion); @@ -1339,6 +1600,26 @@ static int mxs_lradc_probe(struct platform_device *pdev) if (ret) goto err_trig; + /* Populate available ADC input ranges */ + for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) { + for (s = 0; s < ARRAY_SIZE(lradc->scale_avail[i]); s++) { + /* + * [s=0] = optional divider by two disabled (default) + * [s=1] = optional divider by two enabled + * + * The scale is calculated by doing: + * Vref >> (realbits - s) + * which multiplies by two on the second component + * of the array. + */ + scale_uv = ((u64)lradc->vref_mv[i] * 100000000) >> + (iio->channels[i].scan_type.realbits - s); + lradc->scale_avail[i][s].nano = + do_div(scale_uv, 100000000) * 10; + lradc->scale_avail[i][s].integer = scale_uv; + } + } + /* Configure the hardware. */ ret = mxs_lradc_hw_init(lradc); if (ret) diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 0feea5541d02..75ddd4f801a3 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -108,11 +108,6 @@ static int adt7316_i2c_probe(struct i2c_client *client, return adt7316_probe(&client->dev, &bus, id->name); } -static int adt7316_i2c_remove(struct i2c_client *client) -{ - return adt7316_remove(&client->dev); -} - static const struct i2c_device_id adt7316_i2c_id[] = { { "adt7316", 0 }, { "adt7317", 0 }, @@ -132,7 +127,6 @@ static struct i2c_driver adt7316_driver = { .owner = THIS_MODULE, }, .probe = adt7316_i2c_probe, - .remove = adt7316_i2c_remove, .id_table = adt7316_i2c_id, }; module_i2c_driver(adt7316_driver); diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index 7f4f0a8245b4..e480abb72e4a 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -116,11 +116,6 @@ static int adt7316_spi_probe(struct spi_device *spi_dev) return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias); } -static int adt7316_spi_remove(struct spi_device *spi_dev) -{ - return adt7316_remove(&spi_dev->dev); -} - static const struct spi_device_id adt7316_spi_id[] = { { "adt7316", 0 }, { "adt7317", 0 }, @@ -140,7 +135,6 @@ static struct spi_driver adt7316_driver = { .owner = THIS_MODULE, }, .probe = adt7316_spi_probe, - .remove = adt7316_spi_remove, .id_table = adt7316_spi_id, }; module_spi_driver(adt7316_driver); diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 80266e801d56..16a8201228ff 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -2166,7 +2166,7 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, if (ret) return -EIO; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(dev, indio_dev); if (ret) return ret; @@ -2177,16 +2177,6 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus, } EXPORT_SYMBOL(adt7316_probe); -int adt7316_remove(struct device *dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - - iio_device_unregister(indio_dev); - - return 0; -} -EXPORT_SYMBOL(adt7316_remove); - MODULE_AUTHOR("Sonic Zhang "); MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital" " temperature sensor, ADC and DAC driver"); diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index 4d3efff46ae7..2dbfb499528d 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h @@ -31,6 +31,5 @@ extern const struct dev_pm_ops adt7316_pm_ops; #define ADT7316_PM_OPS NULL #endif int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); -int adt7316_remove(struct device *dev); #endif diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index 7e7f9890a642..047af2376300 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -576,10 +576,10 @@ static const struct iio_info ad7150_info = { .event_attrs = &ad7150_event_attribute_group, .driver_module = THIS_MODULE, .read_raw = &ad7150_read_raw, - .read_event_config_new = &ad7150_read_event_config, - .write_event_config_new = &ad7150_write_event_config, - .read_event_value_new = &ad7150_read_event_value, - .write_event_value_new = &ad7150_write_event_value, + .read_event_config = &ad7150_read_event_config, + .write_event_config = &ad7150_write_event_config, + .read_event_value = &ad7150_read_event_value, + .write_event_value = &ad7150_write_event_value, }; /* diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 862d68d99630..cbb1588d591f 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -105,6 +105,11 @@ struct ad7746_chip_info { u8 vt_setup; u8 capdac[2][2]; s8 capdac_set; + + union { + __be32 d32; + u8 d8[4]; + } data ____cacheline_aligned; }; enum ad7746_chan { @@ -566,11 +571,6 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, int ret, delay; u8 regval, reg; - union { - u32 d32; - u8 d8[4]; - } data; - mutex_lock(&indio_dev->mlock); switch (mask) { @@ -591,12 +591,12 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, /* Now read the actual register */ ret = i2c_smbus_read_i2c_block_data(chip->client, - chan->address >> 8, 3, &data.d8[1]); + chan->address >> 8, 3, &chip->data.d8[1]); if (ret < 0) goto out; - *val = (be32_to_cpu(data.d32) & 0xFFFFFF) - 0x800000; + *val = (be32_to_cpu(chip->data.d32) & 0xFFFFFF) - 0x800000; switch (chan->type) { case IIO_TEMP: diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h index c5b701f8aabb..386f4dc8c9a1 100644 --- a/drivers/staging/iio/frequency/ad9832.h +++ b/drivers/staging/iio/frequency/ad9832.h @@ -92,9 +92,9 @@ struct ad9832_state { * transfer buffers to live in their own cache lines. */ union { - unsigned short freq_data[4]____cacheline_aligned; - unsigned short phase_data[2]; - unsigned short data; + __be16 freq_data[4]____cacheline_aligned; + __be16 phase_data[2]; + __be16 data; }; }; diff --git a/drivers/staging/iio/frequency/ad9834.h b/drivers/staging/iio/frequency/ad9834.h index ed5ed8d0007f..8ca6e52bae6b 100644 --- a/drivers/staging/iio/frequency/ad9834.h +++ b/drivers/staging/iio/frequency/ad9834.h @@ -65,8 +65,8 @@ struct ad9834_state { * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - unsigned short data ____cacheline_aligned; - unsigned short freq_data[2] ; + __be16 data ____cacheline_aligned; + __be16 freq_data[2]; }; diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index 6d3d771154f3..d5d395c2e3e4 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -167,7 +167,7 @@ static int adis16060_r_probe(struct spi_device *spi) indio_dev->channels = adis16060_channels; indio_dev->num_channels = ARRAY_SIZE(adis16060_channels); - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; @@ -175,13 +175,6 @@ static int adis16060_r_probe(struct spi_device *spi) return 0; } -/* fixme, confirm ordering in this function */ -static int adis16060_r_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - return 0; -} - static int adis16060_w_probe(struct spi_device *spi) { int ret; @@ -211,7 +204,6 @@ static struct spi_driver adis16060_r_driver = { .owner = THIS_MODULE, }, .probe = adis16060_r_probe, - .remove = adis16060_r_remove, }; static struct spi_driver adis16060_w_driver = { diff --git a/drivers/staging/iio/iio_simple_dummy.c b/drivers/staging/iio/iio_simple_dummy.c index 1fac9894b18c..fd334a03a49a 100644 --- a/drivers/staging/iio/iio_simple_dummy.c +++ b/drivers/staging/iio/iio_simple_dummy.c @@ -370,10 +370,10 @@ static const struct iio_info iio_dummy_info = { .read_raw = &iio_dummy_read_raw, .write_raw = &iio_dummy_write_raw, #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS - .read_event_config_new = &iio_simple_dummy_read_event_config, - .write_event_config_new = &iio_simple_dummy_write_event_config, - .read_event_value_new = &iio_simple_dummy_read_event_value, - .write_event_value_new = &iio_simple_dummy_write_event_value, + .read_event_config = &iio_simple_dummy_read_event_config, + .write_event_config = &iio_simple_dummy_write_event_config, + .read_event_value = &iio_simple_dummy_read_event_value, + .write_event_value = &iio_simple_dummy_write_event_value, #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */ }; diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 488e690388c9..3660a43b5f08 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -585,7 +585,7 @@ static int isl29018_probe(struct i2c_client *client, indio_dev->name = id->name; indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; - err = iio_device_register(indio_dev); + err = devm_iio_device_register(&client->dev, indio_dev); if (err) { dev_err(&client->dev, "iio registration fails\n"); return err; @@ -594,16 +594,6 @@ static int isl29018_probe(struct i2c_client *client, return 0; } -static int isl29018_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - - dev_dbg(&client->dev, "%s()\n", __func__); - iio_device_unregister(indio_dev); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int isl29018_suspend(struct device *dev) { @@ -664,7 +654,6 @@ static struct i2c_driver isl29018_driver = { .of_match_table = isl29018_of_match, }, .probe = isl29018_probe, - .remove = isl29018_remove, .id_table = isl29018_id, }; module_i2c_driver(isl29018_driver); diff --git a/drivers/staging/iio/light/tsl2x7x_core.c b/drivers/staging/iio/light/tsl2x7x_core.c index 18805029d2a9..1e538086d48b 100644 --- a/drivers/staging/iio/light/tsl2x7x_core.c +++ b/drivers/staging/iio/light/tsl2x7x_core.c @@ -1672,10 +1672,10 @@ static const struct iio_info tsl2X7X_device_info[] = { .driver_module = THIS_MODULE, .read_raw = &tsl2x7x_read_raw, .write_raw = &tsl2x7x_write_raw, - .read_event_value_new = &tsl2x7x_read_thresh, - .write_event_value_new = &tsl2x7x_write_thresh, - .read_event_config_new = &tsl2x7x_read_interrupt_config, - .write_event_config_new = &tsl2x7x_write_interrupt_config, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, }, [PRX] = { .attrs = &tsl2X7X_device_attr_group_tbl[PRX], @@ -1683,10 +1683,10 @@ static const struct iio_info tsl2X7X_device_info[] = { .driver_module = THIS_MODULE, .read_raw = &tsl2x7x_read_raw, .write_raw = &tsl2x7x_write_raw, - .read_event_value_new = &tsl2x7x_read_thresh, - .write_event_value_new = &tsl2x7x_write_thresh, - .read_event_config_new = &tsl2x7x_read_interrupt_config, - .write_event_config_new = &tsl2x7x_write_interrupt_config, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, }, [ALSPRX] = { .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX], @@ -1694,10 +1694,10 @@ static const struct iio_info tsl2X7X_device_info[] = { .driver_module = THIS_MODULE, .read_raw = &tsl2x7x_read_raw, .write_raw = &tsl2x7x_write_raw, - .read_event_value_new = &tsl2x7x_read_thresh, - .write_event_value_new = &tsl2x7x_write_thresh, - .read_event_config_new = &tsl2x7x_read_interrupt_config, - .write_event_config_new = &tsl2x7x_write_interrupt_config, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, }, [PRX2] = { .attrs = &tsl2X7X_device_attr_group_tbl[PRX2], @@ -1705,10 +1705,10 @@ static const struct iio_info tsl2X7X_device_info[] = { .driver_module = THIS_MODULE, .read_raw = &tsl2x7x_read_raw, .write_raw = &tsl2x7x_write_raw, - .read_event_value_new = &tsl2x7x_read_thresh, - .write_event_value_new = &tsl2x7x_write_thresh, - .read_event_config_new = &tsl2x7x_read_interrupt_config, - .write_event_config_new = &tsl2x7x_write_interrupt_config, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, }, [ALSPRX2] = { .attrs = &tsl2X7X_device_attr_group_tbl[ALSPRX2], @@ -1716,10 +1716,10 @@ static const struct iio_info tsl2X7X_device_info[] = { .driver_module = THIS_MODULE, .read_raw = &tsl2x7x_read_raw, .write_raw = &tsl2x7x_write_raw, - .read_event_value_new = &tsl2x7x_read_thresh, - .write_event_value_new = &tsl2x7x_write_thresh, - .read_event_config_new = &tsl2x7x_read_interrupt_config, - .write_event_config_new = &tsl2x7x_write_interrupt_config, + .read_event_value = &tsl2x7x_read_thresh, + .write_event_value = &tsl2x7x_write_thresh, + .read_event_config = &tsl2x7x_read_interrupt_config, + .write_event_config = &tsl2x7x_write_interrupt_config, }, }; diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 0485d7f39867..d4f4dd90c699 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -629,10 +629,17 @@ static const struct i2c_device_id hmc5843_id[] = { }; MODULE_DEVICE_TABLE(i2c, hmc5843_id); +static const struct of_device_id hmc5843_of_match[] = { + { .compatible = "honeywell,hmc5843" }, + {} +}; +MODULE_DEVICE_TABLE(of, hmc5843_of_match); + static struct i2c_driver hmc5843_driver = { .driver = { .name = "hmc5843", .pm = HMC5843_PM_OPS, + .of_match_table = hmc5843_of_match, }, .id_table = hmc5843_id, .probe = hmc5843_probe, diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 62d30179301f..36eedd8a0ea9 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -131,7 +131,7 @@ static int ad2s1200_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(ad2s1200_channels); indio_dev->name = spi_get_device_id(spi)->name; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) return ret; @@ -142,13 +142,6 @@ static int ad2s1200_probe(struct spi_device *spi) return 0; } -static int ad2s1200_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - static const struct spi_device_id ad2s1200_id[] = { { "ad2s1200" }, { "ad2s1205" }, @@ -162,7 +155,6 @@ static struct spi_driver ad2s1200_driver = { .owner = THIS_MODULE, }, .probe = ad2s1200_probe, - .remove = ad2s1200_remove, .id_table = ad2s1200_id, }; module_spi_driver(ad2s1200_driver); diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 5032ff7c2259..78319ad176cd 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -53,3 +53,9 @@ config DRM_IMX_IPUV3 depends on DRM_IMX_IPUV3_CORE help Choose this if you have a i.MX5 or i.MX6 processor. + +config DRM_IMX_HDMI + tristate "Freescale i.MX DRM HDMI" + depends on DRM_IMX + help + Choose this if you want to use HDMI on i.MX6. diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 8742432d7b01..4677585b5ad5 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3) += imx-ipuv3-crtc.o +obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 96e4eee344ef..09ef5fb8bae6 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -448,6 +448,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) goto err_vblank; } + platform_set_drvdata(drm->platformdev, drm); mutex_unlock(&imxdrm->mutex); return 0; @@ -848,7 +849,7 @@ static int imx_drm_platform_probe(struct platform_device *pdev) static int imx_drm_platform_remove(struct platform_device *pdev) { - drm_platform_exit(&imx_drm_driver, pdev); + drm_put_dev(platform_get_drvdata(pdev)); return 0; } diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c new file mode 100644 index 000000000000..f3a1f5e2e492 --- /dev/null +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -0,0 +1,1916 @@ +/* + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * SH-Mobile High-Definition Multimedia Interface (HDMI) driver + * for SLISHDMI13T and SLIPHDMIT IP cores + * + * Copyright (C) 2010, Guennadi Liakhovetski + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "ipu-v3/imx-ipu-v3.h" +#include "imx-hdmi.h" +#include "imx-drm.h" + +#define HDMI_EDID_LEN 512 + +#define RGB 0 +#define YCBCR444 1 +#define YCBCR422_16BITS 2 +#define YCBCR422_8BITS 3 +#define XVYCC444 4 + +enum hdmi_datamap { + RGB444_8B = 0x01, + RGB444_10B = 0x03, + RGB444_12B = 0x05, + RGB444_16B = 0x07, + YCbCr444_8B = 0x09, + YCbCr444_10B = 0x0B, + YCbCr444_12B = 0x0D, + YCbCr444_16B = 0x0F, + YCbCr422_8B = 0x16, + YCbCr422_10B = 0x14, + YCbCr422_12B = 0x12, +}; + +enum hdmi_colorimetry { + ITU601, + ITU709, +}; + +enum imx_hdmi_devtype { + IMX6Q_HDMI, + IMX6DL_HDMI, +}; + +static const u16 csc_coeff_default[3][4] = { + { 0x2000, 0x0000, 0x0000, 0x0000 }, + { 0x0000, 0x2000, 0x0000, 0x0000 }, + { 0x0000, 0x0000, 0x2000, 0x0000 } +}; + +static const u16 csc_coeff_rgb_out_eitu601[3][4] = { + { 0x2000, 0x6926, 0x74fd, 0x010e }, + { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, + { 0x2000, 0x0000, 0x38b4, 0x7e3b } +}; + +static const u16 csc_coeff_rgb_out_eitu709[3][4] = { + { 0x2000, 0x7106, 0x7a02, 0x00a7 }, + { 0x2000, 0x3264, 0x0000, 0x7e6d }, + { 0x2000, 0x0000, 0x3b61, 0x7e25 } +}; + +static const u16 csc_coeff_rgb_in_eitu601[3][4] = { + { 0x2591, 0x1322, 0x074b, 0x0000 }, + { 0x6535, 0x2000, 0x7acc, 0x0200 }, + { 0x6acd, 0x7534, 0x2000, 0x0200 } +}; + +static const u16 csc_coeff_rgb_in_eitu709[3][4] = { + { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, + { 0x62f0, 0x2000, 0x7d11, 0x0200 }, + { 0x6756, 0x78ab, 0x2000, 0x0200 } +}; + +struct hdmi_vmode { + bool mdvi; + bool mhsyncpolarity; + bool mvsyncpolarity; + bool minterlaced; + bool mdataenablepolarity; + + unsigned int mpixelclock; + unsigned int mpixelrepetitioninput; + unsigned int mpixelrepetitionoutput; +}; + +struct hdmi_data_info { + unsigned int enc_in_format; + unsigned int enc_out_format; + unsigned int enc_color_depth; + unsigned int colorimetry; + unsigned int pix_repet_factor; + unsigned int hdcp_enable; + struct hdmi_vmode video_mode; +}; + +struct imx_hdmi { + struct drm_connector connector; + struct imx_drm_connector *imx_drm_connector; + struct drm_encoder encoder; + struct imx_drm_encoder *imx_drm_encoder; + + enum imx_hdmi_devtype dev_type; + struct device *dev; + struct clk *isfr_clk; + struct clk *iahb_clk; + + struct hdmi_data_info hdmi_data; + int vic; + + u8 edid[HDMI_EDID_LEN]; + bool cable_plugin; + + bool phy_enabled; + struct drm_display_mode previous_mode; + + struct regmap *regmap; + struct i2c_adapter *ddc; + void __iomem *regs; + + unsigned long pixel_clk_rate; + unsigned int sample_rate; + int ratio; +}; + +static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di) +{ + regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, + IMX6Q_GPR3_HDMI_MUX_CTL_MASK, + ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); +} + +static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) +{ + writeb(val, hdmi->regs + offset); +} + +static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) +{ + return readb(hdmi->regs + offset); +} + +static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, + u8 shift, u8 mask) +{ + u8 value = hdmi_readb(hdmi, reg) & ~mask; + value |= (data << shift) & mask; + hdmi_writeb(hdmi, value, reg); +} + +static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, + unsigned int value) +{ + u8 val; + + hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); + hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2); + hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3); + + /* nshift factor = 0 */ + val = hdmi_readb(hdmi, HDMI_AUD_CTS3); + val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK; + hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); +} + +static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) +{ + u8 val; + + /* Must be set/cleared first */ + val = hdmi_readb(hdmi, HDMI_AUD_CTS3); + val &= ~HDMI_AUD_CTS3_CTS_MANUAL; + hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); + + hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); + hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); + hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | + HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); +} + +static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, + unsigned int ratio) +{ + unsigned int n = (128 * freq) / 1000; + + switch (freq) { + case 32000: + if (pixel_clk == 25170000) + n = (ratio == 150) ? 9152 : 4576; + else if (pixel_clk == 27020000) + n = (ratio == 150) ? 8192 : 4096; + else if (pixel_clk == 74170000 || pixel_clk == 148350000) + n = 11648; + else + n = 4096; + break; + + case 44100: + if (pixel_clk == 25170000) + n = 7007; + else if (pixel_clk == 74170000) + n = 17836; + else if (pixel_clk == 148350000) + n = (ratio == 150) ? 17836 : 8918; + else + n = 6272; + break; + + case 48000: + if (pixel_clk == 25170000) + n = (ratio == 150) ? 9152 : 6864; + else if (pixel_clk == 27020000) + n = (ratio == 150) ? 8192 : 6144; + else if (pixel_clk == 74170000) + n = 11648; + else if (pixel_clk == 148350000) + n = (ratio == 150) ? 11648 : 5824; + else + n = 6144; + break; + + case 88200: + n = hdmi_compute_n(44100, pixel_clk, ratio) * 2; + break; + + case 96000: + n = hdmi_compute_n(48000, pixel_clk, ratio) * 2; + break; + + case 176400: + n = hdmi_compute_n(44100, pixel_clk, ratio) * 4; + break; + + case 192000: + n = hdmi_compute_n(48000, pixel_clk, ratio) * 4; + break; + + default: + break; + } + + return n; +} + +static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, + unsigned int ratio) +{ + unsigned int cts = 0; + + pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq, + pixel_clk, ratio); + + switch (freq) { + case 32000: + if (pixel_clk == 297000000) { + cts = 222750; + break; + } + case 48000: + case 96000: + case 192000: + switch (pixel_clk) { + case 25200000: + case 27000000: + case 54000000: + case 74250000: + case 148500000: + cts = pixel_clk / 1000; + break; + case 297000000: + cts = 247500; + break; + /* + * All other TMDS clocks are not supported by + * DWC_hdmi_tx. The TMDS clocks divided or + * multiplied by 1,001 coefficients are not + * supported. + */ + default: + break; + } + break; + case 44100: + case 88200: + case 176400: + switch (pixel_clk) { + case 25200000: + cts = 28000; + break; + case 27000000: + cts = 30000; + break; + case 54000000: + cts = 60000; + break; + case 74250000: + cts = 82500; + break; + case 148500000: + cts = 165000; + break; + case 297000000: + cts = 247500; + break; + default: + break; + } + break; + default: + break; + } + if (ratio == 100) + return cts; + else + return (cts * ratio) / 100; +} + +static void hdmi_get_pixel_clk(struct imx_hdmi *hdmi) +{ + unsigned long rate; + + rate = 65000000; /* FIXME */ + + if (rate) + hdmi->pixel_clk_rate = rate; +} + +static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi) +{ + unsigned int clk_n, clk_cts; + + clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + + if (!clk_cts) { + dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", + __func__, hdmi->pixel_clk_rate); + return; + } + + dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", + __func__, hdmi->sample_rate, hdmi->ratio, + hdmi->pixel_clk_rate, clk_n, clk_cts); + + hdmi_set_clock_regenerator_n(hdmi, clk_n); + hdmi_regenerate_cts(hdmi, clk_cts); +} + +static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi) +{ + unsigned int clk_n, clk_cts; + + clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, + hdmi->ratio); + + if (!clk_cts) { + dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", + __func__, hdmi->pixel_clk_rate); + return; + } + + dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", + __func__, hdmi->sample_rate, hdmi->ratio, + hdmi->pixel_clk_rate, clk_n, clk_cts); + + hdmi_set_clock_regenerator_n(hdmi, clk_n); + hdmi_regenerate_cts(hdmi, clk_cts); +} + +static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi) +{ + /* Get pixel clock from ipu */ + hdmi_get_pixel_clk(hdmi); + hdmi_set_clk_regenerator(hdmi); +} + +/* + * this submodule is responsible for the video data synchronization. + * for example, for RGB 4:4:4 input, the data map is defined as + * pin{47~40} <==> R[7:0] + * pin{31~24} <==> G[7:0] + * pin{15~8} <==> B[7:0] + */ +static void hdmi_video_sample(struct imx_hdmi *hdmi) +{ + int color_format = 0; + u8 val; + + if (hdmi->hdmi_data.enc_in_format == RGB) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x01; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x03; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x05; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_format = 0x07; + else + return; + } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x09; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x0B; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x0D; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_format = 0x0F; + else + return; + } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { + if (hdmi->hdmi_data.enc_color_depth == 8) + color_format = 0x16; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_format = 0x14; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_format = 0x12; + else + return; + } + + val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | + ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & + HDMI_TX_INVID0_VIDEO_MAPPING_MASK); + hdmi_writeb(hdmi, val, HDMI_TX_INVID0); + + /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ + val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; + hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); + hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); + hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); + hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); + hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); +} + +static int is_color_space_conversion(struct imx_hdmi *hdmi) +{ + return (hdmi->hdmi_data.enc_in_format != + hdmi->hdmi_data.enc_out_format); +} + +static int is_color_space_decimation(struct imx_hdmi *hdmi) +{ + return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) && + (hdmi->hdmi_data.enc_in_format == RGB || + hdmi->hdmi_data.enc_in_format == YCBCR444)); +} + +static int is_color_space_interpolation(struct imx_hdmi *hdmi) +{ + return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) && + (hdmi->hdmi_data.enc_out_format == RGB || + hdmi->hdmi_data.enc_out_format == YCBCR444)); +} + +static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) +{ + const u16 (*csc_coeff)[3][4] = &csc_coeff_default; + u32 csc_scale = 1; + u8 val; + + if (is_color_space_conversion(hdmi)) { + if (hdmi->hdmi_data.enc_out_format == RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + csc_coeff = &csc_coeff_rgb_out_eitu601; + else + csc_coeff = &csc_coeff_rgb_out_eitu709; + } else if (hdmi->hdmi_data.enc_in_format == RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + csc_coeff = &csc_coeff_rgb_in_eitu601; + else + csc_coeff = &csc_coeff_rgb_in_eitu709; + csc_scale = 0; + } + } + + hdmi_writeb(hdmi, ((*csc_coeff)[0][0] & 0xff), HDMI_CSC_COEF_A1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][0] >> 8), HDMI_CSC_COEF_A1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][1] & 0xff), HDMI_CSC_COEF_A2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][1] >> 8), HDMI_CSC_COEF_A2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][2] & 0xff), HDMI_CSC_COEF_A3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][2] >> 8), HDMI_CSC_COEF_A3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][3] & 0xff), HDMI_CSC_COEF_A4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[0][3] >> 8), HDMI_CSC_COEF_A4_MSB); + + hdmi_writeb(hdmi, ((*csc_coeff)[1][0] & 0xff), HDMI_CSC_COEF_B1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][0] >> 8), HDMI_CSC_COEF_B1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][1] & 0xff), HDMI_CSC_COEF_B2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][1] >> 8), HDMI_CSC_COEF_B2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][2] & 0xff), HDMI_CSC_COEF_B3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][2] >> 8), HDMI_CSC_COEF_B3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][3] & 0xff), HDMI_CSC_COEF_B4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[1][3] >> 8), HDMI_CSC_COEF_B4_MSB); + + hdmi_writeb(hdmi, ((*csc_coeff)[2][0] & 0xff), HDMI_CSC_COEF_C1_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][0] >> 8), HDMI_CSC_COEF_C1_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][1] & 0xff), HDMI_CSC_COEF_C2_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][1] >> 8), HDMI_CSC_COEF_C2_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][2] & 0xff), HDMI_CSC_COEF_C3_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][2] >> 8), HDMI_CSC_COEF_C3_MSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][3] & 0xff), HDMI_CSC_COEF_C4_LSB); + hdmi_writeb(hdmi, ((*csc_coeff)[2][3] >> 8), HDMI_CSC_COEF_C4_MSB); + + val = hdmi_readb(hdmi, HDMI_CSC_SCALE); + val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK; + val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK; + hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); +} + +static void hdmi_video_csc(struct imx_hdmi *hdmi) +{ + int color_depth = 0; + int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; + int decimation = 0; + u8 val; + + /* YCC422 interpolation to 444 mode */ + if (is_color_space_interpolation(hdmi)) + interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; + else if (is_color_space_decimation(hdmi)) + decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; + + if (hdmi->hdmi_data.enc_color_depth == 8) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; + else if (hdmi->hdmi_data.enc_color_depth == 10) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; + else if (hdmi->hdmi_data.enc_color_depth == 12) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; + else if (hdmi->hdmi_data.enc_color_depth == 16) + color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; + else + return; + + /* Configure the CSC registers */ + hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); + val = hdmi_readb(hdmi, HDMI_CSC_SCALE); + val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK; + val |= color_depth; + hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); + + imx_hdmi_update_csc_coeffs(hdmi); +} + +/* + * HDMI video packetizer is used to packetize the data. + * for example, if input is YCC422 mode or repeater is used, + * data should be repacked this module can be bypassed. + */ +static void hdmi_video_packetize(struct imx_hdmi *hdmi) +{ + unsigned int color_depth = 0; + unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; + unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; + struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; + u8 val; + + if (hdmi_data->enc_out_format == RGB + || hdmi_data->enc_out_format == YCBCR444) { + if (!hdmi_data->enc_color_depth) + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; + else if (hdmi_data->enc_color_depth == 8) { + color_depth = 4; + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; + } else if (hdmi_data->enc_color_depth == 10) + color_depth = 5; + else if (hdmi_data->enc_color_depth == 12) + color_depth = 6; + else if (hdmi_data->enc_color_depth == 16) + color_depth = 7; + else + return; + } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { + if (!hdmi_data->enc_color_depth || + hdmi_data->enc_color_depth == 8) + remap_size = HDMI_VP_REMAP_YCC422_16bit; + else if (hdmi_data->enc_color_depth == 10) + remap_size = HDMI_VP_REMAP_YCC422_20bit; + else if (hdmi_data->enc_color_depth == 12) + remap_size = HDMI_VP_REMAP_YCC422_24bit; + else + return; + output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; + } else + return; + + /* set the packetizer registers */ + val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & + HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | + ((hdmi_data->pix_repet_factor << + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); + hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK; + val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + /* Data from pixel repeater block */ + if (hdmi_data->pix_repet_factor > 1) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_PR_EN_MASK | + HDMI_VP_CONF_BYPASS_SELECT_MASK); + val |= HDMI_VP_CONF_PR_EN_ENABLE | + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else { /* data from packetizer block */ + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_PR_EN_MASK | + HDMI_VP_CONF_BYPASS_SELECT_MASK); + val |= HDMI_VP_CONF_PR_EN_DISABLE | + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK; + val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); + + if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_ENABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_ENABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK | + HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK); + val |= HDMI_VP_CONF_BYPASS_EN_ENABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); + } else { + return; + } + + val = hdmi_readb(hdmi, HDMI_VP_STUFF); + val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK | + HDMI_VP_STUFF_YCC422_STUFFING_MASK); + val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE; + hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + + val = hdmi_readb(hdmi, HDMI_VP_CONF); + val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK; + val |= output_select; + hdmi_writeb(hdmi, val, HDMI_VP_CONF); +} + +static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTCLR_MASK; + val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) & + HDMI_PHY_TST0_TSTCLR_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTEN_MASK; + val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) & + HDMI_PHY_TST0_TSTEN_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi, + unsigned char bit) +{ + u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0); + val &= ~HDMI_PHY_TST0_TSTCLK_MASK; + val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) & + HDMI_PHY_TST0_TSTCLK_MASK; + hdmi_writeb(hdmi, val, HDMI_PHY_TST0); +} + +static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi, + unsigned char bit) +{ + hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); +} + +static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi, + unsigned char bit) +{ + hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); +} + +static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec) +{ + unsigned char val = 0; + val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3; + while (!val) { + udelay(1000); + if (msec-- == 0) + return false; + val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3; + } + return true; +} + +static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, + unsigned char addr) +{ + hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); + hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); + hdmi_writeb(hdmi, (unsigned char)(data >> 8), + HDMI_PHY_I2CM_DATAO_1_ADDR); + hdmi_writeb(hdmi, (unsigned char)(data >> 0), + HDMI_PHY_I2CM_DATAO_0_ADDR); + hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, + HDMI_PHY_I2CM_OPERATION_ADDR); + hdmi_phy_wait_i2c_done(hdmi, 1000); +} + +static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, + unsigned char addr) +{ + __hdmi_phy_i2c_write(hdmi, data, addr); + return 0; +} + +static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_PDZ_OFFSET, + HDMI_PHY_CONF0_PDZ_MASK); +} + +static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_ENTMDS_OFFSET, + HDMI_PHY_CONF0_ENTMDS_MASK); +} + +static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, + HDMI_PHY_CONF0_GEN2_PDDQ_MASK); +} + +static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); +} + +static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, + HDMI_PHY_CONF0_SELDATAENPOL_MASK); +} + +static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable) +{ + hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, + HDMI_PHY_CONF0_SELDIPIF_OFFSET, + HDMI_PHY_CONF0_SELDIPIF_MASK); +} + +static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, + unsigned char res, int cscon) +{ + u8 val, msec; + + /* color resolution 0 is 8 bit colour depth */ + if (!res) + res = 8; + + if (prep) + return -EINVAL; + else if (res != 8 && res != 12) + return -EINVAL; + + /* Enable csc path */ + if (cscon) + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH; + else + val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS; + + hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL); + + /* gen2 tx power off */ + imx_hdmi_phy_gen2_txpwron(hdmi, 0); + + /* gen2 pddq */ + imx_hdmi_phy_gen2_pddq(hdmi, 1); + + /* PHY reset */ + hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); + hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); + + hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); + + hdmi_phy_test_clear(hdmi, 1); + hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, + HDMI_PHY_I2CM_SLAVE_ADDR); + hdmi_phy_test_clear(hdmi, 0); + + if (hdmi->hdmi_data.video_mode.mpixelclock <= 45250000) { + switch (res) { + case 8: + /* PLL/MPLL Cfg */ + hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */ + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 92500000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x0140, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x2141, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x4142, 0x06); + hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 148500000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + default: + return -EINVAL; + } + } else { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000a, 0x15); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x2001, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x4002, 0x06); + hdmi_phy_i2c_write(hdmi, 0x000f, 0x15); + default: + return -EINVAL; + } + } + + if (hdmi->hdmi_data.video_mode.mpixelclock <= 54000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */ + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 58400000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 72000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 74250000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 118800000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + default: + return -EINVAL; + } + } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 216000000) { + switch (res) { + case 8: + hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10); + break; + case 10: + hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10); + break; + case 12: + hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); + break; + default: + return -EINVAL; + } + } else { + dev_err(hdmi->dev, + "Pixel clock %d - unsupported by HDMI\n", + hdmi->hdmi_data.video_mode.mpixelclock); + return -EINVAL; + } + + hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ + hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); + /* RESISTANCE TERM 133Ohm Cfg */ + hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ + /* PREEMP Cgf 0.00 */ + hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ + /* TX/CK LVL 10 */ + hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ + /* REMOVE CLK TERM */ + hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ + + imx_hdmi_phy_enable_power(hdmi, 1); + + /* toggle TMDS enable */ + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_tmds(hdmi, 1); + + /* gen2 tx power on */ + imx_hdmi_phy_gen2_txpwron(hdmi, 1); + imx_hdmi_phy_gen2_pddq(hdmi, 0); + + /*Wait for PHY PLL lock */ + msec = 5; + do { + val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; + if (!val) + break; + + if (msec == 0) { + dev_err(hdmi->dev, "PHY PLL not locked\n"); + return -ETIMEDOUT; + } + + udelay(1000); + msec--; + } while (1); + + return 0; +} + +static int imx_hdmi_phy_init(struct imx_hdmi *hdmi) +{ + int i, ret; + bool cscon = false; + + /*check csc whether needed activated in HDMI mode */ + cscon = (is_color_space_conversion(hdmi) && + !hdmi->hdmi_data.video_mode.mdvi); + + /* HDMI Phy spec says to do the phy initialization sequence twice */ + for (i = 0; i < 2; i++) { + imx_hdmi_phy_sel_data_en_pol(hdmi, 1); + imx_hdmi_phy_sel_interface_control(hdmi, 0); + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_power(hdmi, 0); + + /* Enable CSC */ + ret = hdmi_phy_configure(hdmi, 0, 8, cscon); + if (ret) + return ret; + } + + hdmi->phy_enabled = true; + return 0; +} + +static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi) +{ + u8 de, val; + + if (hdmi->hdmi_data.video_mode.mdataenablepolarity) + de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH; + else + de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW; + + /* disable rx detect */ + val = hdmi_readb(hdmi, HDMI_A_HDCPCFG0); + val &= HDMI_A_HDCPCFG0_RXDETECT_MASK; + val |= HDMI_A_HDCPCFG0_RXDETECT_DISABLE; + hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG0); + + val = hdmi_readb(hdmi, HDMI_A_VIDPOLCFG); + val &= HDMI_A_VIDPOLCFG_DATAENPOL_MASK; + val |= de; + hdmi_writeb(hdmi, val, HDMI_A_VIDPOLCFG); + + val = hdmi_readb(hdmi, HDMI_A_HDCPCFG1); + val &= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK; + val |= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE; + hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG1); +} + +static void hdmi_config_AVI(struct imx_hdmi *hdmi) +{ + u8 val, pix_fmt, under_scan; + u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry; + bool aspect_16_9; + + aspect_16_9 = false; /* FIXME */ + + /* AVI Data Byte 1 */ + if (hdmi->hdmi_data.enc_out_format == YCBCR444) + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444; + else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422; + else + pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB; + + under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA; + + /* + * Active format identification data is present in the AVI InfoFrame. + * Under scan info, no bar data + */ + val = pix_fmt | under_scan | + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT | + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA; + + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); + + /* AVI Data Byte 2 -Set the Aspect Ratio */ + if (aspect_16_9) { + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9; + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9; + } else { + act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3; + coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3; + } + + /* Set up colorimetry */ + if (hdmi->hdmi_data.enc_out_format == XVYCC444) { + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; + if (hdmi->hdmi_data.colorimetry == ITU601) + ext_colorimetry = + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + else /* hdmi->hdmi_data.colorimetry == ITU709 */ + ext_colorimetry = + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; + } else if (hdmi->hdmi_data.enc_out_format != RGB) { + if (hdmi->hdmi_data.colorimetry == ITU601) + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; + else /* hdmi->hdmi_data.colorimetry == ITU709 */ + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + } else { /* Carries no data */ + colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA; + ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; + } + + val = colorimetry | coded_ratio | act_ratio; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); + + /* AVI Data Byte 3 */ + val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry | + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT | + HDMI_FC_AVICONF2_SCALING_NONE; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); + + /* AVI Data Byte 4 */ + hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID); + + /* AVI Data Byte 5- set up input and output pixel repetition */ + val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | + ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); + hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); + + /* IT Content and quantization range = don't care */ + val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS | + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED; + hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); + + /* AVI Data Bytes 6-13 */ + hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0); + hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1); +} + +static void hdmi_av_composer(struct imx_hdmi *hdmi, + const struct drm_display_mode *mode) +{ + u8 inv_val; + struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; + int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; + + vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC); + vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC); + vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); + vmode->mpixelclock = mode->clock * 1000; + + dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); + + /* Set up HDMI_FC_INVIDCONF */ + inv_val = (hdmi->hdmi_data.hdcp_enable ? + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); + + inv_val |= (vmode->mvsyncpolarity ? + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW); + + inv_val |= (vmode->mhsyncpolarity ? + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW); + + inv_val |= (vmode->mdataenablepolarity ? + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); + + if (hdmi->vic == 39) + inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; + else + inv_val |= (vmode->minterlaced ? + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW); + + inv_val |= (vmode->minterlaced ? + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE); + + inv_val |= (vmode->mdvi ? + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE : + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE); + + hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); + + /* Set up horizontal active pixel width */ + hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); + hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); + + /* Set up vertical active lines */ + hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1); + hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0); + + /* Set up horizontal blanking pixel region width */ + hblank = mode->htotal - mode->hdisplay; + hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); + hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); + + /* Set up vertical blanking pixel region width */ + vblank = mode->vtotal - mode->vdisplay; + hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); + + /* Set up HSYNC active edge delay width (in pixel clks) */ + h_de_hs = mode->hsync_start - mode->hdisplay; + hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); + hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); + + /* Set up VSYNC active edge delay (in lines) */ + v_de_vs = mode->vsync_start - mode->vdisplay; + hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); + + /* Set up HSYNC active pulse width (in pixel clks) */ + hsync_len = mode->hsync_end - mode->hsync_start; + hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); + hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); + + /* Set up VSYNC active edge delay (in lines) */ + vsync_len = mode->vsync_end - mode->vsync_start; + hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); +} + +static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi) +{ + if (!hdmi->phy_enabled) + return; + + imx_hdmi_phy_enable_tmds(hdmi, 0); + imx_hdmi_phy_enable_power(hdmi, 0); + + hdmi->phy_enabled = false; +} + +/* HDMI Initialization Step B.4 */ +static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi) +{ + u8 clkdis; + + /* control period minimum duration */ + hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); + hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); + hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); + + /* Set to fill TMDS data channels */ + hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); + hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); + hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); + + /* Enable pixel clock and tmds data path */ + clkdis = 0x7F; + clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + + clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + + /* Enable csc path */ + if (is_color_space_conversion(hdmi)) { + clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); + } +} + +static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi) +{ + u8 clkdis; + + clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS); + clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; + hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); +} + +/* Workaround to clear the overflow condition */ +static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi) +{ + int count; + u8 val; + + /* TMDS software reset */ + hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); + + val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); + if (hdmi->dev_type == IMX6DL_HDMI) { + hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); + return; + } + + for (count = 0; count < 4; count++) + hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); +} + +static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); + hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); +} + +static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, + HDMI_IH_MUTE_FC_STAT2); +} + +static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) +{ + int ret; + + hdmi_disable_overflow_interrupts(hdmi); + + hdmi->vic = drm_match_cea_mode(mode); + + if (!hdmi->vic) { + dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); + hdmi->hdmi_data.video_mode.mdvi = true; + } else { + dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); + hdmi->hdmi_data.video_mode.mdvi = false; + } + + if ((hdmi->vic == 6) || (hdmi->vic == 7) || + (hdmi->vic == 21) || (hdmi->vic == 22) || + (hdmi->vic == 2) || (hdmi->vic == 3) || + (hdmi->vic == 17) || (hdmi->vic == 18)) + hdmi->hdmi_data.colorimetry = ITU601; + else + hdmi->hdmi_data.colorimetry = ITU709; + + if ((hdmi->vic == 10) || (hdmi->vic == 11) || + (hdmi->vic == 12) || (hdmi->vic == 13) || + (hdmi->vic == 14) || (hdmi->vic == 15) || + (hdmi->vic == 25) || (hdmi->vic == 26) || + (hdmi->vic == 27) || (hdmi->vic == 28) || + (hdmi->vic == 29) || (hdmi->vic == 30) || + (hdmi->vic == 35) || (hdmi->vic == 36) || + (hdmi->vic == 37) || (hdmi->vic == 38)) + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1; + else + hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; + + hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; + + /* TODO: Get input format from IPU (via FB driver interface) */ + hdmi->hdmi_data.enc_in_format = RGB; + + hdmi->hdmi_data.enc_out_format = RGB; + + hdmi->hdmi_data.enc_color_depth = 8; + hdmi->hdmi_data.pix_repet_factor = 0; + hdmi->hdmi_data.hdcp_enable = 0; + hdmi->hdmi_data.video_mode.mdataenablepolarity = true; + + /* HDMI Initialization Step B.1 */ + hdmi_av_composer(hdmi, mode); + + /* HDMI Initializateion Step B.2 */ + ret = imx_hdmi_phy_init(hdmi); + if (ret) + return ret; + + /* HDMI Initialization Step B.3 */ + imx_hdmi_enable_video_path(hdmi); + + /* not for DVI mode */ + if (hdmi->hdmi_data.video_mode.mdvi) + dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); + else { + dev_dbg(hdmi->dev, "%s CEA mode\n", __func__); + + /* HDMI Initialization Step E - Configure audio */ + hdmi_clk_regenerator_update_pixel_clock(hdmi); + hdmi_enable_audio_clk(hdmi); + + /* HDMI Initialization Step F - Configure AVI InfoFrame */ + hdmi_config_AVI(hdmi); + } + + hdmi_video_packetize(hdmi); + hdmi_video_csc(hdmi); + hdmi_video_sample(hdmi); + hdmi_tx_hdcp_config(hdmi); + + imx_hdmi_clear_overflow(hdmi); + if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi) + hdmi_enable_overflow_interrupts(hdmi); + + return 0; +} + +/* Wait until we are registered to enable interrupts */ +static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) +{ + hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, + HDMI_PHY_I2CM_INT_ADDR); + + hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, + HDMI_PHY_I2CM_CTLINT_ADDR); + + /* enable cable hot plug irq */ + hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0); + + /* Clear Hotplug interrupts */ + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); + + /* Unmute interrupts */ + hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); + + return 0; +} + +static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi) +{ + u8 ih_mute; + + /* + * Boot up defaults are: + * HDMI_IH_MUTE = 0x03 (disabled) + * HDMI_IH_MUTE_* = 0x00 (enabled) + * + * Disable top level interrupt bits in HDMI block + */ + ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; + + hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); + + /* by default mask all interrupts */ + hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); + hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); + hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); + hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); + hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); + hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); + + /* Disable interrupts in the IH_MUTE_* registers */ + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); + hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); + + /* Enable top level interrupt bits in HDMI block */ + ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); + hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); +} + +static void imx_hdmi_poweron(struct imx_hdmi *hdmi) +{ + imx_hdmi_setup(hdmi, &hdmi->previous_mode); +} + +static void imx_hdmi_poweroff(struct imx_hdmi *hdmi) +{ + imx_hdmi_phy_disable(hdmi); +} + +static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector + *connector, bool force) +{ + /* FIXME */ + return connector_status_connected; +} + +static void imx_hdmi_connector_destroy(struct drm_connector *connector) +{ +} + +static int imx_hdmi_connector_get_modes(struct drm_connector *connector) +{ + struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, + connector); + struct edid *edid; + int ret; + + if (!hdmi->ddc) + return 0; + + edid = drm_get_edid(connector, hdmi->ddc); + if (edid) { + dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", + edid->width_cm, edid->height_cm); + + drm_mode_connector_update_edid_property(connector, edid); + ret = drm_add_edid_modes(connector, edid); + kfree(edid); + } else { + dev_dbg(hdmi->dev, "failed to get edid\n"); + } + + return 0; +} + +static int imx_hdmi_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + + return MODE_OK; +} + +static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector + *connector) +{ + struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, + connector); + + return &hdmi->encoder; +} + +static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + imx_hdmi_setup(hdmi, mode); + + /* Store the display mode for plugin/DKMS poweron events */ + memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); +} + +static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void imx_hdmi_encoder_disable(struct drm_encoder *encoder) +{ +} + +static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + if (mode) + imx_hdmi_poweroff(hdmi); + else + imx_hdmi_poweron(hdmi); +} + +static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + + imx_hdmi_poweroff(hdmi); + imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE, + V4L2_PIX_FMT_RGB24); +} + +static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) +{ + struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + int mux = imx_drm_encoder_get_mux_id(hdmi->imx_drm_encoder, + encoder->crtc); + + imx_hdmi_set_ipu_di_mux(hdmi, mux); + + imx_hdmi_poweron(hdmi); +} + +static void imx_hdmi_encoder_destroy(struct drm_encoder *encoder) +{ + return; +} + +static struct drm_encoder_funcs imx_hdmi_encoder_funcs = { + .destroy = imx_hdmi_encoder_destroy, +}; + +static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = { + .dpms = imx_hdmi_encoder_dpms, + .prepare = imx_hdmi_encoder_prepare, + .commit = imx_hdmi_encoder_commit, + .mode_set = imx_hdmi_encoder_mode_set, + .mode_fixup = imx_hdmi_encoder_mode_fixup, + .disable = imx_hdmi_encoder_disable, +}; + +static struct drm_connector_funcs imx_hdmi_connector_funcs = { + .dpms = drm_helper_connector_dpms, + .fill_modes = drm_helper_probe_single_connector_modes, + .detect = imx_hdmi_connector_detect, + .destroy = imx_hdmi_connector_destroy, +}; + +static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { + .get_modes = imx_hdmi_connector_get_modes, + .mode_valid = imx_hdmi_connector_mode_valid, + .best_encoder = imx_hdmi_connector_best_encoder, +}; + +static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) +{ + struct imx_hdmi *hdmi = dev_id; + u8 intr_stat; + u8 phy_int_pol; + u8 val; + + intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); + + phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); + + if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { + if (phy_int_pol & HDMI_PHY_HPD) { + dev_dbg(hdmi->dev, "EVENT=plugin\n"); + + val = hdmi_readb(hdmi, HDMI_PHY_POL0); + val &= ~HDMI_PHY_HPD; + hdmi_writeb(hdmi, val, HDMI_PHY_POL0); + + imx_hdmi_poweron(hdmi); + } else { + dev_dbg(hdmi->dev, "EVENT=plugout\n"); + + val = hdmi_readb(hdmi, HDMI_PHY_POL0); + val |= HDMI_PHY_HPD; + hdmi_writeb(hdmi, val, HDMI_PHY_POL0); + + imx_hdmi_poweroff(hdmi); + } + } + + hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); + + return IRQ_HANDLED; +} + +static int imx_hdmi_register(struct imx_hdmi *hdmi) +{ + int ret; + + hdmi->connector.funcs = &imx_hdmi_connector_funcs; + hdmi->encoder.funcs = &imx_hdmi_encoder_funcs; + + hdmi->encoder.encoder_type = DRM_MODE_ENCODER_TMDS; + hdmi->connector.connector_type = DRM_MODE_CONNECTOR_HDMIA; + + drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs); + ret = imx_drm_add_encoder(&hdmi->encoder, &hdmi->imx_drm_encoder, + THIS_MODULE); + if (ret) { + dev_err(hdmi->dev, "adding encoder failed: %d\n", ret); + return ret; + } + + drm_connector_helper_add(&hdmi->connector, + &imx_hdmi_connector_helper_funcs); + + ret = imx_drm_add_connector(&hdmi->connector, + &hdmi->imx_drm_connector, THIS_MODULE); + if (ret) { + imx_drm_remove_encoder(hdmi->imx_drm_encoder); + dev_err(hdmi->dev, "adding connector failed: %d\n", ret); + return ret; + } + + hdmi->connector.encoder = &hdmi->encoder; + + drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder); + + return 0; +} + +static struct platform_device_id imx_hdmi_devtype[] = { + { + .name = "imx6q-hdmi", + .driver_data = IMX6Q_HDMI, + }, { + .name = "imx6dl-hdmi", + .driver_data = IMX6DL_HDMI, + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype); + +static const struct of_device_id imx_hdmi_dt_ids[] = { +{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], }, +{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], }, +{ /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); + +static int imx_hdmi_platform_probe(struct platform_device *pdev) +{ + const struct of_device_id *of_id = + of_match_device(imx_hdmi_dt_ids, &pdev->dev); + struct device_node *np = pdev->dev.of_node; + struct device_node *ddc_node; + struct imx_hdmi *hdmi; + struct resource *iores; + int ret, irq; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + hdmi->dev = &pdev->dev; + + if (of_id) { + const struct platform_device_id *device_id = of_id->data; + hdmi->dev_type = device_id->driver_data; + } + + ddc_node = of_parse_phandle(np, "ddc", 0); + if (ddc_node) { + hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); + if (!hdmi->ddc) + dev_dbg(hdmi->dev, "failed to read ddc node\n"); + + of_node_put(ddc_node); + } else { + dev_dbg(hdmi->dev, "no ddc property found\n"); + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return -EINVAL; + + ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0, + dev_name(&pdev->dev), hdmi); + if (ret) + return ret; + + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hdmi->regs = devm_ioremap_resource(&pdev->dev, iores); + if (IS_ERR(hdmi->regs)) + return PTR_ERR(hdmi->regs); + + hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); + if (IS_ERR(hdmi->regmap)) + return PTR_ERR(hdmi->regmap); + + hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); + if (IS_ERR(hdmi->isfr_clk)) { + ret = PTR_ERR(hdmi->isfr_clk); + dev_err(hdmi->dev, + "Unable to get HDMI isfr clk: %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(hdmi->isfr_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI isfr clock: %d\n", ret); + return ret; + } + + hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); + if (IS_ERR(hdmi->iahb_clk)) { + ret = PTR_ERR(hdmi->iahb_clk); + dev_err(hdmi->dev, + "Unable to get HDMI iahb clk: %d\n", ret); + goto err_isfr; + } + + ret = clk_prepare_enable(hdmi->iahb_clk); + if (ret) { + dev_err(hdmi->dev, + "Cannot enable HDMI iahb clock: %d\n", ret); + goto err_isfr; + } + + /* Product and revision IDs */ + dev_info(&pdev->dev, + "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", + hdmi_readb(hdmi, HDMI_DESIGN_ID), + hdmi_readb(hdmi, HDMI_REVISION_ID), + hdmi_readb(hdmi, HDMI_PRODUCT_ID0), + hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); + + initialize_hdmi_ih_mutes(hdmi); + + /* + * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator + * N and cts values before enabling phy + */ + hdmi_init_clk_regenerator(hdmi); + + /* + * Configure registers related to HDMI interrupt + * generation before registering IRQ. + */ + hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0); + + /* Clear Hotplug interrupts */ + hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); + + ret = imx_hdmi_fb_registered(hdmi); + if (ret) + goto err_iahb; + + ret = imx_hdmi_register(hdmi); + if (ret) + goto err_iahb; + + imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); + + platform_set_drvdata(pdev, hdmi); + + return 0; + +err_iahb: + clk_disable_unprepare(hdmi->iahb_clk); +err_isfr: + clk_disable_unprepare(hdmi->isfr_clk); + + return ret; +} + +static int imx_hdmi_platform_remove(struct platform_device *pdev) +{ + struct imx_hdmi *hdmi = platform_get_drvdata(pdev); + struct drm_connector *connector = &hdmi->connector; + struct drm_encoder *encoder = &hdmi->encoder; + + drm_mode_connector_detach_encoder(connector, encoder); + imx_drm_remove_connector(hdmi->imx_drm_connector); + imx_drm_remove_encoder(hdmi->imx_drm_encoder); + + clk_disable_unprepare(hdmi->iahb_clk); + clk_disable_unprepare(hdmi->isfr_clk); + i2c_put_adapter(hdmi->ddc); + + return 0; +} + +static struct platform_driver imx_hdmi_driver = { + .probe = imx_hdmi_platform_probe, + .remove = imx_hdmi_platform_remove, + .driver = { + .name = "imx-hdmi", + .owner = THIS_MODULE, + .of_match_table = imx_hdmi_dt_ids, + }, +}; + +module_platform_driver(imx_hdmi_driver); + +MODULE_AUTHOR("Sascha Hauer "); +MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imx-hdmi"); diff --git a/drivers/staging/imx-drm/imx-hdmi.h b/drivers/staging/imx-drm/imx-hdmi.h new file mode 100644 index 000000000000..39b677689db6 --- /dev/null +++ b/drivers/staging/imx-drm/imx-hdmi.h @@ -0,0 +1,1032 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __IMX_HDMI_H__ +#define __IMX_HDMI_H__ + +/* Identification Registers */ +#define HDMI_DESIGN_ID 0x0000 +#define HDMI_REVISION_ID 0x0001 +#define HDMI_PRODUCT_ID0 0x0002 +#define HDMI_PRODUCT_ID1 0x0003 +#define HDMI_CONFIG0_ID 0x0004 +#define HDMI_CONFIG1_ID 0x0005 +#define HDMI_CONFIG2_ID 0x0006 +#define HDMI_CONFIG3_ID 0x0007 + +/* Interrupt Registers */ +#define HDMI_IH_FC_STAT0 0x0100 +#define HDMI_IH_FC_STAT1 0x0101 +#define HDMI_IH_FC_STAT2 0x0102 +#define HDMI_IH_AS_STAT0 0x0103 +#define HDMI_IH_PHY_STAT0 0x0104 +#define HDMI_IH_I2CM_STAT0 0x0105 +#define HDMI_IH_CEC_STAT0 0x0106 +#define HDMI_IH_VP_STAT0 0x0107 +#define HDMI_IH_I2CMPHY_STAT0 0x0108 +#define HDMI_IH_AHBDMAAUD_STAT0 0x0109 + +#define HDMI_IH_MUTE_FC_STAT0 0x0180 +#define HDMI_IH_MUTE_FC_STAT1 0x0181 +#define HDMI_IH_MUTE_FC_STAT2 0x0182 +#define HDMI_IH_MUTE_AS_STAT0 0x0183 +#define HDMI_IH_MUTE_PHY_STAT0 0x0184 +#define HDMI_IH_MUTE_I2CM_STAT0 0x0185 +#define HDMI_IH_MUTE_CEC_STAT0 0x0186 +#define HDMI_IH_MUTE_VP_STAT0 0x0187 +#define HDMI_IH_MUTE_I2CMPHY_STAT0 0x0188 +#define HDMI_IH_MUTE_AHBDMAAUD_STAT0 0x0189 +#define HDMI_IH_MUTE 0x01FF + +/* Video Sample Registers */ +#define HDMI_TX_INVID0 0x0200 +#define HDMI_TX_INSTUFFING 0x0201 +#define HDMI_TX_GYDATA0 0x0202 +#define HDMI_TX_GYDATA1 0x0203 +#define HDMI_TX_RCRDATA0 0x0204 +#define HDMI_TX_RCRDATA1 0x0205 +#define HDMI_TX_BCBDATA0 0x0206 +#define HDMI_TX_BCBDATA1 0x0207 + +/* Video Packetizer Registers */ +#define HDMI_VP_STATUS 0x0800 +#define HDMI_VP_PR_CD 0x0801 +#define HDMI_VP_STUFF 0x0802 +#define HDMI_VP_REMAP 0x0803 +#define HDMI_VP_CONF 0x0804 +#define HDMI_VP_STAT 0x0805 +#define HDMI_VP_INT 0x0806 +#define HDMI_VP_MASK 0x0807 +#define HDMI_VP_POL 0x0808 + +/* Frame Composer Registers */ +#define HDMI_FC_INVIDCONF 0x1000 +#define HDMI_FC_INHACTV0 0x1001 +#define HDMI_FC_INHACTV1 0x1002 +#define HDMI_FC_INHBLANK0 0x1003 +#define HDMI_FC_INHBLANK1 0x1004 +#define HDMI_FC_INVACTV0 0x1005 +#define HDMI_FC_INVACTV1 0x1006 +#define HDMI_FC_INVBLANK 0x1007 +#define HDMI_FC_HSYNCINDELAY0 0x1008 +#define HDMI_FC_HSYNCINDELAY1 0x1009 +#define HDMI_FC_HSYNCINWIDTH0 0x100A +#define HDMI_FC_HSYNCINWIDTH1 0x100B +#define HDMI_FC_VSYNCINDELAY 0x100C +#define HDMI_FC_VSYNCINWIDTH 0x100D +#define HDMI_FC_INFREQ0 0x100E +#define HDMI_FC_INFREQ1 0x100F +#define HDMI_FC_INFREQ2 0x1010 +#define HDMI_FC_CTRLDUR 0x1011 +#define HDMI_FC_EXCTRLDUR 0x1012 +#define HDMI_FC_EXCTRLSPAC 0x1013 +#define HDMI_FC_CH0PREAM 0x1014 +#define HDMI_FC_CH1PREAM 0x1015 +#define HDMI_FC_CH2PREAM 0x1016 +#define HDMI_FC_AVICONF3 0x1017 +#define HDMI_FC_GCP 0x1018 +#define HDMI_FC_AVICONF0 0x1019 +#define HDMI_FC_AVICONF1 0x101A +#define HDMI_FC_AVICONF2 0x101B +#define HDMI_FC_AVIVID 0x101C +#define HDMI_FC_AVIETB0 0x101D +#define HDMI_FC_AVIETB1 0x101E +#define HDMI_FC_AVISBB0 0x101F +#define HDMI_FC_AVISBB1 0x1020 +#define HDMI_FC_AVIELB0 0x1021 +#define HDMI_FC_AVIELB1 0x1022 +#define HDMI_FC_AVISRB0 0x1023 +#define HDMI_FC_AVISRB1 0x1024 +#define HDMI_FC_AUDICONF0 0x1025 +#define HDMI_FC_AUDICONF1 0x1026 +#define HDMI_FC_AUDICONF2 0x1027 +#define HDMI_FC_AUDICONF3 0x1028 +#define HDMI_FC_VSDIEEEID0 0x1029 +#define HDMI_FC_VSDSIZE 0x102A +#define HDMI_FC_VSDIEEEID1 0x1030 +#define HDMI_FC_VSDIEEEID2 0x1031 +#define HDMI_FC_VSDPAYLOAD0 0x1032 +#define HDMI_FC_VSDPAYLOAD1 0x1033 +#define HDMI_FC_VSDPAYLOAD2 0x1034 +#define HDMI_FC_VSDPAYLOAD3 0x1035 +#define HDMI_FC_VSDPAYLOAD4 0x1036 +#define HDMI_FC_VSDPAYLOAD5 0x1037 +#define HDMI_FC_VSDPAYLOAD6 0x1038 +#define HDMI_FC_VSDPAYLOAD7 0x1039 +#define HDMI_FC_VSDPAYLOAD8 0x103A +#define HDMI_FC_VSDPAYLOAD9 0x103B +#define HDMI_FC_VSDPAYLOAD10 0x103C +#define HDMI_FC_VSDPAYLOAD11 0x103D +#define HDMI_FC_VSDPAYLOAD12 0x103E +#define HDMI_FC_VSDPAYLOAD13 0x103F +#define HDMI_FC_VSDPAYLOAD14 0x1040 +#define HDMI_FC_VSDPAYLOAD15 0x1041 +#define HDMI_FC_VSDPAYLOAD16 0x1042 +#define HDMI_FC_VSDPAYLOAD17 0x1043 +#define HDMI_FC_VSDPAYLOAD18 0x1044 +#define HDMI_FC_VSDPAYLOAD19 0x1045 +#define HDMI_FC_VSDPAYLOAD20 0x1046 +#define HDMI_FC_VSDPAYLOAD21 0x1047 +#define HDMI_FC_VSDPAYLOAD22 0x1048 +#define HDMI_FC_VSDPAYLOAD23 0x1049 +#define HDMI_FC_SPDVENDORNAME0 0x104A +#define HDMI_FC_SPDVENDORNAME1 0x104B +#define HDMI_FC_SPDVENDORNAME2 0x104C +#define HDMI_FC_SPDVENDORNAME3 0x104D +#define HDMI_FC_SPDVENDORNAME4 0x104E +#define HDMI_FC_SPDVENDORNAME5 0x104F +#define HDMI_FC_SPDVENDORNAME6 0x1050 +#define HDMI_FC_SPDVENDORNAME7 0x1051 +#define HDMI_FC_SDPPRODUCTNAME0 0x1052 +#define HDMI_FC_SDPPRODUCTNAME1 0x1053 +#define HDMI_FC_SDPPRODUCTNAME2 0x1054 +#define HDMI_FC_SDPPRODUCTNAME3 0x1055 +#define HDMI_FC_SDPPRODUCTNAME4 0x1056 +#define HDMI_FC_SDPPRODUCTNAME5 0x1057 +#define HDMI_FC_SDPPRODUCTNAME6 0x1058 +#define HDMI_FC_SDPPRODUCTNAME7 0x1059 +#define HDMI_FC_SDPPRODUCTNAME8 0x105A +#define HDMI_FC_SDPPRODUCTNAME9 0x105B +#define HDMI_FC_SDPPRODUCTNAME10 0x105C +#define HDMI_FC_SDPPRODUCTNAME11 0x105D +#define HDMI_FC_SDPPRODUCTNAME12 0x105E +#define HDMI_FC_SDPPRODUCTNAME13 0x105F +#define HDMI_FC_SDPPRODUCTNAME14 0x1060 +#define HDMI_FC_SPDPRODUCTNAME15 0x1061 +#define HDMI_FC_SPDDEVICEINF 0x1062 +#define HDMI_FC_AUDSCONF 0x1063 +#define HDMI_FC_AUDSSTAT 0x1064 +#define HDMI_FC_DATACH0FILL 0x1070 +#define HDMI_FC_DATACH1FILL 0x1071 +#define HDMI_FC_DATACH2FILL 0x1072 +#define HDMI_FC_CTRLQHIGH 0x1073 +#define HDMI_FC_CTRLQLOW 0x1074 +#define HDMI_FC_ACP0 0x1075 +#define HDMI_FC_ACP28 0x1076 +#define HDMI_FC_ACP27 0x1077 +#define HDMI_FC_ACP26 0x1078 +#define HDMI_FC_ACP25 0x1079 +#define HDMI_FC_ACP24 0x107A +#define HDMI_FC_ACP23 0x107B +#define HDMI_FC_ACP22 0x107C +#define HDMI_FC_ACP21 0x107D +#define HDMI_FC_ACP20 0x107E +#define HDMI_FC_ACP19 0x107F +#define HDMI_FC_ACP18 0x1080 +#define HDMI_FC_ACP17 0x1081 +#define HDMI_FC_ACP16 0x1082 +#define HDMI_FC_ACP15 0x1083 +#define HDMI_FC_ACP14 0x1084 +#define HDMI_FC_ACP13 0x1085 +#define HDMI_FC_ACP12 0x1086 +#define HDMI_FC_ACP11 0x1087 +#define HDMI_FC_ACP10 0x1088 +#define HDMI_FC_ACP9 0x1089 +#define HDMI_FC_ACP8 0x108A +#define HDMI_FC_ACP7 0x108B +#define HDMI_FC_ACP6 0x108C +#define HDMI_FC_ACP5 0x108D +#define HDMI_FC_ACP4 0x108E +#define HDMI_FC_ACP3 0x108F +#define HDMI_FC_ACP2 0x1090 +#define HDMI_FC_ACP1 0x1091 +#define HDMI_FC_ISCR1_0 0x1092 +#define HDMI_FC_ISCR1_16 0x1093 +#define HDMI_FC_ISCR1_15 0x1094 +#define HDMI_FC_ISCR1_14 0x1095 +#define HDMI_FC_ISCR1_13 0x1096 +#define HDMI_FC_ISCR1_12 0x1097 +#define HDMI_FC_ISCR1_11 0x1098 +#define HDMI_FC_ISCR1_10 0x1099 +#define HDMI_FC_ISCR1_9 0x109A +#define HDMI_FC_ISCR1_8 0x109B +#define HDMI_FC_ISCR1_7 0x109C +#define HDMI_FC_ISCR1_6 0x109D +#define HDMI_FC_ISCR1_5 0x109E +#define HDMI_FC_ISCR1_4 0x109F +#define HDMI_FC_ISCR1_3 0x10A0 +#define HDMI_FC_ISCR1_2 0x10A1 +#define HDMI_FC_ISCR1_1 0x10A2 +#define HDMI_FC_ISCR2_15 0x10A3 +#define HDMI_FC_ISCR2_14 0x10A4 +#define HDMI_FC_ISCR2_13 0x10A5 +#define HDMI_FC_ISCR2_12 0x10A6 +#define HDMI_FC_ISCR2_11 0x10A7 +#define HDMI_FC_ISCR2_10 0x10A8 +#define HDMI_FC_ISCR2_9 0x10A9 +#define HDMI_FC_ISCR2_8 0x10AA +#define HDMI_FC_ISCR2_7 0x10AB +#define HDMI_FC_ISCR2_6 0x10AC +#define HDMI_FC_ISCR2_5 0x10AD +#define HDMI_FC_ISCR2_4 0x10AE +#define HDMI_FC_ISCR2_3 0x10AF +#define HDMI_FC_ISCR2_2 0x10B0 +#define HDMI_FC_ISCR2_1 0x10B1 +#define HDMI_FC_ISCR2_0 0x10B2 +#define HDMI_FC_DATAUTO0 0x10B3 +#define HDMI_FC_DATAUTO1 0x10B4 +#define HDMI_FC_DATAUTO2 0x10B5 +#define HDMI_FC_DATMAN 0x10B6 +#define HDMI_FC_DATAUTO3 0x10B7 +#define HDMI_FC_RDRB0 0x10B8 +#define HDMI_FC_RDRB1 0x10B9 +#define HDMI_FC_RDRB2 0x10BA +#define HDMI_FC_RDRB3 0x10BB +#define HDMI_FC_RDRB4 0x10BC +#define HDMI_FC_RDRB5 0x10BD +#define HDMI_FC_RDRB6 0x10BE +#define HDMI_FC_RDRB7 0x10BF +#define HDMI_FC_STAT0 0x10D0 +#define HDMI_FC_INT0 0x10D1 +#define HDMI_FC_MASK0 0x10D2 +#define HDMI_FC_POL0 0x10D3 +#define HDMI_FC_STAT1 0x10D4 +#define HDMI_FC_INT1 0x10D5 +#define HDMI_FC_MASK1 0x10D6 +#define HDMI_FC_POL1 0x10D7 +#define HDMI_FC_STAT2 0x10D8 +#define HDMI_FC_INT2 0x10D9 +#define HDMI_FC_MASK2 0x10DA +#define HDMI_FC_POL2 0x10DB +#define HDMI_FC_PRCONF 0x10E0 + +#define HDMI_FC_GMD_STAT 0x1100 +#define HDMI_FC_GMD_EN 0x1101 +#define HDMI_FC_GMD_UP 0x1102 +#define HDMI_FC_GMD_CONF 0x1103 +#define HDMI_FC_GMD_HB 0x1104 +#define HDMI_FC_GMD_PB0 0x1105 +#define HDMI_FC_GMD_PB1 0x1106 +#define HDMI_FC_GMD_PB2 0x1107 +#define HDMI_FC_GMD_PB3 0x1108 +#define HDMI_FC_GMD_PB4 0x1109 +#define HDMI_FC_GMD_PB5 0x110A +#define HDMI_FC_GMD_PB6 0x110B +#define HDMI_FC_GMD_PB7 0x110C +#define HDMI_FC_GMD_PB8 0x110D +#define HDMI_FC_GMD_PB9 0x110E +#define HDMI_FC_GMD_PB10 0x110F +#define HDMI_FC_GMD_PB11 0x1110 +#define HDMI_FC_GMD_PB12 0x1111 +#define HDMI_FC_GMD_PB13 0x1112 +#define HDMI_FC_GMD_PB14 0x1113 +#define HDMI_FC_GMD_PB15 0x1114 +#define HDMI_FC_GMD_PB16 0x1115 +#define HDMI_FC_GMD_PB17 0x1116 +#define HDMI_FC_GMD_PB18 0x1117 +#define HDMI_FC_GMD_PB19 0x1118 +#define HDMI_FC_GMD_PB20 0x1119 +#define HDMI_FC_GMD_PB21 0x111A +#define HDMI_FC_GMD_PB22 0x111B +#define HDMI_FC_GMD_PB23 0x111C +#define HDMI_FC_GMD_PB24 0x111D +#define HDMI_FC_GMD_PB25 0x111E +#define HDMI_FC_GMD_PB26 0x111F +#define HDMI_FC_GMD_PB27 0x1120 + +#define HDMI_FC_DBGFORCE 0x1200 +#define HDMI_FC_DBGAUD0CH0 0x1201 +#define HDMI_FC_DBGAUD1CH0 0x1202 +#define HDMI_FC_DBGAUD2CH0 0x1203 +#define HDMI_FC_DBGAUD0CH1 0x1204 +#define HDMI_FC_DBGAUD1CH1 0x1205 +#define HDMI_FC_DBGAUD2CH1 0x1206 +#define HDMI_FC_DBGAUD0CH2 0x1207 +#define HDMI_FC_DBGAUD1CH2 0x1208 +#define HDMI_FC_DBGAUD2CH2 0x1209 +#define HDMI_FC_DBGAUD0CH3 0x120A +#define HDMI_FC_DBGAUD1CH3 0x120B +#define HDMI_FC_DBGAUD2CH3 0x120C +#define HDMI_FC_DBGAUD0CH4 0x120D +#define HDMI_FC_DBGAUD1CH4 0x120E +#define HDMI_FC_DBGAUD2CH4 0x120F +#define HDMI_FC_DBGAUD0CH5 0x1210 +#define HDMI_FC_DBGAUD1CH5 0x1211 +#define HDMI_FC_DBGAUD2CH5 0x1212 +#define HDMI_FC_DBGAUD0CH6 0x1213 +#define HDMI_FC_DBGAUD1CH6 0x1214 +#define HDMI_FC_DBGAUD2CH6 0x1215 +#define HDMI_FC_DBGAUD0CH7 0x1216 +#define HDMI_FC_DBGAUD1CH7 0x1217 +#define HDMI_FC_DBGAUD2CH7 0x1218 +#define HDMI_FC_DBGTMDS0 0x1219 +#define HDMI_FC_DBGTMDS1 0x121A +#define HDMI_FC_DBGTMDS2 0x121B + +/* HDMI Source PHY Registers */ +#define HDMI_PHY_CONF0 0x3000 +#define HDMI_PHY_TST0 0x3001 +#define HDMI_PHY_TST1 0x3002 +#define HDMI_PHY_TST2 0x3003 +#define HDMI_PHY_STAT0 0x3004 +#define HDMI_PHY_INT0 0x3005 +#define HDMI_PHY_MASK0 0x3006 +#define HDMI_PHY_POL0 0x3007 + +/* HDMI Master PHY Registers */ +#define HDMI_PHY_I2CM_SLAVE_ADDR 0x3020 +#define HDMI_PHY_I2CM_ADDRESS_ADDR 0x3021 +#define HDMI_PHY_I2CM_DATAO_1_ADDR 0x3022 +#define HDMI_PHY_I2CM_DATAO_0_ADDR 0x3023 +#define HDMI_PHY_I2CM_DATAI_1_ADDR 0x3024 +#define HDMI_PHY_I2CM_DATAI_0_ADDR 0x3025 +#define HDMI_PHY_I2CM_OPERATION_ADDR 0x3026 +#define HDMI_PHY_I2CM_INT_ADDR 0x3027 +#define HDMI_PHY_I2CM_CTLINT_ADDR 0x3028 +#define HDMI_PHY_I2CM_DIV_ADDR 0x3029 +#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR 0x302a +#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR 0x302b +#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR 0x302c +#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR 0x302d +#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR 0x302e +#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR 0x302f +#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR 0x3030 +#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR 0x3031 +#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR 0x3032 + +/* Audio Sampler Registers */ +#define HDMI_AUD_CONF0 0x3100 +#define HDMI_AUD_CONF1 0x3101 +#define HDMI_AUD_INT 0x3102 +#define HDMI_AUD_CONF2 0x3103 +#define HDMI_AUD_N1 0x3200 +#define HDMI_AUD_N2 0x3201 +#define HDMI_AUD_N3 0x3202 +#define HDMI_AUD_CTS1 0x3203 +#define HDMI_AUD_CTS2 0x3204 +#define HDMI_AUD_CTS3 0x3205 +#define HDMI_AUD_INPUTCLKFS 0x3206 +#define HDMI_AUD_SPDIFINT 0x3302 +#define HDMI_AUD_CONF0_HBR 0x3400 +#define HDMI_AUD_HBR_STATUS 0x3401 +#define HDMI_AUD_HBR_INT 0x3402 +#define HDMI_AUD_HBR_POL 0x3403 +#define HDMI_AUD_HBR_MASK 0x3404 + +/* + * Generic Parallel Audio Interface Registers + * Not used as GPAUD interface is not enabled in hw + */ +#define HDMI_GP_CONF0 0x3500 +#define HDMI_GP_CONF1 0x3501 +#define HDMI_GP_CONF2 0x3502 +#define HDMI_GP_STAT 0x3503 +#define HDMI_GP_INT 0x3504 +#define HDMI_GP_MASK 0x3505 +#define HDMI_GP_POL 0x3506 + +/* Audio DMA Registers */ +#define HDMI_AHB_DMA_CONF0 0x3600 +#define HDMI_AHB_DMA_START 0x3601 +#define HDMI_AHB_DMA_STOP 0x3602 +#define HDMI_AHB_DMA_THRSLD 0x3603 +#define HDMI_AHB_DMA_STRADDR0 0x3604 +#define HDMI_AHB_DMA_STRADDR1 0x3605 +#define HDMI_AHB_DMA_STRADDR2 0x3606 +#define HDMI_AHB_DMA_STRADDR3 0x3607 +#define HDMI_AHB_DMA_STPADDR0 0x3608 +#define HDMI_AHB_DMA_STPADDR1 0x3609 +#define HDMI_AHB_DMA_STPADDR2 0x360a +#define HDMI_AHB_DMA_STPADDR3 0x360b +#define HDMI_AHB_DMA_BSTADDR0 0x360c +#define HDMI_AHB_DMA_BSTADDR1 0x360d +#define HDMI_AHB_DMA_BSTADDR2 0x360e +#define HDMI_AHB_DMA_BSTADDR3 0x360f +#define HDMI_AHB_DMA_MBLENGTH0 0x3610 +#define HDMI_AHB_DMA_MBLENGTH1 0x3611 +#define HDMI_AHB_DMA_STAT 0x3612 +#define HDMI_AHB_DMA_INT 0x3613 +#define HDMI_AHB_DMA_MASK 0x3614 +#define HDMI_AHB_DMA_POL 0x3615 +#define HDMI_AHB_DMA_CONF1 0x3616 +#define HDMI_AHB_DMA_BUFFSTAT 0x3617 +#define HDMI_AHB_DMA_BUFFINT 0x3618 +#define HDMI_AHB_DMA_BUFFMASK 0x3619 +#define HDMI_AHB_DMA_BUFFPOL 0x361a + +/* Main Controller Registers */ +#define HDMI_MC_SFRDIV 0x4000 +#define HDMI_MC_CLKDIS 0x4001 +#define HDMI_MC_SWRSTZ 0x4002 +#define HDMI_MC_OPCTRL 0x4003 +#define HDMI_MC_FLOWCTRL 0x4004 +#define HDMI_MC_PHYRSTZ 0x4005 +#define HDMI_MC_LOCKONCLOCK 0x4006 +#define HDMI_MC_HEACPHY_RST 0x4007 + +/* Color Space Converter Registers */ +#define HDMI_CSC_CFG 0x4100 +#define HDMI_CSC_SCALE 0x4101 +#define HDMI_CSC_COEF_A1_MSB 0x4102 +#define HDMI_CSC_COEF_A1_LSB 0x4103 +#define HDMI_CSC_COEF_A2_MSB 0x4104 +#define HDMI_CSC_COEF_A2_LSB 0x4105 +#define HDMI_CSC_COEF_A3_MSB 0x4106 +#define HDMI_CSC_COEF_A3_LSB 0x4107 +#define HDMI_CSC_COEF_A4_MSB 0x4108 +#define HDMI_CSC_COEF_A4_LSB 0x4109 +#define HDMI_CSC_COEF_B1_MSB 0x410A +#define HDMI_CSC_COEF_B1_LSB 0x410B +#define HDMI_CSC_COEF_B2_MSB 0x410C +#define HDMI_CSC_COEF_B2_LSB 0x410D +#define HDMI_CSC_COEF_B3_MSB 0x410E +#define HDMI_CSC_COEF_B3_LSB 0x410F +#define HDMI_CSC_COEF_B4_MSB 0x4110 +#define HDMI_CSC_COEF_B4_LSB 0x4111 +#define HDMI_CSC_COEF_C1_MSB 0x4112 +#define HDMI_CSC_COEF_C1_LSB 0x4113 +#define HDMI_CSC_COEF_C2_MSB 0x4114 +#define HDMI_CSC_COEF_C2_LSB 0x4115 +#define HDMI_CSC_COEF_C3_MSB 0x4116 +#define HDMI_CSC_COEF_C3_LSB 0x4117 +#define HDMI_CSC_COEF_C4_MSB 0x4118 +#define HDMI_CSC_COEF_C4_LSB 0x4119 + +/* HDCP Encryption Engine Registers */ +#define HDMI_A_HDCPCFG0 0x5000 +#define HDMI_A_HDCPCFG1 0x5001 +#define HDMI_A_HDCPOBS0 0x5002 +#define HDMI_A_HDCPOBS1 0x5003 +#define HDMI_A_HDCPOBS2 0x5004 +#define HDMI_A_HDCPOBS3 0x5005 +#define HDMI_A_APIINTCLR 0x5006 +#define HDMI_A_APIINTSTAT 0x5007 +#define HDMI_A_APIINTMSK 0x5008 +#define HDMI_A_VIDPOLCFG 0x5009 +#define HDMI_A_OESSWCFG 0x500A +#define HDMI_A_TIMER1SETUP0 0x500B +#define HDMI_A_TIMER1SETUP1 0x500C +#define HDMI_A_TIMER2SETUP0 0x500D +#define HDMI_A_TIMER2SETUP1 0x500E +#define HDMI_A_100MSCFG 0x500F +#define HDMI_A_2SCFG0 0x5010 +#define HDMI_A_2SCFG1 0x5011 +#define HDMI_A_5SCFG0 0x5012 +#define HDMI_A_5SCFG1 0x5013 +#define HDMI_A_SRMVERLSB 0x5014 +#define HDMI_A_SRMVERMSB 0x5015 +#define HDMI_A_SRMCTRL 0x5016 +#define HDMI_A_SFRSETUP 0x5017 +#define HDMI_A_I2CHSETUP 0x5018 +#define HDMI_A_INTSETUP 0x5019 +#define HDMI_A_PRESETUP 0x501A +#define HDMI_A_SRM_BASE 0x5020 + +/* CEC Engine Registers */ +#define HDMI_CEC_CTRL 0x7D00 +#define HDMI_CEC_STAT 0x7D01 +#define HDMI_CEC_MASK 0x7D02 +#define HDMI_CEC_POLARITY 0x7D03 +#define HDMI_CEC_INT 0x7D04 +#define HDMI_CEC_ADDR_L 0x7D05 +#define HDMI_CEC_ADDR_H 0x7D06 +#define HDMI_CEC_TX_CNT 0x7D07 +#define HDMI_CEC_RX_CNT 0x7D08 +#define HDMI_CEC_TX_DATA0 0x7D10 +#define HDMI_CEC_TX_DATA1 0x7D11 +#define HDMI_CEC_TX_DATA2 0x7D12 +#define HDMI_CEC_TX_DATA3 0x7D13 +#define HDMI_CEC_TX_DATA4 0x7D14 +#define HDMI_CEC_TX_DATA5 0x7D15 +#define HDMI_CEC_TX_DATA6 0x7D16 +#define HDMI_CEC_TX_DATA7 0x7D17 +#define HDMI_CEC_TX_DATA8 0x7D18 +#define HDMI_CEC_TX_DATA9 0x7D19 +#define HDMI_CEC_TX_DATA10 0x7D1a +#define HDMI_CEC_TX_DATA11 0x7D1b +#define HDMI_CEC_TX_DATA12 0x7D1c +#define HDMI_CEC_TX_DATA13 0x7D1d +#define HDMI_CEC_TX_DATA14 0x7D1e +#define HDMI_CEC_TX_DATA15 0x7D1f +#define HDMI_CEC_RX_DATA0 0x7D20 +#define HDMI_CEC_RX_DATA1 0x7D21 +#define HDMI_CEC_RX_DATA2 0x7D22 +#define HDMI_CEC_RX_DATA3 0x7D23 +#define HDMI_CEC_RX_DATA4 0x7D24 +#define HDMI_CEC_RX_DATA5 0x7D25 +#define HDMI_CEC_RX_DATA6 0x7D26 +#define HDMI_CEC_RX_DATA7 0x7D27 +#define HDMI_CEC_RX_DATA8 0x7D28 +#define HDMI_CEC_RX_DATA9 0x7D29 +#define HDMI_CEC_RX_DATA10 0x7D2a +#define HDMI_CEC_RX_DATA11 0x7D2b +#define HDMI_CEC_RX_DATA12 0x7D2c +#define HDMI_CEC_RX_DATA13 0x7D2d +#define HDMI_CEC_RX_DATA14 0x7D2e +#define HDMI_CEC_RX_DATA15 0x7D2f +#define HDMI_CEC_LOCK 0x7D30 +#define HDMI_CEC_WKUPCTRL 0x7D31 + +/* I2C Master Registers (E-DDC) */ +#define HDMI_I2CM_SLAVE 0x7E00 +#define HDMI_I2CMESS 0x7E01 +#define HDMI_I2CM_DATAO 0x7E02 +#define HDMI_I2CM_DATAI 0x7E03 +#define HDMI_I2CM_OPERATION 0x7E04 +#define HDMI_I2CM_INT 0x7E05 +#define HDMI_I2CM_CTLINT 0x7E06 +#define HDMI_I2CM_DIV 0x7E07 +#define HDMI_I2CM_SEGADDR 0x7E08 +#define HDMI_I2CM_SOFTRSTZ 0x7E09 +#define HDMI_I2CM_SEGPTR 0x7E0A +#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR 0x7E0B +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x7E0C +#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR 0x7E0D +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x7E0E +#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR 0x7E0F +#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR 0x7E10 +#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR 0x7E11 +#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR 0x7E12 + +enum { +/* IH_FC_INT2 field values */ + HDMI_IH_FC_INT2_OVERFLOW_MASK = 0x03, + HDMI_IH_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_FC_STAT2 field values */ + HDMI_IH_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_IH_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_PHY_STAT0 field values */ + HDMI_IH_PHY_STAT0_RX_SENSE3 = 0x20, + HDMI_IH_PHY_STAT0_RX_SENSE2 = 0x10, + HDMI_IH_PHY_STAT0_RX_SENSE1 = 0x8, + HDMI_IH_PHY_STAT0_RX_SENSE0 = 0x4, + HDMI_IH_PHY_STAT0_TX_PHY_LOCK = 0x2, + HDMI_IH_PHY_STAT0_HPD = 0x1, + +/* IH_MUTE_I2CMPHY_STAT0 field values */ + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYDONE = 0x2, + HDMI_IH_MUTE_I2CMPHY_STAT0_I2CMPHYERROR = 0x1, + +/* IH_AHBDMAAUD_STAT0 field values */ + HDMI_IH_AHBDMAAUD_STAT0_ERROR = 0x20, + HDMI_IH_AHBDMAAUD_STAT0_LOST = 0x10, + HDMI_IH_AHBDMAAUD_STAT0_RETRY = 0x08, + HDMI_IH_AHBDMAAUD_STAT0_DONE = 0x04, + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = 0x02, + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, + +/* IH_MUTE_FC_STAT2 field values */ + HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_IH_MUTE_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_IH_MUTE_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* IH_MUTE_AHBDMAAUD_STAT0 field values */ + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = 0x20, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = 0x10, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = 0x08, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = 0x04, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = 0x02, + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = 0x01, + +/* IH_MUTE field values */ + HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT = 0x2, + HDMI_IH_MUTE_MUTE_ALL_INTERRUPT = 0x1, + +/* TX_INVID0 field values */ + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_MASK = 0x80, + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_ENABLE = 0x80, + HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE = 0x00, + HDMI_TX_INVID0_VIDEO_MAPPING_MASK = 0x1F, + HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET = 0, + +/* TX_INSTUFFING field values */ + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_MASK = 0x4, + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE = 0x4, + HDMI_TX_INSTUFFING_BDBDATA_STUFFING_DISABLE = 0x0, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_MASK = 0x2, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE = 0x2, + HDMI_TX_INSTUFFING_RCRDATA_STUFFING_DISABLE = 0x0, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_MASK = 0x1, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE = 0x1, + HDMI_TX_INSTUFFING_GYDATA_STUFFING_DISABLE = 0x0, + +/* VP_PR_CD field values */ + HDMI_VP_PR_CD_COLOR_DEPTH_MASK = 0xF0, + HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET = 4, + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK = 0x0F, + HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET = 0, + +/* VP_STUFF field values */ + HDMI_VP_STUFF_IDEFAULT_PHASE_MASK = 0x20, + HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET = 5, + HDMI_VP_STUFF_IFIX_PP_TO_LAST_MASK = 0x10, + HDMI_VP_STUFF_IFIX_PP_TO_LAST_OFFSET = 4, + HDMI_VP_STUFF_ICX_GOTO_P0_ST_MASK = 0x8, + HDMI_VP_STUFF_ICX_GOTO_P0_ST_OFFSET = 3, + HDMI_VP_STUFF_YCC422_STUFFING_MASK = 0x4, + HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE = 0x4, + HDMI_VP_STUFF_YCC422_STUFFING_DIRECT_MODE = 0x0, + HDMI_VP_STUFF_PP_STUFFING_MASK = 0x2, + HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE = 0x2, + HDMI_VP_STUFF_PP_STUFFING_DIRECT_MODE = 0x0, + HDMI_VP_STUFF_PR_STUFFING_MASK = 0x1, + HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE = 0x1, + HDMI_VP_STUFF_PR_STUFFING_DIRECT_MODE = 0x0, + +/* VP_CONF field values */ + HDMI_VP_CONF_BYPASS_EN_MASK = 0x40, + HDMI_VP_CONF_BYPASS_EN_ENABLE = 0x40, + HDMI_VP_CONF_BYPASS_EN_DISABLE = 0x00, + HDMI_VP_CONF_PP_EN_ENMASK = 0x20, + HDMI_VP_CONF_PP_EN_ENABLE = 0x20, + HDMI_VP_CONF_PP_EN_DISABLE = 0x00, + HDMI_VP_CONF_PR_EN_MASK = 0x10, + HDMI_VP_CONF_PR_EN_ENABLE = 0x10, + HDMI_VP_CONF_PR_EN_DISABLE = 0x00, + HDMI_VP_CONF_YCC422_EN_MASK = 0x8, + HDMI_VP_CONF_YCC422_EN_ENABLE = 0x8, + HDMI_VP_CONF_YCC422_EN_DISABLE = 0x0, + HDMI_VP_CONF_BYPASS_SELECT_MASK = 0x4, + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER = 0x4, + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER = 0x0, + HDMI_VP_CONF_OUTPUT_SELECTOR_MASK = 0x3, + HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS = 0x3, + HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422 = 0x1, + HDMI_VP_CONF_OUTPUT_SELECTOR_PP = 0x0, + +/* VP_REMAP field values */ + HDMI_VP_REMAP_MASK = 0x3, + HDMI_VP_REMAP_YCC422_24bit = 0x2, + HDMI_VP_REMAP_YCC422_20bit = 0x1, + HDMI_VP_REMAP_YCC422_16bit = 0x0, + +/* FC_INVIDCONF field values */ + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK = 0x80, + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE = 0x80, + HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE = 0x00, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_MASK = 0x40, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH = 0x40, + HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_MASK = 0x20, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH = 0x20, + HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_MASK = 0x10, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH = 0x10, + HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW = 0x00, + HDMI_FC_INVIDCONF_DVI_MODEZ_MASK = 0x8, + HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE = 0x8, + HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE = 0x0, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_MASK = 0x2, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH = 0x2, + HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW = 0x0, + HDMI_FC_INVIDCONF_IN_I_P_MASK = 0x1, + HDMI_FC_INVIDCONF_IN_I_P_INTERLACED = 0x1, + HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE = 0x0, + +/* FC_AUDICONF0 field values */ + HDMI_FC_AUDICONF0_CC_OFFSET = 4, + HDMI_FC_AUDICONF0_CC_MASK = 0x70, + HDMI_FC_AUDICONF0_CT_OFFSET = 0, + HDMI_FC_AUDICONF0_CT_MASK = 0xF, + +/* FC_AUDICONF1 field values */ + HDMI_FC_AUDICONF1_SS_OFFSET = 3, + HDMI_FC_AUDICONF1_SS_MASK = 0x18, + HDMI_FC_AUDICONF1_SF_OFFSET = 0, + HDMI_FC_AUDICONF1_SF_MASK = 0x7, + +/* FC_AUDICONF3 field values */ + HDMI_FC_AUDICONF3_LFEPBL_OFFSET = 5, + HDMI_FC_AUDICONF3_LFEPBL_MASK = 0x60, + HDMI_FC_AUDICONF3_DM_INH_OFFSET = 4, + HDMI_FC_AUDICONF3_DM_INH_MASK = 0x10, + HDMI_FC_AUDICONF3_LSV_OFFSET = 0, + HDMI_FC_AUDICONF3_LSV_MASK = 0xF, + +/* FC_AUDSCHNLS0 field values */ + HDMI_FC_AUDSCHNLS0_CGMSA_OFFSET = 4, + HDMI_FC_AUDSCHNLS0_CGMSA_MASK = 0x30, + HDMI_FC_AUDSCHNLS0_COPYRIGHT_OFFSET = 0, + HDMI_FC_AUDSCHNLS0_COPYRIGHT_MASK = 0x01, + +/* FC_AUDSCHNLS3-6 field values */ + HDMI_FC_AUDSCHNLS3_OIEC_CH0_OFFSET = 0, + HDMI_FC_AUDSCHNLS3_OIEC_CH0_MASK = 0x0f, + HDMI_FC_AUDSCHNLS3_OIEC_CH1_OFFSET = 4, + HDMI_FC_AUDSCHNLS3_OIEC_CH1_MASK = 0xf0, + HDMI_FC_AUDSCHNLS4_OIEC_CH2_OFFSET = 0, + HDMI_FC_AUDSCHNLS4_OIEC_CH2_MASK = 0x0f, + HDMI_FC_AUDSCHNLS4_OIEC_CH3_OFFSET = 4, + HDMI_FC_AUDSCHNLS4_OIEC_CH3_MASK = 0xf0, + + HDMI_FC_AUDSCHNLS5_OIEC_CH0_OFFSET = 0, + HDMI_FC_AUDSCHNLS5_OIEC_CH0_MASK = 0x0f, + HDMI_FC_AUDSCHNLS5_OIEC_CH1_OFFSET = 4, + HDMI_FC_AUDSCHNLS5_OIEC_CH1_MASK = 0xf0, + HDMI_FC_AUDSCHNLS6_OIEC_CH2_OFFSET = 0, + HDMI_FC_AUDSCHNLS6_OIEC_CH2_MASK = 0x0f, + HDMI_FC_AUDSCHNLS6_OIEC_CH3_OFFSET = 4, + HDMI_FC_AUDSCHNLS6_OIEC_CH3_MASK = 0xf0, + +/* HDMI_FC_AUDSCHNLS7 field values */ + HDMI_FC_AUDSCHNLS7_ACCURACY_OFFSET = 4, + HDMI_FC_AUDSCHNLS7_ACCURACY_MASK = 0x30, + +/* HDMI_FC_AUDSCHNLS8 field values */ + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_MASK = 0xf0, + HDMI_FC_AUDSCHNLS8_ORIGSAMPFREQ_OFFSET = 4, + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_MASK = 0x0f, + HDMI_FC_AUDSCHNLS8_WORDLEGNTH_OFFSET = 0, + +/* FC_AUDSCONF field values */ + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_MASK = 0xF0, + HDMI_FC_AUDSCONF_AUD_PACKET_SAMPFIT_OFFSET = 4, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK = 0x1, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_OFFSET = 0, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1 = 0x1, + HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0 = 0x0, + +/* FC_STAT2 field values */ + HDMI_FC_STAT2_OVERFLOW_MASK = 0x03, + HDMI_FC_STAT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_STAT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_INT2 field values */ + HDMI_FC_INT2_OVERFLOW_MASK = 0x03, + HDMI_FC_INT2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_INT2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_MASK2 field values */ + HDMI_FC_MASK2_OVERFLOW_MASK = 0x03, + HDMI_FC_MASK2_LOW_PRIORITY_OVERFLOW = 0x02, + HDMI_FC_MASK2_HIGH_PRIORITY_OVERFLOW = 0x01, + +/* FC_PRCONF field values */ + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK = 0xF0, + HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET = 4, + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F, + HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0, + +/* FC_AVICONF0-FC_AVICONF3 field values */ + HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03, + HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00, + HDMI_FC_AVICONF0_PIX_FMT_YCBCR422 = 0x01, + HDMI_FC_AVICONF0_PIX_FMT_YCBCR444 = 0x02, + HDMI_FC_AVICONF0_ACTIVE_FMT_MASK = 0x40, + HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT = 0x40, + HDMI_FC_AVICONF0_ACTIVE_FMT_NO_INFO = 0x00, + HDMI_FC_AVICONF0_BAR_DATA_MASK = 0x0C, + HDMI_FC_AVICONF0_BAR_DATA_NO_DATA = 0x00, + HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR = 0x04, + HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR = 0x08, + HDMI_FC_AVICONF0_BAR_DATA_VERT_HORIZ_BAR = 0x0C, + HDMI_FC_AVICONF0_SCAN_INFO_MASK = 0x30, + HDMI_FC_AVICONF0_SCAN_INFO_OVERSCAN = 0x10, + HDMI_FC_AVICONF0_SCAN_INFO_UNDERSCAN = 0x20, + HDMI_FC_AVICONF0_SCAN_INFO_NODATA = 0x00, + + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_MASK = 0x0F, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_USE_CODED = 0x08, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3 = 0x09, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9 = 0x0A, + HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_14_9 = 0x0B, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_MASK = 0x30, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_NO_DATA = 0x00, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3 = 0x10, + HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9 = 0x20, + HDMI_FC_AVICONF1_COLORIMETRY_MASK = 0xC0, + HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA = 0x00, + HDMI_FC_AVICONF1_COLORIMETRY_SMPTE = 0x40, + HDMI_FC_AVICONF1_COLORIMETRY_ITUR = 0x80, + HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO = 0xC0, + + HDMI_FC_AVICONF2_SCALING_MASK = 0x03, + HDMI_FC_AVICONF2_SCALING_NONE = 0x00, + HDMI_FC_AVICONF2_SCALING_HORIZ = 0x01, + HDMI_FC_AVICONF2_SCALING_VERT = 0x02, + HDMI_FC_AVICONF2_SCALING_HORIZ_VERT = 0x03, + HDMI_FC_AVICONF2_RGB_QUANT_MASK = 0x0C, + HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT = 0x00, + HDMI_FC_AVICONF2_RGB_QUANT_LIMITED_RANGE = 0x04, + HDMI_FC_AVICONF2_RGB_QUANT_FULL_RANGE = 0x08, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_MASK = 0x70, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601 = 0x00, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709 = 0x10, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_SYCC601 = 0x20, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_YCC601 = 0x30, + HDMI_FC_AVICONF2_EXT_COLORIMETRY_ADOBE_RGB = 0x40, + HDMI_FC_AVICONF2_IT_CONTENT_MASK = 0x80, + HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA = 0x00, + HDMI_FC_AVICONF2_IT_CONTENT_VALID = 0x80, + + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_MASK = 0x03, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS = 0x00, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_PHOTO = 0x01, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_CINEMA = 0x02, + HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GAME = 0x03, + HDMI_FC_AVICONF3_QUANT_RANGE_MASK = 0x0C, + HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED = 0x00, + HDMI_FC_AVICONF3_QUANT_RANGE_FULL = 0x04, + +/* FC_DBGFORCE field values */ + HDMI_FC_DBGFORCE_FORCEAUDIO = 0x10, + HDMI_FC_DBGFORCE_FORCEVIDEO = 0x1, + +/* PHY_CONF0 field values */ + HDMI_PHY_CONF0_PDZ_MASK = 0x80, + HDMI_PHY_CONF0_PDZ_OFFSET = 7, + HDMI_PHY_CONF0_ENTMDS_MASK = 0x40, + HDMI_PHY_CONF0_ENTMDS_OFFSET = 6, + HDMI_PHY_CONF0_SPARECTRL = 0x20, + HDMI_PHY_CONF0_GEN2_PDDQ_MASK = 0x10, + HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET = 4, + HDMI_PHY_CONF0_GEN2_TXPWRON_MASK = 0x8, + HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET = 3, + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_MASK = 0x4, + HDMI_PHY_CONF0_GEN2_ENHPDRXSENSE_OFFSET = 2, + HDMI_PHY_CONF0_SELDATAENPOL_MASK = 0x2, + HDMI_PHY_CONF0_SELDATAENPOL_OFFSET = 1, + HDMI_PHY_CONF0_SELDIPIF_MASK = 0x1, + HDMI_PHY_CONF0_SELDIPIF_OFFSET = 0, + +/* PHY_TST0 field values */ + HDMI_PHY_TST0_TSTCLR_MASK = 0x20, + HDMI_PHY_TST0_TSTCLR_OFFSET = 5, + HDMI_PHY_TST0_TSTEN_MASK = 0x10, + HDMI_PHY_TST0_TSTEN_OFFSET = 4, + HDMI_PHY_TST0_TSTCLK_MASK = 0x1, + HDMI_PHY_TST0_TSTCLK_OFFSET = 0, + +/* PHY_STAT0 field values */ + HDMI_PHY_RX_SENSE3 = 0x80, + HDMI_PHY_RX_SENSE2 = 0x40, + HDMI_PHY_RX_SENSE1 = 0x20, + HDMI_PHY_RX_SENSE0 = 0x10, + HDMI_PHY_HPD = 0x02, + HDMI_PHY_TX_PHY_LOCK = 0x01, + +/* PHY_I2CM_SLAVE_ADDR field values */ + HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2 = 0x69, + HDMI_PHY_I2CM_SLAVE_ADDR_HEAC_PHY = 0x49, + +/* PHY_I2CM_OPERATION_ADDR field values */ + HDMI_PHY_I2CM_OPERATION_ADDR_WRITE = 0x10, + HDMI_PHY_I2CM_OPERATION_ADDR_READ = 0x1, + +/* HDMI_PHY_I2CM_INT_ADDR */ + HDMI_PHY_I2CM_INT_ADDR_DONE_POL = 0x08, + HDMI_PHY_I2CM_INT_ADDR_DONE_MASK = 0x04, + +/* HDMI_PHY_I2CM_CTLINT_ADDR */ + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL = 0x80, + HDMI_PHY_I2CM_CTLINT_ADDR_NAC_MASK = 0x40, + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL = 0x08, + HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_MASK = 0x04, + +/* AUD_CTS3 field values */ + HDMI_AUD_CTS3_N_SHIFT_OFFSET = 5, + HDMI_AUD_CTS3_N_SHIFT_MASK = 0xe0, + HDMI_AUD_CTS3_N_SHIFT_1 = 0, + HDMI_AUD_CTS3_N_SHIFT_16 = 0x20, + HDMI_AUD_CTS3_N_SHIFT_32 = 0x40, + HDMI_AUD_CTS3_N_SHIFT_64 = 0x60, + HDMI_AUD_CTS3_N_SHIFT_128 = 0x80, + HDMI_AUD_CTS3_N_SHIFT_256 = 0xa0, + /* note that the CTS3 MANUAL bit has been removed + from our part. Can't set it, will read as 0. */ + HDMI_AUD_CTS3_CTS_MANUAL = 0x10, + HDMI_AUD_CTS3_AUDCTS19_16_MASK = 0x0f, + +/* AHB_DMA_CONF0 field values */ + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_OFFSET = 7, + HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK = 0x80, + HDMI_AHB_DMA_CONF0_HBR = 0x10, + HDMI_AHB_DMA_CONF0_EN_HLOCK_OFFSET = 3, + HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK = 0x08, + HDMI_AHB_DMA_CONF0_INCR_TYPE_OFFSET = 1, + HDMI_AHB_DMA_CONF0_INCR_TYPE_MASK = 0x06, + HDMI_AHB_DMA_CONF0_INCR4 = 0x0, + HDMI_AHB_DMA_CONF0_INCR8 = 0x2, + HDMI_AHB_DMA_CONF0_INCR16 = 0x4, + HDMI_AHB_DMA_CONF0_BURST_MODE = 0x1, + +/* HDMI_AHB_DMA_START field values */ + HDMI_AHB_DMA_START_START_OFFSET = 0, + HDMI_AHB_DMA_START_START_MASK = 0x01, + +/* HDMI_AHB_DMA_STOP field values */ + HDMI_AHB_DMA_STOP_STOP_OFFSET = 0, + HDMI_AHB_DMA_STOP_STOP_MASK = 0x01, + +/* AHB_DMA_STAT, AHB_DMA_INT, AHB_DMA_MASK, AHB_DMA_POL field values */ + HDMI_AHB_DMA_DONE = 0x80, + HDMI_AHB_DMA_RETRY_SPLIT = 0x40, + HDMI_AHB_DMA_LOSTOWNERSHIP = 0x20, + HDMI_AHB_DMA_ERROR = 0x10, + HDMI_AHB_DMA_FIFO_THREMPTY = 0x04, + HDMI_AHB_DMA_FIFO_FULL = 0x02, + HDMI_AHB_DMA_FIFO_EMPTY = 0x01, + +/* AHB_DMA_BUFFSTAT, AHB_DMA_BUFFINT,AHB_DMA_BUFFMASK,AHB_DMA_BUFFPOL values */ + HDMI_AHB_DMA_BUFFSTAT_FULL = 0x02, + HDMI_AHB_DMA_BUFFSTAT_EMPTY = 0x01, + +/* MC_CLKDIS field values */ + HDMI_MC_CLKDIS_HDCPCLK_DISABLE = 0x40, + HDMI_MC_CLKDIS_CECCLK_DISABLE = 0x20, + HDMI_MC_CLKDIS_CSCCLK_DISABLE = 0x10, + HDMI_MC_CLKDIS_AUDCLK_DISABLE = 0x8, + HDMI_MC_CLKDIS_PREPCLK_DISABLE = 0x4, + HDMI_MC_CLKDIS_TMDSCLK_DISABLE = 0x2, + HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1, + +/* MC_SWRSTZ field values */ + HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02, + +/* MC_FLOWCTRL field values */ + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_MASK = 0x1, + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH = 0x1, + HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS = 0x0, + +/* MC_PHYRSTZ field values */ + HDMI_MC_PHYRSTZ_ASSERT = 0x0, + HDMI_MC_PHYRSTZ_DEASSERT = 0x1, + +/* MC_HEACPHY_RST field values */ + HDMI_MC_HEACPHY_RST_ASSERT = 0x1, + HDMI_MC_HEACPHY_RST_DEASSERT = 0x0, + +/* CSC_CFG field values */ + HDMI_CSC_CFG_INTMODE_MASK = 0x30, + HDMI_CSC_CFG_INTMODE_OFFSET = 4, + HDMI_CSC_CFG_INTMODE_DISABLE = 0x00, + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1 = 0x10, + HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA2 = 0x20, + HDMI_CSC_CFG_DECMODE_MASK = 0x3, + HDMI_CSC_CFG_DECMODE_OFFSET = 0, + HDMI_CSC_CFG_DECMODE_DISABLE = 0x0, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1 = 0x1, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA2 = 0x2, + HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3 = 0x3, + +/* CSC_SCALE field values */ + HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK = 0xF0, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP = 0x00, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP = 0x50, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP = 0x60, + HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP = 0x70, + HDMI_CSC_SCALE_CSCSCALE_MASK = 0x03, + +/* A_HDCPCFG0 field values */ + HDMI_A_HDCPCFG0_ELVENA_MASK = 0x80, + HDMI_A_HDCPCFG0_ELVENA_ENABLE = 0x80, + HDMI_A_HDCPCFG0_ELVENA_DISABLE = 0x00, + HDMI_A_HDCPCFG0_I2CFASTMODE_MASK = 0x40, + HDMI_A_HDCPCFG0_I2CFASTMODE_ENABLE = 0x40, + HDMI_A_HDCPCFG0_I2CFASTMODE_DISABLE = 0x00, + HDMI_A_HDCPCFG0_BYPENCRYPTION_MASK = 0x20, + HDMI_A_HDCPCFG0_BYPENCRYPTION_ENABLE = 0x20, + HDMI_A_HDCPCFG0_BYPENCRYPTION_DISABLE = 0x00, + HDMI_A_HDCPCFG0_SYNCRICHECK_MASK = 0x10, + HDMI_A_HDCPCFG0_SYNCRICHECK_ENABLE = 0x10, + HDMI_A_HDCPCFG0_SYNCRICHECK_DISABLE = 0x00, + HDMI_A_HDCPCFG0_AVMUTE_MASK = 0x8, + HDMI_A_HDCPCFG0_AVMUTE_ENABLE = 0x8, + HDMI_A_HDCPCFG0_AVMUTE_DISABLE = 0x0, + HDMI_A_HDCPCFG0_RXDETECT_MASK = 0x4, + HDMI_A_HDCPCFG0_RXDETECT_ENABLE = 0x4, + HDMI_A_HDCPCFG0_RXDETECT_DISABLE = 0x0, + HDMI_A_HDCPCFG0_EN11FEATURE_MASK = 0x2, + HDMI_A_HDCPCFG0_EN11FEATURE_ENABLE = 0x2, + HDMI_A_HDCPCFG0_EN11FEATURE_DISABLE = 0x0, + HDMI_A_HDCPCFG0_HDMIDVI_MASK = 0x1, + HDMI_A_HDCPCFG0_HDMIDVI_HDMI = 0x1, + HDMI_A_HDCPCFG0_HDMIDVI_DVI = 0x0, + +/* A_HDCPCFG1 field values */ + HDMI_A_HDCPCFG1_DISSHA1CHECK_MASK = 0x8, + HDMI_A_HDCPCFG1_DISSHA1CHECK_DISABLE = 0x8, + HDMI_A_HDCPCFG1_DISSHA1CHECK_ENABLE = 0x0, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_MASK = 0x4, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_ENABLE = 0x4, + HDMI_A_HDCPCFG1_PH2UPSHFTENC_DISABLE = 0x0, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK = 0x2, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE = 0x2, + HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_ENABLE = 0x0, + HDMI_A_HDCPCFG1_SWRESET_MASK = 0x1, + HDMI_A_HDCPCFG1_SWRESET_ASSERT = 0x0, + +/* A_VIDPOLCFG field values */ + HDMI_A_VIDPOLCFG_UNENCRYPTCONF_MASK = 0x60, + HDMI_A_VIDPOLCFG_UNENCRYPTCONF_OFFSET = 5, + HDMI_A_VIDPOLCFG_DATAENPOL_MASK = 0x10, + HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH = 0x10, + HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW = 0x0, + HDMI_A_VIDPOLCFG_VSYNCPOL_MASK = 0x8, + HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_HIGH = 0x8, + HDMI_A_VIDPOLCFG_VSYNCPOL_ACTIVE_LOW = 0x0, + HDMI_A_VIDPOLCFG_HSYNCPOL_MASK = 0x2, + HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_HIGH = 0x2, + HDMI_A_VIDPOLCFG_HSYNCPOL_ACTIVE_LOW = 0x0, +}; +#endif /* __IMX_HDMI_H__ */ diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 654bf03e05ff..7e593296ac47 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -167,9 +167,8 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, /* set display clock mux to LDB input clock */ ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]); - if (ret) { + if (ret) dev_err(ldb->dev, "unable to set di%d parent clock to ldb_di%d\n", mux, chno); - } } static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) @@ -414,7 +413,7 @@ enum { LVDS_BIT_MAP_JEIDA }; -static const char *imx_ldb_bit_mappings[] = { +static const char * const imx_ldb_bit_mappings[] = { [LVDS_BIT_MAP_SPWG] = "spwg", [LVDS_BIT_MAP_JEIDA] = "jeida", }; diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 2c44fef8d58b..9abc7ca8b6cf 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -560,7 +560,7 @@ static const char *imx_tve_modes[] = { [TVE_MODE_VGA] = "vga", }; -const int of_get_tve_mode(struct device_node *np) +static const int of_get_tve_mode(struct device_node *np) { const char *bm; int ret, i; diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 97ca6924dbb3..ca85d3d70ae3 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index ce6ba987ec91..22be104fbda9 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -218,7 +218,8 @@ static irqreturn_t ipu_irq_handler(int irq, void *dev_id) if (ipu_crtc->newfb) { ipu_crtc->newfb = NULL; - ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.fb, 0, 0); + ipu_plane_set_base(ipu_crtc->plane[0], ipu_crtc->base.fb, + ipu_crtc->plane[0]->x, ipu_crtc->plane[0]->y); ipu_crtc_handle_pageflip(ipu_crtc); } diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index d97454a0dffd..34b642a12f8b 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -64,6 +64,7 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, { struct ipu_ch_param __iomem *cpmem; struct drm_gem_cma_object *cma_obj; + unsigned long eba; cma_obj = drm_fb_cma_get_gem_obj(fb, 0); if (!cma_obj) { @@ -76,8 +77,15 @@ int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, cpmem = ipu_get_cpmem(ipu_plane->ipu_ch); ipu_cpmem_set_stride(cpmem, fb->pitches[0]); - ipu_cpmem_set_buffer(cpmem, 0, cma_obj->paddr + fb->offsets[0] + - fb->pitches[0] * y + x); + + eba = cma_obj->paddr + fb->offsets[0] + + fb->pitches[0] * y + (fb->bits_per_pixel >> 3) * x; + ipu_cpmem_set_buffer(cpmem, 0, eba); + ipu_cpmem_set_buffer(cpmem, 1, eba); + + /* cache offsets for subsequent pageflips */ + ipu_plane->x = x; + ipu_plane->y = y; return 0; } diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 24aa9beedcfb..351d61dede00 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -23,6 +23,7 @@ #include #include #include +#include