]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'iio-for-v3.7e' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Sep 2012 22:52:56 +0000 (15:52 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Sep 2012 22:52:56 +0000 (15:52 -0700)
Fifth round of new drivers and device support for the IIO
subsystem in the 3.7 cycle.

Here we have a mixed bag of new stuff, minor fixes and
more major fixes for drivers added earlier in this cycle.

1) A number of fixes for the HID sensors code added in previous
pull request.  Typical stuff that has become apparent as more eyes
have looked at the code post merging. Similar case for the ad5755 dac.

2) Cleanups of error handing in inkern.c - again typical stuff to see
as code comes into heavier use and people notice the naughty short
cuts that snuck in originally and kindly fix them.

3) A series from Lars that removes some incorrect error handling
from the remove functions of a number of drivers.  These have been
there for a very long time hence I'm not pushing these out for the
3.6 cycle.

4) Support for more parts in the ad7780 driver.

5) A driver for the adcs on the lp8788 power management unit

6) A client driver for IIO to allow it's ADCs to be used for
battery status measurement.  Note this driver has some dependencies
on some utility functions added to IIO in this series, hence it is
coming via this tree rather than Anton's.

7) A null pointer dereference bug in the 'fake' driver. I'm not
doing this as a fix for the 3.6 cycle because it only effects
'fake' hardware and that code is typically only used by people
investigating how IIO works as part of writing new drivers. Hence
it's hardly a critical fix.

57 files changed:
Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt [new file with mode: 0644]
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/bcm/CmHost.c
drivers/staging/bcm/cntrl_SignalingInterface.h
drivers/staging/ced1401/ced_ioc.c
drivers/staging/ced1401/usb1401.c
drivers/staging/comedi/comedi.h
drivers/staging/comedi/comedi_fops.c
drivers/staging/comedi/drivers.c
drivers/staging/comedi/drivers/8253.h
drivers/staging/comedi/drivers/daqboard2000.c
drivers/staging/comedi/drivers/das16.c
drivers/staging/comedi/drivers/das1800.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/comedi/drivers/rtd520.c
drivers/staging/comedi/drivers/s526.c
drivers/staging/comedi/drivers/usbdux.c
drivers/staging/comedi/drivers/usbduxfast.c
drivers/staging/comedi/drivers/usbduxsigma.c
drivers/staging/comedi/kcomedilib/kcomedilib_main.c
drivers/staging/csr/sme_blocking.c
drivers/staging/imx-drm/Kconfig [new file with mode: 0644]
drivers/staging/imx-drm/Makefile [new file with mode: 0644]
drivers/staging/imx-drm/TODO [new file with mode: 0644]
drivers/staging/imx-drm/imx-drm-core.c [new file with mode: 0644]
drivers/staging/imx-drm/imx-drm.h [new file with mode: 0644]
drivers/staging/imx-drm/imx-fb.c [new file with mode: 0644]
drivers/staging/imx-drm/imx-fbdev.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/Makefile [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-common.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-dc.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-di.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-dp.c [new file with mode: 0644]
drivers/staging/imx-drm/ipu-v3/ipu-prv.h [new file with mode: 0644]
drivers/staging/imx-drm/ipuv3-crtc.c [new file with mode: 0644]
drivers/staging/imx-drm/parallel-display.c [new file with mode: 0644]
drivers/staging/omap-thermal/omap-bandgap.c
drivers/staging/ozwpan/ozcdev.c
drivers/staging/panel/panel.c
drivers/staging/rtl8192e/rtllib_softmac.c
drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c
drivers/staging/rts_pstor/rtsx.c
drivers/staging/sbe-2t3e3/2t3e3.h
drivers/staging/sbe-2t3e3/dc.c
drivers/staging/sbe-2t3e3/module.c
drivers/staging/silicom/Kconfig
drivers/staging/silicom/bp_mod.c
drivers/staging/telephony/ixj.c
drivers/staging/tidspbridge/core/wdt.c
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/vhci_hcd.c
drivers/staging/winbond/sme_api.h
drivers/staging/wlan-ng/cfg80211.c

diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt
new file mode 100644 (file)
index 0000000..07654f0
--- /dev/null
@@ -0,0 +1,41 @@
+Freescale i.MX IPUv3
+====================
+
+Required properties:
+- compatible: Should be "fsl,<chip>-ipu"
+- reg: should be register base and length as documented in the
+  datasheet
+- interrupts: Should contain sync interrupt and error interrupt,
+  in this order.
+- #crtc-cells: 1, See below
+
+example:
+
+ipu: ipu@18000000 {
+       #crtc-cells = <1>;
+       compatible = "fsl,imx53-ipu";
+       reg = <0x18000000 0x080000000>;
+       interrupts = <11 10>;
+};
+
+Parallel display support
+========================
+
+Required properties:
+- compatible: Should be "fsl,imx-parallel-display"
+- crtc: the crtc this display is connected to, see below
+Optional properties:
+- interface_pix_fmt: How this display is connected to the
+  crtc. Currently supported types: "rgb24", "rgb565"
+- edid: verbatim EDID data block describing attached display.
+- ddc: phandle describing the i2c bus handling the display data
+  channel
+
+example:
+
+display@di0 {
+       compatible = "fsl,imx-parallel-display";
+       edid = [edid-data];
+       crtc = <&ipu 0>;
+       interface-pix-fmt = "rgb24";
+};
index 025d8c98424af28613d12255b120712e502bc563..0f51a158ef704cbc7a2a6badaf95cbe2f8c1d809 100644 (file)
@@ -140,4 +140,6 @@ source "drivers/staging/silicom/Kconfig"
 
 source "drivers/staging/ced1401/Kconfig"
 
+source "drivers/staging/imx-drm/Kconfig"
+
 endif # STAGING
index 08e9667a4e451a3b69798b233ebbccbefd38cd5c..f4b2bc41f1d1a0f34394824758c78f4fba224ef2 100644 (file)
@@ -62,3 +62,4 @@ obj-$(CONFIG_OMAP_BANDGAP)    += omap-thermal/
 obj-$(CONFIG_ZCACHE2)          += ramster/
 obj-$(CONFIG_NET_VENDOR_SILICOM)       += silicom/
 obj-$(CONFIG_CED1401)          += ced1401/
+obj-$(CONFIG_DRM_IMX)          += imx-drm/
index b6c20a92cbf880553930771b6e190c025d51341e..25aa20aad65ebf7f80ca4fd4460cd8dbffacc452 100644 (file)
@@ -1913,7 +1913,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId
 VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer)
 {
        B_UINT32 u32NumofSFsinMsg = ntohl(*(puiBuffer + 1));
-       stIM_SFHostNotify *pHostInfo = NULL;
+       struct bcm_stim_sfhostnotify *pHostInfo = NULL;
        UINT uiSearchRuleIndex = 0;
        ULONG ulSFID = 0;
 
@@ -1922,7 +1922,7 @@ VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter, PUINT puiBuffer
 
        while (u32NumofSFsinMsg != 0 && u32NumofSFsinMsg < NO_OF_QUEUES) {
                u32NumofSFsinMsg--;
-               pHostInfo = (stIM_SFHostNotify *)puiBuffer;
+               pHostInfo = (struct bcm_stim_sfhostnotify *)puiBuffer;
                puiBuffer = (PUINT)(pHostInfo + 1);
 
                ulSFID = ntohl(pHostInfo->SFID);
index 41d732d8ca4229f8ab725945c2052263bdb0962e..11b3181d537af3bae81c09ca96cf127339ec2646 100644 (file)
 #ifndef CNTRL_SIGNALING_INTERFACE_
 #define CNTRL_SIGNALING_INTERFACE_
 
-
-
-
-#define DSA_REQ 11
-#define DSA_RSP 12
-#define DSA_ACK 13
-#define DSC_REQ 14
-#define DSC_RSP 15
-#define DSC_ACK 16
-#define DSD_REQ 17
-#define DSD_RSP 18
-#define DSD_ACK 19
-#define MAX_CLASSIFIERS_IN_SF  4
-
-
-#define MAX_STRING_LEN 20
-#define MAX_PHS_LENGTHS 255
-#define VENDOR_PHS_PARAM_LENGTH 10
-#define MAX_NUM_ACTIVE_BS 10
-#define AUTH_TOKEN_LENGTH      10
-#define NUM_HARQ_CHANNELS      16      //Changed from 10 to 16 to accommodate all HARQ channels
-#define VENDOR_CLASSIFIER_PARAM_LENGTH 1 //Changed the size to 1 byte since we dnt use it
-#define  VENDOR_SPECIF_QOS_PARAM 1
-#define VENDOR_PHS_PARAM_LENGTH        10
-#define MBS_CONTENTS_ID_LENGTH 10
-#define GLOBAL_SF_CLASSNAME_LENGTH 6
-
-#define TYPE_OF_SERVICE_LENGTH                         3
-#define IP_MASKED_SRC_ADDRESS_LENGTH                   32
-#define IP_MASKED_DEST_ADDRESS_LENGTH          32
-#define PROTOCOL_SRC_PORT_RANGE_LENGTH         4
-#define PROTOCOL_DEST_PORT_RANGE_LENGTH                4
-#define ETHERNET_DEST_MAC_ADDR_LENGTH          12
-#define ETHERNET_SRC_MAC_ADDR_LENGTH           12
-#define NUM_ETHERTYPE_BYTES  3
-#define NUM_IPV6_FLOWLABLE_BYTES 3
-
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////structure Definitions///////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-/// \brief class cCPacketClassificationRule
-struct _stCPacketClassificationRuleSI{
-
-       /**  16bit UserPriority Of The Service Flow*/
-    B_UINT16                        u16UserPriority;
-       /**  16bit VLANID Of The Service Flow*/
-    B_UINT16                        u16VLANID;
-       /**  16bit Packet Classification RuleIndex Of The Service Flow*/
-    B_UINT16                        u16PacketClassificationRuleIndex;
-       /**  8bit Classifier Rule Priority Of The Service Flow*/
-    B_UINT8                         u8ClassifierRulePriority;
-       /**  Length of IP TypeOfService field*/
-       B_UINT8                         u8IPTypeOfServiceLength;
-       /**  3bytes IP TypeOfService */
-    B_UINT8                         u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
-       /** Protocol used in classification of Service Flow*/
-    B_UINT8                         u8Protocol;
-       /**  Length of IP Masked Source Address */
-    B_UINT8                         u8IPMaskedSourceAddressLength;
-       /**  IP Masked Source Address used in classification for the Service Flow*/
-    B_UINT8                         u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
-       /**  Length of IP Destination Address */
-    B_UINT8                         u8IPDestinationAddressLength;
-       /**  IP Destination Address used in classification for the Service Flow*/
-    B_UINT8                         u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
-       /** Length of Protocol Source Port Range */
-    B_UINT8                         u8ProtocolSourcePortRangeLength;
-       /**  Protocol Source Port Range used in the Service Flow*/
-    B_UINT8                         u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
-       /** Length of Protocol Dest Port Range */
-    B_UINT8                         u8ProtocolDestPortRangeLength;
-       /**  Protocol Dest Port Range used in the Service Flow*/
-    B_UINT8                         u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
-       /** Length of Ethernet Destination MAC Address  */
-    B_UINT8                         u8EthernetDestMacAddressLength;
-       /**  Ethernet Destination MAC Address  used in classification of the Service Flow*/
-    B_UINT8                         u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
-       /** Length of Ethernet Source MAC Address  */
-    B_UINT8                         u8EthernetSourceMACAddressLength;
-       /**  Ethernet Source MAC Address  used in classification of the Service Flow*/
-    B_UINT8                         u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
-       /**  Length of Ethertype */
-       B_UINT8                         u8EthertypeLength;
-       /**  3bytes Ethertype Of The Service Flow*/
-    B_UINT8                         u8Ethertype[NUM_ETHERTYPE_BYTES];
-       /**  8bit Associated PHSI Of The Service Flow*/
-    B_UINT8                         u8AssociatedPHSI;
-       /** Length of Vendor Specific Classifier Param length Of The Service Flow*/
-    B_UINT8                         u8VendorSpecificClassifierParamLength;
-       /**  Vendor Specific Classifier Param Of The Service Flow*/
-    B_UINT8                         u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
-    /** Length Of IPv6 Flow Lable of the Service Flow*/
-    B_UINT8                         u8IPv6FlowLableLength;
-       /**  IPv6 Flow Lable Of The Service Flow*/
-    B_UINT8                         u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
-       /**  Action associated with the classifier rule*/
-    B_UINT8                                                    u8ClassifierActionRule;
-    B_UINT16                                                   u16ValidityBitMap;
+#define DSA_REQ                        11
+#define DSA_RSP                        12
+#define DSA_ACK                        13
+#define DSC_REQ                        14
+#define DSC_RSP                        15
+#define DSC_ACK                        16
+#define DSD_REQ                        17
+#define DSD_RSP                        18
+#define DSD_ACK                        19
+#define MAX_CLASSIFIERS_IN_SF  4
+
+#define MAX_STRING_LEN                 20
+#define MAX_PHS_LENGTHS                        255
+#define VENDOR_PHS_PARAM_LENGTH                10
+#define MAX_NUM_ACTIVE_BS              10
+#define AUTH_TOKEN_LENGTH              10
+#define NUM_HARQ_CHANNELS              16 /* Changed from 10 to 16 to accommodate all HARQ channels */
+#define VENDOR_CLASSIFIER_PARAM_LENGTH 1  /* Changed the size to 1 byte since we dnt use it */
+#define  VENDOR_SPECIF_QOS_PARAM       1
+#define VENDOR_PHS_PARAM_LENGTH                10
+#define MBS_CONTENTS_ID_LENGTH         10
+#define GLOBAL_SF_CLASSNAME_LENGTH     6
+
+#define TYPE_OF_SERVICE_LENGTH         3
+#define IP_MASKED_SRC_ADDRESS_LENGTH   32
+#define IP_MASKED_DEST_ADDRESS_LENGTH  32
+#define PROTOCOL_SRC_PORT_RANGE_LENGTH 4
+#define PROTOCOL_DEST_PORT_RANGE_LENGTH        4
+#define ETHERNET_DEST_MAC_ADDR_LENGTH  12
+#define ETHERNET_SRC_MAC_ADDR_LENGTH   12
+#define NUM_ETHERTYPE_BYTES            3
+#define NUM_IPV6_FLOWLABLE_BYTES       3
+
+/*
+ * structure Definitions
+ *
+ * brief class cCPacketClassificationRule
+ */
+struct _stCPacketClassificationRuleSI {
+       /* 16bit UserPriority Of The Service Flow */
+       B_UINT16 u16UserPriority;
+       /* 16bit VLANID Of The Service Flow */
+       B_UINT16 u16VLANID;
+       /* 16bit Packet Classification RuleIndex Of The Service Flow */
+       B_UINT16 u16PacketClassificationRuleIndex;
+       /* 8bit Classifier Rule Priority Of The Service Flow */
+       B_UINT8 u8ClassifierRulePriority;
+       /* Length of IP TypeOfService field */
+       B_UINT8 u8IPTypeOfServiceLength;
+       /* 3bytes IP TypeOfService */
+       B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH];
+       /* Protocol used in classification of Service Flow */
+       B_UINT8 u8Protocol;
+       /* Length of IP Masked Source Address */
+       B_UINT8 u8IPMaskedSourceAddressLength;
+       /* IP Masked Source Address used in classification for the Service Flow */
+       B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH];
+       /* Length of IP Destination Address */
+       B_UINT8 u8IPDestinationAddressLength;
+       /* IP Destination Address used in classification for the Service Flow */
+       B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH];
+       /* Length of Protocol Source Port Range */
+       B_UINT8 u8ProtocolSourcePortRangeLength;
+       /* Protocol Source Port Range used in the Service Flow */
+       B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH];
+       /* Length of Protocol Dest Port Range */
+       B_UINT8 u8ProtocolDestPortRangeLength;
+       /* Protocol Dest Port Range used in the Service Flow */
+       B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH];
+       /* Length of Ethernet Destination MAC Address */
+       B_UINT8 u8EthernetDestMacAddressLength;
+       /* Ethernet Destination MAC Address  used in classification of the Service Flow */
+       B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH];
+       /* Length of Ethernet Source MAC Address */
+       B_UINT8 u8EthernetSourceMACAddressLength;
+       /* Ethernet Source MAC Address  used in classification of the Service Flow */
+       B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH];
+       /* Length of Ethertype */
+       B_UINT8 u8EthertypeLength;
+       /* 3bytes Ethertype Of The Service Flow */
+       B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES];
+       /* 8bit Associated PHSI Of The Service Flow */
+       B_UINT8 u8AssociatedPHSI;
+       /* Length of Vendor Specific Classifier Param length Of The Service Flow */
+       B_UINT8 u8VendorSpecificClassifierParamLength;
+       /* Vendor Specific Classifier Param Of The Service Flow */
+       B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH];
+       /* Length Of IPv6 Flow Lable of the Service Flow */
+       B_UINT8 u8IPv6FlowLableLength;
+       /* IPv6 Flow Lable Of The Service Flow */
+       B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES];
+       /* Action associated with the classifier rule */
+       B_UINT8 u8ClassifierActionRule;
+       B_UINT16 u16ValidityBitMap;
 };
-typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
+typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI, stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI;
 
-/// \brief class CPhsRuleSI
+/* brief class CPhsRuleSI */
 typedef struct _stPhsRuleSI {
-       /**  8bit PHS Index Of The Service Flow*/
-    B_UINT8                         u8PHSI;
-       /**  PHSF Length Of The Service Flow*/
-    B_UINT8                         u8PHSFLength;
-    /** String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS*/
-    B_UINT8                         u8PHSF[MAX_PHS_LENGTHS];
-       /**  PHSM Length Of The Service Flow*/
-    B_UINT8                         u8PHSMLength;
-       /**  PHS Mask for the SF*/
-    B_UINT8                         u8PHSM[MAX_PHS_LENGTHS];
-       /**  8bit Total number of bytes to be suppressed for the Service Flow*/
-    B_UINT8                         u8PHSS;
-       /**  8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
-    B_UINT8                         u8PHSV;
-       /**  Vendor Specific PHS param Length Of The Service Flow*/
-    B_UINT8                         u8VendorSpecificPHSParamsLength;
-       /**  Vendor Specific PHS param Of The Service Flow*/
-    B_UINT8                         u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
-
-       B_UINT8                         u8Padding[2];
-}stPhsRuleSI,*pstPhsRuleSI;
+       /* 8bit PHS Index Of The Service Flow */
+       B_UINT8 u8PHSI;
+       /* PHSF Length Of The Service Flow */
+       B_UINT8 u8PHSFLength;
+       /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */
+       B_UINT8 u8PHSF[MAX_PHS_LENGTHS];
+       /* PHSM Length Of The Service Flow */
+       B_UINT8 u8PHSMLength;
+       /* PHS Mask for the SF */
+       B_UINT8 u8PHSM[MAX_PHS_LENGTHS];
+       /* 8bit Total number of bytes to be suppressed for the Service Flow */
+       B_UINT8 u8PHSS;
+       /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */
+       B_UINT8 u8PHSV;
+       /* Vendor Specific PHS param Length Of The Service Flow */
+       B_UINT8 u8VendorSpecificPHSParamsLength;
+       /* Vendor Specific PHS param Of The Service Flow */
+       B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH];
+       B_UINT8 u8Padding[2];
+} stPhsRuleSI, *pstPhsRuleSI;
 typedef stPhsRuleSI CPhsRuleSI;
 
-/// \brief structure cConvergenceSLTypes
-struct _stConvergenceSLTypes{
-       /**  8bit Phs Classfier Action Of The Service Flow*/
-    B_UINT8                         u8ClassfierDSCAction;
-       /**  8bit Phs DSC Action Of The Service Flow*/
-    B_UINT8                         u8PhsDSCAction;
-       /**   16bit Padding */
-    B_UINT8                         u8Padding[2];
-    /// \brief class cCPacketClassificationRule
-    stCPacketClassificationRuleSI     cCPacketClassificationRule;
-    /// \brief class CPhsRuleSI
-     struct _stPhsRuleSI               cPhsRule;
+/* brief structure cConvergenceSLTypes */
+struct _stConvergenceSLTypes {
+       /* 8bit Phs Classfier Action Of The Service Flow */
+       B_UINT8 u8ClassfierDSCAction;
+       /* 8bit Phs DSC Action Of The Service Flow */
+       B_UINT8 u8PhsDSCAction;
+       /* 16bit Padding */
+       B_UINT8 u8Padding[2];
+       /* brief class cCPacketClassificationRule */
+       stCPacketClassificationRuleSI cCPacketClassificationRule;
+       /* brief class CPhsRuleSI */
+       struct _stPhsRuleSI cPhsRule;
 };
-typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes;
-
-
-/// \brief structure CServiceFlowParamSI
-typedef struct _stServiceFlowParamSI{
-
-     /**  32bitSFID Of The Service Flow*/
-    B_UINT32                        u32SFID;
-
-     /**  32bit Maximum Sustained Traffic Rate of the Service Flow*/
-    B_UINT32                        u32MaxSustainedTrafficRate;
-
-     /**  32bit Maximum Traffic Burst allowed for the Service Flow*/
-    B_UINT32                        u32MaxTrafficBurst;
-
-    /**  32bit Minimum Reserved Traffic Rate of the Service Flow*/
-    B_UINT32                        u32MinReservedTrafficRate;
-
-       /**  32bit Tolerated Jitter of the Service Flow*/
-       B_UINT32                        u32ToleratedJitter;
-
-   /**  32bit Maximum Latency of the Service Flow*/
-    B_UINT32                        u32MaximumLatency;
-
-       /**  16bitCID Of The Service Flow*/
-    B_UINT16                        u16CID;
-
-     /**  16bit SAID on which the service flow being set up shall be mapped*/
-    B_UINT16                        u16TargetSAID;
-
-       /** 16bit  ARQ window size negotiated*/
-    B_UINT16                        u16ARQWindowSize;
-
-     /**  16bit Total Tx delay incl sending, receiving & processing delays     */
-    B_UINT16                        u16ARQRetryTxTimeOut;
-
-       /**  16bit Total Rx delay incl sending, receiving & processing delays   */
-    B_UINT16                        u16ARQRetryRxTimeOut;
-
-       /**  16bit ARQ block lifetime   */
-    B_UINT16                        u16ARQBlockLifeTime;
-
-       /**  16bit ARQ Sync loss timeout*/
-    B_UINT16                        u16ARQSyncLossTimeOut;
-
-        /**  16bit ARQ Purge timeout */
-    B_UINT16                        u16ARQRxPurgeTimeOut;
-//TODO::Remove this once we move to a new CORR2 driver
-    /// \brief Size of an ARQ block
-    B_UINT16                        u16ARQBlockSize;
-
-//#endif
-       /**  16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP*/
-       B_UINT16                        u16SDUInterArrivalTime;
-
-       /**  16bit Specifies the time base for rate measurement         */
-       B_UINT16                        u16TimeBase;
-
-        /** 16bit Interval b/w Successive Grant oppurtunities*/
-       B_UINT16                        u16UnsolicitedGrantInterval;
-
-       /** 16bit Interval b/w Successive Polling grant oppurtunities*/
-       B_UINT16                                                u16UnsolicitedPollingInterval;
-
-        /**   internal var to get the overhead */
-       B_UINT16                                                u16MacOverhead;
-
-        /**  MBS contents Identifier*/
-       B_UINT16                                                u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
-
-       /**  MBS contents Identifier length*/
-       B_UINT8                                                 u8MBSContentsIDLength;
-
-       /**      ServiceClassName Length Of The Service Flow*/
-    B_UINT8                         u8ServiceClassNameLength;
-
-       /**  32bytes ServiceClassName Of The Service Flow*/
-    B_UINT8                         u8ServiceClassName[32];
-
-       /**  8bit Indicates whether or not MBS service is requested for this Serivce Flow*/
-       B_UINT8                                                 u8MBSService;
-
-    /**  8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets*/
-    B_UINT8                         u8QosParamSet;
-
-   /**  8bit Traffic Priority Of the Service Flow */
-    B_UINT8                         u8TrafficPriority;
-
-   /**  8bit Uplink Grant Scheduling Type of The Service Flow */
-    B_UINT8                         u8ServiceFlowSchedulingType;
-
-  /**  8bit Request transmission Policy of the Service Flow*/
-    B_UINT8                                                    u8RequesttransmissionPolicy;
-
-       /**  8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
-    B_UINT8                         u8FixedLengthVSVariableLengthSDUIndicator;
-
-       /**  8bit Length of the SDU for a fixed length SDU service flow*/
-       B_UINT8                         u8SDUSize;
-
-        /** 8bit Indicates whether or not ARQ is requested for this connection*/
-       B_UINT8                         u8ARQEnable;
-
-       /**<  8bit Indicates whether or not data has tobe delivered in order to higher layer*/
-       B_UINT8                         u8ARQDeliverInOrder;
-
-       /**  8bit Receiver ARQ ACK processing time */
-       B_UINT8                         u8RxARQAckProcessingTime;
-
-       /**  8bit Convergence Sublayer Specification Of The Service Flow*/
-       B_UINT8                         u8CSSpecification;
-
-        /**  8 bit Type of data delivery service*/
-       B_UINT8                         u8TypeOfDataDeliveryService;
-
-       /** 8bit Specifies whether a service flow may generate Paging   */
-       B_UINT8                         u8PagingPreference;
-
-       /**  8bit Indicates the MBS Zone through which the connection or virtual connection is valid    */
-       B_UINT8                         u8MBSZoneIdentifierassignment;
-
-       /**  8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode*/
-       B_UINT8                         u8TrafficIndicationPreference;
-
-       /** 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF       */
-       B_UINT8                         u8GlobalServicesClassNameLength;
-
-        /**  6 byte Speciifes the predefined Global QoS parameter set encoding for this SF     */
-       B_UINT8                         u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
-
-        /**  8bit Indicates whether or not SN feedback is enabled for the conn */
-       B_UINT8                         u8SNFeedbackEnabled;
-
-        /**  Indicates the size of the Fragment Sequence Number for the connection     */
-       B_UINT8                         u8FSNSize;
-
-       /** 8bit Number of CIDs in active BS list       */
-       B_UINT8                                                 u8CIDAllocation4activeBSsLength;
-
-       /**  CIDs of BS in the active list      */
-       B_UINT8                                                 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
-
-        /**  Specifies if PDU extended subheader should be applied on every PDU on this conn*/
-       B_UINT8                         u8PDUSNExtendedSubheader4HarqReordering;
-
-        /**  8bit Specifies whether the connection uses HARQ or not    */
-       B_UINT8                         u8HARQServiceFlows;
-
-       /**  Specifies the length of Authorization token*/
-       B_UINT8                                                 u8AuthTokenLength;
-
-       /**  Specifies the Authorization token*/
-       B_UINT8                                                 u8AuthToken[AUTH_TOKEN_LENGTH];
-
-       /**  specifes Number of HARQ channels used to carry data length*/
-       B_UINT8                                                 u8HarqChannelMappingLength;
-
-        /**  specifes HARQ channels used to carry data*/
-       B_UINT8                                                 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
-
-       /**  8bit Length of Vendor Specific QoS Params */
-    B_UINT8                         u8VendorSpecificQoSParamLength;
-
-       /** 1byte  Vendor Specific QoS Param Of The Service Flow*/
-    B_UINT8                          u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
-
-       // indicates total classifiers in the SF
-       B_UINT8                         u8TotalClassifiers;  /**< Total number of valid classifiers*/
-       B_UINT8                                                 bValid; /**<  Validity flag */
-       B_UINT8                         u8Padding;       /**<  Padding byte*/
-
-/**
-Structure for Convergence SubLayer Types with a maximum of 4 classifiers
-*/
-       stConvergenceSLTypes            cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
+typedef struct _stConvergenceSLTypes stConvergenceSLTypes, CConvergenceSLTypes, *pstConvergenceSLTypes;
+
+/* brief structure CServiceFlowParamSI */
+typedef struct _stServiceFlowParamSI {
+       /* 32bitSFID Of The Service Flow */
+       B_UINT32 u32SFID;
+       /* 32bit Maximum Sustained Traffic Rate of the Service Flow */
+       B_UINT32 u32MaxSustainedTrafficRate;
+       /* 32bit Maximum Traffic Burst allowed for the Service Flow */
+       B_UINT32 u32MaxTrafficBurst;
+       /* 32bit Minimum Reserved Traffic Rate of the Service Flow */
+       B_UINT32 u32MinReservedTrafficRate;
+       /* 32bit Tolerated Jitter of the Service Flow */
+       B_UINT32 u32ToleratedJitter;
+       /* 32bit Maximum Latency of the Service Flow */
+       B_UINT32 u32MaximumLatency;
+       /* 16bitCID Of The Service Flow */
+       B_UINT16 u16CID;
+       /* 16bit SAID on which the service flow being set up shall be mapped */
+       B_UINT16 u16TargetSAID;
+       /* 16bit  ARQ window size negotiated */
+       B_UINT16 u16ARQWindowSize;
+       /* 16bit Total Tx delay incl sending, receiving & processing delays */
+       B_UINT16 u16ARQRetryTxTimeOut;
+       /* 16bit Total Rx delay incl sending, receiving & processing delays */
+       B_UINT16 u16ARQRetryRxTimeOut;
+       /* 16bit ARQ block lifetime */
+       B_UINT16 u16ARQBlockLifeTime;
+       /* 16bit ARQ Sync loss timeout */
+       B_UINT16 u16ARQSyncLossTimeOut;
+       /* 16bit ARQ Purge timeout */
+       B_UINT16 u16ARQRxPurgeTimeOut;
+       /* TODO::Remove this once we move to a new CORR2 driver
+        * brief Size of an ARQ block
+        */
+       B_UINT16 u16ARQBlockSize;
+       /* #endif */
+       /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */
+       B_UINT16 u16SDUInterArrivalTime;
+       /* 16bit Specifies the time base for rate measurement */
+       B_UINT16 u16TimeBase;
+       /* 16bit Interval b/w Successive Grant oppurtunities */
+       B_UINT16 u16UnsolicitedGrantInterval;
+       /* 16bit Interval b/w Successive Polling grant oppurtunities */
+       B_UINT16 u16UnsolicitedPollingInterval;
+       /* internal var to get the overhead */
+       B_UINT16 u16MacOverhead;
+       /* MBS contents Identifier */
+       B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH];
+       /* MBS contents Identifier length */
+       B_UINT8 u8MBSContentsIDLength;
+       /* ServiceClassName Length Of The Service Flow */
+       B_UINT8 u8ServiceClassNameLength;
+       /* 32bytes ServiceClassName Of The Service Flow */
+       B_UINT8 u8ServiceClassName[32];
+       /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */
+       B_UINT8 u8MBSService;
+       /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */
+       B_UINT8 u8QosParamSet;
+       /* 8bit Traffic Priority Of the Service Flow */
+       B_UINT8 u8TrafficPriority;
+       /* 8bit Uplink Grant Scheduling Type of The Service Flow */
+       B_UINT8 u8ServiceFlowSchedulingType;
+       /* 8bit Request transmission Policy of the Service Flow */
+       B_UINT8 u8RequesttransmissionPolicy;
+       /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */
+       B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator;
+       /* 8bit Length of the SDU for a fixed length SDU service flow */
+       B_UINT8 u8SDUSize;
+       /* 8bit Indicates whether or not ARQ is requested for this connection */
+       B_UINT8 u8ARQEnable;
+       /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */
+       B_UINT8 u8ARQDeliverInOrder;
+       /* 8bit Receiver ARQ ACK processing time */
+       B_UINT8 u8RxARQAckProcessingTime;
+       /* 8bit Convergence Sublayer Specification Of The Service Flow */
+       B_UINT8 u8CSSpecification;
+       /* 8 bit Type of data delivery service */
+       B_UINT8 u8TypeOfDataDeliveryService;
+       /* 8bit Specifies whether a service flow may generate Paging */
+       B_UINT8 u8PagingPreference;
+       /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */
+       B_UINT8 u8MBSZoneIdentifierassignment;
+       /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */
+       B_UINT8 u8TrafficIndicationPreference;
+       /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */
+       B_UINT8 u8GlobalServicesClassNameLength;
+       /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */
+       B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH];
+       /* 8bit Indicates whether or not SN feedback is enabled for the conn */
+       B_UINT8 u8SNFeedbackEnabled;
+       /* Indicates the size of the Fragment Sequence Number for the connection */
+       B_UINT8 u8FSNSize;
+       /* 8bit Number of CIDs in active BS list */
+       B_UINT8 u8CIDAllocation4activeBSsLength;
+       /* CIDs of BS in the active list */
+       B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS];
+       /* Specifies if PDU extended subheader should be applied on every PDU on this conn */
+       B_UINT8 u8PDUSNExtendedSubheader4HarqReordering;
+       /* 8bit Specifies whether the connection uses HARQ or not */
+       B_UINT8 u8HARQServiceFlows;
+       /* Specifies the length of Authorization token */
+       B_UINT8 u8AuthTokenLength;
+       /* Specifies the Authorization token */
+       B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH];
+       /* specifes Number of HARQ channels used to carry data length */
+       B_UINT8 u8HarqChannelMappingLength;
+       /* specifes HARQ channels used to carry data */
+       B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS];
+       /* 8bit Length of Vendor Specific QoS Params */
+       B_UINT8 u8VendorSpecificQoSParamLength;
+       /* 1byte  Vendor Specific QoS Param Of The Service Flow */
+       B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM];
+       /* indicates total classifiers in the SF */
+       B_UINT8 u8TotalClassifiers;  /* < Total number of valid classifiers */
+       B_UINT8 bValid; /* < Validity flag */
+       B_UINT8 u8Padding;       /* < Padding byte */
+/*
+ * Structure for Convergence SubLayer Types with a maximum of 4 classifiers
+ */
+       stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF];
 
 } stServiceFlowParamSI, *pstServiceFlowParamSI;
 typedef stServiceFlowParamSI CServiceFlowParamSI;
 
-/**
-structure stLocalSFAddRequest
-*/
-typedef struct _stLocalSFAddRequest{
-
-       B_UINT8                         u8Type; /**<  Type*/
-       B_UINT8      eConnectionDir;            /**<  Connection direction*/
-       /// \brief 16 bit TID
-       B_UINT16                        u16TID; /**<  16bit TID*/
-       /// \brief 16bitCID
-       B_UINT16                        u16CID; /**<  16bit CID*/
-       /// \brief 16bitVCID
-       B_UINT16                        u16VCID;        /**<  16bit VCID*/
-    /// \brief structure ParameterSet
-
-       stServiceFlowParamSI    *psfParameterSet;       /**<  structure ParameterSet*/
-
-}stLocalSFAddRequest, *pstLocalSFAddRequest;
-
-
-/**
-structure stLocalSFAddIndication
-*/
-typedef struct _stLocalSFAddIndication{
-
-       B_UINT8                         u8Type; /**<  Type*/
-       B_UINT8      eConnectionDir;    /**<  Connection Direction*/
-       /// \brief 16 bit TID
-       B_UINT16                         u16TID;        /**<  TID*/
-    /// \brief 16bitCID
-    B_UINT16                        u16CID;            /**<  16bitCID*/
-    /// \brief 16bitVCID
-    B_UINT16                        u16VCID;    /**<  16bitVCID*/
-
-
-    /// \brief structure AuthorizedSet
-    /// \brief structure AuthorizedSet
-    stServiceFlowParamSI              *psfAuthorizedSet;       /**<  AuthorizedSet of type stServiceFlowParamSI*/
-    /// \brief structure AdmittedSet
-    stServiceFlowParamSI              *psfAdmittedSet; /**<  AdmittedSet of type stServiceFlowParamSI*/
-    /// \brief structure ActiveSet
-    stServiceFlowParamSI              *psfActiveSet;   /**<  sfActiveSet of type stServiceFlowParamSI*/
-       B_UINT8                            u8CC;        /**<  Confirmation Code*/
-       B_UINT8                            u8Padd;              /**<  8-bit Padding */
-
-    B_UINT16               u16Padd;    /**< 16 bit Padding */
-
-}stLocalSFAddIndication;
-
+/*
+ * structure stLocalSFAddRequest
+ */
+typedef struct _stLocalSFAddRequest {
+       B_UINT8 u8Type; /* < Type */
+       B_UINT8 eConnectionDir; /* < Connection direction */
+       /* brief 16 bit TID */
+       B_UINT16 u16TID; /* < 16bit TID */
+       /* brief 16bitCID */
+       B_UINT16 u16CID; /* < 16bit CID */
+       /* brief 16bitVCID */
+       B_UINT16 u16VCID; /* < 16bit VCID */
+       /* brief structure ParameterSet */
+       stServiceFlowParamSI *psfParameterSet; /* < structure ParameterSet */
+
+} stLocalSFAddRequest, *pstLocalSFAddRequest;
+
+/*
+ * structure stLocalSFAddIndication
+ */
+typedef struct _stLocalSFAddIndication {
+       B_UINT8 u8Type; /* < Type */
+       B_UINT8 eConnectionDir; /* < Connection Direction */
+       /* brief 16 bit TID */
+       B_UINT16 u16TID; /* < TID */
+       /* brief 16bitCID */
+       B_UINT16 u16CID; /* < 16bitCID */
+       /* brief 16bitVCID */
+       B_UINT16 u16VCID; /* < 16bitVCID */
+       /* brief structure AuthorizedSet */
+       /* brief structure AuthorizedSet */
+       stServiceFlowParamSI *psfAuthorizedSet; /* < AuthorizedSet of type stServiceFlowParamSI */
+       /* brief structure AdmittedSet */
+       stServiceFlowParamSI *psfAdmittedSet; /* < AdmittedSet of type stServiceFlowParamSI */
+       /* brief structure ActiveSet */
+       stServiceFlowParamSI *psfActiveSet; /* < sfActiveSet of type stServiceFlowParamSI */
+       B_UINT8 u8CC; /* <Confirmation Code */
+       B_UINT8 u8Padd; /* < 8-bit Padding */
+       B_UINT16 u16Padd; /* < 16 bit Padding */
+
+} stLocalSFAddIndication;
 
 typedef struct _stLocalSFAddIndication *pstLocalSFAddIndication;
-/**
-structure stLocalSFChangeRequest is same as structure stLocalSFAddIndication
-*/
+/*
+ * structure stLocalSFChangeRequest is same as structure stLocalSFAddIndication
+ */
 typedef struct _stLocalSFAddIndication stLocalSFChangeRequest, *pstLocalSFChangeRequest;
-/**
-structure stLocalSFChangeIndication is same as structure stLocalSFAddIndication
-*/
+/*
+ * structure stLocalSFChangeIndication is same as structure stLocalSFAddIndication
+ */
 typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFChangeIndication;
 
-/**
-structure stLocalSFDeleteRequest
-*/
-typedef struct _stLocalSFDeleteRequest{
-       B_UINT8                         u8Type;  /**< Type*/
-       B_UINT8                         u8Padding;       /**<  Padding byte*/
-       B_UINT16                        u16TID;          /**<  TID*/
-    /// \brief 32bitSFID
-    B_UINT32                        u32SFID;    /**<  SFID*/
-}stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
-
-/**
-structure stLocalSFDeleteIndication
-*/
-typedef struct stLocalSFDeleteIndication{
-       B_UINT8                         u8Type; /**< Type */
-       B_UINT8                         u8Padding;      /**< Padding  */
-       B_UINT16                        u16TID;                 /**< TID */
-       /// \brief 16bitCID
-    B_UINT16                        u16CID;                    /**< CID */
-    /// \brief 16bitVCID
-    B_UINT16                        u16VCID;           /**< VCID */
-    /// \brief 32bitSFID
-    B_UINT32                        u32SFID;           /**< SFID */
-       /// \brief 8bit Confirmation code
-       B_UINT8                         u8ConfirmationCode;     /**< Confirmation code */
-       B_UINT8                         u8Padding1[3];          /**< 3 byte Padding  */
-}stLocalSFDeleteIndication;
-
-typedef struct _stIM_SFHostNotify
-{
-       B_UINT32        SFID;      //SFID of the service flow
-       B_UINT16        newCID;   //the new/changed CID
-       B_UINT16        VCID;             //Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid
-       B_UINT8         RetainSF;        //Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete
-       B_UINT8         QoSParamSet; //QoS paramset of the retained SF
-       B_UINT16        u16reserved;  //For byte alignment
-
-} stIM_SFHostNotify;
+/*
+ * structure stLocalSFDeleteRequest
+ */
+typedef struct _stLocalSFDeleteRequest {
+       B_UINT8 u8Type; /* < Type */
+       B_UINT8 u8Padding; /* < Padding byte */
+       B_UINT16 u16TID; /* < TID */
+       /* brief 32bitSFID */
+       B_UINT32 u32SFID; /* < SFID */
+} stLocalSFDeleteRequest, *pstLocalSFDeleteRequest;
+
+/*
+ * structure stLocalSFDeleteIndication
+ */
+typedef struct stLocalSFDeleteIndication {
+       B_UINT8 u8Type; /* < Type */
+       B_UINT8 u8Padding; /* < Padding */
+       B_UINT16 u16TID; /* < TID */
+       /* brief 16bitCID */
+       B_UINT16 u16CID; /* < CID */
+       /* brief 16bitVCID */
+       B_UINT16 u16VCID; /* < VCID */
+       /* brief 32bitSFID */
+       B_UINT32 u32SFID; /* < SFID */
+       /* brief 8bit Confirmation code */
+       B_UINT8 u8ConfirmationCode; /* < Confirmation code */
+       B_UINT8 u8Padding1[3]; /* < 3 byte Padding */
+} stLocalSFDeleteIndication;
+
+struct bcm_stim_sfhostnotify {
+       B_UINT32 SFID; /* SFID of the service flow */
+       B_UINT16 newCID; /* the new/changed CID */
+       B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */
+       B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */
+       B_UINT8 QoSParamSet; /* QoS paramset of the retained SF */
+       B_UINT16 u16reserved; /* For byte alignment */
+};
 
 #endif
index 693c4544c29d410d0e4c68feb749e93e33e693d4..c9492edaaddb97ffb06ba796e0079f265549d6d7 100644 (file)
@@ -837,7 +837,7 @@ int SetEvent(DEVICE_EXTENSION * pdx, TRANSFEREVENT __user * pTE)
 int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut)
 {
        int iReturn;
-       if ((unsigned)nArea > MAX_TRANSAREAS)
+       if ((unsigned)nArea >= MAX_TRANSAREAS)
                return U14ERR_BADAREA;
        else {
                int iWait;
@@ -884,7 +884,7 @@ int WaitEvent(DEVICE_EXTENSION * pdx, int nArea, int msTimeOut)
 int TestEvent(DEVICE_EXTENSION * pdx, int nArea)
 {
        int iReturn;
-       if ((unsigned)nArea > MAX_TRANSAREAS)
+       if ((unsigned)nArea >= MAX_TRANSAREAS)
                iReturn = U14ERR_BADAREA;
        else {
                TRANSAREA *pTA = &pdx->rTransDef[nArea];
index 69b7f20c9d5101fa4398ca1df922a95e610e2e8b..6ba0ef6525611f0de97284ad744de1e0cfa437fd 100644 (file)
@@ -261,24 +261,6 @@ static int ced_flush(struct file *file, fl_owner_t id)
        return res;
 }
 
-static ssize_t ced_read(struct file *file, char *buffer, size_t count,
-                       loff_t * ppos)
-{
-       DEVICE_EXTENSION *pdx = file->private_data;
-       dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb",
-               __func__);
-       return 0;               // as we do not do reads this way
-}
-
-static ssize_t ced_write(struct file *file, const char *user_buffer,
-                        size_t count, loff_t * ppos)
-{
-       DEVICE_EXTENSION *pdx = file->private_data;
-       dev_err(&pdx->interface->dev, "%s called: use ioctl for cedusb",
-               __func__);
-       return 0;
-}
-
 /***************************************************************************
 ** CanAcceptIoRequests
 ** If the device is removed, interface is set NULL. We also clear our pointer
@@ -1402,8 +1384,6 @@ static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd,
 
 static const struct file_operations ced_fops = {
        .owner = THIS_MODULE,
-       .read = ced_read,
-       .write = ced_write,
        .open = ced_open,
        .release = ced_release,
        .flush = ced_flush,
@@ -1653,19 +1633,5 @@ static struct usb_driver ced_driver = {
        .supports_autosuspend = 1,
 };
 
-static int __init usb_skel_init(void)
-{
-       /* register this driver with the USB subsystem */
-       return usb_register(&ced_driver);
-}
-
-static void __exit usb_skel_exit(void)
-{
-       /* deregister this driver with the USB subsystem */
-       usb_deregister(&ced_driver);
-}
-
-module_init(usb_skel_init);
-module_exit(usb_skel_exit);
-
+module_usb_driver(ced_driver);
 MODULE_LICENSE("GPL");
index 8ea55aef10a7bb15299f477bb6f02ba2f08cb98a..133f013e0f6d783c0c7dfb5835f9e978edda7902 100644 (file)
 
 /* subdevice types */
 
-       enum comedi_subdevice_type {
-               COMEDI_SUBD_UNUSED,     /* unused by driver */
-               COMEDI_SUBD_AI, /* analog input */
-               COMEDI_SUBD_AO, /* analog output */
-               COMEDI_SUBD_DI, /* digital input */
-               COMEDI_SUBD_DO, /* digital output */
-               COMEDI_SUBD_DIO,        /* digital input/output */
-               COMEDI_SUBD_COUNTER,    /* counter */
-               COMEDI_SUBD_TIMER,      /* timer */
-               COMEDI_SUBD_MEMORY,     /* memory, EEPROM, DPRAM */
-               COMEDI_SUBD_CALIB,      /* calibration DACs */
-               COMEDI_SUBD_PROC,       /* processor, DSP */
-               COMEDI_SUBD_SERIAL,     /* serial IO */
-               COMEDI_SUBD_PWM /* PWM */
-       };
+enum comedi_subdevice_type {
+       COMEDI_SUBD_UNUSED,     /* unused by driver */
+       COMEDI_SUBD_AI,         /* analog input */
+       COMEDI_SUBD_AO,         /* analog output */
+       COMEDI_SUBD_DI,         /* digital input */
+       COMEDI_SUBD_DO,         /* digital output */
+       COMEDI_SUBD_DIO,        /* digital input/output */
+       COMEDI_SUBD_COUNTER,    /* counter */
+       COMEDI_SUBD_TIMER,      /* timer */
+       COMEDI_SUBD_MEMORY,     /* memory, EEPROM, DPRAM */
+       COMEDI_SUBD_CALIB,      /* calibration DACs */
+       COMEDI_SUBD_PROC,       /* processor, DSP */
+       COMEDI_SUBD_SERIAL,     /* serial IO */
+       COMEDI_SUBD_PWM         /* PWM */
+};
 
 /* configuration instructions */
 
-       enum configuration_ids {
-               INSN_CONFIG_DIO_INPUT = 0,
-               INSN_CONFIG_DIO_OUTPUT = 1,
-               INSN_CONFIG_DIO_OPENDRAIN = 2,
-               INSN_CONFIG_ANALOG_TRIG = 16,
+enum configuration_ids {
+       INSN_CONFIG_DIO_INPUT = 0,
+       INSN_CONFIG_DIO_OUTPUT = 1,
+       INSN_CONFIG_DIO_OPENDRAIN = 2,
+       INSN_CONFIG_ANALOG_TRIG = 16,
 /*     INSN_CONFIG_WAVEFORM = 17, */
 /*     INSN_CONFIG_TRIG = 18, */
 /*     INSN_CONFIG_COUNTER = 19, */
-               INSN_CONFIG_ALT_SOURCE = 20,
-               INSN_CONFIG_DIGITAL_TRIG = 21,
-               INSN_CONFIG_BLOCK_SIZE = 22,
-               INSN_CONFIG_TIMER_1 = 23,
-               INSN_CONFIG_FILTER = 24,
-               INSN_CONFIG_CHANGE_NOTIFY = 25,
-
-                /*ALPHA*/ INSN_CONFIG_SERIAL_CLOCK = 26,
-               INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
-               INSN_CONFIG_DIO_QUERY = 28,
-               INSN_CONFIG_PWM_OUTPUT = 29,
-               INSN_CONFIG_GET_PWM_OUTPUT = 30,
-               INSN_CONFIG_ARM = 31,
-               INSN_CONFIG_DISARM = 32,
-               INSN_CONFIG_GET_COUNTER_STATUS = 33,
-               INSN_CONFIG_RESET = 34,
-               /* Use CTR as single pulsegenerator */
-               INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,
-               /* Use CTR as pulsetraingenerator */
-               INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,
-               /* Use the counter as encoder */
-               INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,
-               INSN_CONFIG_SET_GATE_SRC = 2001,        /* Set gate source */
-               INSN_CONFIG_GET_GATE_SRC = 2002,        /* Get gate source */
-               /* Set master clock source */
-               INSN_CONFIG_SET_CLOCK_SRC = 2003,
-               INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
-               INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
-               /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */
-               /* Get size in bytes of subdevice's on-board fifos used during
-                * streaming input/output */
-               INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
-               INSN_CONFIG_SET_COUNTER_MODE = 4097,
-               /* INSN_CONFIG_8254_SET_MODE is deprecated */
-               INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,
-               INSN_CONFIG_8254_READ_STATUS = 4098,
-               INSN_CONFIG_SET_ROUTING = 4099,
-               INSN_CONFIG_GET_ROUTING = 4109,
-/* PWM */
-               INSN_CONFIG_PWM_SET_PERIOD = 5000,      /* sets frequency */
-               INSN_CONFIG_PWM_GET_PERIOD = 5001,      /* gets frequency */
-               INSN_CONFIG_GET_PWM_STATUS = 5002,      /* is it running? */
-               /* sets H bridge: duty cycle and sign bit for a relay at the
-                * same time */
-               INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
-               /* gets H bridge data: duty cycle and the sign bit */
-               INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
-       };
-
-       enum comedi_io_direction {
-               COMEDI_INPUT = 0,
-               COMEDI_OUTPUT = 1,
-               COMEDI_OPENDRAIN = 2
-       };
-
-       enum comedi_support_level {
-               COMEDI_UNKNOWN_SUPPORT = 0,
-               COMEDI_SUPPORTED,
-               COMEDI_UNSUPPORTED
-       };
+       INSN_CONFIG_ALT_SOURCE = 20,
+       INSN_CONFIG_DIGITAL_TRIG = 21,
+       INSN_CONFIG_BLOCK_SIZE = 22,
+       INSN_CONFIG_TIMER_1 = 23,
+       INSN_CONFIG_FILTER = 24,
+       INSN_CONFIG_CHANGE_NOTIFY = 25,
+
+       INSN_CONFIG_SERIAL_CLOCK = 26,  /*ALPHA*/
+       INSN_CONFIG_BIDIRECTIONAL_DATA = 27,
+       INSN_CONFIG_DIO_QUERY = 28,
+       INSN_CONFIG_PWM_OUTPUT = 29,
+       INSN_CONFIG_GET_PWM_OUTPUT = 30,
+       INSN_CONFIG_ARM = 31,
+       INSN_CONFIG_DISARM = 32,
+       INSN_CONFIG_GET_COUNTER_STATUS = 33,
+       INSN_CONFIG_RESET = 34,
+       /* Use CTR as single pulsegenerator */
+       INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR = 1001,
+       /* Use CTR as pulsetraingenerator */
+       INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR = 1002,
+       /* Use the counter as encoder */
+       INSN_CONFIG_GPCT_QUADRATURE_ENCODER = 1003,
+       INSN_CONFIG_SET_GATE_SRC = 2001,        /* Set gate source */
+       INSN_CONFIG_GET_GATE_SRC = 2002,        /* Get gate source */
+       /* Set master clock source */
+       INSN_CONFIG_SET_CLOCK_SRC = 2003,
+       INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
+       INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
+       /* INSN_CONFIG_GET_OTHER_SRC = 2006,*//* Get other source */
+       /* Get size in bytes of subdevice's on-board fifos used during
+        * streaming input/output */
+       INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006,
+       INSN_CONFIG_SET_COUNTER_MODE = 4097,
+       /* INSN_CONFIG_8254_SET_MODE is deprecated */
+       INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE,
+       INSN_CONFIG_8254_READ_STATUS = 4098,
+       INSN_CONFIG_SET_ROUTING = 4099,
+       INSN_CONFIG_GET_ROUTING = 4109,
+       /* PWM */
+       INSN_CONFIG_PWM_SET_PERIOD = 5000,      /* sets frequency */
+       INSN_CONFIG_PWM_GET_PERIOD = 5001,      /* gets frequency */
+       INSN_CONFIG_GET_PWM_STATUS = 5002,      /* is it running? */
+       /* sets H bridge: duty cycle and sign bit for a relay at the
+        * same time */
+       INSN_CONFIG_PWM_SET_H_BRIDGE = 5003,
+       /* gets H bridge data: duty cycle and the sign bit */
+       INSN_CONFIG_PWM_GET_H_BRIDGE = 5004
+};
+
+enum comedi_io_direction {
+       COMEDI_INPUT = 0,
+       COMEDI_OUTPUT = 1,
+       COMEDI_OPENDRAIN = 2
+};
+
+enum comedi_support_level {
+       COMEDI_UNKNOWN_SUPPORT = 0,
+       COMEDI_SUPPORTED,
+       COMEDI_UNSUPPORTED
+};
 
 /* ioctls */
 
 
 /* structures */
 
-       struct comedi_trig {
-               unsigned int subdev;    /* subdevice */
-               unsigned int mode;      /* mode */
-               unsigned int flags;
-               unsigned int n_chan;    /* number of channels */
-               unsigned int *chanlist; /* channel/range list */
-               short *data;    /* data list, size depends on subd flags */
-               unsigned int n; /* number of scans */
-               unsigned int trigsrc;
-               unsigned int trigvar;
-               unsigned int trigvar1;
-               unsigned int data_len;
-               unsigned int unused[3];
-       };
-
-       struct comedi_insn {
-               unsigned int insn;
-               unsigned int n;
-               unsigned int __user *data;
-               unsigned int subdev;
-               unsigned int chanspec;
-               unsigned int unused[3];
-       };
-
-       struct comedi_insnlist {
-               unsigned int n_insns;
-               struct comedi_insn __user *insns;
-       };
-
-       struct comedi_cmd {
-               unsigned int subdev;
-               unsigned int flags;
-
-               unsigned int start_src;
-               unsigned int start_arg;
-
-               unsigned int scan_begin_src;
-               unsigned int scan_begin_arg;
-
-               unsigned int convert_src;
-               unsigned int convert_arg;
-
-               unsigned int scan_end_src;
-               unsigned int scan_end_arg;
-
-               unsigned int stop_src;
-               unsigned int stop_arg;
-
-               unsigned int __user *chanlist;  /* channel/range list */
-               unsigned int chanlist_len;
-
-               short __user *data; /* data list, size depends on subd flags */
-               unsigned int data_len;
-       };
-
-       struct comedi_chaninfo {
-               unsigned int subdev;
-               unsigned int __user *maxdata_list;
-               unsigned int __user *flaglist;
-               unsigned int __user *rangelist;
-               unsigned int unused[4];
-       };
-
-       struct comedi_rangeinfo {
-               unsigned int range_type;
-               void __user *range_ptr;
-       };
-
-       struct comedi_krange {
-               int min;        /* fixed point, multiply by 1e-6 */
-               int max;        /* fixed point, multiply by 1e-6 */
-               unsigned int flags;
-       };
-
-       struct comedi_subdinfo {
-               unsigned int type;
-               unsigned int n_chan;
-               unsigned int subd_flags;
-               unsigned int timer_type;
-               unsigned int len_chanlist;
-               unsigned int maxdata;
-               unsigned int flags;     /* channel flags */
-               unsigned int range_type;        /* lookup in kernel */
-               unsigned int settling_time_0;
-               /* see support_level enum for values */
-               unsigned insn_bits_support;
-               unsigned int unused[8];
-       };
-
-       struct comedi_devinfo {
-               unsigned int version_code;
-               unsigned int n_subdevs;
-               char driver_name[COMEDI_NAMELEN];
-               char board_name[COMEDI_NAMELEN];
-               int read_subdevice;
-               int write_subdevice;
-               int unused[30];
-       };
-
-       struct comedi_devconfig {
-               char board_name[COMEDI_NAMELEN];
-               int options[COMEDI_NDEVCONFOPTS];
-       };
-
-       struct comedi_bufconfig {
-               unsigned int subdevice;
-               unsigned int flags;
-
-               unsigned int maximum_size;
-               unsigned int size;
-
-               unsigned int unused[4];
-       };
-
-       struct comedi_bufinfo {
-               unsigned int subdevice;
-               unsigned int bytes_read;
-
-               unsigned int buf_write_ptr;
-               unsigned int buf_read_ptr;
-               unsigned int buf_write_count;
-               unsigned int buf_read_count;
-
-               unsigned int bytes_written;
-
-               unsigned int unused[4];
-       };
+struct comedi_trig {
+       unsigned int subdev;    /* subdevice */
+       unsigned int mode;      /* mode */
+       unsigned int flags;
+       unsigned int n_chan;    /* number of channels */
+       unsigned int *chanlist; /* channel/range list */
+       short *data;            /* data list, size depends on subd flags */
+       unsigned int n;         /* number of scans */
+       unsigned int trigsrc;
+       unsigned int trigvar;
+       unsigned int trigvar1;
+       unsigned int data_len;
+       unsigned int unused[3];
+};
+
+struct comedi_insn {
+       unsigned int insn;
+       unsigned int n;
+       unsigned int __user *data;
+       unsigned int subdev;
+       unsigned int chanspec;
+       unsigned int unused[3];
+};
+
+struct comedi_insnlist {
+       unsigned int n_insns;
+       struct comedi_insn __user *insns;
+};
+
+struct comedi_cmd {
+       unsigned int subdev;
+       unsigned int flags;
+
+       unsigned int start_src;
+       unsigned int start_arg;
+
+       unsigned int scan_begin_src;
+       unsigned int scan_begin_arg;
+
+       unsigned int convert_src;
+       unsigned int convert_arg;
+
+       unsigned int scan_end_src;
+       unsigned int scan_end_arg;
+
+       unsigned int stop_src;
+       unsigned int stop_arg;
+
+       unsigned int *chanlist; /* channel/range list */
+       unsigned int chanlist_len;
+
+       short __user *data; /* data list, size depends on subd flags */
+       unsigned int data_len;
+};
+
+struct comedi_chaninfo {
+       unsigned int subdev;
+       unsigned int __user *maxdata_list;
+       unsigned int __user *flaglist;
+       unsigned int __user *rangelist;
+       unsigned int unused[4];
+};
+
+struct comedi_rangeinfo {
+       unsigned int range_type;
+       void __user *range_ptr;
+};
+
+struct comedi_krange {
+       int min;        /* fixed point, multiply by 1e-6 */
+       int max;        /* fixed point, multiply by 1e-6 */
+       unsigned int flags;
+};
+
+struct comedi_subdinfo {
+       unsigned int type;
+       unsigned int n_chan;
+       unsigned int subd_flags;
+       unsigned int timer_type;
+       unsigned int len_chanlist;
+       unsigned int maxdata;
+       unsigned int flags;             /* channel flags */
+       unsigned int range_type;        /* lookup in kernel */
+       unsigned int settling_time_0;
+       /* see support_level enum for values */
+       unsigned insn_bits_support;
+       unsigned int unused[8];
+};
+
+struct comedi_devinfo {
+       unsigned int version_code;
+       unsigned int n_subdevs;
+       char driver_name[COMEDI_NAMELEN];
+       char board_name[COMEDI_NAMELEN];
+       int read_subdevice;
+       int write_subdevice;
+       int unused[30];
+};
+
+struct comedi_devconfig {
+       char board_name[COMEDI_NAMELEN];
+       int options[COMEDI_NDEVCONFOPTS];
+};
+
+struct comedi_bufconfig {
+       unsigned int subdevice;
+       unsigned int flags;
+
+       unsigned int maximum_size;
+       unsigned int size;
+
+       unsigned int unused[4];
+};
+
+struct comedi_bufinfo {
+       unsigned int subdevice;
+       unsigned int bytes_read;
+
+       unsigned int buf_write_ptr;
+       unsigned int buf_read_ptr;
+       unsigned int buf_write_count;
+       unsigned int buf_read_count;
+
+       unsigned int bytes_written;
+
+       unsigned int unused[4];
+};
 
 /* range stuff */
 
 
 */
 
-       enum i8254_mode {
-               I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
-               I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */
-               I8254_MODE2 = (2 << 1), /* Rate generator */
-               I8254_MODE3 = (3 << 1), /* Square wave mode */
-               I8254_MODE4 = (4 << 1), /* Software triggered strobe */
-               I8254_MODE5 = (5 << 1), /* Hardware triggered strobe
-                                        * (retriggerable) */
-               I8254_BCD = 1,  /* use binary-coded decimal instead of binary
+enum i8254_mode {
+       I8254_MODE0 = (0 << 1), /* Interrupt on terminal count */
+       I8254_MODE1 = (1 << 1), /* Hardware retriggerable one-shot */
+       I8254_MODE2 = (2 << 1), /* Rate generator */
+       I8254_MODE3 = (3 << 1), /* Square wave mode */
+       I8254_MODE4 = (4 << 1), /* Software triggered strobe */
+       I8254_MODE5 = (5 << 1), /* Hardware triggered strobe
+                                * (retriggerable) */
+       I8254_BCD = 1,          /* use binary-coded decimal instead of binary
                                 * (pretty useless) */
-               I8254_BINARY = 0
-       };
-
-       static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
-       {
-               if (pfi_channel < 10)
-                       return 0x1 + pfi_channel;
-               else
-                       return 0xb + pfi_channel;
-       }
-
-       static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)
-       {
-               if (rtsi_channel < 7)
-                       return 0xb + rtsi_channel;
-               else
-                       return 0x1b;
-       }
+       I8254_BINARY = 0
+};
+
+static inline unsigned NI_USUAL_PFI_SELECT(unsigned pfi_channel)
+{
+       if (pfi_channel < 10)
+               return 0x1 + pfi_channel;
+       else
+               return 0xb + pfi_channel;
+}
+
+static inline unsigned NI_USUAL_RTSI_SELECT(unsigned rtsi_channel)
+{
+       if (rtsi_channel < 7)
+               return 0xb + rtsi_channel;
+       else
+               return 0x1b;
+}
 
 /* mode bits for NI general-purpose counters, set with
  * INSN_CONFIG_SET_COUNTER_MODE */
 #define NI_GPCT_COUNTING_MODE_SHIFT 16
 #define NI_GPCT_INDEX_PHASE_BITSHIFT 20
 #define NI_GPCT_COUNTING_DIRECTION_SHIFT 24
-       enum ni_gpct_mode_bits {
-               NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
-               NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
-               NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
-               NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
-               NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
-               NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
-               NI_GPCT_STOP_MODE_MASK = 0x60,
-               NI_GPCT_STOP_ON_GATE_BITS = 0x00,
-               NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
-               NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
-               NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
-               NI_GPCT_OUTPUT_MODE_MASK = 0x300,
-               NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
-               NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
-               NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
-               NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
-               NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
-               NI_GPCT_DISARM_AT_TC_BITS = 0x400,
-               NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
-               NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
-               NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
-               NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
-               NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_NORMAL_BITS =
-                   0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
-                   0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
-                   0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
-                   0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
-                   0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
-                   0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
-               NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-               NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
-                   0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-               NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
-                   0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-               NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
-                   0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-               NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
-                   0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
-               NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
-               NI_GPCT_COUNTING_DIRECTION_MASK =
-                   0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-               NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
-                   0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-               NI_GPCT_COUNTING_DIRECTION_UP_BITS =
-                   0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-               NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
-                   0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-               NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
-                   0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
-               NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
-               NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
-               NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
-               NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
-               NI_GPCT_OR_GATE_BIT = 0x10000000,
-               NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
-       };
+enum ni_gpct_mode_bits {
+       NI_GPCT_GATE_ON_BOTH_EDGES_BIT = 0x4,
+       NI_GPCT_EDGE_GATE_MODE_MASK = 0x18,
+       NI_GPCT_EDGE_GATE_STARTS_STOPS_BITS = 0x0,
+       NI_GPCT_EDGE_GATE_STOPS_STARTS_BITS = 0x8,
+       NI_GPCT_EDGE_GATE_STARTS_BITS = 0x10,
+       NI_GPCT_EDGE_GATE_NO_STARTS_NO_STOPS_BITS = 0x18,
+       NI_GPCT_STOP_MODE_MASK = 0x60,
+       NI_GPCT_STOP_ON_GATE_BITS = 0x00,
+       NI_GPCT_STOP_ON_GATE_OR_TC_BITS = 0x20,
+       NI_GPCT_STOP_ON_GATE_OR_SECOND_TC_BITS = 0x40,
+       NI_GPCT_LOAD_B_SELECT_BIT = 0x80,
+       NI_GPCT_OUTPUT_MODE_MASK = 0x300,
+       NI_GPCT_OUTPUT_TC_PULSE_BITS = 0x100,
+       NI_GPCT_OUTPUT_TC_TOGGLE_BITS = 0x200,
+       NI_GPCT_OUTPUT_TC_OR_GATE_TOGGLE_BITS = 0x300,
+       NI_GPCT_HARDWARE_DISARM_MASK = 0xc00,
+       NI_GPCT_NO_HARDWARE_DISARM_BITS = 0x000,
+       NI_GPCT_DISARM_AT_TC_BITS = 0x400,
+       NI_GPCT_DISARM_AT_GATE_BITS = 0x800,
+       NI_GPCT_DISARM_AT_TC_OR_GATE_BITS = 0xc00,
+       NI_GPCT_LOADING_ON_TC_BIT = 0x1000,
+       NI_GPCT_LOADING_ON_GATE_BIT = 0x4000,
+       NI_GPCT_COUNTING_MODE_MASK = 0x7 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_NORMAL_BITS =
+               0x0 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_QUADRATURE_X1_BITS =
+               0x1 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_QUADRATURE_X2_BITS =
+               0x2 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS =
+               0x3 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_TWO_PULSE_BITS =
+               0x4 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_COUNTING_MODE_SYNC_SOURCE_BITS =
+               0x6 << NI_GPCT_COUNTING_MODE_SHIFT,
+       NI_GPCT_INDEX_PHASE_MASK = 0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+       NI_GPCT_INDEX_PHASE_LOW_A_LOW_B_BITS =
+               0x0 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+       NI_GPCT_INDEX_PHASE_LOW_A_HIGH_B_BITS =
+               0x1 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+       NI_GPCT_INDEX_PHASE_HIGH_A_LOW_B_BITS =
+               0x2 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+       NI_GPCT_INDEX_PHASE_HIGH_A_HIGH_B_BITS =
+               0x3 << NI_GPCT_INDEX_PHASE_BITSHIFT,
+       NI_GPCT_INDEX_ENABLE_BIT = 0x400000,
+       NI_GPCT_COUNTING_DIRECTION_MASK =
+               0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+       NI_GPCT_COUNTING_DIRECTION_DOWN_BITS =
+               0x00 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+       NI_GPCT_COUNTING_DIRECTION_UP_BITS =
+               0x1 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+       NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS =
+               0x2 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+       NI_GPCT_COUNTING_DIRECTION_HW_GATE_BITS =
+               0x3 << NI_GPCT_COUNTING_DIRECTION_SHIFT,
+       NI_GPCT_RELOAD_SOURCE_MASK = 0xc000000,
+       NI_GPCT_RELOAD_SOURCE_FIXED_BITS = 0x0,
+       NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS = 0x4000000,
+       NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS = 0x8000000,
+       NI_GPCT_OR_GATE_BIT = 0x10000000,
+       NI_GPCT_INVERT_OUTPUT_BIT = 0x20000000
+};
 
 /* Bits for setting a clock source with
  * INSN_CONFIG_SET_CLOCK_SRC when using NI general-purpose counters. */
-       enum ni_gpct_clock_source_bits {
-               NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
-               NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
-               NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
-               NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
-               NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
-               NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
-               NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
-               /* NI 660x-specific */
-               NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,
-               NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
-               NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
-               NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
-               NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
-               NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
-               /* divide source by 2 */
-               NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,
-               /* divide source by 8 */
-               NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
-               NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
-       };
-       static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
-       {
-               /* NI 660x-specific */
-               return 0x10 + n;
-       }
-       static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
-       {
-               return 0x18 + n;
-       }
-       static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
-       {
-               /* no pfi on NI 660x */
-               return 0x20 + n;
-       }
+enum ni_gpct_clock_source_bits {
+       NI_GPCT_CLOCK_SRC_SELECT_MASK = 0x3f,
+       NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS = 0x0,
+       NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS = 0x1,
+       NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS = 0x2,
+       NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS = 0x3,
+       NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS = 0x4,
+       NI_GPCT_NEXT_TC_CLOCK_SRC_BITS = 0x5,
+       /* NI 660x-specific */
+       NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS = 0x6,
+       NI_GPCT_PXI10_CLOCK_SRC_BITS = 0x7,
+       NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS = 0x8,
+       NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS = 0x9,
+       NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK = 0x30000000,
+       NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS = 0x0,
+       /* divide source by 2 */
+       NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS = 0x10000000,
+       /* divide source by 8 */
+       NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS = 0x20000000,
+       NI_GPCT_INVERT_CLOCK_SRC_BIT = 0x80000000
+};
+static inline unsigned NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(unsigned n)
+{
+       /* NI 660x-specific */
+       return 0x10 + n;
+}
+static inline unsigned NI_GPCT_RTSI_CLOCK_SRC_BITS(unsigned n)
+{
+       return 0x18 + n;
+}
+static inline unsigned NI_GPCT_PFI_CLOCK_SRC_BITS(unsigned n)
+{
+       /* no pfi on NI 660x */
+       return 0x20 + n;
+}
 
 /* Possibilities for setting a gate source with
 INSN_CONFIG_SET_GATE_SRC when using NI general-purpose counters.
 May be bitwise-or'd with CR_EDGE or CR_INVERT. */
-       enum ni_gpct_gate_select {
-               /* m-series gates */
-               NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
-               NI_GPCT_AI_START2_GATE_SELECT = 0x12,
-               NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
-               NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
-               NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
-               NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
-               NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
-               NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
-               /* more gates for 660x */
-               NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
-               NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
-               /* more gates for 660x "second gate" */
-               NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
-               NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
-               /* m-series "second gate" sources are unknown,
-                * we should add them here with an offset of 0x300 when
-                * known. */
-               NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
-       };
-       static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
-       {
-               return 0x102 + n;
-       }
-       static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
-       {
-               return NI_USUAL_RTSI_SELECT(n);
-       }
-       static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
-       {
-               return NI_USUAL_PFI_SELECT(n);
-       }
-       static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
-       {
-               return 0x202 + n;
-       }
+enum ni_gpct_gate_select {
+       /* m-series gates */
+       NI_GPCT_TIMESTAMP_MUX_GATE_SELECT = 0x0,
+       NI_GPCT_AI_START2_GATE_SELECT = 0x12,
+       NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT = 0x13,
+       NI_GPCT_NEXT_OUT_GATE_SELECT = 0x14,
+       NI_GPCT_AI_START1_GATE_SELECT = 0x1c,
+       NI_GPCT_NEXT_SOURCE_GATE_SELECT = 0x1d,
+       NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT = 0x1e,
+       NI_GPCT_LOGIC_LOW_GATE_SELECT = 0x1f,
+       /* more gates for 660x */
+       NI_GPCT_SOURCE_PIN_i_GATE_SELECT = 0x100,
+       NI_GPCT_GATE_PIN_i_GATE_SELECT = 0x101,
+       /* more gates for 660x "second gate" */
+       NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT = 0x201,
+       NI_GPCT_SELECTED_GATE_GATE_SELECT = 0x21e,
+       /* m-series "second gate" sources are unknown,
+        * we should add them here with an offset of 0x300 when
+        * known. */
+       NI_GPCT_DISABLED_GATE_SELECT = 0x8000,
+};
+static inline unsigned NI_GPCT_GATE_PIN_GATE_SELECT(unsigned n)
+{
+       return 0x102 + n;
+}
+static inline unsigned NI_GPCT_RTSI_GATE_SELECT(unsigned n)
+{
+       return NI_USUAL_RTSI_SELECT(n);
+}
+static inline unsigned NI_GPCT_PFI_GATE_SELECT(unsigned n)
+{
+       return NI_USUAL_PFI_SELECT(n);
+}
+static inline unsigned NI_GPCT_UP_DOWN_PIN_GATE_SELECT(unsigned n)
+{
+       return 0x202 + n;
+}
 
 /* Possibilities for setting a source with
 INSN_CONFIG_SET_OTHER_SRC when using NI general-purpose counters. */
-       enum ni_gpct_other_index {
-               NI_GPCT_SOURCE_ENCODER_A,
-               NI_GPCT_SOURCE_ENCODER_B,
-               NI_GPCT_SOURCE_ENCODER_Z
-       };
-       enum ni_gpct_other_select {
-               /* m-series gates */
-               /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
-               NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
-       };
-       static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
-       {
-               return NI_USUAL_PFI_SELECT(n);
-       }
+enum ni_gpct_other_index {
+       NI_GPCT_SOURCE_ENCODER_A,
+       NI_GPCT_SOURCE_ENCODER_B,
+       NI_GPCT_SOURCE_ENCODER_Z
+};
+enum ni_gpct_other_select {
+       /* m-series gates */
+       /* Still unknown, probably only need NI_GPCT_PFI_OTHER_SELECT */
+       NI_GPCT_DISABLED_OTHER_SELECT = 0x8000,
+};
+static inline unsigned NI_GPCT_PFI_OTHER_SELECT(unsigned n)
+{
+       return NI_USUAL_PFI_SELECT(n);
+}
 
 /* start sources for ni general-purpose counters for use with
 INSN_CONFIG_ARM */
-       enum ni_gpct_arm_source {
-               NI_GPCT_ARM_IMMEDIATE = 0x0,
-               NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter
-                                                    * and the adjacent paired
-                                                    * counter simultaneously */
-               /* NI doesn't document bits for selecting hardware arm triggers.
-                * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
-                * significant bits (3 bits for 660x or 5 bits for m-series)
-                * through to the hardware.  This will at least allow someone to
-                * figure out what the bits do later. */
-               NI_GPCT_ARM_UNKNOWN = 0x1000,
-       };
+enum ni_gpct_arm_source {
+       NI_GPCT_ARM_IMMEDIATE = 0x0,
+       NI_GPCT_ARM_PAIRED_IMMEDIATE = 0x1, /* Start both the counter
+                                            * and the adjacent paired
+                                            * counter simultaneously */
+       /* NI doesn't document bits for selecting hardware arm triggers.
+        * If the NI_GPCT_ARM_UNKNOWN bit is set, we will pass the least
+        * significant bits (3 bits for 660x or 5 bits for m-series)
+        * through to the hardware.  This will at least allow someone to
+        * figure out what the bits do later. */
+       NI_GPCT_ARM_UNKNOWN = 0x1000,
+};
 
 /* digital filtering options for ni 660x for use with INSN_CONFIG_FILTER. */
-       enum ni_gpct_filter_select {
-               NI_GPCT_FILTER_OFF = 0x0,
-               NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
-               NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
-               NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
-               NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
-               NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
-               NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
-       };
+enum ni_gpct_filter_select {
+       NI_GPCT_FILTER_OFF = 0x0,
+       NI_GPCT_FILTER_TIMEBASE_3_SYNC = 0x1,
+       NI_GPCT_FILTER_100x_TIMEBASE_1 = 0x2,
+       NI_GPCT_FILTER_20x_TIMEBASE_1 = 0x3,
+       NI_GPCT_FILTER_10x_TIMEBASE_1 = 0x4,
+       NI_GPCT_FILTER_2x_TIMEBASE_1 = 0x5,
+       NI_GPCT_FILTER_2x_TIMEBASE_3 = 0x6
+};
 
 /* PFI digital filtering options for ni m-series for use with
  * INSN_CONFIG_FILTER. */
-       enum ni_pfi_filter_select {
-               NI_PFI_FILTER_OFF = 0x0,
-               NI_PFI_FILTER_125ns = 0x1,
-               NI_PFI_FILTER_6425ns = 0x2,
-               NI_PFI_FILTER_2550us = 0x3
-       };
+enum ni_pfi_filter_select {
+       NI_PFI_FILTER_OFF = 0x0,
+       NI_PFI_FILTER_125ns = 0x1,
+       NI_PFI_FILTER_6425ns = 0x2,
+       NI_PFI_FILTER_2550us = 0x3
+};
 
 /* master clock sources for ni mio boards and INSN_CONFIG_SET_CLOCK_SRC */
-       enum ni_mio_clock_source {
-               NI_MIO_INTERNAL_CLOCK = 0,
-               NI_MIO_RTSI_CLOCK = 1,  /* doesn't work for m-series, use
-                                          NI_MIO_PLL_RTSI_CLOCK() */
-               /* the NI_MIO_PLL_* sources are m-series only */
-               NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
-               NI_MIO_PLL_PXI10_CLOCK = 3,
-               NI_MIO_PLL_RTSI0_CLOCK = 4
-       };
-       static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
-       {
-               return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
-       }
+enum ni_mio_clock_source {
+       NI_MIO_INTERNAL_CLOCK = 0,
+       NI_MIO_RTSI_CLOCK = 1,  /* doesn't work for m-series, use
+                                  NI_MIO_PLL_RTSI_CLOCK() */
+       /* the NI_MIO_PLL_* sources are m-series only */
+       NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK = 2,
+       NI_MIO_PLL_PXI10_CLOCK = 3,
+       NI_MIO_PLL_RTSI0_CLOCK = 4
+};
+static inline unsigned NI_MIO_PLL_RTSI_CLOCK(unsigned rtsi_channel)
+{
+       return NI_MIO_PLL_RTSI0_CLOCK + rtsi_channel;
+}
 
 /* Signals which can be routed to an NI RTSI pin with INSN_CONFIG_SET_ROUTING.
  The numbers assigned are not arbitrary, they correspond to the bits required
  to program the board. */
-       enum ni_rtsi_routing {
-               NI_RTSI_OUTPUT_ADR_START1 = 0,
-               NI_RTSI_OUTPUT_ADR_START2 = 1,
-               NI_RTSI_OUTPUT_SCLKG = 2,
-               NI_RTSI_OUTPUT_DACUPDN = 3,
-               NI_RTSI_OUTPUT_DA_START1 = 4,
-               NI_RTSI_OUTPUT_G_SRC0 = 5,
-               NI_RTSI_OUTPUT_G_GATE0 = 6,
-               NI_RTSI_OUTPUT_RGOUT0 = 7,
-               NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
-               NI_RTSI_OUTPUT_RTSI_OSC = 12    /* pre-m-series always have RTSI
-                                                * clock on line 7 */
-       };
-       static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
-       {
-               return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
-       }
+enum ni_rtsi_routing {
+       NI_RTSI_OUTPUT_ADR_START1 = 0,
+       NI_RTSI_OUTPUT_ADR_START2 = 1,
+       NI_RTSI_OUTPUT_SCLKG = 2,
+       NI_RTSI_OUTPUT_DACUPDN = 3,
+       NI_RTSI_OUTPUT_DA_START1 = 4,
+       NI_RTSI_OUTPUT_G_SRC0 = 5,
+       NI_RTSI_OUTPUT_G_GATE0 = 6,
+       NI_RTSI_OUTPUT_RGOUT0 = 7,
+       NI_RTSI_OUTPUT_RTSI_BRD_0 = 8,
+       NI_RTSI_OUTPUT_RTSI_OSC = 12    /* pre-m-series always have RTSI
+                                        * clock on line 7 */
+};
+static inline unsigned NI_RTSI_OUTPUT_RTSI_BRD(unsigned n)
+{
+       return NI_RTSI_OUTPUT_RTSI_BRD_0 + n;
+}
 
 /* Signals which can be routed to an NI PFI pin on an m-series board with
  * INSN_CONFIG_SET_ROUTING.  These numbers are also returned by
  * INSN_CONFIG_GET_ROUTING on pre-m-series boards, even though their routing
  * cannot be changed.  The numbers assigned are not arbitrary, they correspond
  * to the bits required to program the board. */
-       enum ni_pfi_routing {
-               NI_PFI_OUTPUT_PFI_DEFAULT = 0,
-               NI_PFI_OUTPUT_AI_START1 = 1,
-               NI_PFI_OUTPUT_AI_START2 = 2,
-               NI_PFI_OUTPUT_AI_CONVERT = 3,
-               NI_PFI_OUTPUT_G_SRC1 = 4,
-               NI_PFI_OUTPUT_G_GATE1 = 5,
-               NI_PFI_OUTPUT_AO_UPDATE_N = 6,
-               NI_PFI_OUTPUT_AO_START1 = 7,
-               NI_PFI_OUTPUT_AI_START_PULSE = 8,
-               NI_PFI_OUTPUT_G_SRC0 = 9,
-               NI_PFI_OUTPUT_G_GATE0 = 10,
-               NI_PFI_OUTPUT_EXT_STROBE = 11,
-               NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
-               NI_PFI_OUTPUT_GOUT0 = 13,
-               NI_PFI_OUTPUT_GOUT1 = 14,
-               NI_PFI_OUTPUT_FREQ_OUT = 15,
-               NI_PFI_OUTPUT_PFI_DO = 16,
-               NI_PFI_OUTPUT_I_ATRIG = 17,
-               NI_PFI_OUTPUT_RTSI0 = 18,
-               NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
-               NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
-               NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
-               NI_PFI_OUTPUT_CDI_SAMPLE = 29,
-               NI_PFI_OUTPUT_CDO_UPDATE = 30
-       };
-       static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
-       {
-               return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
-       }
+enum ni_pfi_routing {
+       NI_PFI_OUTPUT_PFI_DEFAULT = 0,
+       NI_PFI_OUTPUT_AI_START1 = 1,
+       NI_PFI_OUTPUT_AI_START2 = 2,
+       NI_PFI_OUTPUT_AI_CONVERT = 3,
+       NI_PFI_OUTPUT_G_SRC1 = 4,
+       NI_PFI_OUTPUT_G_GATE1 = 5,
+       NI_PFI_OUTPUT_AO_UPDATE_N = 6,
+       NI_PFI_OUTPUT_AO_START1 = 7,
+       NI_PFI_OUTPUT_AI_START_PULSE = 8,
+       NI_PFI_OUTPUT_G_SRC0 = 9,
+       NI_PFI_OUTPUT_G_GATE0 = 10,
+       NI_PFI_OUTPUT_EXT_STROBE = 11,
+       NI_PFI_OUTPUT_AI_EXT_MUX_CLK = 12,
+       NI_PFI_OUTPUT_GOUT0 = 13,
+       NI_PFI_OUTPUT_GOUT1 = 14,
+       NI_PFI_OUTPUT_FREQ_OUT = 15,
+       NI_PFI_OUTPUT_PFI_DO = 16,
+       NI_PFI_OUTPUT_I_ATRIG = 17,
+       NI_PFI_OUTPUT_RTSI0 = 18,
+       NI_PFI_OUTPUT_PXI_STAR_TRIGGER_IN = 26,
+       NI_PFI_OUTPUT_SCXI_TRIG1 = 27,
+       NI_PFI_OUTPUT_DIO_CHANGE_DETECT_RTSI = 28,
+       NI_PFI_OUTPUT_CDI_SAMPLE = 29,
+       NI_PFI_OUTPUT_CDO_UPDATE = 30
+};
+static inline unsigned NI_PFI_OUTPUT_RTSI(unsigned rtsi_channel)
+{
+       return NI_PFI_OUTPUT_RTSI0 + rtsi_channel;
+}
 
 /* Signals which can be routed to output on a NI PFI pin on a 660x board
  with INSN_CONFIG_SET_ROUTING.  The numbers assigned are
@@ -802,113 +802,112 @@ INSN_CONFIG_ARM */
  to program the board.  Lines 0 to 7 can only be set to
  NI_660X_PFI_OUTPUT_DIO.  Lines 32 to 39 can only be set to
  NI_660X_PFI_OUTPUT_COUNTER. */
-       enum ni_660x_pfi_routing {
-               NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
-               NI_660X_PFI_OUTPUT_DIO = 2,     /* static digital output */
-       };
+enum ni_660x_pfi_routing {
+       NI_660X_PFI_OUTPUT_COUNTER = 1, /* counter */
+       NI_660X_PFI_OUTPUT_DIO = 2,     /* static digital output */
+};
 
 /* NI External Trigger lines.  These values are not arbitrary, but are related
  * to the bits required to program the board (offset by 1 for historical
  * reasons). */
-       static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
-       {
-               return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
-       }
-       static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
-       {
-               return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
-       }
+static inline unsigned NI_EXT_PFI(unsigned pfi_channel)
+{
+       return NI_USUAL_PFI_SELECT(pfi_channel) - 1;
+}
+static inline unsigned NI_EXT_RTSI(unsigned rtsi_channel)
+{
+       return NI_USUAL_RTSI_SELECT(rtsi_channel) - 1;
+}
 
 /* status bits for INSN_CONFIG_GET_COUNTER_STATUS */
-       enum comedi_counter_status_flags {
-               COMEDI_COUNTER_ARMED = 0x1,
-               COMEDI_COUNTER_COUNTING = 0x2,
-               COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
-       };
+enum comedi_counter_status_flags {
+       COMEDI_COUNTER_ARMED = 0x1,
+       COMEDI_COUNTER_COUNTING = 0x2,
+       COMEDI_COUNTER_TERMINAL_COUNT = 0x4,
+};
 
 /* Clock sources for CDIO subdevice on NI m-series boards.  Used as the
  * scan_begin_arg for a comedi_command. These sources may also be bitwise-or'd
  * with CR_INVERT to change polarity. */
-       enum ni_m_series_cdio_scan_begin_src {
-               NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
-               NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
-               NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
-               NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
-               NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
-               NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
-               NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
-               NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
-               NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
-               NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
-       };
-       static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-       {
-               return NI_USUAL_PFI_SELECT(pfi_channel);
-       }
-       static inline unsigned
-               NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-       {
-               return NI_USUAL_RTSI_SELECT(rtsi_channel);
-       }
+enum ni_m_series_cdio_scan_begin_src {
+       NI_CDIO_SCAN_BEGIN_SRC_GROUND = 0,
+       NI_CDIO_SCAN_BEGIN_SRC_AI_START = 18,
+       NI_CDIO_SCAN_BEGIN_SRC_AI_CONVERT = 19,
+       NI_CDIO_SCAN_BEGIN_SRC_PXI_STAR_TRIGGER = 20,
+       NI_CDIO_SCAN_BEGIN_SRC_G0_OUT = 28,
+       NI_CDIO_SCAN_BEGIN_SRC_G1_OUT = 29,
+       NI_CDIO_SCAN_BEGIN_SRC_ANALOG_TRIGGER = 30,
+       NI_CDIO_SCAN_BEGIN_SRC_AO_UPDATE = 31,
+       NI_CDIO_SCAN_BEGIN_SRC_FREQ_OUT = 32,
+       NI_CDIO_SCAN_BEGIN_SRC_DIO_CHANGE_DETECT_IRQ = 33
+};
+static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
+{
+       return NI_USUAL_PFI_SELECT(pfi_channel);
+}
+static inline unsigned NI_CDIO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
+{
+       return NI_USUAL_RTSI_SELECT(rtsi_channel);
+}
 
 /* scan_begin_src for scan_begin_arg==TRIG_EXT with analog output command on NI
  * boards.  These scan begin sources can also be bitwise-or'd with CR_INVERT to
  * change polarity. */
-       static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
-       {
-               return NI_USUAL_PFI_SELECT(pfi_channel);
-       }
-       static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
-       {
-               return NI_USUAL_RTSI_SELECT(rtsi_channel);
-       }
+static inline unsigned NI_AO_SCAN_BEGIN_SRC_PFI(unsigned pfi_channel)
+{
+       return NI_USUAL_PFI_SELECT(pfi_channel);
+}
+static inline unsigned NI_AO_SCAN_BEGIN_SRC_RTSI(unsigned rtsi_channel)
+{
+       return NI_USUAL_RTSI_SELECT(rtsi_channel);
+}
 
 /* Bits for setting a clock source with
  * INSN_CONFIG_SET_CLOCK_SRC when using NI frequency output subdevice. */
-       enum ni_freq_out_clock_source_bits {
-               NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
-               NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC        /* 100 KHz */
-       };
+enum ni_freq_out_clock_source_bits {
+       NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC, /* 10 MHz */
+       NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC        /* 100 KHz */
+};
 
 /* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for
  * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
-       enum amplc_dio_clock_source {
-               AMPLC_DIO_CLK_CLKN,     /* per channel external clock
-                                          input/output pin (pin is only an
-                                          input when clock source set to this
-                                          value, otherwise it is an output) */
-               AMPLC_DIO_CLK_10MHZ,    /* 10 MHz internal clock */
-               AMPLC_DIO_CLK_1MHZ,     /* 1 MHz internal clock */
-               AMPLC_DIO_CLK_100KHZ,   /* 100 kHz internal clock */
-               AMPLC_DIO_CLK_10KHZ,    /* 10 kHz internal clock */
-               AMPLC_DIO_CLK_1KHZ,     /* 1 kHz internal clock */
-               AMPLC_DIO_CLK_OUTNM1,   /* output of preceding counter channel
-                                          (for channel 0, preceding counter
-                                          channel is channel 2 on preceding
-                                          counter subdevice, for first counter
-                                          subdevice, preceding counter
-                                          subdevice is the last counter
-                                          subdevice) */
-               AMPLC_DIO_CLK_EXT       /* per chip external input pin */
-       };
+enum amplc_dio_clock_source {
+       AMPLC_DIO_CLK_CLKN,     /* per channel external clock
+                                  input/output pin (pin is only an
+                                  input when clock source set to this
+                                  value, otherwise it is an output) */
+       AMPLC_DIO_CLK_10MHZ,    /* 10 MHz internal clock */
+       AMPLC_DIO_CLK_1MHZ,     /* 1 MHz internal clock */
+       AMPLC_DIO_CLK_100KHZ,   /* 100 kHz internal clock */
+       AMPLC_DIO_CLK_10KHZ,    /* 10 kHz internal clock */
+       AMPLC_DIO_CLK_1KHZ,     /* 1 kHz internal clock */
+       AMPLC_DIO_CLK_OUTNM1,   /* output of preceding counter channel
+                                  (for channel 0, preceding counter
+                                  channel is channel 2 on preceding
+                                  counter subdevice, for first counter
+                                  subdevice, preceding counter
+                                  subdevice is the last counter
+                                  subdevice) */
+       AMPLC_DIO_CLK_EXT       /* per chip external input pin */
+};
 
 /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for
  * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */
-       enum amplc_dio_gate_source {
-               AMPLC_DIO_GAT_VCC,      /* internal high logic level */
-               AMPLC_DIO_GAT_GND,      /* internal low logic level */
-               AMPLC_DIO_GAT_GATN,     /* per channel external gate input */
-               AMPLC_DIO_GAT_NOUTNM2,  /* negated output of counter channel
-                                          minus 2 (for channels 0 or 1,
-                                          channel minus 2 is channel 1 or 2 on
-                                          the preceding counter subdevice, for
-                                          the first counter subdevice the
-                                          preceding counter subdevice is the
-                                          last counter subdevice) */
-               AMPLC_DIO_GAT_RESERVED4,
-               AMPLC_DIO_GAT_RESERVED5,
-               AMPLC_DIO_GAT_RESERVED6,
-               AMPLC_DIO_GAT_RESERVED7
-       };
+enum amplc_dio_gate_source {
+       AMPLC_DIO_GAT_VCC,      /* internal high logic level */
+       AMPLC_DIO_GAT_GND,      /* internal low logic level */
+       AMPLC_DIO_GAT_GATN,     /* per channel external gate input */
+       AMPLC_DIO_GAT_NOUTNM2,  /* negated output of counter channel
+                                  minus 2 (for channels 0 or 1,
+                                  channel minus 2 is channel 1 or 2 on
+                                  the preceding counter subdevice, for
+                                  the first counter subdevice the
+                                  preceding counter subdevice is the
+                                  last counter subdevice) */
+       AMPLC_DIO_GAT_RESERVED4,
+       AMPLC_DIO_GAT_RESERVED5,
+       AMPLC_DIO_GAT_RESERVED6,
+       AMPLC_DIO_GAT_RESERVED7
+};
 
 #endif /* _COMEDI_H */
index 00d8d1fd6e89f3e012242bd15f3045bf955ae4af..c2a32cf95a82a76888810fed16708ea742be2317 100644 (file)
@@ -370,7 +370,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev,
                        return -ENOMEM;
 
                if (copy_from_user(aux_data,
-                                  comedi_aux_data(it.options, 0), aux_len)) {
+                                  (unsigned char __user *
+                                   )comedi_aux_data(it.options, 0), aux_len)) {
                        vfree(aux_data);
                        return -EFAULT;
                }
@@ -949,7 +950,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
                                ret = -EAGAIN;
                                break;
                        }
-                       ret = s->async->inttrig(dev, s, insn->data[0]);
+                       ret = s->async->inttrig(dev, s, data[0]);
                        if (ret >= 0)
                                ret = 1;
                        break;
@@ -1131,37 +1132,37 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s,
 }
 
 static int do_cmd_ioctl(struct comedi_device *dev,
-                       struct comedi_cmd __user *cmd, void *file)
+                       struct comedi_cmd __user *arg, void *file)
 {
-       struct comedi_cmd user_cmd;
+       struct comedi_cmd cmd;
        struct comedi_subdevice *s;
        struct comedi_async *async;
        int ret = 0;
-       unsigned int __user *chanlist_saver = NULL;
+       unsigned int __user *user_chanlist;
 
-       if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) {
+       if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                return -EFAULT;
        }
        /* save user's chanlist pointer so it can be restored later */
-       chanlist_saver = user_cmd.chanlist;
+       user_chanlist = (unsigned int __user *)cmd.chanlist;
 
-       if (user_cmd.subdev >= dev->n_subdevices) {
-               DPRINTK("%d no such subdevice\n", user_cmd.subdev);
+       if (cmd.subdev >= dev->n_subdevices) {
+               DPRINTK("%d no such subdevice\n", cmd.subdev);
                return -ENODEV;
        }
 
-       s = &dev->subdevices[user_cmd.subdev];
+       s = &dev->subdevices[cmd.subdev];
        async = s->async;
 
        if (s->type == COMEDI_SUBD_UNUSED) {
-               DPRINTK("%d not valid subdevice\n", user_cmd.subdev);
+               DPRINTK("%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",
-                       user_cmd.subdev);
+                       cmd.subdev);
                return -EIO;
        }
 
@@ -1179,23 +1180,22 @@ static int do_cmd_ioctl(struct comedi_device *dev,
        s->busy = file;
 
        /* make sure channel/gain list isn't too long */
-       if (user_cmd.chanlist_len > s->len_chanlist) {
+       if (cmd.chanlist_len > s->len_chanlist) {
                DPRINTK("channel/gain list too long %u > %d\n",
-                       user_cmd.chanlist_len, s->len_chanlist);
+                       cmd.chanlist_len, s->len_chanlist);
                ret = -EINVAL;
                goto cleanup;
        }
 
        /* make sure channel/gain list isn't too short */
-       if (user_cmd.chanlist_len < 1) {
+       if (cmd.chanlist_len < 1) {
                DPRINTK("channel/gain list too short %u < 1\n",
-                       user_cmd.chanlist_len);
+                       cmd.chanlist_len);
                ret = -EINVAL;
                goto cleanup;
        }
 
-       kfree(async->cmd.chanlist);
-       async->cmd = user_cmd;
+       async->cmd = cmd;
        async->cmd.data = NULL;
        /* load channel/gain list */
        async->cmd.chanlist =
@@ -1206,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev,
                goto cleanup;
        }
 
-       if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist,
+       if (copy_from_user(async->cmd.chanlist, user_chanlist,
                           async->cmd.chanlist_len * sizeof(int))) {
                DPRINTK("fault reading chanlist\n");
                ret = -EFAULT;
@@ -1226,11 +1226,11 @@ static int do_cmd_ioctl(struct comedi_device *dev,
 
        if (async->cmd.flags & TRIG_BOGUS || ret) {
                DPRINTK("test returned %d\n", ret);
-               user_cmd = async->cmd;
+               cmd = async->cmd;
                /* restore chanlist pointer before copying back */
-               user_cmd.chanlist = chanlist_saver;
-               user_cmd.data = NULL;
-               if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) {
+               cmd.chanlist = (unsigned int __force *)user_chanlist;
+               cmd.data = NULL;
+               if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
                        DPRINTK("fault writing cmd\n");
                        ret = -EFAULT;
                        goto cleanup;
@@ -1283,77 +1283,77 @@ cleanup:
 static int do_cmdtest_ioctl(struct comedi_device *dev,
                            struct comedi_cmd __user *arg, void *file)
 {
-       struct comedi_cmd user_cmd;
+       struct comedi_cmd cmd;
        struct comedi_subdevice *s;
        int ret = 0;
        unsigned int *chanlist = NULL;
-       unsigned int __user *chanlist_saver = NULL;
+       unsigned int __user *user_chanlist;
 
-       if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
+       if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                return -EFAULT;
        }
        /* save user's chanlist pointer so it can be restored later */
-       chanlist_saver = user_cmd.chanlist;
+       user_chanlist = (unsigned int __user *)cmd.chanlist;
 
-       if (user_cmd.subdev >= dev->n_subdevices) {
-               DPRINTK("%d no such subdevice\n", user_cmd.subdev);
+       if (cmd.subdev >= dev->n_subdevices) {
+               DPRINTK("%d no such subdevice\n", cmd.subdev);
                return -ENODEV;
        }
 
-       s = &dev->subdevices[user_cmd.subdev];
+       s = &dev->subdevices[cmd.subdev];
        if (s->type == COMEDI_SUBD_UNUSED) {
-               DPRINTK("%d not valid subdevice\n", user_cmd.subdev);
+               DPRINTK("%d not valid subdevice\n", cmd.subdev);
                return -EIO;
        }
 
        if (!s->do_cmd || !s->do_cmdtest) {
                DPRINTK("subdevice %i does not support commands\n",
-                       user_cmd.subdev);
+                       cmd.subdev);
                return -EIO;
        }
 
        /* make sure channel/gain list isn't too long */
-       if (user_cmd.chanlist_len > s->len_chanlist) {
+       if (cmd.chanlist_len > s->len_chanlist) {
                DPRINTK("channel/gain list too long %d > %d\n",
-                       user_cmd.chanlist_len, s->len_chanlist);
+                       cmd.chanlist_len, s->len_chanlist);
                ret = -EINVAL;
                goto cleanup;
        }
 
        /* load channel/gain list */
-       if (user_cmd.chanlist) {
+       if (cmd.chanlist) {
                chanlist =
-                   kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL);
+                   kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL);
                if (!chanlist) {
                        DPRINTK("allocation failed\n");
                        ret = -ENOMEM;
                        goto cleanup;
                }
 
-               if (copy_from_user(chanlist, user_cmd.chanlist,
-                                  user_cmd.chanlist_len * sizeof(int))) {
+               if (copy_from_user(chanlist, user_chanlist,
+                                  cmd.chanlist_len * sizeof(int))) {
                        DPRINTK("fault reading chanlist\n");
                        ret = -EFAULT;
                        goto cleanup;
                }
 
                /* make sure each element in channel/gain list is valid */
-               ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist);
+               ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist);
                if (ret < 0) {
                        DPRINTK("bad chanlist\n");
                        goto cleanup;
                }
 
-               user_cmd.chanlist = chanlist;
+               cmd.chanlist = chanlist;
        }
 
-       ret = s->do_cmdtest(dev, s, &user_cmd);
+       ret = s->do_cmdtest(dev, s, &cmd);
 
        /* restore chanlist pointer before copying back */
-       user_cmd.chanlist = chanlist_saver;
+       cmd.chanlist = (unsigned int __force *)user_chanlist;
 
-       if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
+       if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                ret = -EFAULT;
                goto cleanup;
@@ -2032,6 +2032,8 @@ static void do_become_nonbusy(struct comedi_device *dev,
        if (async) {
                comedi_reset_async_buf(async);
                async->inttrig = NULL;
+               kfree(async->cmd.chanlist);
+               async->cmd.chanlist = NULL;
        } else {
                dev_err(dev->class_dev,
                        "BUG: (?) do_become_nonbusy called with async=NULL\n");
index 2c21dbd89455361debf6979755921bb9fbef0df9..1db6bfdbf13bd70695492f3cabea51ca7a325e43 100644 (file)
@@ -415,7 +415,6 @@ static int insn_rw_emulate_bits(struct comedi_device *dev,
        new_insn.insn = INSN_BITS;
        new_insn.chanspec = base_bitfield_channel;
        new_insn.n = 2;
-       new_insn.data = new_data;
        new_insn.subdev = insn->subdev;
 
        if (insn->insn == INSN_WRITE) {
index 3eb45d46e05b77f109b0e590d9daa524a7d0df4e..429e0d60c0a3836bfb3770980257a6bfb1c31c31 100644 (file)
@@ -262,8 +262,10 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift,
        return 0;
 }
 
-static inline int i8254_mm_load(void *base_address, unsigned int regshift,
-                               unsigned int counter_number, unsigned int count,
+static inline int i8254_mm_load(void __iomem *base_address,
+                               unsigned int regshift,
+                               unsigned int counter_number,
+                               unsigned int count,
                                unsigned int mode)
 {
        unsigned int byte;
@@ -311,7 +313,8 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift,
        return ret;
 }
 
-static inline int i8254_mm_read(void *base_address, unsigned int regshift,
+static inline int i8254_mm_read(void __iomem *base_address,
+                               unsigned int regshift,
                                unsigned int counter_number)
 {
        unsigned int byte;
@@ -348,7 +351,7 @@ static inline void i8254_write(unsigned long base_address,
        outb(byte, base_address + (counter_number << regshift));
 }
 
-static inline void i8254_mm_write(void *base_address,
+static inline void i8254_mm_write(void __iomem *base_address,
                                  unsigned int regshift,
                                  unsigned int counter_number,
                                  unsigned int count)
@@ -390,7 +393,7 @@ static inline int i8254_set_mode(unsigned long base_address,
        return 0;
 }
 
-static inline int i8254_mm_set_mode(void *base_address,
+static inline int i8254_mm_set_mode(void __iomem *base_address,
                                    unsigned int regshift,
                                    unsigned int counter_number,
                                    unsigned int mode)
@@ -419,7 +422,7 @@ static inline int i8254_status(unsigned long base_address,
        return inb(base_address + (counter_number << regshift));
 }
 
-static inline int i8254_mm_status(void *base_address,
+static inline int i8254_mm_status(void __iomem *base_address,
                                  unsigned int regshift,
                                  unsigned int counter_number)
 {
index 39a2b1eed8117673423264d37cf6b11344c6fe6a..d13c8c5822bf4dade515d951181feed4f4bea118 100644 (file)
@@ -31,16 +31,10 @@ Devices: [IOTech] DAQBoard/2000 (daqboard2000)
 Much of the functionality of this driver was determined from reading
 the source code for the Windows driver.
 
-The FPGA on the board requires initialization code, which can
-be loaded by comedi_config using the -i
-option.  The initialization code is available from http://www.comedi.org
-in the comedi_nonfree_firmware tarball.
-
-Configuration options:
-  [0] - PCI bus of device (optional)
-  [1] - PCI slot of device (optional)
-  If bus/slot is not specified, the first supported
-  PCI device found will be used.
+The FPGA on the board requires fimware, which is available from
+http://www.comedi.org in the comedi_nonfree_firmware tarball.
+
+Configuration options: not applicable, uses PCI auto config
 */
 /*
    This card was obviously never intended to leave the Windows world,
@@ -117,17 +111,17 @@ Configuration options:
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/firmware.h>
 
 #include "8255.h"
 
+#define DAQBOARD2000_FIRMWARE          "daqboard2000_firmware.bin"
+
 #define PCI_VENDOR_ID_IOTECH           0x1616
 
 #define DAQBOARD2000_SUBSYSTEM_IDS2    0x0002  /* Daqboard/2000 - 2 Dacs */
 #define DAQBOARD2000_SUBSYSTEM_IDS4    0x0004  /* Daqboard/2000 - 4 Dacs */
 
-#define DAQBOARD2000_DAQ_SIZE          0x1002
-#define DAQBOARD2000_PLX_SIZE          0x100
-
 /* Initialization bits for the Serial EEPROM Control Register */
 #define DAQBOARD2000_SECRProgPinHi      0x8001767e
 #define DAQBOARD2000_SECRProgPinLo      0x8000767e
@@ -143,85 +137,56 @@ Configuration options:
 #define DAQBOARD2000_CPLD_INIT                 0x0002
 #define DAQBOARD2000_CPLD_DONE                 0x0004
 
-/* Available ranges */
-static const struct comedi_lrange range_daqboard2000_ai = { 13, {
-                                                                RANGE(-10, 10),
-                                                                RANGE(-5, 5),
-                                                                RANGE(-2.5,
-                                                                      2.5),
-                                                                RANGE(-1.25,
-                                                                      1.25),
-                                                                RANGE(-0.625,
-                                                                      0.625),
-                                                                RANGE(-0.3125,
-                                                                      0.3125),
-                                                                RANGE(-0.156,
-                                                                      0.156),
-                                                                RANGE(0, 10),
-                                                                RANGE(0, 5),
-                                                                RANGE(0, 2.5),
-                                                                RANGE(0, 1.25),
-                                                                RANGE(0,
-                                                                      0.625),
-                                                                RANGE(0,
-                                                                      0.3125)
-                                                                }
-};
-
-static const struct comedi_lrange range_daqboard2000_ao = { 1, {
-                                                               RANGE(-10, 10)
-                                                               }
+static const struct comedi_lrange range_daqboard2000_ai = {
+       13, {
+               BIP_RANGE(10),
+               BIP_RANGE(5),
+               BIP_RANGE(2.5),
+               BIP_RANGE(1.25),
+               BIP_RANGE(0.625),
+               BIP_RANGE(0.3125),
+               BIP_RANGE(0.156),
+               UNI_RANGE(10),
+               UNI_RANGE(5),
+               UNI_RANGE(2.5),
+               UNI_RANGE(1.25),
+               UNI_RANGE(0.625),
+               UNI_RANGE(0.3125)
+       }
 };
 
-struct daqboard2000_hw {
-       volatile u16 acqControl;        /*  0x00 */
-       volatile u16 acqScanListFIFO;   /*  0x02 */
-       volatile u32 acqPacerClockDivLow;       /*  0x04 */
-
-       volatile u16 acqScanCounter;    /*  0x08 */
-       volatile u16 acqPacerClockDivHigh;      /*  0x0a */
-       volatile u16 acqTriggerCount;   /*  0x0c */
-       volatile u16 fill2;     /*  0x0e */
-       volatile u16 acqResultsFIFO;    /*  0x10 */
-       volatile u16 fill3;     /*  0x12 */
-       volatile u16 acqResultsShadow;  /*  0x14 */
-       volatile u16 fill4;     /*  0x16 */
-       volatile u16 acqAdcResult;      /*  0x18 */
-       volatile u16 fill5;     /*  0x1a */
-       volatile u16 dacScanCounter;    /*  0x1c */
-       volatile u16 fill6;     /*  0x1e */
-
-       volatile u16 dacControl;        /*  0x20 */
-       volatile u16 fill7;     /*  0x22 */
-       volatile s16 dacFIFO;   /*  0x24 */
-       volatile u16 fill8[2];  /*  0x26 */
-       volatile u16 dacPacerClockDiv;  /*  0x2a */
-       volatile u16 refDacs;   /*  0x2c */
-       volatile u16 fill9;     /*  0x2e */
-
-       volatile u16 dioControl;        /*  0x30 */
-       volatile s16 dioP3hsioData;     /*  0x32 */
-       volatile u16 dioP3Control;      /*  0x34 */
-       volatile u16 calEepromControl;  /*  0x36 */
-       volatile s16 dacSetting[4];     /*  0x38 */
-       volatile s16 dioP2ExpansionIO8Bit[32];  /*  0x40 */
-
-       volatile u16 ctrTmrControl;     /*  0x80 */
-       volatile u16 fill10[3]; /*  0x82 */
-       volatile s16 ctrInput[4];       /*  0x88 */
-       volatile u16 fill11[8]; /*  0x90 */
-       volatile u16 timerDivisor[2];   /*  0xa0 */
-       volatile u16 fill12[6]; /*  0xa4 */
-
-       volatile u16 dmaControl;        /*  0xb0 */
-       volatile u16 trigControl;       /*  0xb2 */
-       volatile u16 fill13[2]; /*  0xb4 */
-       volatile u16 calEeprom; /*  0xb8 */
-       volatile u16 acqDigitalMark;    /*  0xba */
-       volatile u16 trigDacs;  /*  0xbc */
-       volatile u16 fill14;    /*  0xbe */
-       volatile s16 dioP2ExpansionIO16Bit[32]; /*  0xc0 */
-};
+/*
+ * Register Memory Map
+ */
+#define acqControl                     0x00            /* u16 */
+#define acqScanListFIFO                        0x02            /* u16 */
+#define acqPacerClockDivLow            0x04            /* u32 */
+#define acqScanCounter                 0x08            /* u16 */
+#define acqPacerClockDivHigh           0x0a            /* u16 */
+#define acqTriggerCount                        0x0c            /* u16 */
+#define acqResultsFIFO                 0x10            /* u16 */
+#define acqResultsShadow               0x14            /* u16 */
+#define acqAdcResult                   0x18            /* u16 */
+#define dacScanCounter                 0x1c            /* u16 */
+#define dacControl                     0x20            /* u16 */
+#define dacFIFO                                0x24            /* s16 */
+#define dacPacerClockDiv               0x2a            /* u16 */
+#define refDacs                                0x2c            /* u16 */
+#define dioControl                     0x30            /* u16 */
+#define dioP3hsioData                  0x32            /* s16 */
+#define dioP3Control                   0x34            /* u16 */
+#define calEepromControl               0x36            /* u16 */
+#define dacSetting(x)                  (0x38 + (x)*2)  /* s16 */
+#define dioP2ExpansionIO8Bit           0x40            /* s16 */
+#define ctrTmrControl                  0x80            /* u16 */
+#define ctrInput(x)                    (0x88 + (x)*2)  /* s16 */
+#define timerDivisor(x)                        (0xa0 + (x)*2)  /* u16 */
+#define dmaControl                     0xb0            /* u16 */
+#define trigControl                    0xb2            /* u16 */
+#define calEeprom                      0xb8            /* u16 */
+#define acqDigitalMark                 0xba            /* u16 */
+#define trigDacs                       0xbc            /* u16 */
+#define dioP2ExpansionIO16Bit(x)       (0xc0 + (x)*2)  /* s16 */
 
 /* Scan Sequencer programming */
 #define DAQBOARD2000_SeqStartScanList            0x0011
@@ -311,27 +276,23 @@ static const struct daq200_boardtype boardtypes[] = {
        {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4},
 };
 
-#define this_board ((const struct daq200_boardtype *)dev->board_ptr)
-
 struct daqboard2000_private {
        enum {
                card_daqboard_2000
        } card;
-       void *daq;
+       void __iomem *daq;
        void __iomem *plx;
        unsigned int ao_readback[2];
 };
 
-#define devpriv ((struct daqboard2000_private *)dev->private)
-
 static void writeAcqScanListEntry(struct comedi_device *dev, u16 entry)
 {
-       struct daqboard2000_hw *fpga = devpriv->daq;
+       struct daqboard2000_private *devpriv = dev->private;
 
-/* udelay(4); */
-       fpga->acqScanListFIFO = entry & 0x00ff;
-/* udelay(4); */
-       fpga->acqScanListFIFO = (entry >> 8) & 0x00ff;
+       /* udelay(4); */
+       writew(entry & 0x00ff, devpriv->daq + acqScanListFIFO);
+       /* udelay(4); */
+       writew((entry >> 8) & 0x00ff, devpriv->daq + acqScanListFIFO);
 }
 
 static void setup_sampling(struct comedi_device *dev, int chan, int gain)
@@ -372,7 +333,6 @@ static void setup_sampling(struct comedi_device *dev, int chan, int gain)
        /* These should be read from EEPROM */
        word2 |= 0x0800;
        word3 |= 0xc000;
-/*  printk("%d %4.4x %4.4x %4.4x %4.4x\n", chan, word0, word1, word2, word3);*/
        writeAcqScanListEntry(dev, word0);
        writeAcqScanListEntry(dev, word1);
        writeAcqScanListEntry(dev, word2);
@@ -384,21 +344,22 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
                                     struct comedi_insn *insn,
                                     unsigned int *data)
 {
-       int i;
-       struct daqboard2000_hw *fpga = devpriv->daq;
+       struct daqboard2000_private *devpriv = dev->private;
+       unsigned int val;
        int gain, chan, timeout;
+       int i;
 
-       fpga->acqControl =
-           DAQBOARD2000_AcqResetScanListFifo |
-           DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe;
+       writew(DAQBOARD2000_AcqResetScanListFifo |
+              DAQBOARD2000_AcqResetResultsFifo |
+              DAQBOARD2000_AcqResetConfigPipe, devpriv->daq + acqControl);
 
        /*
         * If pacer clock is not set to some high value (> 10 us), we
         * risk multiple samples to be put into the result FIFO.
         */
        /* 1 second, should be long enough */
-       fpga->acqPacerClockDivLow = 1000000;
-       fpga->acqPacerClockDivHigh = 0;
+       writel(1000000, devpriv->daq + acqPacerClockDivLow);
+       writew(0, devpriv->daq + acqPacerClockDivHigh);
 
        gain = CR_RANGE(insn->chanspec);
        chan = CR_CHAN(insn->chanspec);
@@ -410,28 +371,30 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev,
        for (i = 0; i < insn->n; i++) {
                setup_sampling(dev, chan, gain);
                /* Enable reading from the scanlist FIFO */
-               fpga->acqControl = DAQBOARD2000_SeqStartScanList;
+               writew(DAQBOARD2000_SeqStartScanList,
+                      devpriv->daq + acqControl);
                for (timeout = 0; timeout < 20; timeout++) {
-                       if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull)
+                       val = readw(devpriv->daq + acqControl);
+                       if (val & DAQBOARD2000_AcqConfigPipeFull)
                                break;
                        /* udelay(2); */
                }
-               fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
+               writew(DAQBOARD2000_AdcPacerEnable, devpriv->daq + acqControl);
                for (timeout = 0; timeout < 20; timeout++) {
-                       if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning)
+                       val = readw(devpriv->daq + acqControl);
+                       if (val & DAQBOARD2000_AcqLogicScanning)
                                break;
                        /* udelay(2); */
                }
                for (timeout = 0; timeout < 20; timeout++) {
-                       if (fpga->acqControl &
-                           DAQBOARD2000_AcqResultsFIFOHasValidData) {
+                       val = readw(devpriv->daq + acqControl);
+                       if (val & DAQBOARD2000_AcqResultsFIFOHasValidData)
                                break;
-                       }
                        /* udelay(2); */
                }
-               data[i] = fpga->acqResultsFIFO;
-               fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
-               fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+               data[i] = readw(devpriv->daq + acqResultsFIFO);
+               writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
+               writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
        }
 
        return i;
@@ -442,8 +405,9 @@ static int daqboard2000_ao_insn_read(struct comedi_device *dev,
                                     struct comedi_insn *insn,
                                     unsigned int *data)
 {
-       int i;
+       struct daqboard2000_private *devpriv = dev->private;
        int chan = CR_CHAN(insn->chanspec);
+       int i;
 
        for (i = 0; i < insn->n; i++)
                data[i] = devpriv->ao_readback[chan];
@@ -456,28 +420,39 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
                                      struct comedi_insn *insn,
                                      unsigned int *data)
 {
-       int i;
+       struct daqboard2000_private *devpriv = dev->private;
        int chan = CR_CHAN(insn->chanspec);
-       struct daqboard2000_hw *fpga = devpriv->daq;
+       unsigned int val;
        int timeout;
+       int i;
 
        for (i = 0; i < insn->n; i++) {
+#if 0
                /*
-                * OK, since it works OK without enabling the DAC's, let's keep
-                * it as simple as possible...
+                * OK, since it works OK without enabling the DAC's,
+                * let's keep it as simple as possible...
                 */
-               /* fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; udelay(1000); */
-               fpga->dacSetting[chan] = data[i];
+               writew((chan + 2) * 0x0010 | 0x0001,
+                      devpriv->daq + dacControl);
+               udelay(1000);
+#endif
+               writew(data[i], devpriv->daq + dacSetting(chan));
                for (timeout = 0; timeout < 20; timeout++) {
-                       if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0)
+                       val = readw(devpriv->daq + dacControl);
+                       if ((val & ((chan + 1) * 0x0010)) == 0)
                                break;
                        /* udelay(2); */
                }
                devpriv->ao_readback[chan] = data[i];
+#if 0
                /*
-                * Since we never enabled the DAC's, we don't need to disable it...
-                * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; udelay(1000);
+                * Since we never enabled the DAC's, we don't need
+                * to disable it...
                 */
+               writew((chan + 2) * 0x0010 | 0x0000,
+                      devpriv->daq + dacControl);
+               udelay(1000);
+#endif
        }
 
        return i;
@@ -485,7 +460,8 @@ static int daqboard2000_ao_insn_write(struct comedi_device *dev,
 
 static void daqboard2000_resetLocalBus(struct comedi_device *dev)
 {
-       dev_dbg(dev->class_dev, "daqboard2000_resetLocalBus\n");
+       struct daqboard2000_private *devpriv = dev->private;
+
        writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
        udelay(10000);
        writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
@@ -494,7 +470,8 @@ static void daqboard2000_resetLocalBus(struct comedi_device *dev)
 
 static void daqboard2000_reloadPLX(struct comedi_device *dev)
 {
-       dev_dbg(dev->class_dev, "daqboard2000_reloadPLX\n");
+       struct daqboard2000_private *devpriv = dev->private;
+
        writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
        udelay(10000);
        writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
@@ -505,7 +482,8 @@ static void daqboard2000_reloadPLX(struct comedi_device *dev)
 
 static void daqboard2000_pulseProgPin(struct comedi_device *dev)
 {
-       dev_dbg(dev->class_dev, "daqboard2000_pulseProgPin 1\n");
+       struct daqboard2000_private *devpriv = dev->private;
+
        writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
        udelay(10000);
        writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
@@ -514,6 +492,7 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
 
 static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
 {
+       struct daqboard2000_private *devpriv = dev->private;
        int result = 0;
        int i;
        int cpld;
@@ -533,6 +512,7 @@ static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
 
 static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
 {
+       struct daqboard2000_private *devpriv = dev->private;
        int result = 0;
 
        udelay(10);
@@ -545,41 +525,29 @@ static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
 }
 
 static int initialize_daqboard2000(struct comedi_device *dev,
-                                  unsigned char *cpld_array, int len)
+                                  const u8 *cpld_array, size_t len)
 {
+       struct daqboard2000_private *devpriv = dev->private;
        int result = -EIO;
        /* Read the serial EEPROM control register */
        int secr;
        int retry;
-       int i;
+       size_t i;
 
        /* Check to make sure the serial eeprom is present on the board */
        secr = readl(devpriv->plx + 0x6c);
-       if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {
-#ifdef DEBUG_EEPROM
-               dev_dbg(dev->class_dev, "no serial eeprom\n");
-#endif
+       if (!(secr & DAQBOARD2000_EEPROM_PRESENT))
                return -EIO;
-       }
 
        for (retry = 0; retry < 3; retry++) {
-#ifdef DEBUG_EEPROM
-               dev_dbg(dev->class_dev, "Programming EEPROM try %x\n", retry);
-#endif
-
                daqboard2000_resetLocalBus(dev);
                daqboard2000_reloadPLX(dev);
                daqboard2000_pulseProgPin(dev);
                if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
                        for (i = 0; i < len; i++) {
-                               if (cpld_array[i] == 0xff
-                                   && cpld_array[i + 1] == 0x20) {
-#ifdef DEBUG_EEPROM
-                                       dev_dbg(dev->class_dev,
-                                               "Preamble found at %d\n", i);
-#endif
+                               if (cpld_array[i] == 0xff &&
+                                   cpld_array[i + 1] == 0x20)
                                        break;
-                               }
                        }
                        for (; i < len; i += 2) {
                                int data =
@@ -588,9 +556,6 @@ static int initialize_daqboard2000(struct comedi_device *dev,
                                        break;
                        }
                        if (i >= len) {
-#ifdef DEBUG_EEPROM
-                               dev_dbg(dev->class_dev, "Programmed\n");
-#endif
                                daqboard2000_resetLocalBus(dev);
                                daqboard2000_reloadPLX(dev);
                                result = 0;
@@ -601,28 +566,45 @@ static int initialize_daqboard2000(struct comedi_device *dev,
        return result;
 }
 
+static int daqboard2000_upload_firmware(struct comedi_device *dev)
+{
+       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+       const struct firmware *fw;
+       int ret;
+
+       ret = request_firmware(&fw, DAQBOARD2000_FIRMWARE, &pcidev->dev);
+       if (ret)
+               return ret;
+
+       ret = initialize_daqboard2000(dev, fw->data, fw->size);
+       release_firmware(fw);
+
+       return ret;
+}
+
 static void daqboard2000_adcStopDmaTransfer(struct comedi_device *dev)
 {
-/*  printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/
 }
 
 static void daqboard2000_adcDisarm(struct comedi_device *dev)
 {
-       struct daqboard2000_hw *fpga = devpriv->daq;
+       struct daqboard2000_private *devpriv = dev->private;
 
        /* Disable hardware triggers */
        udelay(2);
-       fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable;
+       writew(DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable,
+              devpriv->daq + trigControl);
        udelay(2);
-       fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable;
+       writew(DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable,
+              devpriv->daq + trigControl);
 
        /* Stop the scan list FIFO from loading the configuration pipe */
        udelay(2);
-       fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+       writew(DAQBOARD2000_SeqStopScanList, devpriv->daq + acqControl);
 
        /* Stop the pacer clock */
        udelay(2);
-       fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+       writew(DAQBOARD2000_AdcPacerDisable, devpriv->daq + acqControl);
 
        /* Stop the input dma (abort channel 1) */
        daqboard2000_adcStopDmaTransfer(dev);
@@ -630,41 +612,39 @@ static void daqboard2000_adcDisarm(struct comedi_device *dev)
 
 static void daqboard2000_activateReferenceDacs(struct comedi_device *dev)
 {
-       struct daqboard2000_hw *fpga = devpriv->daq;
+       struct daqboard2000_private *devpriv = dev->private;
+       unsigned int val;
        int timeout;
 
        /*  Set the + reference dac value in the FPGA */
-       fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;
+       writew(0x80 | DAQBOARD2000_PosRefDacSelect, devpriv->daq + refDacs);
        for (timeout = 0; timeout < 20; timeout++) {
-               if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0)
+               val = readw(devpriv->daq + dacControl);
+               if ((val & DAQBOARD2000_RefBusy) == 0)
                        break;
                udelay(2);
        }
-/*  printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/
 
        /*  Set the - reference dac value in the FPGA */
-       fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;
+       writew(0x80 | DAQBOARD2000_NegRefDacSelect, devpriv->daq + refDacs);
        for (timeout = 0; timeout < 20; timeout++) {
-               if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0)
+               val = readw(devpriv->daq + dacControl);
+               if ((val & DAQBOARD2000_RefBusy) == 0)
                        break;
                udelay(2);
        }
-/*  printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/
 }
 
 static void daqboard2000_initializeCtrs(struct comedi_device *dev)
 {
-/*  printk("Implement: daqboard2000_initializeCtrs\n");*/
 }
 
 static void daqboard2000_initializeTmrs(struct comedi_device *dev)
 {
-/*  printk("Implement: daqboard2000_initializeTmrs\n");*/
 }
 
 static void daqboard2000_dacDisarm(struct comedi_device *dev)
 {
-/*  printk("Implement: daqboard2000_dacDisarm\n");*/
 }
 
 static void daqboard2000_initializeAdc(struct comedi_device *dev)
@@ -680,92 +660,66 @@ static void daqboard2000_initializeDac(struct comedi_device *dev)
        daqboard2000_dacDisarm(dev);
 }
 
-/*
-The test command, REMOVE!!:
-
-rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages
-*/
-
 static int daqboard2000_8255_cb(int dir, int port, int data,
                                unsigned long ioaddr)
 {
-       int result = 0;
+       void __iomem *mmio_base = (void __iomem *)ioaddr;
+
        if (dir) {
-               writew(data, ((void *)ioaddr) + port * 2);
-               result = 0;
+               writew(data, mmio_base + port * 2);
+               return 0;
        } else {
-               result = readw(((void *)ioaddr) + port * 2);
+               return readw(mmio_base + port * 2);
        }
-/*
-  printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n",
-        arg, dir, port, data, result);
-*/
-       return result;
 }
 
-static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev,
-                                                struct comedi_devconfig *it)
+static const void *daqboard2000_find_boardinfo(struct comedi_device *dev,
+                                              struct pci_dev *pcidev)
 {
-       struct pci_dev *pcidev = NULL;
-       int bus = it->options[0];
-       int slot = it->options[1];
+       const struct daq200_boardtype *board;
        int i;
 
-       for_each_pci_dev(pcidev) {
-               if (bus || slot) {
-                       if (bus != pcidev->bus->number ||
-                           slot != PCI_SLOT(pcidev->devfn))
-                               continue;
-               }
-               if (pcidev->vendor != PCI_VENDOR_ID_IOTECH ||
-                   pcidev->device != 0x0409 ||
-                   pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH)
-                       continue;
-
-               for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
-                       if (boardtypes[i].id != pcidev->subsystem_device)
-                               continue;
-                       dev->board_ptr = boardtypes + i;
-                       return pcidev;
-               }
+       if (pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH)
+               return NULL;
+
+       for (i = 0; i < ARRAY_SIZE(boardtypes); i++) {
+               board = &boardtypes[i];
+               if (pcidev->subsystem_device == board->id)
+                       return board;
        }
-       dev_err(dev->class_dev,
-               "No supported board found! (req. bus %d, slot %d)\n",
-               bus, slot);
        return NULL;
 }
 
-static int daqboard2000_attach(struct comedi_device *dev,
-                              struct comedi_devconfig *it)
+static int daqboard2000_attach_pci(struct comedi_device *dev,
+                                  struct pci_dev *pcidev)
 {
-       struct pci_dev *pcidev;
+       const struct daq200_boardtype *board;
+       struct daqboard2000_private *devpriv;
        struct comedi_subdevice *s;
-       resource_size_t pci_base;
-       void *aux_data;
-       unsigned int aux_len;
        int result;
 
-       result = alloc_private(dev, sizeof(struct daqboard2000_private));
+       comedi_set_hw_dev(dev, &pcidev->dev);
+
+       board = daqboard2000_find_boardinfo(dev, pcidev);
+       if (!board)
+               return -ENODEV;
+       dev->board_ptr = board;
+       dev->board_name = board->name;
+
+       result = alloc_private(dev, sizeof(*devpriv));
        if (result < 0)
                return -ENOMEM;
+       devpriv = dev->private;
 
-       pcidev = daqboard2000_find_pci_dev(dev, it);
-       if (!pcidev)
-               return -EIO;
-       comedi_set_hw_dev(dev, &pcidev->dev);
-
-       result = comedi_pci_enable(pcidev, "daqboard2000");
-       if (result < 0) {
-               dev_err(dev->class_dev,
-                       "failed to enable PCI device and request regions\n");
-               return -EIO;
-       }
+       result = comedi_pci_enable(pcidev, dev->driver->driver_name);
+       if (result < 0)
+               return result;
        dev->iobase = 1;        /* the "detach" needs this */
 
-       pci_base = pci_resource_start(pcidev, 0);
-       devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE);
-       pci_base = pci_resource_start(pcidev, 2);
-       devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE);
+       devpriv->plx = ioremap(pci_resource_start(pcidev, 0),
+                              pci_resource_len(pcidev, 0));
+       devpriv->daq = ioremap(pci_resource_start(pcidev, 2),
+                              pci_resource_len(pcidev, 2));
        if (!devpriv->plx || !devpriv->daq)
                return -ENOMEM;
 
@@ -775,34 +729,12 @@ static int daqboard2000_attach(struct comedi_device *dev,
 
        readl(devpriv->plx + 0x6c);
 
-       /*
-          u8 interrupt;
-          Windows code does restore interrupts, but since we don't use them...
-          pci_read_config_byte(pcidev, PCI_INTERRUPT_LINE, &interrupt);
-          printk("Interrupt before is: %x\n", interrupt);
-        */
-
-       aux_data = comedi_aux_data(it->options, 0);
-       aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
-
-       if (aux_data && aux_len) {
-               result = initialize_daqboard2000(dev, aux_data, aux_len);
-       } else {
-               dev_dbg(dev->class_dev,
-                       "no FPGA initialization code, aborting\n");
-               result = -EIO;
-       }
+       result = daqboard2000_upload_firmware(dev);
        if (result < 0)
-               goto out;
+               return result;
+
        daqboard2000_initializeAdc(dev);
        daqboard2000_initializeDac(dev);
-       /*
-          Windows code does restore interrupts, but since we don't use them...
-          pci_read_config_byte(pcidev, PCI_INTERRUPT_LINE, &interrupt);
-          printk("Interrupt after is: %x\n", interrupt);
-        */
-
-       dev->board_name = this_board->name;
 
        s = &dev->subdevices[0];
        /* ai subdevice */
@@ -821,19 +753,24 @@ static int daqboard2000_attach(struct comedi_device *dev,
        s->maxdata = 0xffff;
        s->insn_read = daqboard2000_ao_insn_read;
        s->insn_write = daqboard2000_ao_insn_write;
-       s->range_table = &range_daqboard2000_ao;
+       s->range_table = &range_bipolar10;
 
        s = &dev->subdevices[2];
        result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
-                                 (unsigned long)(devpriv->daq + 0x40));
+                       (unsigned long)(devpriv->daq + dioP2ExpansionIO8Bit));
+       if (result)
+               return result;
 
-out:
-       return result;
+       dev_info(dev->class_dev, "%s: %s attached\n",
+               dev->driver->driver_name, dev->board_name);
+
+       return 0;
 }
 
 static void daqboard2000_detach(struct comedi_device *dev)
 {
        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+       struct daqboard2000_private *devpriv = dev->private;
 
        if (dev->subdevices)
                subdev_8255_cleanup(dev, &dev->subdevices[2]);
@@ -855,7 +792,7 @@ static void daqboard2000_detach(struct comedi_device *dev)
 static struct comedi_driver daqboard2000_driver = {
        .driver_name    = "daqboard2000",
        .module         = THIS_MODULE,
-       .attach         = daqboard2000_attach,
+       .attach_pci     = daqboard2000_attach_pci,
        .detach         = daqboard2000_detach,
 };
 
@@ -887,3 +824,4 @@ module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver);
 MODULE_AUTHOR("Comedi http://www.comedi.org");
 MODULE_DESCRIPTION("Comedi low-level driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(DAQBOARD2000_FIRMWARE);
index 2a38915c69e8f414e40085e338a80bd3d353ee88..744376a49d082942fe80b794e3660791452d9721 100644 (file)
@@ -558,7 +558,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 
 /* utility function that suggests a dma transfer size in bytes */
 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
-                                               struct comedi_cmd cmd)
+                                               const struct comedi_cmd *cmd)
 {
        unsigned int size;
        unsigned int freq;
@@ -571,16 +571,16 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
 
        /* otherwise, we are relying on dma terminal count interrupt,
         * so pick a reasonable size */
-       if (cmd.convert_src == TRIG_TIMER)
-               freq = 1000000000 / cmd.convert_arg;
-       else if (cmd.scan_begin_src == TRIG_TIMER)
-               freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
+       if (cmd->convert_src == TRIG_TIMER)
+               freq = 1000000000 / cmd->convert_arg;
+       else if (cmd->scan_begin_src == TRIG_TIMER)
+               freq = (1000000000 / cmd->scan_begin_arg) * cmd->chanlist_len;
        /*  return some default value */
        else
                freq = 0xffffffff;
 
-       if (cmd.flags & TRIG_WAKE_EOS) {
-               size = sample_size * cmd.chanlist_len;
+       if (cmd->flags & TRIG_WAKE_EOS) {
+               size = sample_size * cmd->chanlist_len;
        } else {
                /*  make buffer fill in no more than 1/3 second */
                size = (freq / 3) * sample_size;
@@ -592,7 +592,7 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
        else if (size < sample_size)
                size = sample_size;
 
-       if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
+       if (cmd->stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
                size = devpriv->adc_byte_count;
 
        return size;
@@ -685,7 +685,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
        set_dma_addr(devpriv->dma_chan,
                     devpriv->dma_buffer_addr[devpriv->current_buffer]);
        /*  set appropriate size of transfer */
-       devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
+       devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, cmd);
        set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
        enable_dma(devpriv->dma_chan);
        release_dma_lock(flags);
index 5aca8fbdc246ee047291d3c0d563a3ae35b0cab7..711d4e243b88cacefd196c2040ac0749349cc514 100644 (file)
@@ -958,14 +958,14 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev,
 }
 
 /* returns appropriate bits for control register a, depending on command */
-static int control_a_bits(struct comedi_cmd cmd)
+static int control_a_bits(const struct comedi_cmd *cmd)
 {
        int control_a;
 
        control_a = FFEN;       /* enable fifo */
-       if (cmd.stop_src == TRIG_EXT)
+       if (cmd->stop_src == TRIG_EXT)
                control_a |= ATEN;
-       switch (cmd.start_src) {
+       switch (cmd->start_src) {
        case TRIG_EXT:
                control_a |= TGEN | CGSL;
                break;
@@ -980,7 +980,7 @@ static int control_a_bits(struct comedi_cmd cmd)
 }
 
 /* returns appropriate bits for control register c, depending on command */
-static int control_c_bits(struct comedi_cmd cmd)
+static int control_c_bits(const struct comedi_cmd *cmd)
 {
        int control_c;
        int aref;
@@ -988,18 +988,18 @@ static int control_c_bits(struct comedi_cmd cmd)
        /* set clock source to internal or external, select analog reference,
         * select unipolar / bipolar
         */
-       aref = CR_AREF(cmd.chanlist[0]);
+       aref = CR_AREF(cmd->chanlist[0]);
        control_c = UQEN;       /* enable upper qram addresses */
        if (aref != AREF_DIFF)
                control_c |= SD;
        if (aref == AREF_COMMON)
                control_c |= CMEN;
        /* if a unipolar range was selected */
-       if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
+       if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
                control_c |= UB;
-       switch (cmd.scan_begin_src) {
+       switch (cmd->scan_begin_src) {
        case TRIG_FOLLOW:       /*  not in burst mode */
-               switch (cmd.convert_src) {
+               switch (cmd->convert_src) {
                case TRIG_TIMER:
                        /* trig on cascaded counters */
                        control_c |= IPCLK;
@@ -1047,29 +1047,33 @@ static int das1800_set_frequency(struct comedi_device *dev)
 }
 
 /* sets up counters */
-static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
+static int setup_counters(struct comedi_device *dev,
+                         const struct comedi_cmd *cmd)
 {
+       unsigned int period;
+
        /*  setup cascaded counters for conversion/scan frequency */
-       switch (cmd.scan_begin_src) {
+       switch (cmd->scan_begin_src) {
        case TRIG_FOLLOW:       /*  not in burst mode */
-               if (cmd.convert_src == TRIG_TIMER) {
+               if (cmd->convert_src == TRIG_TIMER) {
                        /* set conversion frequency */
+                       period = cmd->convert_arg;
                        i8253_cascade_ns_to_timer_2div(TIMER_BASE,
-                                                      &(devpriv->divisor1),
-                                                      &(devpriv->divisor2),
-                                                      &(cmd.convert_arg),
-                                                      cmd.
-                                                      flags & TRIG_ROUND_MASK);
+                                                      &devpriv->divisor1,
+                                                      &devpriv->divisor2,
+                                                      &period,
+                                                      cmd->flags &
+                                                       TRIG_ROUND_MASK);
                        if (das1800_set_frequency(dev) < 0)
                                return -1;
                }
                break;
        case TRIG_TIMER:        /*  in burst mode */
                /* set scan frequency */
-               i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
-                                              &(devpriv->divisor2),
-                                              &(cmd.scan_begin_arg),
-                                              cmd.flags & TRIG_ROUND_MASK);
+               period = cmd->scan_begin_arg;
+               i8253_cascade_ns_to_timer_2div(TIMER_BASE, &devpriv->divisor1,
+                                              &devpriv->divisor2, &period,
+                                              cmd->flags & TRIG_ROUND_MASK);
                if (das1800_set_frequency(dev) < 0)
                        return -1;
                break;
@@ -1078,7 +1082,7 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
        }
 
        /*  setup counter 0 for 'about triggering' */
-       if (cmd.stop_src == TRIG_EXT) {
+       if (cmd->stop_src == TRIG_EXT) {
                /*  load counter 0 in mode 0 */
                i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
        }
@@ -1087,7 +1091,7 @@ static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd)
 }
 
 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
-static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
+static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
 {
        unsigned int size = DMA_BUF_SIZE;
        static const int sample_size = 2;       /*  size in bytes of one sample from board */
@@ -1125,7 +1129,7 @@ static unsigned int suggest_transfer_size(struct comedi_cmd *cmd)
 }
 
 /* sets up dma */
-static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
+static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
 {
        unsigned long lock_flags;
        const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
@@ -1134,7 +1138,7 @@ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
                return;
 
        /* determine a reasonable dma transfer size */
-       devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
+       devpriv->dma_transfer_size = suggest_transfer_size(cmd);
        lock_flags = claim_dma_lock();
        disable_dma(devpriv->dma0);
        /* clear flip-flop to make sure 2-byte registers for
@@ -1163,14 +1167,15 @@ static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd)
 }
 
 /* programs channel/gain list into card */
-static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
+static void program_chanlist(struct comedi_device *dev,
+                            const struct comedi_cmd *cmd)
 {
        int i, n, chan_range;
        unsigned long irq_flags;
        const int range_mask = 0x3;     /* masks unipolar/bipolar bit off range */
        const int range_bitshift = 8;
 
-       n = cmd.chanlist_len;
+       n = cmd->chanlist_len;
        /*  spinlock protects indirect addressing */
        spin_lock_irqsave(&dev->spinlock, irq_flags);
        outb(QRAM, dev->iobase + DAS1800_SELECT);       /* select QRAM for baseAddress + 0x0 */
@@ -1178,9 +1183,9 @@ static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd)
        /* make channel / gain list */
        for (i = 0; i < n; i++) {
                chan_range =
-                   CR_CHAN(cmd.
-                           chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) &
-                                            range_mask) << range_bitshift);
+                   CR_CHAN(cmd->chanlist[i]) |
+                   ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
+                    range_bitshift);
                outw(chan_range, dev->iobase + DAS1800_QRAM);
        }
        outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);        /*finish write to QRAM */
@@ -1196,7 +1201,7 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
        int ret;
        int control_a, control_c;
        struct comedi_async *async = s->async;
-       struct comedi_cmd cmd = async->cmd;
+       const struct comedi_cmd *cmd = &async->cmd;
 
        if (!dev->irq) {
                comedi_error(dev,
@@ -1206,12 +1211,12 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
 
        /* 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))
+       if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
                devpriv->irq_dma_bits &= ~DMA_ENABLED;
        else
                devpriv->irq_dma_bits |= devpriv->dma_bits;
        /*  interrupt on end of conversion for TRIG_WAKE_EOS */
-       if (cmd.flags & TRIG_WAKE_EOS) {
+       if (cmd->flags & TRIG_WAKE_EOS) {
                /*  interrupt fifo not empty */
                devpriv->irq_dma_bits &= ~FIMD;
        } else {
@@ -1219,8 +1224,8 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
                devpriv->irq_dma_bits |= FIMD;
        }
        /*  determine how many conversions we need */
-       if (cmd.stop_src == TRIG_COUNT)
-               devpriv->count = cmd.stop_arg * cmd.chanlist_len;
+       if (cmd->stop_src == TRIG_COUNT)
+               devpriv->count = cmd->stop_arg * cmd->chanlist_len;
 
        das1800_cancel(dev, s);
 
@@ -1240,9 +1245,9 @@ static int das1800_ai_do_cmd(struct comedi_device *dev,
        /*  set conversion rate and length for burst mode */
        if (control_c & BMDE) {
                /*  program conversion period with number of microseconds minus 1 */
-               outb(cmd.convert_arg / 1000 - 1,
+               outb(cmd->convert_arg / 1000 - 1,
                     dev->iobase + DAS1800_BURST_RATE);
-               outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
+               outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
        }
        outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);   /*  enable irq/dma */
        outb(control_a, dev->iobase + DAS1800_CONTROL_A);       /* enable fifo and triggering */
index c68c407feb563a1bb327db78c08d6ba4d912197d..2ce0b14af589ccca2d4eb5d7417a2a7b2734960b 100644 (file)
@@ -41,22 +41,14 @@ Configuration options:
 
     If bus/slot is not specified, the first available PCI
     device will be used.
-
-The 2600 requires a firmware upload, which can be accomplished
-using the -i or --init-data option of comedi_config.
-The firmware can be
-found in the comedi_nonfree_firmware tarball available
-from http://www.comedi.org
-
 */
 
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/firmware.h>
 #include "../comedidev.h"
 
-/*#include "me2600_fw.h" */
-
-#define ME_DRIVER_NAME         "me_daq"
+#define ME2600_FIRMWARE                "me2600_firmware.bin"
 
 #define PCI_VENDOR_ID_MEILHAUS 0x1402
 #define ME2000_DEVICE_ID       0x2000
@@ -198,8 +190,7 @@ struct me_board {
 
 static const struct me_board me_boards[] = {
        {
-        /* -- ME-2600i -- */
-        .name = ME_DRIVER_NAME,
+        .name = "me-2600i",
         .device_id = ME2600_DEVICE_ID,
         /* Analog Output */
         .ao_channel_nbr = 4,
@@ -214,8 +205,7 @@ static const struct me_board me_boards[] = {
         .dio_channel_nbr = 32,
         },
        {
-        /* -- ME-2000i -- */
-        .name = ME_DRIVER_NAME,
+        .name = "me-2000i",
         .device_id = ME2000_DEVICE_ID,
         /* Analog Output */
         .ao_channel_nbr = 0,
@@ -524,8 +514,7 @@ static int me_ao_insn_read(struct comedi_device *dev,
 
 /* Xilinx firmware download for card: ME-2600i */
 static int me2600_xilinx_download(struct comedi_device *dev,
-                                 unsigned char *me2600_firmware,
-                                 unsigned int length)
+                                 const u8 *data, size_t size)
 {
        unsigned int value;
        unsigned int file_length;
@@ -552,19 +541,20 @@ static int me2600_xilinx_download(struct comedi_device *dev,
         * Byte 8-11:  date
         * Byte 12-15: reserved
         */
-       if (length < 16)
+       if (size < 16)
                return -EINVAL;
-       file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) +
-           (((unsigned int)me2600_firmware[1] & 0xff) << 16) +
-           (((unsigned int)me2600_firmware[2] & 0xff) << 8) +
-           ((unsigned int)me2600_firmware[3] & 0xff);
+
+       file_length = (((unsigned int)data[0] & 0xff) << 24) +
+           (((unsigned int)data[1] & 0xff) << 16) +
+           (((unsigned int)data[2] & 0xff) << 8) +
+           ((unsigned int)data[3] & 0xff);
 
        /*
         * Loop for writing firmware byte by byte to xilinx
         * Firmware data start at offfset 16
         */
        for (i = 0; i < file_length; i++)
-               writeb((me2600_firmware[16 + i] & 0xff),
+               writeb((data[16 + i] & 0xff),
                       dev_private->me_regbase + 0x0);
 
        /* Write 5 dummy values to xilinx */
@@ -590,6 +580,22 @@ static int me2600_xilinx_download(struct comedi_device *dev,
        return 0;
 }
 
+static int me2600_upload_firmware(struct comedi_device *dev)
+{
+       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
+       const struct firmware *fw;
+       int ret;
+
+       ret = request_firmware(&fw, ME2600_FIRMWARE, &pcidev->dev);
+       if (ret)
+               return ret;
+
+       ret = me2600_xilinx_download(dev, fw->data, fw->size);
+       release_firmware(fw);
+
+       return ret;
+}
+
 /* Reset device */
 static int me_reset(struct comedi_device *dev)
 {
@@ -607,44 +613,24 @@ static int me_reset(struct comedi_device *dev)
        return 0;
 }
 
-static struct pci_dev *me_find_pci_dev(struct comedi_device *dev,
-                                      struct comedi_devconfig *it)
+static const void *me_find_boardinfo(struct comedi_device *dev,
+                                    struct pci_dev *pcidev)
 {
        const struct me_board *board;
-       struct pci_dev *pcidev = NULL;
-       int bus = it->options[0];
-       int slot = it->options[1];
        int i;
 
-       for_each_pci_dev(pcidev) {
-               if (bus || slot) {
-                       if (pcidev->bus->number != bus ||
-                           PCI_SLOT(pcidev->devfn) != slot)
-                               continue;
-               }
-               if (pcidev->vendor != PCI_VENDOR_ID_MEILHAUS)
-                       continue;
-
-               for (i = 0; i < ARRAY_SIZE(me_boards); i++) {
-                       board = &me_boards[i];
-                       if (board->device_id != pcidev->device)
-                               continue;
-
-                       dev->board_ptr = board;
-                       return pcidev;
-               }
+       for (i = 0; i < ARRAY_SIZE(me_boards); i++) {
+               board = &me_boards[i];
+               if (board->device_id == pcidev->device)
+                       return board;
        }
-       dev_err(dev->class_dev,
-               "No supported board found! (req. bus %d, slot %d)\n",
-               bus, slot);
        return NULL;
 }
 
-static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev)
 {
-       struct pci_dev *pci_device;
+       const struct me_board *board;
        struct comedi_subdevice *s;
-       struct me_board *board;
        resource_size_t plx_regbase_tmp;
        unsigned long plx_regbase_size_tmp;
        resource_size_t me_regbase_tmp;
@@ -654,29 +640,28 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        resource_size_t regbase_tmp;
        int result, error;
 
+       comedi_set_hw_dev(dev, &pcidev->dev);
+
+       board = me_find_boardinfo(dev, pcidev);
+       if (!board)
+               return -ENODEV;
+       dev->board_ptr = board;
+       dev->board_name = board->name;
+
        /* Allocate private memory */
        if (alloc_private(dev, sizeof(struct me_private_data)) < 0)
                return -ENOMEM;
 
-       pci_device = me_find_pci_dev(dev, it);
-       if (!pci_device)
-               return -EIO;
-       comedi_set_hw_dev(dev, &pci_device->dev);
-       board = (struct me_board *)dev->board_ptr;
-
        /* Enable PCI device and request PCI regions */
-       if (comedi_pci_enable(pci_device, ME_DRIVER_NAME) < 0) {
+       if (comedi_pci_enable(pcidev, dev->board_name) < 0) {
                printk(KERN_ERR "comedi%d: Failed to enable PCI device and "
                       "request regions\n", dev->minor);
                return -EIO;
        }
 
-       /* Set data in device structure */
-       dev->board_name = board->name;
-
        /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */
-       plx_regbase_tmp = pci_resource_start(pci_device, 0);
-       plx_regbase_size_tmp = pci_resource_len(pci_device, 0);
+       plx_regbase_tmp = pci_resource_start(pcidev, 0);
+       plx_regbase_size_tmp = pci_resource_len(pcidev, 0);
        dev_private->plx_regbase =
            ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
        dev_private->plx_regbase_size = plx_regbase_size_tmp;
@@ -687,8 +672,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        /* Read Swap base address [PCI_BASE_ADDRESS #5]. */
 
-       swap_regbase_tmp = pci_resource_start(pci_device, 5);
-       swap_regbase_size_tmp = pci_resource_len(pci_device, 5);
+       swap_regbase_tmp = pci_resource_start(pcidev, 5);
+       swap_regbase_size_tmp = pci_resource_len(pcidev, 5);
 
        if (!swap_regbase_tmp)
                printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor);
@@ -702,20 +687,20 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                        plx_regbase_tmp = swap_regbase_tmp;
                        swap_regbase_tmp = regbase_tmp;
 
-                       result = pci_write_config_dword(pci_device,
+                       result = pci_write_config_dword(pcidev,
                                                        PCI_BASE_ADDRESS_0,
                                                        plx_regbase_tmp);
                        if (result != PCIBIOS_SUCCESSFUL)
                                return -EIO;
 
-                       result = pci_write_config_dword(pci_device,
+                       result = pci_write_config_dword(pcidev,
                                                        PCI_BASE_ADDRESS_5,
                                                        swap_regbase_tmp);
                        if (result != PCIBIOS_SUCCESSFUL)
                                return -EIO;
                } else {
                        plx_regbase_tmp -= 0x80;
-                       result = pci_write_config_dword(pci_device,
+                       result = pci_write_config_dword(pcidev,
                                                        PCI_BASE_ADDRESS_0,
                                                        plx_regbase_tmp);
                        if (result != PCIBIOS_SUCCESSFUL)
@@ -726,8 +711,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */
 
-       me_regbase_tmp = pci_resource_start(pci_device, 2);
-       me_regbase_size_tmp = pci_resource_len(pci_device, 2);
+       me_regbase_tmp = pci_resource_start(pcidev, 2);
+       me_regbase_size_tmp = pci_resource_len(pcidev, 2);
        dev_private->me_regbase_size = me_regbase_size_tmp;
        dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp);
        if (!dev_private->me_regbase) {
@@ -735,23 +720,13 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                       dev->minor);
                return -ENOMEM;
        }
+
        /* Download firmware and reset card */
        if (board->device_id == ME2600_DEVICE_ID) {
-               unsigned char *aux_data;
-               int aux_len;
-
-               aux_data = comedi_aux_data(it->options, 0);
-               aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
-
-               if (!aux_data || aux_len < 1) {
-                       comedi_error(dev, "You must provide me2600 firmware "
-                                    "using the --init-data option of "
-                                    "comedi_config");
-                       return -EINVAL;
-               }
-               me2600_xilinx_download(dev, aux_data, aux_len);
+               result = me2600_upload_firmware(dev);
+               if (result < 0)
+                       return result;
        }
-
        me_reset(dev);
 
        error = comedi_alloc_subdevices(dev, 3);
@@ -791,8 +766,9 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        s->insn_config = me_dio_insn_config;
        s->io_bits = 0;
 
-       printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n",
-              dev->minor);
+       dev_info(dev->class_dev, "%s: %s attached\n",
+               dev->driver->driver_name, dev->board_name);
+
        return 0;
 }
 
@@ -818,7 +794,7 @@ static void me_detach(struct comedi_device *dev)
 static struct comedi_driver me_daq_driver = {
        .driver_name    = "me_daq",
        .module         = THIS_MODULE,
-       .attach         = me_attach,
+       .attach_pci     = me_attach_pci,
        .detach         = me_detach,
 };
 
@@ -851,3 +827,4 @@ module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver);
 MODULE_AUTHOR("Comedi http://www.comedi.org");
 MODULE_DESCRIPTION("Comedi low-level driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(ME2600_FIRMWARE);
index 295ddbb4d586690610e4e26672c50da7f9f18e31..d534e63d886e03e715be49d8265e3df48f2cbc53 100644 (file)
@@ -206,6 +206,13 @@ NI manuals:
 #define   INIT_A1_BITS 0x70
 #define COUNTER_B_BASE_REG     0x18
 
+enum scan_mode {
+       MODE_SINGLE_CHAN,
+       MODE_SINGLE_CHAN_INTERVAL,
+       MODE_MULT_CHAN_UP,
+       MODE_MULT_CHAN_DOWN,
+};
+
 static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 static irqreturn_t labpc_interrupt(int irq, void *d);
 static int labpc_drain_fifo(struct comedi_device *dev);
@@ -236,9 +243,10 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
                                   struct comedi_insn *insn,
                                   unsigned int *data);
-static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd);
+static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
+                            enum scan_mode scan_mode);
 #ifdef CONFIG_ISA_DMA_API
-static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd);
+static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd);
 #endif
 static int labpc_dio_mem_callback(int dir, int port, int data,
                                  unsigned long arg);
@@ -254,13 +262,6 @@ static int labpc_eeprom_write(struct comedi_device *dev,
 static void write_caldac(struct comedi_device *dev, unsigned int channel,
                         unsigned int value);
 
-enum scan_mode {
-       MODE_SINGLE_CHAN,
-       MODE_SINGLE_CHAN_INTERVAL,
-       MODE_MULT_CHAN_UP,
-       MODE_MULT_CHAN_DOWN,
-};
-
 /* analog input ranges */
 #define NUM_LABPC_PLUS_AI_RANGES 16
 /* indicates unipolar ranges */
@@ -409,12 +410,12 @@ static inline void labpc_outb(unsigned int byte, unsigned long address)
 
 static inline unsigned int labpc_readb(unsigned long address)
 {
-       return readb((void *)address);
+       return readb((void __iomem *)address);
 }
 
 static inline void labpc_writeb(unsigned int byte, unsigned long address)
 {
-       writeb(byte, (void *)address);
+       writeb(byte, (void __iomem *)address);
 }
 
 static const struct labpc_board_struct labpc_boards[] = {
@@ -494,8 +495,8 @@ static inline int labpc_counter_load(struct comedi_device *dev,
                                     unsigned int count, unsigned int mode)
 {
        if (thisboard->memory_mapped_io)
-               return i8254_mm_load((void *)base_address, 0, counter_number,
-                                    count, mode);
+               return i8254_mm_load((void __iomem *)base_address, 0,
+                                    counter_number, count, mode);
        else
                return i8254_load(base_address, 0, counter_number, count, mode);
 }
@@ -839,15 +840,14 @@ static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
 }
 
 static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
-                                    const struct comedi_cmd *cmd)
+                                    const struct comedi_cmd *cmd,
+                                    enum scan_mode mode)
 {
-       int mode, channel, range, aref, i;
+       int channel, range, aref, i;
 
        if (cmd->chanlist == NULL)
                return 0;
 
-       mode = labpc_ai_scan_mode(cmd);
-
        if (mode == MODE_SINGLE_CHAN)
                return 0;
 
@@ -911,9 +911,10 @@ static int labpc_ai_chanlist_invalid(const struct comedi_device *dev,
        return 0;
 }
 
-static int labpc_use_continuous_mode(const struct comedi_cmd *cmd)
+static int labpc_use_continuous_mode(const struct comedi_cmd *cmd,
+                                    enum scan_mode mode)
 {
-       if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN)
+       if (mode == MODE_SINGLE_CHAN)
                return 1;
 
        if (cmd->scan_begin_src == TRIG_FOLLOW)
@@ -922,24 +923,25 @@ static int labpc_use_continuous_mode(const struct comedi_cmd *cmd)
        return 0;
 }
 
-static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd)
+static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
+                                           enum scan_mode mode)
 {
        if (cmd->convert_src != TRIG_TIMER)
                return 0;
 
-       if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-           cmd->scan_begin_src == TRIG_TIMER)
+       if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
                return cmd->scan_begin_arg;
 
        return cmd->convert_arg;
 }
 
-static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, unsigned int ns)
+static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
+                                       enum scan_mode mode, unsigned int ns)
 {
        if (cmd->convert_src != TRIG_TIMER)
                return;
 
-       if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+       if (mode == MODE_SINGLE_CHAN &&
            cmd->scan_begin_src == TRIG_TIMER) {
                cmd->scan_begin_arg = ns;
                if (cmd->convert_arg > cmd->scan_begin_arg)
@@ -948,25 +950,25 @@ static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, unsigned int ns)
                cmd->convert_arg = ns;
 }
 
-static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd)
+static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
+                                       enum scan_mode mode)
 {
        if (cmd->scan_begin_src != TRIG_TIMER)
                return 0;
 
-       if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-           cmd->convert_src == TRIG_TIMER)
+       if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
                return 0;
 
        return cmd->scan_begin_arg;
 }
 
-static void labpc_set_ai_scan_period(struct comedi_cmd *cmd, unsigned int ns)
+static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
+                                    enum scan_mode mode, unsigned int ns)
 {
        if (cmd->scan_begin_src != TRIG_TIMER)
                return;
 
-       if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
-           cmd->convert_src == TRIG_TIMER)
+       if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
                return;
 
        cmd->scan_begin_arg = ns;
@@ -978,6 +980,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
        int err = 0;
        int tmp, tmp2;
        int stop_mask;
+       enum scan_mode mode;
 
        /* step 1: make sure trigger sources are trivially valid */
 
@@ -1099,14 +1102,15 @@ static int labpc_ai_cmdtest(struct comedi_device *dev,
 
        tmp = cmd->convert_arg;
        tmp2 = cmd->scan_begin_arg;
-       labpc_adc_timing(dev, cmd);
+       mode = labpc_ai_scan_mode(cmd);
+       labpc_adc_timing(dev, cmd, mode);
        if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
                err++;
 
        if (err)
                return 4;
 
-       if (labpc_ai_chanlist_invalid(dev, cmd))
+       if (labpc_ai_chanlist_invalid(dev, cmd, mode))
                return 5;
 
        return 0;
@@ -1122,6 +1126,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        struct comedi_async *async = s->async;
        struct comedi_cmd *cmd = &async->cmd;
        enum transfer_type xfer;
+       enum scan_mode mode;
        unsigned long flags;
 
        if (!dev->irq) {
@@ -1187,6 +1192,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        } else
                xfer = fifo_not_empty_transfer;
        devpriv->current_transfer = xfer;
+       mode = labpc_ai_scan_mode(cmd);
 
        /*  setup command6 register for 1200 boards */
        if (thisboard->register_layout == labpc_1200_layout) {
@@ -1211,7 +1217,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                else
                        devpriv->command6_bits &= ~A1_INTR_EN_BIT;
                /*  are we scanning up or down through channels? */
-               if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+               if (mode == MODE_MULT_CHAN_UP)
                        devpriv->command6_bits |= ADC_SCAN_UP_BIT;
                else
                        devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
@@ -1222,19 +1228,18 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        /* setup channel list, etc (command1 register) */
        devpriv->command1_bits = 0;
-       if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+       if (mode == MODE_MULT_CHAN_UP)
                channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
        else
                channel = CR_CHAN(cmd->chanlist[0]);
        /* munge channel bits for differential / scan disabled mode */
-       if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
+       if (mode != MODE_SINGLE_CHAN && aref == AREF_DIFF)
                channel *= 2;
        devpriv->command1_bits |= ADC_CHAN_BITS(channel);
        devpriv->command1_bits |= thisboard->ai_range_code[range];
        devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
        /* manual says to set scan enable bit on second pass */
-       if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
-           labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
+       if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
                devpriv->command1_bits |= ADC_SCAN_EN_BIT;
                /* need a brief delay before enabling scan, or scan
                 * list will get screwed when you switch
@@ -1249,7 +1254,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
        /* XXX should discard first scan when using interval scanning
         * since manual says it is not synced with scan clock */
-       if (labpc_use_continuous_mode(cmd) == 0) {
+       if (labpc_use_continuous_mode(cmd, mode) == 0) {
                devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
                if (cmd->scan_begin_src == TRIG_EXT)
                        devpriv->command4_bits |= EXT_SCAN_EN_BIT;
@@ -1267,7 +1272,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
        if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) {
                /*  set up pacing */
-               labpc_adc_timing(dev, cmd);
+               labpc_adc_timing(dev, cmd, mode);
                /*  load counter b0 in mode 3 */
                ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
                                         0, devpriv->divisor_b0, 3);
@@ -1277,7 +1282,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                }
        }
        /*  set up conversion pacing */
-       if (labpc_ai_convert_period(cmd)) {
+       if (labpc_ai_convert_period(cmd, mode)) {
                /*  load counter a0 in mode 2 */
                ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
                                         0, devpriv->divisor_a0, 2);
@@ -1290,7 +1295,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                                    dev->iobase + COUNTER_A_CONTROL_REG);
 
        /*  set up scan pacing */
-       if (labpc_ai_scan_period(cmd)) {
+       if (labpc_ai_scan_period(cmd, mode)) {
                /*  load counter b1 in mode 2 */
                ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
                                         1, devpriv->divisor_b1, 2);
@@ -1313,7 +1318,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
                set_dma_addr(devpriv->dma_chan,
                             virt_to_bus(devpriv->dma_buffer));
                /*  set appropriate size of transfer */
-               devpriv->dma_transfer_size = labpc_suggest_transfer_size(*cmd);
+               devpriv->dma_transfer_size = labpc_suggest_transfer_size(cmd);
                if (cmd->stop_src == TRIG_COUNT &&
                    devpriv->count * sample_size < devpriv->dma_transfer_size) {
                        devpriv->dma_transfer_size =
@@ -1766,13 +1771,13 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev,
 
 #ifdef CONFIG_ISA_DMA_API
 /* utility function that suggests a dma transfer size in bytes */
-static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
+static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd)
 {
        unsigned int size;
        unsigned int freq;
 
-       if (cmd.convert_src == TRIG_TIMER)
-               freq = 1000000000 / cmd.convert_arg;
+       if (cmd->convert_src == TRIG_TIMER)
+               freq = 1000000000 / cmd->convert_arg;
        /* return some default value */
        else
                freq = 0xffffffff;
@@ -1791,24 +1796,29 @@ static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
 #endif
 
 /* figures out what counter values to use based on command */
-static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
+                            enum scan_mode mode)
 {
        /* max value for 16 bit counter in mode 2 */
        const int max_counter_value = 0x10000;
        /* min value for 16 bit counter in mode 2 */
        const int min_counter_value = 2;
        unsigned int base_period;
+       unsigned int scan_period;
+       unsigned int convert_period;
 
        /*
         * if both convert and scan triggers are TRIG_TIMER, then they
         * both rely on counter b0
         */
-       if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
+       convert_period = labpc_ai_convert_period(cmd, mode);
+       scan_period = labpc_ai_scan_period(cmd, mode);
+       if (convert_period && scan_period) {
                /*
                 * pick the lowest b0 divisor value we can (for maximum input
                 * clock speed on convert and scan counters)
                 */
-               devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
+               devpriv->divisor_b0 = (scan_period - 1) /
                    (LABPC_TIMER_BASE * max_counter_value) + 1;
                if (devpriv->divisor_b0 < min_counter_value)
                        devpriv->divisor_b0 = min_counter_value;
@@ -1822,25 +1832,19 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                default:
                case TRIG_ROUND_NEAREST:
                        devpriv->divisor_a0 =
-                           (labpc_ai_convert_period(cmd) +
-                            (base_period / 2)) / base_period;
+                           (convert_period + (base_period / 2)) / base_period;
                        devpriv->divisor_b1 =
-                           (labpc_ai_scan_period(cmd) +
-                            (base_period / 2)) / base_period;
+                           (scan_period + (base_period / 2)) / base_period;
                        break;
                case TRIG_ROUND_UP:
                        devpriv->divisor_a0 =
-                           (labpc_ai_convert_period(cmd) + (base_period -
-                                                            1)) / base_period;
+                           (convert_period + (base_period - 1)) / base_period;
                        devpriv->divisor_b1 =
-                           (labpc_ai_scan_period(cmd) + (base_period -
-                                                         1)) / base_period;
+                           (scan_period + (base_period - 1)) / base_period;
                        break;
                case TRIG_ROUND_DOWN:
-                       devpriv->divisor_a0 =
-                           labpc_ai_convert_period(cmd) / base_period;
-                       devpriv->divisor_b1 =
-                           labpc_ai_scan_period(cmd) / base_period;
+                       devpriv->divisor_a0 = convert_period / base_period;
+                       devpriv->divisor_b1 = scan_period / base_period;
                        break;
                }
                /*  make sure a0 and b1 values are acceptable */
@@ -1853,18 +1857,15 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                if (devpriv->divisor_b1 > max_counter_value)
                        devpriv->divisor_b1 = max_counter_value;
                /*  write corrected timings to command */
-               labpc_set_ai_convert_period(cmd,
+               labpc_set_ai_convert_period(cmd, mode,
                                            base_period * devpriv->divisor_a0);
-               labpc_set_ai_scan_period(cmd,
+               labpc_set_ai_scan_period(cmd, mode,
                                         base_period * devpriv->divisor_b1);
                /*
                 * if only one TRIG_TIMER is used, we can employ the generic
                 * cascaded timing functions
                 */
-       } else if (labpc_ai_scan_period(cmd)) {
-               unsigned int scan_period;
-
-               scan_period = labpc_ai_scan_period(cmd);
+       } else if (scan_period) {
                /*
                 * calculate cascaded counter values
                 * that give desired scan timing
@@ -1874,11 +1875,8 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                                               &(devpriv->divisor_b0),
                                               &scan_period,
                                               cmd->flags & TRIG_ROUND_MASK);
-               labpc_set_ai_scan_period(cmd, scan_period);
-       } else if (labpc_ai_convert_period(cmd)) {
-               unsigned int convert_period;
-
-               convert_period = labpc_ai_convert_period(cmd);
+               labpc_set_ai_scan_period(cmd, mode, scan_period);
+       } else if (convert_period) {
                /*
                 * calculate cascaded counter values
                 * that give desired conversion timing
@@ -1888,7 +1886,7 @@ static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
                                               &(devpriv->divisor_b0),
                                               &convert_period,
                                               cmd->flags & TRIG_ROUND_MASK);
-               labpc_set_ai_convert_period(cmd, convert_period);
+               labpc_set_ai_convert_period(cmd, mode, convert_period);
        }
 }
 
@@ -1896,10 +1894,10 @@ static int labpc_dio_mem_callback(int dir, int port, int data,
                                  unsigned long iobase)
 {
        if (dir) {
-               writeb(data, (void *)(iobase + port));
+               writeb(data, (void __iomem *)(iobase + port));
                return 0;
        } else {
-               return readb((void *)(iobase + port));
+               return readb((void __iomem *)(iobase + port));
        }
 }
 
index 58f5922d6e4c843395d765b712f234e9f3d1a303..d0e4844e5248c6a863eec16d5162aa3c20f64f04 100644 (file)
@@ -964,7 +964,7 @@ static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 /*
   cmdtest tests a particular command to see if it is valid.
   Using the cmdtest ioctl, a user can create a valid cmd
-  and then have it executed by the cmd ioctl (asyncronously).
+  and then have it executed by the cmd ioctl (asynchronously).
 
   cmdtest returns 1,2,3,4 or 0, depending on which tests
   the command passes.
index c89bd6cde8bc5621dadb929c4e320b34737ae682..4ad6adfcbb9cbf25ec05d48c5ec0a85f743e78c1 100644 (file)
@@ -83,36 +83,6 @@ comedi_config /dev/comedi0 s526 0x2C0,0x3
 #define REG_EED 0x32
 #define REG_EEC 0x34
 
-static const int s526_ports[] = {
-       REG_TCR,
-       REG_WDC,
-       REG_DAC,
-       REG_ADC,
-       REG_ADD,
-       REG_DIO,
-       REG_IER,
-       REG_ISR,
-       REG_MSC,
-       REG_C0L,
-       REG_C0H,
-       REG_C0M,
-       REG_C0C,
-       REG_C1L,
-       REG_C1H,
-       REG_C1M,
-       REG_C1C,
-       REG_C2L,
-       REG_C2H,
-       REG_C2M,
-       REG_C2C,
-       REG_C3L,
-       REG_C3H,
-       REG_C3M,
-       REG_C3C,
-       REG_EED,
-       REG_EEC
-};
-
 struct counter_mode_register_t {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
        unsigned short coutSource:1;
@@ -148,122 +118,48 @@ union cmReg {
        unsigned short value;
 };
 
-#define MAX_GPCT_CONFIG_DATA 6
-
-/* Different Application Classes for GPCT Subdevices */
-/* The list is not exhaustive and needs discussion! */
-enum S526_GPCT_APP_CLASS {
-       CountingAndTimeMeasurement,
-       SinglePulseGeneration,
-       PulseTrainGeneration,
-       PositionMeasurement,
-       Miscellaneous
-};
-
-/* Config struct for different GPCT subdevice Application Classes and
-   their options
-*/
-struct s526GPCTConfig {
-       enum S526_GPCT_APP_CLASS app;
-       int data[MAX_GPCT_CONFIG_DATA];
-};
-
-/*
- * Board descriptions for two imaginary boards.  Describing the
- * boards in this way is optional, and completely driver-dependent.
- * Some drivers use arrays such as this, other do not.
- */
-struct s526_board {
-       const char *name;
-       int gpct_chans;
-       int gpct_bits;
-       int ad_chans;
-       int ad_bits;
-       int da_chans;
-       int da_bits;
-       int have_dio;
-};
-
-static const struct s526_board s526_boards[] = {
-       {
-        .name = "s526",
-        .gpct_chans = 4,
-        .gpct_bits = 24,
-        .ad_chans = 8,
-        .ad_bits = 16,
-        .da_chans = 4,
-        .da_bits = 16,
-        .have_dio = 1,
-        }
-};
-
-#define ADDR_REG(reg) (dev->iobase + (reg))
-#define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8)
-
-/* this structure is for data unique to this hardware driver.  If
-   several hardware drivers keep similar information in this structure,
-   feel free to suggest moving the variable to the struct comedi_device
-   struct.
-*/
 struct s526_private {
        unsigned int ao_readback[2];
-       struct s526GPCTConfig s526_gpct_config[4];
-       unsigned short s526_ai_config;
+       unsigned int gpct_config[4];
+       unsigned short ai_config;
 };
 
-/*
- * most drivers define the following macro to make it easy to
- * access the private structure.
- */
-#define devpriv ((struct s526_private *)dev->private)
-
 static int s526_gpct_rinsn(struct comedi_device *dev,
-                          struct comedi_subdevice *s, struct comedi_insn *insn,
+                          struct comedi_subdevice *s,
+                          struct comedi_insn *insn,
                           unsigned int *data)
 {
-       int i;                  /*  counts the Data */
-       int counter_channel = CR_CHAN(insn->chanspec);
-       unsigned short datalow;
-       unsigned short datahigh;
-
-       /*  Check if (n > 0) */
-       if (insn->n <= 0) {
-               printk(KERN_ERR "s526: INSN_READ: n should be > 0\n");
-               return -EINVAL;
-       }
-       /*  Read the low word first */
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned long chan_iobase = dev->iobase + chan * 8;
+       unsigned int lo;
+       unsigned int hi;
+       int i;
+
        for (i = 0; i < insn->n; i++) {
-               datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel));
-               datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel));
-               data[i] = (int)(datahigh & 0x00FF);
-               data[i] = (data[i] << 16) | (datalow & 0xFFFF);
-               /* printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n",
-                  counter_channel, data[i], datahigh, datalow); */
+               /* Read the low word first */
+               lo = inw(chan_iobase + REG_C0L) & 0xffff;
+               hi = inw(chan_iobase + REG_C0H) & 0xff;
+
+               data[i] = (hi << 16) | lo;
        }
-       return i;
+
+       return insn->n;
 }
 
 static int s526_gpct_insn_config(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       int subdev_channel = CR_CHAN(insn->chanspec);   /*  Unpack chanspec */
-       int i;
-       short value;
+       struct s526_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned long chan_iobase = dev->iobase + chan * 8;
+       unsigned int val;
        union cmReg cmReg;
 
-       /* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n",
-                                               subdev_channel); */
-
-       for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) {
-               devpriv->s526_gpct_config[subdev_channel].data[i] =
-                   insn->data[i];
-/* printk("data[%d]=%x\n", i, insn->data[i]); */
-       }
-
        /*  Check what type of Counter the user requested, data[0] contains */
        /*  the Application type */
-       switch (insn->data[0]) {
+       switch (data[0]) {
        case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
                /*
                   data[0]: Application Type
@@ -271,9 +167,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                   data[2]: Pre-load Register Value
                   data[3]: Conter Control Register
                 */
-               printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring Encoder\n");
-               devpriv->s526_gpct_config[subdev_channel].app =
-                   PositionMeasurement;
+               devpriv->gpct_config[chan] = data[0];
 
 #if 0
                /*  Example of Counter Application */
@@ -290,34 +184,32 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                cmReg.reg.preloadRegSel = 0;    /*  PR0 */
                cmReg.reg.reserved = 0;
 
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
-               outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
-               outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               outw(0x0001, chan_iobase + REG_C0H);
+               outw(0x3C68, chan_iobase + REG_C0L);
 
                /*  Reset the counter */
-               outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               outw(0x8000, chan_iobase + REG_C0C);
                /*  Load the counter from PR0 */
-               outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               outw(0x4000, chan_iobase + REG_C0C);
 
                /*  Reset RCAP (fires one-shot) */
-               outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               outw(0x0008, chan_iobase + REG_C0C);
 
 #endif
 
 #if 1
                /*  Set Counter Mode Register */
-               cmReg.value = insn->data[1] & 0xFFFF;
-
-/* printk("s526: Counter Mode register=%x\n", cmReg.value); */
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               cmReg.value = data[1] & 0xffff;
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Reset the counter if it is software preload */
                if (cmReg.reg.autoLoadResetRcap == 0) {
                        /*  Reset the counter */
-                       outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+                       outw(0x8000, chan_iobase + REG_C0C);
                        /* Load the counter from PR0
-                        * outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+                        * outw(0x4000, chan_iobase + REG_C0C);
                         */
                }
 #else
@@ -325,47 +217,47 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                cmReg.reg.countDirCtrl = 0;
 
                /*  data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */
-               if (insn->data[1] == GPCT_X2)
+               if (data[1] == GPCT_X2)
                        cmReg.reg.clockSource = 1;
-               else if (insn->data[1] == GPCT_X4)
+               else if (data[1] == GPCT_X4)
                        cmReg.reg.clockSource = 2;
                else
                        cmReg.reg.clockSource = 0;
 
                /*  When to take into account the indexpulse: */
-               /*if (insn->data[2] == GPCT_IndexPhaseLowLow) {
-               } else if (insn->data[2] == GPCT_IndexPhaseLowHigh) {
-               } else if (insn->data[2] == GPCT_IndexPhaseHighLow) {
-               } else if (insn->data[2] == GPCT_IndexPhaseHighHigh) {
+               /*if (data[2] == GPCT_IndexPhaseLowLow) {
+               } else if (data[2] == GPCT_IndexPhaseLowHigh) {
+               } else if (data[2] == GPCT_IndexPhaseHighLow) {
+               } else if (data[2] == GPCT_IndexPhaseHighHigh) {
                }*/
                /*  Take into account the index pulse? */
-               if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX)
+               if (data[3] == GPCT_RESET_COUNTER_ON_INDEX)
                        /*  Auto load with INDEX^ */
                        cmReg.reg.autoLoadResetRcap = 4;
 
                /*  Set Counter Mode Register */
-               cmReg.value = (short)(insn->data[1] & 0xFFFF);
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               cmReg.value = data[1] & 0xffff;
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Load the pre-load register high word */
-               value = (short)((insn->data[2] >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+               val = (data[2] >> 16) & 0xffff;
+               outw(val, chan_iobase + REG_C0H);
 
                /*  Load the pre-load register low word */
-               value = (short)(insn->data[2] & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               val = data[2] & 0xffff;
+               outw(val, chan_iobase + REG_C0L);
 
                /*  Write the Counter Control Register */
-               if (insn->data[3] != 0) {
-                       value = (short)(insn->data[3] & 0xFFFF);
-                       outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               if (data[3]) {
+                       val = data[3] & 0xffff;
+                       outw(val, chan_iobase + REG_C0C);
                }
                /*  Reset the counter if it is software preload */
                if (cmReg.reg.autoLoadResetRcap == 0) {
                        /*  Reset the counter */
-                       outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+                       outw(0x8000, chan_iobase + REG_C0C);
                        /*  Load the counter from PR0 */
-                       outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+                       outw(0x4000, chan_iobase + REG_C0C);
                }
 #endif
                break;
@@ -378,40 +270,38 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                   data[3]: Pre-load Register 1 Value
                   data[4]: Conter Control Register
                 */
-               printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring SPG\n");
-               devpriv->s526_gpct_config[subdev_channel].app =
-                   SinglePulseGeneration;
+               devpriv->gpct_config[chan] = data[0];
 
                /*  Set Counter Mode Register */
-               cmReg.value = (short)(insn->data[1] & 0xFFFF);
+               cmReg.value = data[1] & 0xffff;
                cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Load the pre-load register 0 high word */
-               value = (short)((insn->data[2] >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+               val = (data[2] >> 16) & 0xffff;
+               outw(val, chan_iobase + REG_C0H);
 
                /*  Load the pre-load register 0 low word */
-               value = (short)(insn->data[2] & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               val = data[2] & 0xffff;
+               outw(val, chan_iobase + REG_C0L);
 
                /*  Set Counter Mode Register */
-               cmReg.value = (short)(insn->data[1] & 0xFFFF);
+               cmReg.value = data[1] & 0xffff;
                cmReg.reg.preloadRegSel = 1;    /*  PR1 */
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Load the pre-load register 1 high word */
-               value = (short)((insn->data[3] >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+               val = (data[3] >> 16) & 0xffff;
+               outw(val, chan_iobase + REG_C0H);
 
                /*  Load the pre-load register 1 low word */
-               value = (short)(insn->data[3] & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               val = data[3] & 0xffff;
+               outw(val, chan_iobase + REG_C0L);
 
                /*  Write the Counter Control Register */
-               if (insn->data[4] != 0) {
-                       value = (short)(insn->data[4] & 0xFFFF);
-                       outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               if (data[4]) {
+                       val = data[4] & 0xffff;
+                       outw(val, chan_iobase + REG_C0C);
                }
                break;
 
@@ -423,45 +313,42 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
                   data[3]: Pre-load Register 1 Value
                   data[4]: Conter Control Register
                 */
-               printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring PTG\n");
-               devpriv->s526_gpct_config[subdev_channel].app =
-                   PulseTrainGeneration;
+               devpriv->gpct_config[chan] = data[0];
 
                /*  Set Counter Mode Register */
-               cmReg.value = (short)(insn->data[1] & 0xFFFF);
+               cmReg.value = data[1] & 0xffff;
                cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Load the pre-load register 0 high word */
-               value = (short)((insn->data[2] >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+               val = (data[2] >> 16) & 0xffff;
+               outw(val, chan_iobase + REG_C0H);
 
                /*  Load the pre-load register 0 low word */
-               value = (short)(insn->data[2] & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               val = data[2] & 0xffff;
+               outw(val, chan_iobase + REG_C0L);
 
                /*  Set Counter Mode Register */
-               cmReg.value = (short)(insn->data[1] & 0xFFFF);
+               cmReg.value = data[1] & 0xffff;
                cmReg.reg.preloadRegSel = 1;    /*  PR1 */
-               outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+               outw(cmReg.value, chan_iobase + REG_C0M);
 
                /*  Load the pre-load register 1 high word */
-               value = (short)((insn->data[3] >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+               val = (data[3] >> 16) & 0xffff;
+               outw(val, chan_iobase + REG_C0H);
 
                /*  Load the pre-load register 1 low word */
-               value = (short)(insn->data[3] & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               val = data[3] & 0xffff;
+               outw(val, chan_iobase + REG_C0L);
 
                /*  Write the Counter Control Register */
-               if (insn->data[4] != 0) {
-                       value = (short)(insn->data[4] & 0xFFFF);
-                       outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+               if (data[4]) {
+                       val = data[4] & 0xffff;
+                       outw(val, chan_iobase + REG_C0C);
                }
                break;
 
        default:
-               printk(KERN_ERR "s526: unsupported GPCT_insn_config\n");
                return -EINVAL;
                break;
        }
@@ -470,65 +357,40 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
 }
 
 static int s526_gpct_winsn(struct comedi_device *dev,
-                          struct comedi_subdevice *s, struct comedi_insn *insn,
+                          struct comedi_subdevice *s,
+                          struct comedi_insn *insn,
                           unsigned int *data)
 {
-       int subdev_channel = CR_CHAN(insn->chanspec);   /*  Unpack chanspec */
-       short value;
-       union cmReg cmReg;
-
-       printk(KERN_INFO "s526: GPCT_INSN_WRITE on channel %d\n",
-                                       subdev_channel);
-       cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel));
-       printk(KERN_INFO "s526: Counter Mode Register: %x\n", cmReg.value);
-       /*  Check what Application of Counter this channel is configured for */
-       switch (devpriv->s526_gpct_config[subdev_channel].app) {
-       case PositionMeasurement:
-               printk(KERN_INFO "S526: INSN_WRITE: PM\n");
-               outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
-                                                            subdev_channel));
-               outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
-               break;
+       struct s526_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned long chan_iobase = dev->iobase + chan * 8;
 
-       case SinglePulseGeneration:
-               printk(KERN_INFO "S526: INSN_WRITE: SPG\n");
-               outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
-                                                            subdev_channel));
-               outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
-               break;
+       inw(chan_iobase + REG_C0M);     /* Is this read required? */
 
-       case PulseTrainGeneration:
+       /*  Check what Application of Counter this channel is configured for */
+       switch (devpriv->gpct_config[chan]) {
+       case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
                /* data[0] contains the PULSE_WIDTH
                   data[1] contains the PULSE_PERIOD
                   @pre PULSE_PERIOD > PULSE_WIDTH > 0
                   The above periods must be expressed as a multiple of the
                   pulse frequency on the selected source
                 */
-               printk(KERN_INFO "S526: INSN_WRITE: PTG\n");
-               if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) {
-                       (devpriv->s526_gpct_config[subdev_channel]).data[0] =
-                           insn->data[0];
-                       (devpriv->s526_gpct_config[subdev_channel]).data[1] =
-                           insn->data[1];
-               } else {
-                       printk(KERN_ERR "s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n",
-                               insn->data[0], insn->data[1]);
+               if ((data[1] < data[0]) || !data[0])
                        return -EINVAL;
-               }
 
-               value = (short)((*data >> 16) & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
-               value = (short)(*data & 0xFFFF);
-               outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+               /* Fall thru to write the PULSE_WIDTH */
+
+       case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
+       case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
+               outw((data[0] >> 16) & 0xffff, chan_iobase + REG_C0H);
+               outw(data[0] & 0xffff, chan_iobase + REG_C0L);
                break;
-       default:                /*  Impossible */
-               printk
-                   ("s526: INSN_WRITE: Functionality %d not implemented yet\n",
-                    devpriv->s526_gpct_config[subdev_channel].app);
+
+       default:
                return -EINVAL;
-               break;
        }
-       /*  return the number of samples written */
+
        return insn->n;
 }
 
@@ -537,6 +399,7 @@ static int s526_ai_insn_config(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data)
 {
+       struct s526_private *devpriv = dev->private;
        int result = -EINVAL;
 
        if (insn->n < 1)
@@ -552,62 +415,50 @@ static int s526_ai_insn_config(struct comedi_device *dev,
         * INSN_READ handler. */
 
        /*  Enable ADC interrupt */
-       outw(ISR_ADC_DONE, ADDR_REG(REG_IER));
-/* printk("s526: ADC current value: 0x%04x\n", inw(ADDR_REG(REG_ADC))); */
-       devpriv->s526_ai_config = (data[0] & 0x3FF) << 5;
+       outw(ISR_ADC_DONE, dev->iobase + REG_IER);
+       devpriv->ai_config = (data[0] & 0x3ff) << 5;
        if (data[1] > 0)
-               devpriv->s526_ai_config |= 0x8000;      /* set the delay */
+               devpriv->ai_config |= 0x8000;   /* set the delay */
 
-       devpriv->s526_ai_config |= 0x0001;      /*  ADC start bit. */
+       devpriv->ai_config |= 0x0001;           /* ADC start bit */
 
        return result;
 }
 
-/*
- * "instructions" read/write data in "one-shot" or "software-triggered"
- * mode.
- */
 static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                         struct comedi_insn *insn, unsigned int *data)
 {
+       struct s526_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int n, i;
-       int chan = CR_CHAN(insn->chanspec);
        unsigned short value;
        unsigned int d;
        unsigned int status;
 
        /* Set configured delay, enable channel for this channel only,
         * select "ADC read" channel, set "ADC start" bit. */
-       value = (devpriv->s526_ai_config & 0x8000) |
-           ((1 << 5) << chan) | (chan << 1) | 0x0001;
+       value = (devpriv->ai_config & 0x8000) |
+               ((1 << 5) << chan) | (chan << 1) | 0x0001;
 
        /* convert n samples */
        for (n = 0; n < insn->n; n++) {
                /* trigger conversion */
-               outw(value, ADDR_REG(REG_ADC));
-/* printk("s526: Wrote 0x%04x to ADC\n", value); */
-/* printk("s526: ADC reg=0x%04x\n", inw(ADDR_REG(REG_ADC))); */
+               outw(value, dev->iobase + REG_ADC);
 
 #define TIMEOUT 100
                /* wait for conversion to end */
                for (i = 0; i < TIMEOUT; i++) {
-                       status = inw(ADDR_REG(REG_ISR));
+                       status = inw(dev->iobase + REG_ISR);
                        if (status & ISR_ADC_DONE) {
-                               outw(ISR_ADC_DONE, ADDR_REG(REG_ISR));
+                               outw(ISR_ADC_DONE, dev->iobase + REG_ISR);
                                break;
                        }
                }
-               if (i == TIMEOUT) {
-                       /* printk() should be used instead of printk()
-                        * whenever the code can be called from real-time. */
-                       printk(KERN_ERR "s526: ADC(0x%04x) timeout\n",
-                              inw(ADDR_REG(REG_ISR)));
+               if (i == TIMEOUT)
                        return -ETIMEDOUT;
-               }
 
                /* read data */
-               d = inw(ADDR_REG(REG_ADD));
-/* printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF)); */
+               d = inw(dev->iobase + REG_ADD);
 
                /* munge data */
                data[n] = d ^ 0x8000;
@@ -620,40 +471,30 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
                         struct comedi_insn *insn, unsigned int *data)
 {
-       int i;
-       int chan = CR_CHAN(insn->chanspec);
+       struct s526_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned short val;
+       int i;
 
-/* printk("s526_ao_winsn\n"); */
        val = chan << 1;
-/* outw(val, dev->iobase + REG_DAC); */
-       outw(val, ADDR_REG(REG_DAC));
+       outw(val, dev->iobase + REG_DAC);
 
-       /* Writing a list of values to an AO channel is probably not
-        * very useful, but that's how the interface is defined. */
        for (i = 0; i < insn->n; i++) {
-               /* a typical programming sequence */
-               /* write the data to preload register
-                * outw(data[i], dev->iobase + REG_ADD);
-                */
-               /* write the data to preload register */
-               outw(data[i], ADDR_REG(REG_ADD));
+               outw(data[i], dev->iobase + REG_ADD);
                devpriv->ao_readback[chan] = data[i];
-/* outw(val + 1, dev->iobase + REG_DAC);  starts the D/A conversion. */
-               outw(val + 1, ADDR_REG(REG_DAC)); /*starts the D/A conversion.*/
+               /* starts the D/A conversion */
+               outw(val + 1, dev->iobase + REG_DAC);
        }
 
-       /* return the number of samples read/written */
        return i;
 }
 
-/* AO subdevices should have a read insn as well as a write insn.
- * Usually this means copying a value stored in devpriv. */
 static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
                         struct comedi_insn *insn, unsigned int *data)
 {
+       struct s526_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int i;
-       int chan = CR_CHAN(insn->chanspec);
 
        for (i = 0; i < insn->n; i++)
                data[i] = devpriv->ao_readback[chan];
@@ -661,30 +502,18 @@ static int s526_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
        return i;
 }
 
-/* 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 */
 static int s526_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn, unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
        if (data[0]) {
                s->state &= ~data[0];
                s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outw(s->state, ADDR_REG(REG_DIO));
+
+               outw(s->state, dev->iobase + REG_DIO);
        }
 
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state & 0xFF; */
+       data[1] = inw(dev->iobase + REG_DIO) & 0xff;
 
        return insn->n;
 }
@@ -693,16 +522,9 @@ static int s526_dio_insn_config(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
        int group, mask;
 
-       printk(KERN_INFO "S526 DIO insn_config\n");
-
-       /* The input or output configuration of each digital line is
-        * configured by a special insn_config instruction.  chanspec
-        * contains the channel to be changed, and data[0] contains the
-        * value COMEDI_INPUT or COMEDI_OUTPUT. */
-
        group = chan >> 2;
        mask = 0xF << (group << 2);
        switch (data[0]) {
@@ -721,48 +543,31 @@ static int s526_dio_insn_config(struct comedi_device *dev,
        default:
                return -EINVAL;
        }
-       outw(s->state, ADDR_REG(REG_DIO));
+       outw(s->state, dev->iobase + REG_DIO);
 
        return 1;
 }
 
 static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
-       const struct s526_board *board = comedi_board(dev);
+       struct s526_private *devpriv;
        struct comedi_subdevice *s;
        int iobase;
-       int i, n;
        int ret;
-/* short value; */
-/* int subdev_channel = 0; */
-       union cmReg cmReg;
 
-       printk(KERN_INFO "comedi%d: s526: ", dev->minor);
+       dev->board_name = dev->driver->driver_name;
 
        iobase = it->options[0];
-       if (!iobase || !request_region(iobase, S526_IOSIZE, board->name)) {
+       if (!iobase || !request_region(iobase, S526_IOSIZE, dev->board_name)) {
                comedi_error(dev, "I/O port conflict");
                return -EIO;
        }
        dev->iobase = iobase;
 
-       printk("iobase=0x%lx\n", dev->iobase);
-
-       /*** make it a little quieter, exw, 8/29/06
-       for (i = 0; i < S526_NUM_PORTS; i++) {
-               printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]),
-                               inw(ADDR_REG(s526_ports[i])));
-       }
-       ***/
-
-       dev->board_name = board->name;
-
-/*
- * Allocate the private structure area.  alloc_private() is a
- * convenient macro defined in comedidev.h.
- */
-       if (alloc_private(dev, sizeof(struct s526_private)) < 0)
-               return -ENOMEM;
+       ret = alloc_private(dev, sizeof(*devpriv));
+       if (ret)
+               return ret;
+       devpriv = dev->private;
 
        ret = comedi_alloc_subdevices(dev, 4);
        if (ret)
@@ -772,33 +577,22 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */
        s->type = COMEDI_SUBD_COUNTER;
        s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
-       /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */
-       s->n_chan = board->gpct_chans;
+       s->n_chan = 4;
        s->maxdata = 0x00ffffff;        /* 24 bit counter */
        s->insn_read = s526_gpct_rinsn;
        s->insn_config = s526_gpct_insn_config;
        s->insn_write = s526_gpct_winsn;
 
-       /* Command are not implemented yet, however they are necessary to
-          allocate the necessary memory for the comedi_async struct (used
-          to trigger the GPCT in case of pulsegenerator function */
-       /* s->do_cmd = s526_gpct_cmd; */
-       /* s->do_cmdtest = s526_gpct_cmdtest; */
-       /* s->cancel = s526_gpct_cancel; */
-
        s = &dev->subdevices[1];
-       /* dev->read_subdev=s; */
        /* analog input subdevice */
        s->type = COMEDI_SUBD_AI;
-       /* we support differential */
        s->subdev_flags = SDF_READABLE | SDF_DIFF;
        /* channels 0 to 7 are the regular differential inputs */
        /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */
        s->n_chan = 10;
        s->maxdata = 0xffff;
        s->range_table = &range_bipolar10;
-       s->len_chanlist = 16;   /* This is the maximum chanlist length that
-                                  the board can handle */
+       s->len_chanlist = 16;
        s->insn_read = s526_ai_rinsn;
        s->insn_config = s526_ai_insn_config;
 
@@ -814,103 +608,16 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        s = &dev->subdevices[3];
        /* digital i/o subdevice */
-       if (board->have_dio) {
-               s->type = COMEDI_SUBD_DIO;
-               s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-               s->n_chan = 8;
-               s->maxdata = 1;
-               s->range_table = &range_digital;
-               s->insn_bits = s526_dio_insn_bits;
-               s->insn_config = s526_dio_insn_config;
-       } else {
-               s->type = COMEDI_SUBD_UNUSED;
-       }
-
-       printk(KERN_INFO "attached\n");
-
-       return 1;
-
-#if 0
-       /*  Example of Counter Application */
-       /* One-shot (software trigger) */
-       cmReg.reg.coutSource = 0;       /*  out RCAP */
-       cmReg.reg.coutPolarity = 1;     /*  Polarity inverted */
-       cmReg.reg.autoLoadResetRcap = 1;/*  Auto load 0:disabled, 1:enabled */
-       cmReg.reg.hwCtEnableSource = 3; /*  NOT RCAP */
-       cmReg.reg.ctEnableCtrl = 2;     /*  Hardware */
-       cmReg.reg.clockSource = 2;      /*  Internal */
-       cmReg.reg.countDir = 1; /*  Down */
-       cmReg.reg.countDirCtrl = 1;     /*  Software */
-       cmReg.reg.outputRegLatchCtrl = 0;       /*  latch on read */
-       cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-       cmReg.reg.reserved = 0;
-
-       outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
-
-       outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
-       outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
-
-       /*  Reset the counter */
-       outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
-       /*  Load the counter from PR0 */
-       outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel));
-       /*  Reset RCAP (fires one-shot) */
-       outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel));
-
-#else
-
-       /*  Set Counter Mode Register */
-       cmReg.reg.coutSource = 0;       /*  out RCAP */
-       cmReg.reg.coutPolarity = 0;     /*  Polarity inverted */
-       cmReg.reg.autoLoadResetRcap = 0;        /*  Auto load disabled */
-       cmReg.reg.hwCtEnableSource = 2; /*  NOT RCAP */
-       cmReg.reg.ctEnableCtrl = 1;     /*  1: Software,  >1 : Hardware */
-       cmReg.reg.clockSource = 3;      /*  x4 */
-       cmReg.reg.countDir = 0; /*  up */
-       cmReg.reg.countDirCtrl = 0;     /*  quadrature */
-       cmReg.reg.outputRegLatchCtrl = 0;       /*  latch on read */
-       cmReg.reg.preloadRegSel = 0;    /*  PR0 */
-       cmReg.reg.reserved = 0;
-
-       n = 0;
-       printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n",
-               cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
-       outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
-       udelay(1000);
-       printk(KERN_INFO "Read back mode reg=0x%04x\n",
-               inw(ADDR_CHAN_REG(REG_C0M, n)));
-
-       /*  Load the pre-load register high word */
-/* value = (short) (0x55); */
-/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */
-
-       /*  Load the pre-load register low word */
-/* value = (short)(0xaa55); */
-/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */
-
-       /*  Write the Counter Control Register */
-/* outw(value, ADDR_CHAN_REG(REG_C0C, 0)); */
-
-       /*  Reset the counter if it is software preload */
-       if (cmReg.reg.autoLoadResetRcap == 0) {
-               /*  Reset the counter */
-               outw(0x8000, ADDR_CHAN_REG(REG_C0C, n));
-               /*  Load the counter from PR0 */
-               outw(0x4000, ADDR_CHAN_REG(REG_C0C, n));
-       }
+       s->type = COMEDI_SUBD_DIO;
+       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+       s->n_chan = 8;
+       s->maxdata = 1;
+       s->range_table = &range_digital;
+       s->insn_bits = s526_dio_insn_bits;
+       s->insn_config = s526_dio_insn_config;
 
-       outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
-       udelay(1000);
-       printk(KERN_INFO "Read back mode reg=0x%04x\n",
-                       inw(ADDR_CHAN_REG(REG_C0M, n)));
+       dev_info(dev->class_dev, "%s attached\n", dev->board_name);
 
-#endif
-       printk(KERN_INFO "Current registres:\n");
-
-       for (i = 0; i < S526_NUM_PORTS; i++) {
-               printk(KERN_INFO "0x%02lx: 0x%04x\n",
-                       ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i])));
-       }
        return 1;
 }
 
@@ -925,9 +632,6 @@ static struct comedi_driver s526_driver = {
        .module         = THIS_MODULE,
        .attach         = s526_attach,
        .detach         = s526_detach,
-       .board_name     = &s526_boards[0].name,
-       .offset         = sizeof(struct s526_board),
-       .num_names      = ARRAY_SIZE(s526_boards),
 };
 module_comedi_driver(s526_driver);
 
index 7aac213fb6abdcddbea52d7a98be9bb23e59b893..bc5fc5cc4641aebd2f2a10e7fc8cf8be47afa911 100644 (file)
@@ -2293,10 +2293,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
        usbduxsub_tmp->pwm_cmd_running = 0;
 }
 
-/* common part of attach and attach_usb */
 static int usbdux_attach_common(struct comedi_device *dev,
-                               struct usbduxsub *udev,
-                               void *aux_data, int aux_len)
+                               struct usbduxsub *udev)
 {
        int ret;
        struct comedi_subdevice *s = NULL;
@@ -2306,10 +2304,6 @@ static int usbdux_attach_common(struct comedi_device *dev,
        /* pointer back to the corresponding comedi device */
        udev->comedidev = dev;
 
-       /* trying to upload the firmware into the chip */
-       if (aux_data)
-               firmwareUpload(udev, aux_data, aux_len);
-
        dev->board_name = "usbdux";
 
        /* set number of subdevices */
@@ -2429,48 +2423,6 @@ static int usbdux_attach_common(struct comedi_device *dev,
        return 0;
 }
 
-/* is called when comedi-config is called */
-static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
-{
-       int ret;
-       int index;
-       int i;
-       void *aux_data;
-       int aux_len;
-
-       dev->private = NULL;
-
-       aux_data = comedi_aux_data(it->options, 0);
-       aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
-       if (aux_data == NULL)
-               aux_len = 0;
-       else if (aux_len == 0)
-               aux_data = NULL;
-
-       down(&start_stop_sem);
-       /* find a valid device which has been detected by the probe function of
-        * the usb */
-       index = -1;
-       for (i = 0; i < NUMUSBDUX; i++) {
-               if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
-                       index = i;
-                       break;
-               }
-       }
-
-       if (index < 0) {
-               printk(KERN_ERR
-                      "comedi%d: usbdux: error: attach failed, no usbdux devs connected to the usb bus.\n",
-                      dev->minor);
-               ret = -ENODEV;
-       } else
-               ret = usbdux_attach_common(dev, &usbduxsub[index],
-                                          aux_data, aux_len);
-       up(&start_stop_sem);
-       return ret;
-}
-
-/* is called from comedi_usb_auto_config() */
 static int usbdux_attach_usb(struct comedi_device *dev,
                             struct usb_interface *uinterf)
 {
@@ -2492,7 +2444,7 @@ static int usbdux_attach_usb(struct comedi_device *dev,
                       dev->minor);
                ret = -ENODEV;
        } else
-               ret = usbdux_attach_common(dev, this_usbduxsub, NULL, 0);
+               ret = usbdux_attach_common(dev, this_usbduxsub);
        up(&start_stop_sem);
        return ret;
 }
@@ -2513,9 +2465,8 @@ static void usbdux_detach(struct comedi_device *dev)
 static struct comedi_driver usbdux_driver = {
        .driver_name    = "usbdux",
        .module         = THIS_MODULE,
-       .attach         = usbdux_attach,
-       .detach         = usbdux_detach,
        .attach_usb     = usbdux_attach_usb,
+       .detach         = usbdux_detach,
 };
 
 static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
index 3f68fc396301bebe65ddb97d2338d5f7d2877709..0f6c1392f6ce5ab8aef48dd9c1c789e708b4d8db 100644 (file)
@@ -1430,10 +1430,8 @@ static void tidy_up(struct usbduxfastsub_s *udfs)
        udfs->ai_cmd_running = 0;
 }
 
-/* common part of attach and attach_usb */
 static int usbduxfast_attach_common(struct comedi_device *dev,
-                                   struct usbduxfastsub_s *udfs,
-                                   void *aux_data, int aux_len)
+                                   struct usbduxfastsub_s *udfs)
 {
        int ret;
        struct comedi_subdevice *s;
@@ -1441,9 +1439,6 @@ static int usbduxfast_attach_common(struct comedi_device *dev,
        down(&udfs->sem);
        /* pointer back to the corresponding comedi device */
        udfs->comedidev = dev;
-       /* trying to upload the firmware into the chip */
-       if (aux_data)
-               firmwareUpload(udfs, aux_data, aux_len);
        dev->board_name = "usbduxfast";
        ret = comedi_alloc_subdevices(dev, 1);
        if (ret) {
@@ -1485,48 +1480,6 @@ static int usbduxfast_attach_common(struct comedi_device *dev,
        return 0;
 }
 
-/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */
-static int usbduxfast_attach(struct comedi_device *dev,
-                            struct comedi_devconfig *it)
-{
-       int ret;
-       int index;
-       int i;
-       void *aux_data;
-       int aux_len;
-
-       dev->private = NULL;
-
-       aux_data = comedi_aux_data(it->options, 0);
-       aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
-       if (aux_data == NULL)
-               aux_len = 0;
-       else if (aux_len == 0)
-               aux_data = NULL;
-       down(&start_stop_sem);
-       /*
-        * find a valid device which has been detected by the
-        * probe function of the usb
-        */
-       index = -1;
-       for (i = 0; i < NUMUSBDUXFAST; i++) {
-               if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) {
-                       index = i;
-                       break;
-               }
-       }
-       if (index < 0) {
-               dev_err(dev->class_dev,
-                       "usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n");
-               ret = -ENODEV;
-       } else
-               ret = usbduxfast_attach_common(dev, &usbduxfastsub[index],
-                                              aux_data, aux_len);
-       up(&start_stop_sem);
-       return ret;
-}
-
-/* is called from comedi_usb_auto_config() */
 static int usbduxfast_attach_usb(struct comedi_device *dev,
                                 struct usb_interface *uinterf)
 {
@@ -1545,7 +1498,7 @@ static int usbduxfast_attach_usb(struct comedi_device *dev,
                       "usbduxfast: error: attach_usb failed, already attached\n");
                ret = -ENODEV;
        } else
-               ret = usbduxfast_attach_common(dev, udfs, NULL, 0);
+               ret = usbduxfast_attach_common(dev, udfs);
        up(&start_stop_sem);
        return ret;
 }
@@ -1568,9 +1521,8 @@ static void usbduxfast_detach(struct comedi_device *dev)
 static struct comedi_driver usbduxfast_driver = {
        .driver_name    = "usbduxfast",
        .module         = THIS_MODULE,
-       .attach         = usbduxfast_attach,
-       .detach         = usbduxfast_detach,
        .attach_usb     = usbduxfast_attach_usb,
+       .detach         = usbduxfast_detach,
 };
 
 static void usbduxfast_firmware_request_complete_handler(const struct firmware
index 034f5dfc05f8dbd7d06c18ba6f1c34045f8890e4..b4ab83f1215f89a8abc9219dba296462e4319a16 100644 (file)
@@ -2301,10 +2301,8 @@ static void tidy_up(struct usbduxsub *usbduxsub_tmp)
        usbduxsub_tmp->pwm_cmd_running = 0;
 }
 
-/* common part of attach and attach_usb */
 static int usbduxsigma_attach_common(struct comedi_device *dev,
-                                    struct usbduxsub *uds,
-                                    void *aux_data, int aux_len)
+                                    struct usbduxsub *uds)
 {
        int ret;
        struct comedi_subdevice *s;
@@ -2314,9 +2312,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
        down(&uds->sem);
        /* pointer back to the corresponding comedi device */
        uds->comedidev = dev;
-       /* trying to upload the firmware into the FX2 */
-       if (aux_data)
-               firmwareUpload(uds, aux_data, aux_len);
        dev->board_name = "usbduxsigma";
        /* set number of subdevices */
        if (uds->high_speed)
@@ -2419,47 +2414,6 @@ static int usbduxsigma_attach_common(struct comedi_device *dev,
        return 0;
 }
 
-/* is called for COMEDI_DEVCONFIG ioctl (when comedi_config is run) */
-static int usbduxsigma_attach(struct comedi_device *dev,
-                             struct comedi_devconfig *it)
-{
-       int ret;
-       int index;
-       int i;
-       void *aux_data;
-       int aux_len;
-
-       dev->private = NULL;
-
-       aux_data = comedi_aux_data(it->options, 0);
-       aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
-       if (aux_data == NULL)
-               aux_len = 0;
-       else if (aux_len == 0)
-               aux_data = NULL;
-
-       down(&start_stop_sem);
-       /* find a valid device which has been detected by the probe function of
-        * the usb */
-       index = -1;
-       for (i = 0; i < NUMUSBDUX; i++) {
-               if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) {
-                       index = i;
-                       break;
-               }
-       }
-       if (index < 0) {
-               dev_err(dev->class_dev,
-                       "usbduxsigma: error: attach failed, dev not connected to the usb bus.\n");
-               ret = -ENODEV;
-       } else
-               ret = usbduxsigma_attach_common(dev, &usbduxsub[index],
-                                               aux_data, aux_len);
-       up(&start_stop_sem);
-       return ret;
-}
-
-/* is called from comedi_usb_auto_config() */
 static int usbduxsigma_attach_usb(struct comedi_device *dev,
                                  struct usb_interface *uinterf)
 {
@@ -2478,7 +2432,7 @@ static int usbduxsigma_attach_usb(struct comedi_device *dev,
                       "usbduxsigma: error: attach_usb failed, already attached\n");
                ret = -ENODEV;
        } else
-               ret = usbduxsigma_attach_common(dev, uds, NULL, 0);
+               ret = usbduxsigma_attach_common(dev, uds);
        up(&start_stop_sem);
        return ret;
 }
@@ -2499,9 +2453,8 @@ static void usbduxsigma_detach(struct comedi_device *dev)
 static struct comedi_driver usbduxsigma_driver = {
        .driver_name    = "usbduxsigma",
        .module         = THIS_MODULE,
-       .attach         = usbduxsigma_attach,
-       .detach         = usbduxsigma_detach,
        .attach_usb     = usbduxsigma_attach_usb,
+       .detach         = usbduxsigma_detach,
 };
 
 static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
index f96416d1d2f7521d1f07814cc3b018aee1bb1ac8..3f20ea55b8d0b45452bba1ed2dc4350cd6be007a 100644 (file)
@@ -80,7 +80,9 @@ int comedi_close(struct comedi_device *d)
 }
 EXPORT_SYMBOL(comedi_close);
 
-static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
+static int comedi_do_insn(struct comedi_device *dev,
+                         struct comedi_insn *insn,
+                         unsigned int *data)
 {
        struct comedi_subdevice *s;
        int ret = 0;
@@ -115,11 +117,11 @@ static int comedi_do_insn(struct comedi_device *dev, struct comedi_insn *insn)
 
        switch (insn->insn) {
        case INSN_BITS:
-               ret = s->insn_bits(dev, s, insn, insn->data);
+               ret = s->insn_bits(dev, s, insn, data);
                break;
        case INSN_CONFIG:
                /* XXX should check instruction length */
-               ret = s->insn_config(dev, s, insn, insn->data);
+               ret = s->insn_config(dev, s, insn, data);
                break;
        default:
                ret = -EINVAL;
@@ -140,11 +142,10 @@ int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
        memset(&insn, 0, sizeof(insn));
        insn.insn = INSN_CONFIG;
        insn.n = 1;
-       insn.data = &io;
        insn.subdev = subdev;
        insn.chanspec = CR_PACK(chan, 0, 0);
 
-       return comedi_do_insn(dev, &insn);
+       return comedi_do_insn(dev, &insn, &io);
 }
 EXPORT_SYMBOL(comedi_dio_config);
 
@@ -158,13 +159,12 @@ int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev,
        memset(&insn, 0, sizeof(insn));
        insn.insn = INSN_BITS;
        insn.n = 2;
-       insn.data = data;
        insn.subdev = subdev;
 
        data[0] = mask;
        data[1] = *bits;
 
-       ret = comedi_do_insn(dev, &insn);
+       ret = comedi_do_insn(dev, &insn, data);
 
        *bits = data[1];
 
index acf0f0fe3b377e47c26fe595ee53c55e9442f4cb..543e8f2c407a048ece010a23fbb920f34d42a947 100644 (file)
 
 
 /*
- * This file also contains the implementation of the asyncronous
+ * This file also contains the implementation of the asynchronous
  * requests to the SME.
  *
- * Before calling an asyncronous SME function, we call sme_init_request()
+ * Before calling an asynchronous SME function, we call sme_init_request()
  * which gets hold of the SME semaphore and updates the request status.
  * The semaphore makes sure that there is only one pending request to
  * the SME at a time.
diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig
new file mode 100644 (file)
index 0000000..14b4449
--- /dev/null
@@ -0,0 +1,35 @@
+config DRM_IMX
+       tristate "DRM Support for Freescale i.MX"
+       select DRM_KMS_HELPER
+       select DRM_GEM_CMA_HELPER
+       select DRM_KMS_CMA_HELPER
+       depends on DRM && ARCH_MXC
+       help
+         enable i.MX graphics support
+
+config DRM_IMX_FB_HELPER
+       tristate "provide legacy framebuffer /dev/fb0"
+       select DRM_KMS_CMA_HELPER
+       depends on DRM_IMX
+       help
+         The DRM framework can provide a legacy /dev/fb0 framebuffer
+         for your device. This is necessary to get a framebuffer console
+         and also for appplications using the legacy framebuffer API
+
+config DRM_IMX_PARALLEL_DISPLAY
+       tristate "Support for parallel displays"
+       depends on DRM_IMX
+
+config DRM_IMX_IPUV3_CORE
+       tristate "IPUv3 core support"
+       depends on DRM_IMX
+       help
+         Choose this if you have a i.MX5/6 system and want
+         to use the IPU. This option only enables IPU base
+         support.
+
+config DRM_IMX_IPUV3
+       tristate "DRM Support for i.MX IPUv3"
+       depends on DRM_IMX
+       help
+         Choose this if you have a i.MX5 or i.MX6 processor.
diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile
new file mode 100644 (file)
index 0000000..83a9056
--- /dev/null
@@ -0,0 +1,9 @@
+
+imxdrm-objs := imx-drm-core.o imx-fb.o
+
+obj-$(CONFIG_DRM_IMX) += imxdrm.o
+
+obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o
+obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o
+obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/
+obj-$(CONFIG_DRM_IMX_IPUV3)    += ipuv3-crtc.o
diff --git a/drivers/staging/imx-drm/TODO b/drivers/staging/imx-drm/TODO
new file mode 100644 (file)
index 0000000..e52adc4
--- /dev/null
@@ -0,0 +1,22 @@
+TODO:
+- get DRM Maintainer review for this code
+- Factor out more code to common helper functions
+- decide where to put the base driver. It is not specific to a subsystem
+  and would be used by DRM/KMS and media/V4L2
+- convert irq driver to irq_domain_add_linear
+
+Missing features (not necessarily for moving out of staging):
+
+- Add KMS plane support for CRTC driver
+- Add LDB (LVDS Display Bridge) support
+- Add i.MX6 HDMI support
+- Add support for IC (Image converter)
+- Add support for CSI (CMOS Sensor interface)
+- Add support for VDIC (Video Deinterlacer)
+
+Many work-in-progress patches for the above features exist. Contact
+Sascha Hauer <kernel@pengutronix.de> if you are interested in working
+on a specific feature.
+
+Please send any patches to Greg Kroah-Hartman <gregkh@linuxfoundation.org> and
+Sascha Hauer <kernel@pengutronix.de>
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
new file mode 100644 (file)
index 0000000..1913199
--- /dev/null
@@ -0,0 +1,884 @@
+/*
+ * Freescale i.MX drm driver
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix
+ *
+ * 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 <linux/device.h>
+#include <linux/platform_device.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/fb.h>
+#include <linux/module.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "imx-drm.h"
+
+#define MAX_CRTC       4
+
+struct crtc_cookie {
+       void *cookie;
+       int id;
+       struct list_head list;
+};
+
+struct imx_drm_device {
+       struct drm_device                       *drm;
+       struct device                           *dev;
+       struct list_head                        crtc_list;
+       struct list_head                        encoder_list;
+       struct list_head                        connector_list;
+       struct mutex                            mutex;
+       int                                     references;
+       int                                     pipes;
+       struct drm_fbdev_cma                    *fbhelper;
+};
+
+struct imx_drm_crtc {
+       struct drm_crtc                         *crtc;
+       struct list_head                        list;
+       struct imx_drm_device                   *imxdrm;
+       int                                     pipe;
+       struct imx_drm_crtc_helper_funcs        imx_drm_helper_funcs;
+       struct module                           *owner;
+       struct crtc_cookie                      cookie;
+};
+
+struct imx_drm_encoder {
+       struct drm_encoder                      *encoder;
+       struct list_head                        list;
+       struct module                           *owner;
+       struct list_head                        possible_crtcs;
+};
+
+struct imx_drm_connector {
+       struct drm_connector                    *connector;
+       struct list_head                        list;
+       struct module                           *owner;
+};
+
+static int imx_drm_driver_firstopen(struct drm_device *drm)
+{
+       if (!imx_drm_device_get())
+               return -EINVAL;
+
+       return 0;
+}
+
+static void imx_drm_driver_lastclose(struct drm_device *drm)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+
+       if (imxdrm->fbhelper)
+               drm_fbdev_cma_restore_mode(imxdrm->fbhelper);
+
+       imx_drm_device_put();
+}
+
+static int imx_drm_driver_unload(struct drm_device *drm)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+
+       drm_mode_config_cleanup(imxdrm->drm);
+       drm_kms_helper_poll_fini(imxdrm->drm);
+
+       return 0;
+}
+
+/*
+ * We don't care at all for crtc numbers, but the core expects the
+ * crtcs to be numbered
+ */
+static struct imx_drm_crtc *imx_drm_crtc_by_num(struct imx_drm_device *imxdrm,
+               int num)
+{
+       struct imx_drm_crtc *imx_drm_crtc;
+
+       list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list)
+               if (imx_drm_crtc->pipe == num)
+                       return imx_drm_crtc;
+       return NULL;
+}
+
+int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type,
+               u32 interface_pix_fmt)
+{
+       struct imx_drm_device *imxdrm = crtc->dev->dev_private;
+       struct imx_drm_crtc *imx_crtc;
+       struct imx_drm_crtc_helper_funcs *helper;
+
+       mutex_lock(&imxdrm->mutex);
+
+       list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list)
+               if (imx_crtc->crtc == crtc)
+                       goto found;
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return -EINVAL;
+found:
+       mutex_unlock(&imxdrm->mutex);
+
+       helper = &imx_crtc->imx_drm_helper_funcs;
+       if (helper->set_interface_pix_fmt)
+               return helper->set_interface_pix_fmt(crtc,
+                               encoder_type, interface_pix_fmt);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format);
+
+int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
+{
+       return drm_vblank_get(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get);
+
+void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc)
+{
+       drm_vblank_put(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put);
+
+void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc)
+{
+       drm_handle_vblank(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe);
+}
+EXPORT_SYMBOL_GPL(imx_drm_handle_vblank);
+
+static int imx_drm_enable_vblank(struct drm_device *drm, int crtc)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct imx_drm_crtc *imx_drm_crtc;
+       int ret;
+
+       imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc);
+       if (!imx_drm_crtc)
+               return -EINVAL;
+
+       if (!imx_drm_crtc->imx_drm_helper_funcs.enable_vblank)
+               return -ENOSYS;
+
+       ret = imx_drm_crtc->imx_drm_helper_funcs.enable_vblank(
+                       imx_drm_crtc->crtc);
+
+       return ret;
+}
+
+static void imx_drm_disable_vblank(struct drm_device *drm, int crtc)
+{
+       struct imx_drm_device *imxdrm = drm->dev_private;
+       struct imx_drm_crtc *imx_drm_crtc;
+
+       imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc);
+       if (!imx_drm_crtc)
+               return;
+
+       if (!imx_drm_crtc->imx_drm_helper_funcs.disable_vblank)
+               return;
+
+       imx_drm_crtc->imx_drm_helper_funcs.disable_vblank(imx_drm_crtc->crtc);
+}
+
+static const struct file_operations imx_drm_driver_fops = {
+       .owner = THIS_MODULE,
+       .open = drm_open,
+       .release = drm_release,
+       .unlocked_ioctl = drm_ioctl,
+       .mmap = drm_gem_cma_mmap,
+       .poll = drm_poll,
+       .fasync = drm_fasync,
+       .read = drm_read,
+       .llseek = noop_llseek,
+};
+
+static struct imx_drm_device *imx_drm_device;
+
+static struct imx_drm_device *__imx_drm_device(void)
+{
+       return imx_drm_device;
+}
+
+struct drm_device *imx_drm_device_get(void)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_encoder *enc;
+       struct imx_drm_connector *con;
+       struct imx_drm_crtc *crtc;
+
+       mutex_lock(&imxdrm->mutex);
+
+       list_for_each_entry(enc, &imxdrm->encoder_list, list) {
+               if (!try_module_get(enc->owner)) {
+                       dev_err(imxdrm->dev, "could not get module %s\n",
+                                       module_name(enc->owner));
+                       goto unwind_enc;
+               }
+       }
+
+       list_for_each_entry(con, &imxdrm->connector_list, list) {
+               if (!try_module_get(con->owner)) {
+                       dev_err(imxdrm->dev, "could not get module %s\n",
+                                       module_name(con->owner));
+                       goto unwind_con;
+               }
+       }
+
+       list_for_each_entry(crtc, &imxdrm->crtc_list, list) {
+               if (!try_module_get(crtc->owner)) {
+                       dev_err(imxdrm->dev, "could not get module %s\n",
+                                       module_name(crtc->owner));
+                       goto unwind_crtc;
+               }
+       }
+
+       imxdrm->references++;
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return imxdrm->drm;
+
+unwind_crtc:
+       list_for_each_entry_continue_reverse(crtc, &imxdrm->crtc_list, list)
+               module_put(crtc->owner);
+unwind_con:
+       list_for_each_entry_continue_reverse(con, &imxdrm->connector_list, list)
+               module_put(con->owner);
+unwind_enc:
+       list_for_each_entry_continue_reverse(enc, &imxdrm->encoder_list, list)
+               module_put(enc->owner);
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return NULL;
+
+}
+EXPORT_SYMBOL_GPL(imx_drm_device_get);
+
+void imx_drm_device_put(void)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_encoder *enc;
+       struct imx_drm_connector *con;
+       struct imx_drm_crtc *crtc;
+
+       mutex_lock(&imxdrm->mutex);
+
+       list_for_each_entry(crtc, &imxdrm->crtc_list, list)
+               module_put(crtc->owner);
+
+       list_for_each_entry(con, &imxdrm->connector_list, list)
+               module_put(con->owner);
+
+       list_for_each_entry(enc, &imxdrm->encoder_list, list)
+               module_put(enc->owner);
+
+       imxdrm->references--;
+
+       mutex_unlock(&imxdrm->mutex);
+}
+EXPORT_SYMBOL_GPL(imx_drm_device_put);
+
+static int drm_mode_group_reinit(struct drm_device *dev)
+{
+       struct drm_mode_group *group = &dev->primary->mode_group;
+       uint32_t *id_list = group->id_list;
+       int ret;
+
+       ret = drm_mode_group_init_legacy_group(dev, group);
+       if (ret < 0)
+               return ret;
+
+       kfree(id_list);
+       return 0;
+}
+
+/*
+ * register an encoder to the drm core
+ */
+static int imx_drm_encoder_register(struct imx_drm_encoder *imx_drm_encoder)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       INIT_LIST_HEAD(&imx_drm_encoder->possible_crtcs);
+
+       drm_encoder_init(imxdrm->drm, imx_drm_encoder->encoder,
+                       imx_drm_encoder->encoder->funcs,
+                       imx_drm_encoder->encoder->encoder_type);
+
+       drm_mode_group_reinit(imxdrm->drm);
+
+       return 0;
+}
+
+/*
+ * unregister an encoder from the drm core
+ */
+static void imx_drm_encoder_unregister(struct imx_drm_encoder
+               *imx_drm_encoder)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       drm_encoder_cleanup(imx_drm_encoder->encoder);
+
+       drm_mode_group_reinit(imxdrm->drm);
+}
+
+/*
+ * register a connector to the drm core
+ */
+static int imx_drm_connector_register(
+               struct imx_drm_connector *imx_drm_connector)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       drm_connector_init(imxdrm->drm, imx_drm_connector->connector,
+                       imx_drm_connector->connector->funcs,
+                       imx_drm_connector->connector->connector_type);
+       drm_mode_group_reinit(imxdrm->drm);
+
+       return drm_sysfs_connector_add(imx_drm_connector->connector);
+}
+
+/*
+ * unregister a connector from the drm core
+ */
+static void imx_drm_connector_unregister(
+               struct imx_drm_connector *imx_drm_connector)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       drm_sysfs_connector_remove(imx_drm_connector->connector);
+       drm_connector_cleanup(imx_drm_connector->connector);
+
+       drm_mode_group_reinit(imxdrm->drm);
+}
+
+/*
+ * register a crtc to the drm core
+ */
+static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       int ret;
+
+       drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc,
+                       imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs);
+       ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256);
+       if (ret)
+               return ret;
+
+       drm_crtc_helper_add(imx_drm_crtc->crtc,
+                       imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs);
+
+       drm_mode_group_reinit(imxdrm->drm);
+
+       return 0;
+}
+
+/*
+ * Called by the CRTC driver when all CRTCs are registered. This
+ * puts all the pieces together and initializes the driver.
+ * Once this is called no more CRTCs can be registered since
+ * the drm core has hardcoded the number of crtcs in several
+ * places.
+ */
+static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       int ret;
+
+       imxdrm->drm = drm;
+
+       drm->dev_private = imxdrm;
+
+       /*
+        * enable drm irq mode.
+        * - with irq_enabled = 1, we can use the vblank feature.
+        *
+        * P.S. note that we wouldn't use drm irq handler but
+        *      just specific driver own one instead because
+        *      drm framework supports only one irq handler and
+        *      drivers can well take care of their interrupts
+        */
+       drm->irq_enabled = 1;
+
+       drm_mode_config_init(drm);
+       imx_drm_mode_config_init(drm);
+
+       mutex_lock(&imxdrm->mutex);
+
+       drm_kms_helper_poll_init(imxdrm->drm);
+
+       /* setup the grouping for the legacy output */
+       ret = drm_mode_group_init_legacy_group(imxdrm->drm,
+                       &imxdrm->drm->primary->mode_group);
+       if (ret)
+               goto err_init;
+
+       ret = drm_vblank_init(imxdrm->drm, MAX_CRTC);
+       if (ret)
+               goto err_init;
+
+       /*
+        * with vblank_disable_allowed = 1, vblank interrupt will be disabled
+        * by drm timer once a current process gives up ownership of
+        * vblank event.(after drm_vblank_put function is called)
+        */
+       imxdrm->drm->vblank_disable_allowed = 1;
+
+       ret = 0;
+
+err_init:
+       mutex_unlock(&imxdrm->mutex);
+
+       return ret;
+}
+
+static void imx_drm_update_possible_crtcs(void)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_crtc *imx_drm_crtc;
+       struct imx_drm_encoder *enc;
+       struct crtc_cookie *cookie;
+
+       list_for_each_entry(enc, &imxdrm->encoder_list, list) {
+               u32 possible_crtcs = 0;
+
+               list_for_each_entry(cookie, &enc->possible_crtcs, list) {
+                       list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list) {
+                               if (imx_drm_crtc->cookie.cookie == cookie->cookie &&
+                                               imx_drm_crtc->cookie.id == cookie->id) {
+                                       possible_crtcs |= 1 << imx_drm_crtc->pipe;
+                               }
+                       }
+               }
+               enc->encoder->possible_crtcs = possible_crtcs;
+               enc->encoder->possible_clones = possible_crtcs;
+       }
+}
+
+/*
+ * imx_drm_add_crtc - add a new crtc
+ *
+ * The return value if !NULL is a cookie for the caller to pass to
+ * imx_drm_remove_crtc later.
+ */
+int imx_drm_add_crtc(struct drm_crtc *crtc,
+               struct imx_drm_crtc **new_crtc,
+               const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs,
+               struct module *owner, void *cookie, int id)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_crtc *imx_drm_crtc;
+       const struct drm_crtc_funcs *crtc_funcs;
+       int ret;
+
+       mutex_lock(&imxdrm->mutex);
+
+       if (imxdrm->references) {
+               ret = -EBUSY;
+               goto err_busy;
+       }
+
+       imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
+       if (!imx_drm_crtc) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
+
+       imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs;
+       imx_drm_crtc->pipe = imxdrm->pipes++;
+       imx_drm_crtc->cookie.cookie = cookie;
+       imx_drm_crtc->cookie.id = id;
+
+       crtc_funcs = imx_drm_helper_funcs->crtc_funcs;
+
+       imx_drm_crtc->crtc = crtc;
+       imx_drm_crtc->imxdrm = imxdrm;
+
+       imx_drm_crtc->owner = owner;
+
+       list_add_tail(&imx_drm_crtc->list, &imxdrm->crtc_list);
+
+       *new_crtc = imx_drm_crtc;
+
+       ret = imx_drm_crtc_register(imx_drm_crtc);
+       if (ret)
+               goto err_register;
+
+       imx_drm_update_possible_crtcs();
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return 0;
+
+err_register:
+       kfree(imx_drm_crtc);
+err_alloc:
+err_busy:
+       mutex_unlock(&imxdrm->mutex);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(imx_drm_add_crtc);
+
+/*
+ * imx_drm_remove_crtc - remove a crtc
+ */
+int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc)
+{
+       struct imx_drm_device *imxdrm = imx_drm_crtc->imxdrm;
+
+       mutex_lock(&imxdrm->mutex);
+
+       drm_crtc_cleanup(imx_drm_crtc->crtc);
+
+       list_del(&imx_drm_crtc->list);
+
+       drm_mode_group_reinit(imxdrm->drm);
+
+       mutex_unlock(&imxdrm->mutex);
+
+       kfree(imx_drm_crtc);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_remove_crtc);
+
+/*
+ * imx_drm_add_encoder - add a new encoder
+ */
+int imx_drm_add_encoder(struct drm_encoder *encoder,
+               struct imx_drm_encoder **newenc, struct module *owner)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_encoder *imx_drm_encoder;
+       int ret;
+
+       mutex_lock(&imxdrm->mutex);
+
+       if (imxdrm->references) {
+               ret = -EBUSY;
+               goto err_busy;
+       }
+
+       imx_drm_encoder = kzalloc(sizeof(*imx_drm_encoder), GFP_KERNEL);
+       if (!imx_drm_encoder) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
+
+       imx_drm_encoder->encoder = encoder;
+       imx_drm_encoder->owner = owner;
+
+       ret = imx_drm_encoder_register(imx_drm_encoder);
+       if (ret) {
+               kfree(imx_drm_encoder);
+               ret = -ENOMEM;
+               goto err_register;
+       }
+
+       list_add_tail(&imx_drm_encoder->list, &imxdrm->encoder_list);
+
+       *newenc = imx_drm_encoder;
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return 0;
+
+err_register:
+       kfree(imx_drm_encoder);
+err_alloc:
+err_busy:
+       mutex_unlock(&imxdrm->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(imx_drm_add_encoder);
+
+int imx_drm_encoder_add_possible_crtcs(
+               struct imx_drm_encoder *imx_drm_encoder,
+               struct device_node *np)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct of_phandle_args args;
+       struct crtc_cookie *c;
+       int ret = 0;
+       int i;
+
+       if (!list_empty(&imx_drm_encoder->possible_crtcs))
+               return -EBUSY;
+
+       for (i = 0; !ret; i++) {
+               ret = of_parse_phandle_with_args(np, "crtcs",
+                               "#crtc-cells", i, &args);
+               if (ret < 0)
+                       break;
+
+               c = kzalloc(sizeof(*c), GFP_KERNEL);
+               if (!c) {
+                       of_node_put(args.np);
+                       return -ENOMEM;
+               }
+
+               c->cookie = args.np;
+               c->id = args.args_count > 0 ? args.args[0] : 0;
+
+               of_node_put(args.np);
+
+               mutex_lock(&imxdrm->mutex);
+
+               list_add_tail(&c->list, &imx_drm_encoder->possible_crtcs);
+
+               mutex_unlock(&imxdrm->mutex);
+       }
+
+       imx_drm_update_possible_crtcs();
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_encoder_add_possible_crtcs);
+
+int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder,
+               struct drm_crtc *crtc)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_crtc *imx_crtc;
+       int i = 0;
+
+       mutex_lock(&imxdrm->mutex);
+
+       list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) {
+               if (imx_crtc->crtc == crtc)
+                       goto found;
+               i++;
+       }
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return -EINVAL;
+found:
+       mutex_unlock(&imxdrm->mutex);
+
+       return i;
+}
+
+/*
+ * imx_drm_remove_encoder - remove an encoder
+ */
+int imx_drm_remove_encoder(struct imx_drm_encoder *imx_drm_encoder)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct crtc_cookie *c, *tmp;
+
+       mutex_lock(&imxdrm->mutex);
+
+       imx_drm_encoder_unregister(imx_drm_encoder);
+
+       list_del(&imx_drm_encoder->list);
+
+       list_for_each_entry_safe(c, tmp, &imx_drm_encoder->possible_crtcs,
+                       list)
+               kfree(c);
+
+       mutex_unlock(&imxdrm->mutex);
+
+       kfree(imx_drm_encoder);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_remove_encoder);
+
+/*
+ * imx_drm_add_connector - add a connector
+ */
+int imx_drm_add_connector(struct drm_connector *connector,
+               struct imx_drm_connector **new_con,
+               struct module *owner)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+       struct imx_drm_connector *imx_drm_connector;
+       int ret;
+
+       mutex_lock(&imxdrm->mutex);
+
+       if (imxdrm->references) {
+               ret = -EBUSY;
+               goto err_busy;
+       }
+
+       imx_drm_connector = kzalloc(sizeof(*imx_drm_connector), GFP_KERNEL);
+       if (!imx_drm_connector) {
+               ret = -ENOMEM;
+               goto err_alloc;
+       }
+
+       imx_drm_connector->connector = connector;
+       imx_drm_connector->owner = owner;
+
+       ret = imx_drm_connector_register(imx_drm_connector);
+       if (ret)
+               goto err_register;
+
+       list_add_tail(&imx_drm_connector->list, &imxdrm->connector_list);
+
+       *new_con = imx_drm_connector;
+
+       mutex_unlock(&imxdrm->mutex);
+
+       return 0;
+
+err_register:
+       kfree(imx_drm_connector);
+err_alloc:
+err_busy:
+       mutex_unlock(&imxdrm->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(imx_drm_add_connector);
+
+void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       imxdrm->fbhelper = fbdev_helper;
+}
+EXPORT_SYMBOL_GPL(imx_drm_fb_helper_set);
+
+/*
+ * imx_drm_remove_connector - remove a connector
+ */
+int imx_drm_remove_connector(struct imx_drm_connector *imx_drm_connector)
+{
+       struct imx_drm_device *imxdrm = __imx_drm_device();
+
+       mutex_lock(&imxdrm->mutex);
+
+       imx_drm_connector_unregister(imx_drm_connector);
+
+       list_del(&imx_drm_connector->list);
+
+       mutex_unlock(&imxdrm->mutex);
+
+       kfree(imx_drm_connector);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(imx_drm_remove_connector);
+
+static struct drm_ioctl_desc imx_drm_ioctls[] = {
+       /* none so far */
+};
+
+static struct drm_driver imx_drm_driver = {
+       .driver_features        = DRIVER_MODESET | DRIVER_GEM,
+       .load                   = imx_drm_driver_load,
+       .unload                 = imx_drm_driver_unload,
+       .firstopen              = imx_drm_driver_firstopen,
+       .lastclose              = imx_drm_driver_lastclose,
+       .gem_free_object        = drm_gem_cma_free_object,
+       .gem_vm_ops             = &drm_gem_cma_vm_ops,
+       .dumb_create            = drm_gem_cma_dumb_create,
+       .dumb_map_offset        = drm_gem_cma_dumb_map_offset,
+       .dumb_destroy           = drm_gem_cma_dumb_destroy,
+
+       .get_vblank_counter     = drm_vblank_count,
+       .enable_vblank          = imx_drm_enable_vblank,
+       .disable_vblank         = imx_drm_disable_vblank,
+       .ioctls                 = imx_drm_ioctls,
+       .num_ioctls             = ARRAY_SIZE(imx_drm_ioctls),
+       .fops                   = &imx_drm_driver_fops,
+       .name                   = "imx-drm",
+       .desc                   = "i.MX DRM graphics",
+       .date                   = "20120507",
+       .major                  = 1,
+       .minor                  = 0,
+       .patchlevel             = 0,
+};
+
+static int imx_drm_platform_probe(struct platform_device *pdev)
+{
+       imx_drm_device->dev = &pdev->dev;
+
+       return drm_platform_init(&imx_drm_driver, pdev);
+}
+
+static int imx_drm_platform_remove(struct platform_device *pdev)
+{
+       drm_platform_exit(&imx_drm_driver, pdev);
+
+       return 0;
+}
+
+static struct platform_driver imx_drm_pdrv = {
+       .probe          = imx_drm_platform_probe,
+       .remove         = __devexit_p(imx_drm_platform_remove),
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "imx-drm",
+       },
+};
+
+static struct platform_device *imx_drm_pdev;
+
+static int __init imx_drm_init(void)
+{
+       int ret;
+
+       imx_drm_device = kzalloc(sizeof(*imx_drm_device), GFP_KERNEL);
+       if (!imx_drm_device)
+               return -ENOMEM;
+
+       mutex_init(&imx_drm_device->mutex);
+       INIT_LIST_HEAD(&imx_drm_device->crtc_list);
+       INIT_LIST_HEAD(&imx_drm_device->connector_list);
+       INIT_LIST_HEAD(&imx_drm_device->encoder_list);
+
+       imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0);
+       if (!imx_drm_pdev) {
+               ret = -EINVAL;
+               goto err_pdev;
+       }
+
+       imx_drm_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32),
+
+       ret = platform_driver_register(&imx_drm_pdrv);
+       if (ret)
+               goto err_pdrv;
+
+       return 0;
+
+err_pdrv:
+       platform_device_unregister(imx_drm_pdev);
+err_pdev:
+       kfree(imx_drm_device);
+
+       return ret;
+}
+
+static void __exit imx_drm_exit(void)
+{
+       platform_device_unregister(imx_drm_pdev);
+       platform_driver_unregister(&imx_drm_pdrv);
+
+       kfree(imx_drm_device);
+}
+
+module_init(imx_drm_init);
+module_exit(imx_drm_exit);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("i.MX drm driver core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h
new file mode 100644 (file)
index 0000000..ae28a49
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _IMX_DRM_H_
+#define _IMX_DRM_H_
+
+struct imx_drm_crtc;
+struct drm_fbdev_cma;
+
+struct imx_drm_crtc_helper_funcs {
+       int (*enable_vblank)(struct drm_crtc *crtc);
+       void (*disable_vblank)(struct drm_crtc *crtc);
+       int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
+                       u32 pix_fmt);
+       const struct drm_crtc_helper_funcs *crtc_helper_funcs;
+       const struct drm_crtc_funcs *crtc_funcs;
+};
+
+int imx_drm_add_crtc(struct drm_crtc *crtc,
+               struct imx_drm_crtc **new_crtc,
+               const struct imx_drm_crtc_helper_funcs *imx_helper_funcs,
+               struct module *owner, void *cookie, int id);
+int imx_drm_remove_crtc(struct imx_drm_crtc *);
+int imx_drm_init_drm(struct platform_device *pdev,
+               int preferred_bpp);
+int imx_drm_exit_drm(void);
+
+int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc);
+void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc);
+void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc);
+
+struct imx_drm_encoder;
+int imx_drm_add_encoder(struct drm_encoder *encoder,
+               struct imx_drm_encoder **new_enc,
+               struct module *owner);
+int imx_drm_remove_encoder(struct imx_drm_encoder *);
+
+struct imx_drm_connector;
+int imx_drm_add_connector(struct drm_connector *connector,
+               struct imx_drm_connector **new_con,
+               struct module *owner);
+int imx_drm_remove_connector(struct imx_drm_connector *);
+
+void imx_drm_mode_config_init(struct drm_device *drm);
+
+struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
+
+struct drm_device *imx_drm_device_get(void);
+void imx_drm_device_put(void);
+int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type,
+               u32 interface_pix_fmt);
+void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper);
+
+struct device_node;
+
+int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder,
+               struct drm_crtc *crtc);
+int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder,
+               struct device_node *np);
+
+#endif /* _IMX_DRM_H_ */
diff --git a/drivers/staging/imx-drm/imx-fb.c b/drivers/staging/imx-drm/imx-fb.c
new file mode 100644 (file)
index 0000000..03a7b4e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * i.MX drm driver
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * Based on Samsung Exynos code
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * 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 <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "imx-drm.h"
+
+static struct drm_mode_config_funcs imx_drm_mode_config_funcs = {
+       .fb_create = drm_fb_cma_create,
+};
+
+void imx_drm_mode_config_init(struct drm_device *dev)
+{
+       dev->mode_config.min_width = 64;
+       dev->mode_config.min_height = 64;
+
+       /*
+        * set max width and height as default value(4096x4096).
+        * this value would be used to check framebuffer size limitation
+        * at drm_mode_addfb().
+        */
+       dev->mode_config.max_width = 4096;
+       dev->mode_config.max_height = 4096;
+
+       dev->mode_config.funcs = &imx_drm_mode_config_funcs;
+}
diff --git a/drivers/staging/imx-drm/imx-fbdev.c b/drivers/staging/imx-drm/imx-fbdev.c
new file mode 100644 (file)
index 0000000..8331739
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * i.MX drm driver
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * Based on Samsung Exynos code
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *
+ * 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 <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "imx-drm.h"
+
+#define MAX_CONNECTOR          4
+#define PREFERRED_BPP          16
+
+static struct drm_fbdev_cma *fbdev_cma;
+
+static int legacyfb_depth = 16;
+
+module_param(legacyfb_depth, int, 0444);
+
+static int __init imx_fb_helper_init(void)
+{
+       struct drm_device *drm = imx_drm_device_get();
+
+       if (!drm)
+               return -EINVAL;
+
+       if (legacyfb_depth != 16 && legacyfb_depth != 32) {
+               pr_warn("i.MX legacyfb: invalid legacyfb_depth setting. defaulting to 16bpp\n");
+               legacyfb_depth = 16;
+       }
+
+       fbdev_cma = drm_fbdev_cma_init(drm, legacyfb_depth,
+                       drm->mode_config.num_crtc, MAX_CONNECTOR);
+
+       if (IS_ERR(fbdev_cma)) {
+               imx_drm_device_put();
+               return PTR_ERR(fbdev_cma);
+       }
+
+       imx_drm_fb_helper_set(fbdev_cma);
+
+       return 0;
+}
+
+static void __exit imx_fb_helper_exit(void)
+{
+       imx_drm_fb_helper_set(NULL);
+       drm_fbdev_cma_fini(fbdev_cma);
+       imx_drm_device_put();
+}
+
+late_initcall(imx_fb_helper_init);
+module_exit(imx_fb_helper_exit);
+
+MODULE_DESCRIPTION("Freescale i.MX legacy fb driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/imx-drm/ipu-v3/Makefile b/drivers/staging/imx-drm/ipu-v3/Makefile
new file mode 100644 (file)
index 0000000..28ed72e
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += imx-ipu-v3.o
+
+imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o
diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h
new file mode 100644 (file)
index 0000000..74158dd
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License.  You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#ifndef __DRM_IPU_H__
+#define __DRM_IPU_H__
+
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/bitmap.h>
+#include <linux/fb.h>
+#include <linux/videodev2.h>
+
+struct ipu_soc;
+
+enum ipuv3_type {
+       IPUV3EX,
+       IPUV3M,
+       IPUV3H,
+};
+
+/*
+ * Bitfield of Display Interface signal polarities.
+ */
+struct ipu_di_signal_cfg {
+       unsigned datamask_en:1;
+       unsigned interlaced:1;
+       unsigned odd_field_first:1;
+       unsigned clksel_en:1;
+       unsigned clkidle_en:1;
+       unsigned data_pol:1;    /* true = inverted */
+       unsigned clk_pol:1;     /* true = rising edge */
+       unsigned enable_pol:1;
+       unsigned Hsync_pol:1;   /* true = active high */
+       unsigned Vsync_pol:1;
+
+       u16 width;
+       u16 height;
+       u32 pixel_fmt;
+       u16 h_start_width;
+       u16 h_sync_width;
+       u16 h_end_width;
+       u16 v_start_width;
+       u16 v_sync_width;
+       u16 v_end_width;
+       u32 v_to_h_sync;
+       unsigned long pixelclock;
+#define IPU_DI_CLKMODE_SYNC    (1 << 0)
+#define IPU_DI_CLKMODE_EXT     (1 << 1)
+       unsigned long clkflags;
+};
+
+enum ipu_color_space {
+       IPUV3_COLORSPACE_RGB,
+       IPUV3_COLORSPACE_YUV,
+       IPUV3_COLORSPACE_UNKNOWN,
+};
+
+struct ipuv3_channel;
+
+enum ipu_channel_irq {
+       IPU_IRQ_EOF = 0,
+       IPU_IRQ_NFACK = 64,
+       IPU_IRQ_NFB4EOF = 128,
+       IPU_IRQ_EOS = 192,
+};
+
+int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
+               enum ipu_channel_irq irq);
+
+#define IPU_IRQ_DP_SF_START            (448 + 2)
+#define IPU_IRQ_DP_SF_END              (448 + 3)
+#define IPU_IRQ_BG_SF_END              IPU_IRQ_DP_SF_END,
+#define IPU_IRQ_DC_FC_0                        (448 + 8)
+#define IPU_IRQ_DC_FC_1                        (448 + 9)
+#define IPU_IRQ_DC_FC_2                        (448 + 10)
+#define IPU_IRQ_DC_FC_3                        (448 + 11)
+#define IPU_IRQ_DC_FC_4                        (448 + 12)
+#define IPU_IRQ_DC_FC_6                        (448 + 13)
+#define IPU_IRQ_VSYNC_PRE_0            (448 + 14)
+#define IPU_IRQ_VSYNC_PRE_1            (448 + 15)
+
+/*
+ * IPU Image DMA Controller (idmac) functions
+ */
+struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned channel);
+void ipu_idmac_put(struct ipuv3_channel *);
+
+int ipu_idmac_enable_channel(struct ipuv3_channel *channel);
+int ipu_idmac_disable_channel(struct ipuv3_channel *channel);
+
+void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
+               bool doublebuffer);
+void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num);
+
+/*
+ * IPU Display Controller (dc) functions
+ */
+struct ipu_dc;
+struct ipu_di;
+struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel);
+void ipu_dc_put(struct ipu_dc *dc);
+int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
+               u32 pixel_fmt, u32 width);
+void ipu_dc_enable_channel(struct ipu_dc *dc);
+void ipu_dc_disable_channel(struct ipu_dc *dc);
+
+/*
+ * IPU Display Interface (di) functions
+ */
+struct ipu_di *ipu_di_get(struct ipu_soc *ipu, int disp);
+void ipu_di_put(struct ipu_di *);
+int ipu_di_disable(struct ipu_di *);
+int ipu_di_enable(struct ipu_di *);
+int ipu_di_get_num(struct ipu_di *);
+int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig);
+
+/*
+ * IPU Display Multi FIFO Controller (dmfc) functions
+ */
+struct dmfc_channel;
+int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc);
+void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc);
+int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc,
+               unsigned long bandwidth_mbs, int burstsize);
+void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc);
+int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width);
+struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipuv3_channel);
+void ipu_dmfc_put(struct dmfc_channel *dmfc);
+
+/*
+ * IPU Display Processor (dp) functions
+ */
+#define IPU_DP_FLOW_SYNC_BG    0
+#define IPU_DP_FLOW_SYNC_FG    1
+#define IPU_DP_FLOW_ASYNC0_BG  2
+#define IPU_DP_FLOW_ASYNC0_FG  3
+#define IPU_DP_FLOW_ASYNC1_BG  4
+#define IPU_DP_FLOW_ASYNC1_FG  5
+
+struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow);
+void ipu_dp_put(struct ipu_dp *);
+int ipu_dp_enable_channel(struct ipu_dp *dp);
+void ipu_dp_disable_channel(struct ipu_dp *dp);
+int ipu_dp_setup_channel(struct ipu_dp *dp,
+               enum ipu_color_space in, enum ipu_color_space out);
+int ipu_dp_set_window_pos(struct ipu_dp *, u16 x_pos, u16 y_pos);
+int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha,
+               bool bg_chan);
+
+#define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size))
+
+#define IPU_FIELD_UBO          IPU_CPMEM_WORD(0, 46, 22)
+#define IPU_FIELD_VBO          IPU_CPMEM_WORD(0, 68, 22)
+#define IPU_FIELD_IOX          IPU_CPMEM_WORD(0, 90, 4)
+#define IPU_FIELD_RDRW         IPU_CPMEM_WORD(0, 94, 1)
+#define IPU_FIELD_SO           IPU_CPMEM_WORD(0, 113, 1)
+#define IPU_FIELD_SLY          IPU_CPMEM_WORD(1, 102, 14)
+#define IPU_FIELD_SLUV         IPU_CPMEM_WORD(1, 128, 14)
+
+#define IPU_FIELD_XV           IPU_CPMEM_WORD(0, 0, 10)
+#define IPU_FIELD_YV           IPU_CPMEM_WORD(0, 10, 9)
+#define IPU_FIELD_XB           IPU_CPMEM_WORD(0, 19, 13)
+#define IPU_FIELD_YB           IPU_CPMEM_WORD(0, 32, 12)
+#define IPU_FIELD_NSB_B                IPU_CPMEM_WORD(0, 44, 1)
+#define IPU_FIELD_CF           IPU_CPMEM_WORD(0, 45, 1)
+#define IPU_FIELD_SX           IPU_CPMEM_WORD(0, 46, 12)
+#define IPU_FIELD_SY           IPU_CPMEM_WORD(0, 58, 11)
+#define IPU_FIELD_NS           IPU_CPMEM_WORD(0, 69, 10)
+#define IPU_FIELD_SDX          IPU_CPMEM_WORD(0, 79, 7)
+#define IPU_FIELD_SM           IPU_CPMEM_WORD(0, 86, 10)
+#define IPU_FIELD_SCC          IPU_CPMEM_WORD(0, 96, 1)
+#define IPU_FIELD_SCE          IPU_CPMEM_WORD(0, 97, 1)
+#define IPU_FIELD_SDY          IPU_CPMEM_WORD(0, 98, 7)
+#define IPU_FIELD_SDRX         IPU_CPMEM_WORD(0, 105, 1)
+#define IPU_FIELD_SDRY         IPU_CPMEM_WORD(0, 106, 1)
+#define IPU_FIELD_BPP          IPU_CPMEM_WORD(0, 107, 3)
+#define IPU_FIELD_DEC_SEL      IPU_CPMEM_WORD(0, 110, 2)
+#define IPU_FIELD_DIM          IPU_CPMEM_WORD(0, 112, 1)
+#define IPU_FIELD_BNDM         IPU_CPMEM_WORD(0, 114, 3)
+#define IPU_FIELD_BM           IPU_CPMEM_WORD(0, 117, 2)
+#define IPU_FIELD_ROT          IPU_CPMEM_WORD(0, 119, 1)
+#define IPU_FIELD_HF           IPU_CPMEM_WORD(0, 120, 1)
+#define IPU_FIELD_VF           IPU_CPMEM_WORD(0, 121, 1)
+#define IPU_FIELD_THE          IPU_CPMEM_WORD(0, 122, 1)
+#define IPU_FIELD_CAP          IPU_CPMEM_WORD(0, 123, 1)
+#define IPU_FIELD_CAE          IPU_CPMEM_WORD(0, 124, 1)
+#define IPU_FIELD_FW           IPU_CPMEM_WORD(0, 125, 13)
+#define IPU_FIELD_FH           IPU_CPMEM_WORD(0, 138, 12)
+#define IPU_FIELD_EBA0         IPU_CPMEM_WORD(1, 0, 29)
+#define IPU_FIELD_EBA1         IPU_CPMEM_WORD(1, 29, 29)
+#define IPU_FIELD_ILO          IPU_CPMEM_WORD(1, 58, 20)
+#define IPU_FIELD_NPB          IPU_CPMEM_WORD(1, 78, 7)
+#define IPU_FIELD_PFS          IPU_CPMEM_WORD(1, 85, 4)
+#define IPU_FIELD_ALU          IPU_CPMEM_WORD(1, 89, 1)
+#define IPU_FIELD_ALBM         IPU_CPMEM_WORD(1, 90, 3)
+#define IPU_FIELD_ID           IPU_CPMEM_WORD(1, 93, 2)
+#define IPU_FIELD_TH           IPU_CPMEM_WORD(1, 95, 7)
+#define IPU_FIELD_SL           IPU_CPMEM_WORD(1, 102, 14)
+#define IPU_FIELD_WID0         IPU_CPMEM_WORD(1, 116, 3)
+#define IPU_FIELD_WID1         IPU_CPMEM_WORD(1, 119, 3)
+#define IPU_FIELD_WID2         IPU_CPMEM_WORD(1, 122, 3)
+#define IPU_FIELD_WID3         IPU_CPMEM_WORD(1, 125, 3)
+#define IPU_FIELD_OFS0         IPU_CPMEM_WORD(1, 128, 5)
+#define IPU_FIELD_OFS1         IPU_CPMEM_WORD(1, 133, 5)
+#define IPU_FIELD_OFS2         IPU_CPMEM_WORD(1, 138, 5)
+#define IPU_FIELD_OFS3         IPU_CPMEM_WORD(1, 143, 5)
+#define IPU_FIELD_SXYS         IPU_CPMEM_WORD(1, 148, 1)
+#define IPU_FIELD_CRE          IPU_CPMEM_WORD(1, 149, 1)
+#define IPU_FIELD_DEC_SEL2     IPU_CPMEM_WORD(1, 150, 1)
+
+struct ipu_cpmem_word {
+       u32 data[5];
+       u32 res[3];
+};
+
+struct ipu_ch_param {
+       struct ipu_cpmem_word word[2];
+};
+
+void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v);
+u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs);
+struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel);
+void ipu_ch_param_dump(struct ipu_ch_param __iomem *p);
+
+static inline void ipu_ch_param_zero(struct ipu_ch_param __iomem *p)
+{
+       int i;
+       void __iomem *base = p;
+
+       for (i = 0; i < sizeof(*p) / sizeof(u32); i++)
+               writel(0, base + i * sizeof(u32));
+}
+
+static inline void ipu_cpmem_set_buffer(struct ipu_ch_param __iomem *p,
+               int bufnum, dma_addr_t buf)
+{
+       if (bufnum)
+               ipu_ch_param_write_field(p, IPU_FIELD_EBA1, buf >> 3);
+       else
+               ipu_ch_param_write_field(p, IPU_FIELD_EBA0, buf >> 3);
+}
+
+static inline void ipu_cpmem_set_resolution(struct ipu_ch_param __iomem *p,
+               int xres, int yres)
+{
+       ipu_ch_param_write_field(p, IPU_FIELD_FW, xres - 1);
+       ipu_ch_param_write_field(p, IPU_FIELD_FH, yres - 1);
+}
+
+static inline void ipu_cpmem_set_stride(struct ipu_ch_param __iomem *p,
+               int stride)
+{
+       ipu_ch_param_write_field(p, IPU_FIELD_SLY, stride - 1);
+}
+
+void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel);
+
+struct ipu_rgb {
+       struct fb_bitfield      red;
+       struct fb_bitfield      green;
+       struct fb_bitfield      blue;
+       struct fb_bitfield      transp;
+       int                     bits_per_pixel;
+};
+
+struct ipu_image {
+       struct v4l2_pix_format pix;
+       struct v4l2_rect rect;
+       dma_addr_t phys;
+};
+
+int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
+               int width);
+
+int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *,
+               struct ipu_rgb *rgb);
+
+static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p,
+               int stride)
+{
+       ipu_ch_param_write_field(p, IPU_FIELD_SO, 1);
+       ipu_ch_param_write_field(p, IPU_FIELD_ILO, stride / 8);
+       ipu_ch_param_write_field(p, IPU_FIELD_SLY, (stride * 2) - 1);
+};
+
+void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
+                       int stride, int height);
+void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p,
+               u32 pixel_format, int stride, int u_offset, int v_offset);
+int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat);
+int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
+               struct ipu_image *image);
+
+enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat);
+
+static inline void ipu_cpmem_set_burstsize(struct ipu_ch_param __iomem *p,
+               int burstsize)
+{
+       ipu_ch_param_write_field(p, IPU_FIELD_NPB, burstsize - 1);
+};
+
+struct ipu_client_platformdata {
+       int di;
+       int dc;
+       int dp;
+       int dmfc;
+       int dma[2];
+};
+
+#endif /* __DRM_IPU_H__ */
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c
new file mode 100644 (file)
index 0000000..f381960
--- /dev/null
@@ -0,0 +1,1143 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 <linux/module.h>
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+#include <linux/irq.h>
+#include <linux/of_device.h>
+#include <asm/mach/irq.h>
+
+#include "imx-ipu-v3.h"
+#include "ipu-prv.h"
+
+static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
+{
+       return readl(ipu->cm_reg + offset);
+}
+
+static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
+{
+       writel(value, ipu->cm_reg + offset);
+}
+
+static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
+{
+       return readl(ipu->idmac_reg + offset);
+}
+
+static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value,
+               unsigned offset)
+{
+       writel(value, ipu->idmac_reg + offset);
+}
+
+void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
+{
+       u32 val;
+
+       val = ipu_cm_read(ipu, IPU_SRM_PRI2);
+       val |= 0x8;
+       ipu_cm_write(ipu, val, IPU_SRM_PRI2);
+}
+EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update);
+
+struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+
+       return ipu->cpmem_base + channel->num;
+}
+EXPORT_SYMBOL_GPL(ipu_get_cpmem);
+
+void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       struct ipu_ch_param __iomem *p = ipu_get_cpmem(channel);
+       u32 val;
+
+       if (ipu->ipu_type == IPUV3EX)
+               ipu_ch_param_write_field(p, IPU_FIELD_ID, 1);
+
+       val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(channel->num));
+       val |= 1 << (channel->num % 32);
+       ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(channel->num));
+};
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority);
+
+void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v)
+{
+       u32 bit = (wbs >> 8) % 160;
+       u32 size = wbs & 0xff;
+       u32 word = (wbs >> 8) / 160;
+       u32 i = bit / 32;
+       u32 ofs = bit % 32;
+       u32 mask = (1 << size) - 1;
+       u32 val;
+
+       pr_debug("%s %d %d %d\n", __func__, word, bit , size);
+
+       val = readl(&base->word[word].data[i]);
+       val &= ~(mask << ofs);
+       val |= v << ofs;
+       writel(val, &base->word[word].data[i]);
+
+       if ((bit + size - 1) / 32 > i) {
+               val = readl(&base->word[word].data[i + 1]);
+               val &= ~(mask >> (ofs ? (32 - ofs) : 0));
+               val |= v >> (ofs ? (32 - ofs) : 0);
+               writel(val, &base->word[word].data[i + 1]);
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_ch_param_write_field);
+
+u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs)
+{
+       u32 bit = (wbs >> 8) % 160;
+       u32 size = wbs & 0xff;
+       u32 word = (wbs >> 8) / 160;
+       u32 i = bit / 32;
+       u32 ofs = bit % 32;
+       u32 mask = (1 << size) - 1;
+       u32 val = 0;
+
+       pr_debug("%s %d %d %d\n", __func__, word, bit , size);
+
+       val = (readl(&base->word[word].data[i]) >> ofs) & mask;
+
+       if ((bit + size - 1) / 32 > i) {
+               u32 tmp;
+               tmp = readl(&base->word[word].data[i + 1]);
+               tmp &= mask >> (ofs ? (32 - ofs) : 0);
+               val |= tmp << (ofs ? (32 - ofs) : 0);
+       }
+
+       return val;
+}
+EXPORT_SYMBOL_GPL(ipu_ch_param_read_field);
+
+int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p,
+               struct ipu_rgb *rgb)
+{
+       int bpp = 0, npb = 0, ro, go, bo, to;
+
+       ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset;
+       go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset;
+       bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset;
+       to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset;
+
+       ipu_ch_param_write_field(p, IPU_FIELD_WID0, rgb->red.length - 1);
+       ipu_ch_param_write_field(p, IPU_FIELD_OFS0, ro);
+       ipu_ch_param_write_field(p, IPU_FIELD_WID1, rgb->green.length - 1);
+       ipu_ch_param_write_field(p, IPU_FIELD_OFS1, go);
+       ipu_ch_param_write_field(p, IPU_FIELD_WID2, rgb->blue.length - 1);
+       ipu_ch_param_write_field(p, IPU_FIELD_OFS2, bo);
+
+       if (rgb->transp.length) {
+               ipu_ch_param_write_field(p, IPU_FIELD_WID3,
+                               rgb->transp.length - 1);
+               ipu_ch_param_write_field(p, IPU_FIELD_OFS3, to);
+       } else {
+               ipu_ch_param_write_field(p, IPU_FIELD_WID3, 7);
+               ipu_ch_param_write_field(p, IPU_FIELD_OFS3,
+                               rgb->bits_per_pixel);
+       }
+
+       switch (rgb->bits_per_pixel) {
+       case 32:
+               bpp = 0;
+               npb = 15;
+               break;
+       case 24:
+               bpp = 1;
+               npb = 19;
+               break;
+       case 16:
+               bpp = 3;
+               npb = 31;
+               break;
+       case 8:
+               bpp = 5;
+               npb = 63;
+               break;
+       default:
+               return -EINVAL;
+       }
+       ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp);
+       ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb);
+       ipu_ch_param_write_field(p, IPU_FIELD_PFS, 7); /* rgb mode */
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb);
+
+int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
+               int width)
+{
+       int bpp = 0, npb = 0;
+
+       switch (width) {
+       case 32:
+               bpp = 0;
+               npb = 15;
+               break;
+       case 24:
+               bpp = 1;
+               npb = 19;
+               break;
+       case 16:
+               bpp = 3;
+               npb = 31;
+               break;
+       case 8:
+               bpp = 5;
+               npb = 63;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp);
+       ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb);
+       ipu_ch_param_write_field(p, IPU_FIELD_PFS, 6); /* raw mode */
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough);
+
+void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p,
+               u32 pixel_format, int stride, int u_offset, int v_offset)
+{
+       switch (pixel_format) {
+       case V4L2_PIX_FMT_YUV420:
+               ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1);
+               ipu_ch_param_write_field(p, IPU_FIELD_UBO, u_offset / 8);
+               ipu_ch_param_write_field(p, IPU_FIELD_VBO, v_offset / 8);
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
+
+void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
+               int stride, int height)
+{
+       int u_offset, v_offset;
+       int uv_stride = 0;
+
+       switch (pixel_format) {
+       case V4L2_PIX_FMT_YUV420:
+               uv_stride = stride / 2;
+               u_offset = stride * height;
+               v_offset = u_offset + (uv_stride * height / 2);
+               ipu_cpmem_set_yuv_planar_full(p, V4L2_PIX_FMT_YUV420, stride,
+                               u_offset, v_offset);
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar);
+
+static struct ipu_rgb def_rgb_32 = {
+       .red    = { .offset = 16, .length = 8, },
+       .green  = { .offset =  8, .length = 8, },
+       .blue   = { .offset =  0, .length = 8, },
+       .transp = { .offset = 24, .length = 8, },
+       .bits_per_pixel = 32,
+};
+
+static struct ipu_rgb def_bgr_32 = {
+       .red    = { .offset = 16, .length = 8, },
+       .green  = { .offset =  8, .length = 8, },
+       .blue   = { .offset =  0, .length = 8, },
+       .transp = { .offset = 24, .length = 8, },
+       .bits_per_pixel = 32,
+};
+
+static struct ipu_rgb def_rgb_24 = {
+       .red    = { .offset =  0, .length = 8, },
+       .green  = { .offset =  8, .length = 8, },
+       .blue   = { .offset = 16, .length = 8, },
+       .transp = { .offset =  0, .length = 0, },
+       .bits_per_pixel = 24,
+};
+
+static struct ipu_rgb def_bgr_24 = {
+       .red    = { .offset = 16, .length = 8, },
+       .green  = { .offset =  8, .length = 8, },
+       .blue   = { .offset =  0, .length = 8, },
+       .transp = { .offset =  0, .length = 0, },
+       .bits_per_pixel = 24,
+};
+
+static struct ipu_rgb def_rgb_16 = {
+       .red    = { .offset = 11, .length = 5, },
+       .green  = { .offset =  5, .length = 6, },
+       .blue   = { .offset =  0, .length = 5, },
+       .transp = { .offset =  0, .length = 0, },
+       .bits_per_pixel = 16,
+};
+
+#define Y_OFFSET(pix, x, y)    ((x) + pix->width * (y))
+#define U_OFFSET(pix, x, y)    ((pix->width * pix->height) + \
+                                       (pix->width * (y) / 4) + (x) / 2)
+#define V_OFFSET(pix, x, y)    ((pix->width * pix->height) + \
+                                       (pix->width * pix->height / 4) + \
+                                       (pix->width * (y) / 4) + (x) / 2)
+
+int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
+{
+       switch (pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+               /* pix format */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2);
+               /* burst size */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63);
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               /* bits/pixel */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
+               /* pix format */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0xA);
+               /* burst size */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
+               break;
+       case V4L2_PIX_FMT_YUYV:
+               /* bits/pixel */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
+               /* pix format */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0x8);
+               /* burst size */
+               ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
+               break;
+       case V4L2_PIX_FMT_RGB32:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
+               break;
+       case V4L2_PIX_FMT_RGB565:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
+               break;
+       case V4L2_PIX_FMT_BGR32:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
+               break;
+       case V4L2_PIX_FMT_RGB24:
+               ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24);
+               break;
+       case V4L2_PIX_FMT_BGR24:
+               ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
+
+int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
+               struct ipu_image *image)
+{
+       struct v4l2_pix_format *pix = &image->pix;
+       int y_offset, u_offset, v_offset;
+
+       pr_debug("%s: resolution: %dx%d stride: %d\n",
+                       __func__, pix->width, pix->height,
+                       pix->bytesperline);
+
+       ipu_cpmem_set_resolution(cpmem, image->rect.width,
+                       image->rect.height);
+       ipu_cpmem_set_stride(cpmem, pix->bytesperline);
+
+       ipu_cpmem_set_fmt(cpmem, pix->pixelformat);
+
+       switch (pix->pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+               y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top);
+               u_offset = U_OFFSET(pix, image->rect.left,
+                               image->rect.top) - y_offset;
+               v_offset = V_OFFSET(pix, image->rect.left,
+                               image->rect.top) - y_offset;
+
+               ipu_cpmem_set_yuv_planar_full(cpmem, pix->pixelformat,
+                               pix->bytesperline, u_offset, v_offset);
+               ipu_cpmem_set_buffer(cpmem, 0, image->phys + y_offset);
+               break;
+       case V4L2_PIX_FMT_UYVY:
+               ipu_cpmem_set_buffer(cpmem, 0, image->phys +
+                               image->rect.left * 2 +
+                               image->rect.top * image->pix.bytesperline);
+               break;
+       case V4L2_PIX_FMT_RGB32:
+       case V4L2_PIX_FMT_BGR32:
+               ipu_cpmem_set_buffer(cpmem, 0, image->phys +
+                               image->rect.left * 4 +
+                               image->rect.top * image->pix.bytesperline);
+               break;
+       case V4L2_PIX_FMT_RGB565:
+               ipu_cpmem_set_buffer(cpmem, 0, image->phys +
+                               image->rect.left * 2 +
+                               image->rect.top * image->pix.bytesperline);
+               break;
+       case V4L2_PIX_FMT_RGB24:
+       case V4L2_PIX_FMT_BGR24:
+               ipu_cpmem_set_buffer(cpmem, 0, image->phys +
+                               image->rect.left * 3 +
+                               image->rect.top * image->pix.bytesperline);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_cpmem_set_image);
+
+enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
+{
+       switch (pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+       case V4L2_PIX_FMT_UYVY:
+       case V4L2_PIX_FMT_YVYU:
+               return IPUV3_COLORSPACE_YUV;
+       case V4L2_PIX_FMT_RGB32:
+       case V4L2_PIX_FMT_BGR32:
+       case V4L2_PIX_FMT_RGB24:
+       case V4L2_PIX_FMT_BGR24:
+       case V4L2_PIX_FMT_RGB565:
+               return IPUV3_COLORSPACE_RGB;
+       default:
+               return IPUV3_COLORSPACE_UNKNOWN;
+       }
+}
+EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace);
+
+struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
+{
+       struct ipuv3_channel *channel;
+
+       dev_dbg(ipu->dev, "%s %d\n", __func__, num);
+
+       if (num > 63)
+               return ERR_PTR(-ENODEV);
+
+       mutex_lock(&ipu->channel_lock);
+
+       channel = &ipu->channel[num];
+
+       if (channel->busy) {
+               channel = ERR_PTR(-EBUSY);
+               goto out;
+       }
+
+       channel->busy = 1;
+       channel->num = num;
+
+out:
+       mutex_unlock(&ipu->channel_lock);
+
+       return channel;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_get);
+
+void ipu_idmac_put(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+
+       dev_dbg(ipu->dev, "%s %d\n", __func__, channel->num);
+
+       mutex_lock(&ipu->channel_lock);
+
+       channel->busy = 0;
+
+       mutex_unlock(&ipu->channel_lock);
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_put);
+
+#define idma_mask(ch)                  (1 << (ch & 0x1f))
+
+void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
+               bool doublebuffer)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
+       if (doublebuffer)
+               reg |= idma_mask(channel->num);
+       else
+               reg &= ~idma_mask(channel->num);
+       ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer);
+
+int ipu_module_enable(struct ipu_soc *ipu, u32 mask)
+{
+       unsigned long lock_flags;
+       u32 val;
+
+       spin_lock_irqsave(&ipu->lock, lock_flags);
+
+       val = ipu_cm_read(ipu, IPU_DISP_GEN);
+
+       if (mask & IPU_CONF_DI0_EN)
+               val |= IPU_DI0_COUNTER_RELEASE;
+       if (mask & IPU_CONF_DI1_EN)
+               val |= IPU_DI1_COUNTER_RELEASE;
+
+       ipu_cm_write(ipu, val, IPU_DISP_GEN);
+
+       val = ipu_cm_read(ipu, IPU_CONF);
+       val |= mask;
+       ipu_cm_write(ipu, val, IPU_CONF);
+
+       spin_unlock_irqrestore(&ipu->lock, lock_flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_module_enable);
+
+int ipu_module_disable(struct ipu_soc *ipu, u32 mask)
+{
+       unsigned long lock_flags;
+       u32 val;
+
+       spin_lock_irqsave(&ipu->lock, lock_flags);
+
+       val = ipu_cm_read(ipu, IPU_CONF);
+       val &= ~mask;
+       ipu_cm_write(ipu, val, IPU_CONF);
+
+       val = ipu_cm_read(ipu, IPU_DISP_GEN);
+
+       if (mask & IPU_CONF_DI0_EN)
+               val &= ~IPU_DI0_COUNTER_RELEASE;
+       if (mask & IPU_CONF_DI1_EN)
+               val &= ~IPU_DI1_COUNTER_RELEASE;
+
+       ipu_cm_write(ipu, val, IPU_DISP_GEN);
+
+       spin_unlock_irqrestore(&ipu->lock, lock_flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_module_disable);
+
+void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       unsigned int chno = channel->num;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       /* Mark buffer as ready. */
+       if (buf_num == 0)
+               ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
+       else
+               ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer);
+
+int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
+       val |= idma_mask(channel->num);
+       ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
+
+int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
+{
+       struct ipu_soc *ipu = channel->ipu;
+       u32 val;
+       unsigned long flags;
+       unsigned long timeout;
+
+       timeout = jiffies + msecs_to_jiffies(50);
+       while (ipu_idmac_read(ipu, IDMAC_CHA_BUSY(channel->num)) &
+                       idma_mask(channel->num)) {
+               if (time_after(jiffies, timeout)) {
+                       dev_warn(ipu->dev, "disabling busy idmac channel %d\n",
+                                       channel->num);
+                       break;
+               }
+               cpu_relax();
+       }
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       /* Disable DMA channel(s) */
+       val = ipu_idmac_read(ipu, IDMAC_CHA_EN(channel->num));
+       val &= ~idma_mask(channel->num);
+       ipu_idmac_write(ipu, val, IDMAC_CHA_EN(channel->num));
+
+       /* Set channel buffers NOT to be ready */
+       ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */
+
+       if (ipu_cm_read(ipu, IPU_CHA_BUF0_RDY(channel->num)) &
+                       idma_mask(channel->num)) {
+               ipu_cm_write(ipu, idma_mask(channel->num),
+                            IPU_CHA_BUF0_RDY(channel->num));
+       }
+
+       if (ipu_cm_read(ipu, IPU_CHA_BUF1_RDY(channel->num)) &
+                       idma_mask(channel->num)) {
+               ipu_cm_write(ipu, idma_mask(channel->num),
+                            IPU_CHA_BUF1_RDY(channel->num));
+       }
+
+       ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
+
+       /* Reset the double buffer */
+       val = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
+       val &= ~idma_mask(channel->num);
+       ipu_cm_write(ipu, val, IPU_CHA_DB_MODE_SEL(channel->num));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
+
+static int ipu_reset(struct ipu_soc *ipu)
+{
+       unsigned long timeout;
+
+       ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
+
+       timeout = jiffies + msecs_to_jiffies(1000);
+       while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
+               if (time_after(jiffies, timeout))
+                       return -ETIME;
+               cpu_relax();
+       }
+
+       mdelay(300);
+
+       return 0;
+}
+
+struct ipu_devtype {
+       const char *name;
+       unsigned long cm_ofs;
+       unsigned long cpmem_ofs;
+       unsigned long srm_ofs;
+       unsigned long tpm_ofs;
+       unsigned long disp0_ofs;
+       unsigned long disp1_ofs;
+       unsigned long dc_tmpl_ofs;
+       unsigned long vdi_ofs;
+       enum ipuv3_type type;
+};
+
+static struct ipu_devtype ipu_type_imx51 = {
+       .name = "IPUv3EX",
+       .cm_ofs = 0x1e000000,
+       .cpmem_ofs = 0x1f000000,
+       .srm_ofs = 0x1f040000,
+       .tpm_ofs = 0x1f060000,
+       .disp0_ofs = 0x1e040000,
+       .disp1_ofs = 0x1e048000,
+       .dc_tmpl_ofs = 0x1f080000,
+       .vdi_ofs = 0x1e068000,
+       .type = IPUV3EX,
+};
+
+static struct ipu_devtype ipu_type_imx53 = {
+       .name = "IPUv3M",
+       .cm_ofs = 0x06000000,
+       .cpmem_ofs = 0x07000000,
+       .srm_ofs = 0x07040000,
+       .tpm_ofs = 0x07060000,
+       .disp0_ofs = 0x06040000,
+       .disp1_ofs = 0x06048000,
+       .dc_tmpl_ofs = 0x07080000,
+       .vdi_ofs = 0x06068000,
+       .type = IPUV3M,
+};
+
+static struct ipu_devtype ipu_type_imx6q = {
+       .name = "IPUv3H",
+       .cm_ofs = 0x00200000,
+       .cpmem_ofs = 0x00300000,
+       .srm_ofs = 0x00340000,
+       .tpm_ofs = 0x00360000,
+       .disp0_ofs = 0x00240000,
+       .disp1_ofs = 0x00248000,
+       .dc_tmpl_ofs = 0x00380000,
+       .vdi_ofs = 0x00268000,
+       .type = IPUV3H,
+};
+
+static const struct of_device_id imx_ipu_dt_ids[] = {
+       { .compatible = "fsl,imx51-ipu", .data = &ipu_type_imx51, },
+       { .compatible = "fsl,imx53-ipu", .data = &ipu_type_imx53, },
+       { .compatible = "fsl,imx6q-ipu", .data = &ipu_type_imx6q, },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_ipu_dt_ids);
+
+static int ipu_submodules_init(struct ipu_soc *ipu,
+               struct platform_device *pdev, unsigned long ipu_base,
+               struct clk *ipu_clk)
+{
+       char *unit;
+       int ret;
+       struct device *dev = &pdev->dev;
+       const struct ipu_devtype *devtype = ipu->devtype;
+
+       ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
+                       IPU_CONF_DI0_EN, ipu_clk);
+       if (ret) {
+               unit = "di0";
+               goto err_di_0;
+       }
+
+       ret = ipu_di_init(ipu, dev, 1, ipu_base + devtype->disp1_ofs,
+                       IPU_CONF_DI1_EN, ipu_clk);
+       if (ret) {
+               unit = "di1";
+               goto err_di_1;
+       }
+
+       ret = ipu_dc_init(ipu, dev, ipu_base + devtype->cm_ofs +
+                       IPU_CM_DC_REG_OFS, ipu_base + devtype->dc_tmpl_ofs);
+       if (ret) {
+               unit = "dc_template";
+               goto err_dc;
+       }
+
+       ret = ipu_dmfc_init(ipu, dev, ipu_base +
+                       devtype->cm_ofs + IPU_CM_DMFC_REG_OFS, ipu_clk);
+       if (ret) {
+               unit = "dmfc";
+               goto err_dmfc;
+       }
+
+       ret = ipu_dp_init(ipu, dev, ipu_base + devtype->srm_ofs);
+       if (ret) {
+               unit = "dp";
+               goto err_dp;
+       }
+
+       return 0;
+
+err_dp:
+       ipu_dmfc_exit(ipu);
+err_dmfc:
+       ipu_dc_exit(ipu);
+err_dc:
+       ipu_di_exit(ipu, 1);
+err_di_1:
+       ipu_di_exit(ipu, 0);
+err_di_0:
+       dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret);
+       return ret;
+}
+
+static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
+{
+       unsigned long status;
+       int i, bit, irq_base;
+
+       for (i = 0; i < num_regs; i++) {
+
+               status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
+               status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
+
+               irq_base = ipu->irq_start + regs[i] * 32;
+               for_each_set_bit(bit, &status, 32)
+                       generic_handle_irq(irq_base + bit);
+       }
+}
+
+static void ipu_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
+       const int int_reg[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
+       struct irq_chip *chip = irq_get_chip(irq);
+
+       chained_irq_enter(chip, desc);
+
+       ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
+
+       chained_irq_exit(chip, desc);
+}
+
+static void ipu_err_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+       struct ipu_soc *ipu = irq_desc_get_handler_data(desc);
+       const int int_reg[] = { 4, 5, 8, 9};
+       struct irq_chip *chip = irq_get_chip(irq);
+
+       chained_irq_enter(chip, desc);
+
+       ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
+
+       chained_irq_exit(chip, desc);
+}
+
+static void ipu_ack_irq(struct irq_data *d)
+{
+       struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->irq - ipu->irq_start;
+
+       ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32));
+}
+
+static void ipu_unmask_irq(struct irq_data *d)
+{
+       struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->irq - ipu->irq_start;
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32));
+       reg |= 1 << (irq % 32);
+       ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+}
+
+static void ipu_mask_irq(struct irq_data *d)
+{
+       struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
+       unsigned int irq = d->irq - ipu->irq_start;
+       unsigned long flags;
+       u32 reg;
+
+       spin_lock_irqsave(&ipu->lock, flags);
+
+       reg = ipu_cm_read(ipu, IPU_INT_CTRL(irq / 32));
+       reg &= ~(1 << (irq % 32));
+       ipu_cm_write(ipu, reg, IPU_INT_CTRL(irq / 32));
+
+       spin_unlock_irqrestore(&ipu->lock, flags);
+}
+
+static struct irq_chip ipu_irq_chip = {
+       .name = "IPU",
+       .irq_ack = ipu_ack_irq,
+       .irq_mask = ipu_mask_irq,
+       .irq_unmask = ipu_unmask_irq,
+};
+
+int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
+               enum ipu_channel_irq irq_type)
+{
+       return ipu->irq_start + irq_type + channel->num;
+}
+EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
+
+static void ipu_submodules_exit(struct ipu_soc *ipu)
+{
+       ipu_dp_exit(ipu);
+       ipu_dmfc_exit(ipu);
+       ipu_dc_exit(ipu);
+       ipu_di_exit(ipu, 1);
+       ipu_di_exit(ipu, 0);
+}
+
+static int platform_remove_devices_fn(struct device *dev, void *unused)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+
+       platform_device_unregister(pdev);
+
+       return 0;
+}
+
+static void platform_device_unregister_children(struct platform_device *pdev)
+{
+       device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn);
+}
+
+struct ipu_platform_reg {
+       struct ipu_client_platformdata pdata;
+       const char *name;
+};
+
+static const struct ipu_platform_reg client_reg[] = {
+       {
+               .pdata = {
+                       .di = 0,
+                       .dc = 5,
+                       .dp = IPU_DP_FLOW_SYNC_BG,
+                       .dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
+                       .dma[1] = -EINVAL,
+               },
+               .name = "imx-ipuv3-crtc",
+       }, {
+               .pdata = {
+                       .di = 1,
+                       .dc = 1,
+                       .dp = -EINVAL,
+                       .dma[0] = IPUV3_CHANNEL_MEM_DC_SYNC,
+                       .dma[1] = -EINVAL,
+               },
+               .name = "imx-ipuv3-crtc",
+       },
+};
+
+static int ipu_client_id;
+
+static int ipu_add_subdevice_pdata(struct device *dev,
+               const struct ipu_platform_reg *reg)
+{
+       struct platform_device *pdev;
+
+       pdev = platform_device_register_data(dev, reg->name, ipu_client_id++,
+                       &reg->pdata, sizeof(struct ipu_platform_reg));
+
+       return pdev ? 0 : -EINVAL;
+}
+
+static int ipu_add_client_devices(struct ipu_soc *ipu)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
+               const struct ipu_platform_reg *reg = &client_reg[i];
+               ret = ipu_add_subdevice_pdata(ipu->dev, reg);
+               if (ret)
+                       goto err_register;
+       }
+
+       return 0;
+
+err_register:
+       platform_device_unregister_children(to_platform_device(ipu->dev));
+
+       return ret;
+}
+
+static int ipu_irq_init(struct ipu_soc *ipu)
+{
+       int i;
+
+       ipu->irq_start = irq_alloc_descs(-1, 0, IPU_NUM_IRQS, 0);
+       if (ipu->irq_start < 0)
+               return ipu->irq_start;
+
+       for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) {
+               irq_set_chip_and_handler(i, &ipu_irq_chip, handle_level_irq);
+               set_irq_flags(i, IRQF_VALID);
+               irq_set_chip_data(i, ipu);
+       }
+
+       irq_set_chained_handler(ipu->irq_sync, ipu_irq_handler);
+       irq_set_handler_data(ipu->irq_sync, ipu);
+       irq_set_chained_handler(ipu->irq_err, ipu_err_irq_handler);
+       irq_set_handler_data(ipu->irq_err, ipu);
+
+       return 0;
+}
+
+static void ipu_irq_exit(struct ipu_soc *ipu)
+{
+       int i;
+
+       irq_set_chained_handler(ipu->irq_err, NULL);
+       irq_set_handler_data(ipu->irq_err, NULL);
+       irq_set_chained_handler(ipu->irq_sync, NULL);
+       irq_set_handler_data(ipu->irq_sync, NULL);
+
+       for (i = ipu->irq_start; i < ipu->irq_start + IPU_NUM_IRQS; i++) {
+               set_irq_flags(i, 0);
+               irq_set_chip(i, NULL);
+               irq_set_chip_data(i, NULL);
+       }
+
+       irq_free_descs(ipu->irq_start, IPU_NUM_IRQS);
+}
+
+static int __devinit ipu_probe(struct platform_device *pdev)
+{
+       const struct of_device_id *of_id =
+                       of_match_device(imx_ipu_dt_ids, &pdev->dev);
+       struct ipu_soc *ipu;
+       struct resource *res;
+       unsigned long ipu_base;
+       int i, ret, irq_sync, irq_err;
+       const struct ipu_devtype *devtype;
+
+       devtype = of_id->data;
+
+       dev_info(&pdev->dev, "Initializing %s\n", devtype->name);
+
+       irq_sync = platform_get_irq(pdev, 0);
+       irq_err = platform_get_irq(pdev, 1);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       dev_info(&pdev->dev, "irq_sync: %d irq_err: %d\n",
+                       irq_sync, irq_err);
+
+       if (!res || irq_sync < 0 || irq_err < 0)
+               return -ENODEV;
+
+       ipu_base = res->start;
+
+       ipu = devm_kzalloc(&pdev->dev, sizeof(*ipu), GFP_KERNEL);
+       if (!ipu)
+               return -ENODEV;
+
+       for (i = 0; i < 64; i++)
+               ipu->channel[i].ipu = ipu;
+       ipu->devtype = devtype;
+       ipu->ipu_type = devtype->type;
+
+       spin_lock_init(&ipu->lock);
+       mutex_init(&ipu->channel_lock);
+
+       dev_info(&pdev->dev, "cm_reg:   0x%08lx\n",
+                       ipu_base + devtype->cm_ofs);
+       dev_info(&pdev->dev, "idmac:    0x%08lx\n",
+                       ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS);
+       dev_info(&pdev->dev, "cpmem:    0x%08lx\n",
+                       ipu_base + devtype->cpmem_ofs);
+       dev_info(&pdev->dev, "disp0:    0x%08lx\n",
+                       ipu_base + devtype->disp0_ofs);
+       dev_info(&pdev->dev, "disp1:    0x%08lx\n",
+                       ipu_base + devtype->disp1_ofs);
+       dev_info(&pdev->dev, "srm:      0x%08lx\n",
+                       ipu_base + devtype->srm_ofs);
+       dev_info(&pdev->dev, "tpm:      0x%08lx\n",
+                       ipu_base + devtype->tpm_ofs);
+       dev_info(&pdev->dev, "dc:       0x%08lx\n",
+                       ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS);
+       dev_info(&pdev->dev, "ic:       0x%08lx\n",
+                       ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS);
+       dev_info(&pdev->dev, "dmfc:     0x%08lx\n",
+                       ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS);
+       dev_info(&pdev->dev, "vdi:      0x%08lx\n",
+                       ipu_base + devtype->vdi_ofs);
+
+       ipu->cm_reg = devm_ioremap(&pdev->dev,
+                       ipu_base + devtype->cm_ofs, PAGE_SIZE);
+       ipu->idmac_reg = devm_ioremap(&pdev->dev,
+                       ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS,
+                       PAGE_SIZE);
+       ipu->cpmem_base = devm_ioremap(&pdev->dev,
+                       ipu_base + devtype->cpmem_ofs, PAGE_SIZE);
+
+       if (!ipu->cm_reg || !ipu->idmac_reg || !ipu->cpmem_base) {
+               ret = -ENOMEM;
+               goto failed_ioremap;
+       }
+
+       ipu->clk = devm_clk_get(&pdev->dev, "bus");
+       if (IS_ERR(ipu->clk)) {
+               ret = PTR_ERR(ipu->clk);
+               dev_err(&pdev->dev, "clk_get failed with %d", ret);
+               goto failed_clk_get;
+       }
+
+       platform_set_drvdata(pdev, ipu);
+
+       clk_prepare_enable(ipu->clk);
+
+       ipu->dev = &pdev->dev;
+       ipu->irq_sync = irq_sync;
+       ipu->irq_err = irq_err;
+
+       ret = ipu_irq_init(ipu);
+       if (ret)
+               goto out_failed_irq;
+
+       ipu_reset(ipu);
+
+       /* Set MCU_T to divide MCU access window into 2 */
+       ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
+                       IPU_DISP_GEN);
+
+       ret = ipu_submodules_init(ipu, pdev, ipu_base, ipu->clk);
+       if (ret)
+               goto failed_submodules_init;
+
+       ret = ipu_add_client_devices(ipu);
+       if (ret) {
+               dev_err(&pdev->dev, "adding client devices failed with %d\n",
+                               ret);
+               goto failed_add_clients;
+       }
+
+       return 0;
+
+failed_add_clients:
+       ipu_submodules_exit(ipu);
+failed_submodules_init:
+       ipu_irq_exit(ipu);
+out_failed_irq:
+       clk_disable_unprepare(ipu->clk);
+failed_clk_get:
+failed_ioremap:
+       return ret;
+}
+
+static int __devexit ipu_remove(struct platform_device *pdev)
+{
+       struct ipu_soc *ipu = platform_get_drvdata(pdev);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       platform_device_unregister_children(pdev);
+       ipu_submodules_exit(ipu);
+       ipu_irq_exit(ipu);
+
+       clk_disable_unprepare(ipu->clk);
+
+       return 0;
+}
+
+static struct platform_driver imx_ipu_driver = {
+       .driver = {
+               .name = "imx-ipuv3",
+               .of_match_table = imx_ipu_dt_ids,
+       },
+       .probe = ipu_probe,
+       .remove = __devexit_p(ipu_remove),
+};
+
+module_platform_driver(imx_ipu_driver);
+
+MODULE_DESCRIPTION("i.MX IPU v3 driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dc.c b/drivers/staging/imx-drm/ipu-v3/ipu-dc.c
new file mode 100644 (file)
index 0000000..93c7579
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 <linux/export.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "imx-ipu-v3.h"
+#include "ipu-prv.h"
+
+#define DC_MAP_CONF_PTR(n)     (0x108 + ((n) & ~0x1) * 2)
+#define DC_MAP_CONF_VAL(n)     (0x144 + ((n) & ~0x1) * 2)
+
+#define DC_EVT_NF              0
+#define DC_EVT_NL              1
+#define DC_EVT_EOF             2
+#define DC_EVT_NFIELD          3
+#define DC_EVT_EOL             4
+#define DC_EVT_EOFIELD         5
+#define DC_EVT_NEW_ADDR                6
+#define DC_EVT_NEW_CHAN                7
+#define DC_EVT_NEW_DATA                8
+
+#define DC_EVT_NEW_ADDR_W_0    0
+#define DC_EVT_NEW_ADDR_W_1    1
+#define DC_EVT_NEW_CHAN_W_0    2
+#define DC_EVT_NEW_CHAN_W_1    3
+#define DC_EVT_NEW_DATA_W_0    4
+#define DC_EVT_NEW_DATA_W_1    5
+#define DC_EVT_NEW_ADDR_R_0    6
+#define DC_EVT_NEW_ADDR_R_1    7
+#define DC_EVT_NEW_CHAN_R_0    8
+#define DC_EVT_NEW_CHAN_R_1    9
+#define DC_EVT_NEW_DATA_R_0    10
+#define DC_EVT_NEW_DATA_R_1    11
+
+#define DC_WR_CH_CONF          0x0
+#define DC_WR_CH_ADDR          0x4
+#define DC_RL_CH(evt)          (8 + ((evt) & ~0x1) * 2)
+
+#define DC_GEN                 0xd4
+#define DC_DISP_CONF1(disp)    (0xd8 + (disp) * 4)
+#define DC_DISP_CONF2(disp)    (0xe8 + (disp) * 4)
+#define DC_STAT                        0x1c8
+
+#define WROD(lf)               (0x18 | ((lf) << 1))
+#define WRG                    0x01
+
+#define SYNC_WAVE 0
+
+#define DC_GEN_SYNC_1_6_SYNC   (2 << 1)
+#define DC_GEN_SYNC_PRIORITY_1 (1 << 7)
+
+#define DC_WR_CH_CONF_WORD_SIZE_8              (0 << 0)
+#define DC_WR_CH_CONF_WORD_SIZE_16             (1 << 0)
+#define DC_WR_CH_CONF_WORD_SIZE_24             (2 << 0)
+#define DC_WR_CH_CONF_WORD_SIZE_32             (3 << 0)
+#define DC_WR_CH_CONF_DISP_ID_PARALLEL(i)      (((i) & 0x1) << 3)
+#define DC_WR_CH_CONF_DISP_ID_SERIAL           (2 << 3)
+#define DC_WR_CH_CONF_DISP_ID_ASYNC            (3 << 4)
+#define DC_WR_CH_CONF_FIELD_MODE               (1 << 9)
+#define DC_WR_CH_CONF_PROG_TYPE_NORMAL         (4 << 5)
+#define DC_WR_CH_CONF_PROG_TYPE_MASK           (7 << 5)
+#define DC_WR_CH_CONF_PROG_DI_ID               (1 << 2)
+#define DC_WR_CH_CONF_PROG_DISP_ID(i)          (((i) & 0x1) << 3)
+
+#define IPU_DC_NUM_CHANNELS    10
+
+struct ipu_dc_priv;
+
+enum ipu_dc_map {
+       IPU_DC_MAP_RGB24,
+       IPU_DC_MAP_RGB565,
+};
+
+struct ipu_dc {
+       /* The display interface number assigned to this dc channel */
+       unsigned int            di;
+       void __iomem            *base;
+       struct ipu_dc_priv      *priv;
+       int                     chno;
+       bool                    in_use;
+};
+
+struct ipu_dc_priv {
+       void __iomem            *dc_reg;
+       void __iomem            *dc_tmpl_reg;
+       struct ipu_soc          *ipu;
+       struct device           *dev;
+       struct ipu_dc           channels[IPU_DC_NUM_CHANNELS];
+       struct mutex            mutex;
+};
+
+static void dc_link_event(struct ipu_dc *dc, int event, int addr, int priority)
+{
+       u32 reg;
+
+       reg = readl(dc->base + DC_RL_CH(event));
+       reg &= ~(0xffff << (16 * (event & 0x1)));
+       reg |= ((addr << 8) | priority) << (16 * (event & 0x1));
+       writel(reg, dc->base + DC_RL_CH(event));
+}
+
+static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand,
+               int map, int wave, int glue, int sync)
+{
+       struct ipu_dc_priv *priv = dc->priv;
+       u32 reg;
+       int stop = 1;
+
+       reg = sync | glue << 4 | ++wave << 11 | ++map << 15 | ((operand << 20) & 0xfff00000);
+       writel(reg, priv->dc_tmpl_reg + word * 8);
+       reg = operand >> 12 | opcode << 4 | stop << 9;
+       writel(reg, priv->dc_tmpl_reg + word * 8 + 4);
+}
+
+static int ipu_pixfmt_to_map(u32 fmt)
+{
+       switch (fmt) {
+       case V4L2_PIX_FMT_RGB24:
+               return IPU_DC_MAP_RGB24;
+       case V4L2_PIX_FMT_RGB565:
+               return IPU_DC_MAP_RGB565;
+       default:
+               return -EINVAL;
+       }
+}
+
+int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
+               u32 pixel_fmt, u32 width)
+{
+       struct ipu_dc_priv *priv = dc->priv;
+       u32 reg = 0, map;
+
+       dc->di = ipu_di_get_num(di);
+
+       map = ipu_pixfmt_to_map(pixel_fmt);
+       if (map < 0) {
+               dev_dbg(priv->dev, "IPU_DISP: No MAP\n");
+               return -EINVAL;
+       }
+
+       if (interlaced) {
+               dc_link_event(dc, DC_EVT_NL, 0, 3);
+               dc_link_event(dc, DC_EVT_EOL, 0, 2);
+               dc_link_event(dc, DC_EVT_NEW_DATA, 0, 1);
+
+               /* Init template microcode */
+               dc_write_tmpl(dc, 0, WROD(0), 0, map, SYNC_WAVE, 0, 8);
+       } else {
+               if (dc->di) {
+                       dc_link_event(dc, DC_EVT_NL, 2, 3);
+                       dc_link_event(dc, DC_EVT_EOL, 3, 2);
+                       dc_link_event(dc, DC_EVT_NEW_DATA, 4, 1);
+                       /* Init template microcode */
+                       dc_write_tmpl(dc, 2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       dc_write_tmpl(dc, 3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       dc_write_tmpl(dc, 4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+               } else {
+                       dc_link_event(dc, DC_EVT_NL, 5, 3);
+                       dc_link_event(dc, DC_EVT_EOL, 6, 2);
+                       dc_link_event(dc, DC_EVT_NEW_DATA, 7, 1);
+                       /* Init template microcode */
+                       dc_write_tmpl(dc, 5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       dc_write_tmpl(dc, 6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       dc_write_tmpl(dc, 7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+               }
+       }
+       dc_link_event(dc, DC_EVT_NF, 0, 0);
+       dc_link_event(dc, DC_EVT_NFIELD, 0, 0);
+       dc_link_event(dc, DC_EVT_EOF, 0, 0);
+       dc_link_event(dc, DC_EVT_EOFIELD, 0, 0);
+       dc_link_event(dc, DC_EVT_NEW_CHAN, 0, 0);
+       dc_link_event(dc, DC_EVT_NEW_ADDR, 0, 0);
+
+       reg = readl(dc->base + DC_WR_CH_CONF);
+       if (interlaced)
+               reg |= DC_WR_CH_CONF_FIELD_MODE;
+       else
+               reg &= ~DC_WR_CH_CONF_FIELD_MODE;
+       writel(reg, dc->base + DC_WR_CH_CONF);
+
+       writel(0x0, dc->base + DC_WR_CH_ADDR);
+       writel(width, priv->dc_reg + DC_DISP_CONF2(dc->di));
+
+       ipu_module_enable(priv->ipu, IPU_CONF_DC_EN);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dc_init_sync);
+
+void ipu_dc_enable_channel(struct ipu_dc *dc)
+{
+       int di;
+       u32 reg;
+
+       di = dc->di;
+
+       reg = readl(dc->base + DC_WR_CH_CONF);
+       reg |= DC_WR_CH_CONF_PROG_TYPE_NORMAL;
+       writel(reg, dc->base + DC_WR_CH_CONF);
+}
+EXPORT_SYMBOL_GPL(ipu_dc_enable_channel);
+
+void ipu_dc_disable_channel(struct ipu_dc *dc)
+{
+       struct ipu_dc_priv *priv = dc->priv;
+       u32 val;
+       int irq = 0, timeout = 50;
+
+       if (dc->chno == 1)
+               irq = IPU_IRQ_DC_FC_1;
+       else if (dc->chno == 5)
+               irq = IPU_IRQ_DP_SF_END;
+       else
+               return;
+
+       /* should wait for the interrupt here */
+       mdelay(50);
+
+       if (dc->di == 0)
+               val = 0x00000002;
+       else
+               val = 0x00000020;
+
+       /* Wait for DC triple buffer to empty */
+       while ((readl(priv->dc_reg + DC_STAT) & val) != val) {
+               msleep(2);
+               timeout -= 2;
+               if (timeout <= 0)
+                       break;
+       }
+
+       val = readl(dc->base + DC_WR_CH_CONF);
+       val &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
+       writel(val, dc->base + DC_WR_CH_CONF);
+}
+EXPORT_SYMBOL_GPL(ipu_dc_disable_channel);
+
+static void ipu_dc_map_config(struct ipu_dc_priv *priv, enum ipu_dc_map map,
+               int byte_num, int offset, int mask)
+{
+       int ptr = map * 3 + byte_num;
+       u32 reg;
+
+       reg = readl(priv->dc_reg + DC_MAP_CONF_VAL(ptr));
+       reg &= ~(0xffff << (16 * (ptr & 0x1)));
+       reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1));
+       writel(reg, priv->dc_reg + DC_MAP_CONF_VAL(ptr));
+
+       reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map));
+       reg &= ~(0x1f << ((16 * (map & 0x1)) + (5 * byte_num)));
+       reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num));
+       writel(reg, priv->dc_reg + DC_MAP_CONF_PTR(map));
+}
+
+static void ipu_dc_map_clear(struct ipu_dc_priv *priv, int map)
+{
+       u32 reg = readl(priv->dc_reg + DC_MAP_CONF_PTR(map));
+
+       writel(reg & ~(0xffff << (16 * (map & 0x1))),
+                    priv->dc_reg + DC_MAP_CONF_PTR(map));
+}
+
+struct ipu_dc *ipu_dc_get(struct ipu_soc *ipu, int channel)
+{
+       struct ipu_dc_priv *priv = ipu->dc_priv;
+       struct ipu_dc *dc;
+
+       if (channel >= IPU_DC_NUM_CHANNELS)
+               return ERR_PTR(-ENODEV);
+
+       dc = &priv->channels[channel];
+
+       mutex_lock(&priv->mutex);
+
+       if (dc->in_use) {
+               mutex_unlock(&priv->mutex);
+               return ERR_PTR(-EBUSY);
+       }
+
+       dc->in_use = 1;
+
+       mutex_unlock(&priv->mutex);
+
+       return dc;
+}
+EXPORT_SYMBOL_GPL(ipu_dc_get);
+
+void ipu_dc_put(struct ipu_dc *dc)
+{
+       struct ipu_dc_priv *priv = dc->priv;
+
+       mutex_lock(&priv->mutex);
+       dc->in_use = 0;
+       mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL_GPL(ipu_dc_put);
+
+int ipu_dc_init(struct ipu_soc *ipu, struct device *dev,
+               unsigned long base, unsigned long template_base)
+{
+       struct ipu_dc_priv *priv;
+       static int channel_offsets[] = { 0, 0x1c, 0x38, 0x54, 0x58, 0x5c,
+               0x78, 0, 0x94, 0xb4};
+       int i;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       mutex_init(&priv->mutex);
+
+       priv->dev = dev;
+       priv->ipu = ipu;
+       priv->dc_reg = devm_ioremap(dev, base, PAGE_SIZE);
+       priv->dc_tmpl_reg = devm_ioremap(dev, template_base, PAGE_SIZE);
+       if (!priv->dc_reg || !priv->dc_tmpl_reg)
+               return -ENOMEM;
+
+       for (i = 0; i < IPU_DC_NUM_CHANNELS; i++) {
+               priv->channels[i].chno = i;
+               priv->channels[i].priv = priv;
+               priv->channels[i].base = priv->dc_reg + channel_offsets[i];
+       }
+
+       writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(1) |
+                       DC_WR_CH_CONF_PROG_DI_ID,
+                       priv->channels[1].base + DC_WR_CH_CONF);
+       writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(0),
+                       priv->channels[5].base + DC_WR_CH_CONF);
+
+       writel(DC_GEN_SYNC_1_6_SYNC | DC_GEN_SYNC_PRIORITY_1, priv->dc_reg + DC_GEN);
+
+       ipu->dc_priv = priv;
+
+       dev_dbg(dev, "DC base: 0x%08lx template base: 0x%08lx\n",
+                       base, template_base);
+
+       /* rgb24 */
+       ipu_dc_map_clear(priv, IPU_DC_MAP_RGB24);
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 0, 7, 0xff); /* blue */
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 1, 15, 0xff); /* green */
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB24, 2, 23, 0xff); /* red */
+
+       /* rgb565 */
+       ipu_dc_map_clear(priv, IPU_DC_MAP_RGB565);
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 0, 4, 0xf8); /* blue */
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 1, 10, 0xfc); /* green */
+       ipu_dc_map_config(priv, IPU_DC_MAP_RGB565, 2, 15, 0xf8); /* red */
+
+       return 0;
+}
+
+void ipu_dc_exit(struct ipu_soc *ipu)
+{
+}
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-di.c b/drivers/staging/imx-drm/ipu-v3/ipu-di.c
new file mode 100644 (file)
index 0000000..67d974f
--- /dev/null
@@ -0,0 +1,700 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 <linux/export.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+#include "imx-ipu-v3.h"
+#include "ipu-prv.h"
+
+struct ipu_di {
+       void __iomem *base;
+       int id;
+       u32 module;
+       struct clk *clk_di;     /* display input clock */
+       struct clk *clk_ipu;    /* IPU bus clock */
+       struct clk *clk_di_pixel; /* resulting pixel clock */
+       struct clk_hw clk_hw_out;
+       char *clk_name;
+       bool inuse;
+       unsigned long clkflags;
+       struct ipu_soc *ipu;
+};
+
+static DEFINE_MUTEX(di_mutex);
+
+struct di_sync_config {
+       int run_count;
+       int run_src;
+       int offset_count;
+       int offset_src;
+       int repeat_count;
+       int cnt_clr_src;
+       int cnt_polarity_gen_en;
+       int cnt_polarity_clr_src;
+       int cnt_polarity_trigger_src;
+       int cnt_up;
+       int cnt_down;
+};
+
+enum di_pins {
+       DI_PIN11 = 0,
+       DI_PIN12 = 1,
+       DI_PIN13 = 2,
+       DI_PIN14 = 3,
+       DI_PIN15 = 4,
+       DI_PIN16 = 5,
+       DI_PIN17 = 6,
+       DI_PIN_CS = 7,
+
+       DI_PIN_SER_CLK = 0,
+       DI_PIN_SER_RS = 1,
+};
+
+enum di_sync_wave {
+       DI_SYNC_NONE = 0,
+       DI_SYNC_CLK = 1,
+       DI_SYNC_INT_HSYNC = 2,
+       DI_SYNC_HSYNC = 3,
+       DI_SYNC_VSYNC = 4,
+       DI_SYNC_DE = 6,
+};
+
+#define SYNC_WAVE 0
+
+#define DI_GENERAL             0x0000
+#define DI_BS_CLKGEN0          0x0004
+#define DI_BS_CLKGEN1          0x0008
+#define DI_SW_GEN0(gen)                (0x000c + 4 * ((gen) - 1))
+#define DI_SW_GEN1(gen)                (0x0030 + 4 * ((gen) - 1))
+#define DI_STP_REP(gen)                (0x0148 + 4 * (((gen) - 1)/2))
+#define DI_SYNC_AS_GEN         0x0054
+#define DI_DW_GEN(gen)         (0x0058 + 4 * (gen))
+#define DI_DW_SET(gen, set)    (0x0088 + 4 * ((gen) + 0xc * (set)))
+#define DI_SER_CONF            0x015c
+#define DI_SSC                 0x0160
+#define DI_POL                 0x0164
+#define DI_AW0                 0x0168
+#define DI_AW1                 0x016c
+#define DI_SCR_CONF            0x0170
+#define DI_STAT                        0x0174
+
+#define DI_SW_GEN0_RUN_COUNT(x)                        ((x) << 19)
+#define DI_SW_GEN0_RUN_SRC(x)                  ((x) << 16)
+#define DI_SW_GEN0_OFFSET_COUNT(x)             ((x) << 3)
+#define DI_SW_GEN0_OFFSET_SRC(x)               ((x) << 0)
+
+#define DI_SW_GEN1_CNT_POL_GEN_EN(x)           ((x) << 29)
+#define DI_SW_GEN1_CNT_CLR_SRC(x)              ((x) << 25)
+#define DI_SW_GEN1_CNT_POL_TRIGGER_SRC(x)      ((x) << 12)
+#define DI_SW_GEN1_CNT_POL_CLR_SRC(x)          ((x) << 9)
+#define DI_SW_GEN1_CNT_DOWN(x)                 ((x) << 16)
+#define DI_SW_GEN1_CNT_UP(x)                   (x)
+#define DI_SW_GEN1_AUTO_RELOAD                 (0x10000000)
+
+#define DI_DW_GEN_ACCESS_SIZE_OFFSET           24
+#define DI_DW_GEN_COMPONENT_SIZE_OFFSET                16
+
+#define DI_GEN_POLARITY_1                      (1 << 0)
+#define DI_GEN_POLARITY_2                      (1 << 1)
+#define DI_GEN_POLARITY_3                      (1 << 2)
+#define DI_GEN_POLARITY_4                      (1 << 3)
+#define DI_GEN_POLARITY_5                      (1 << 4)
+#define DI_GEN_POLARITY_6                      (1 << 5)
+#define DI_GEN_POLARITY_7                      (1 << 6)
+#define DI_GEN_POLARITY_8                      (1 << 7)
+#define DI_GEN_POLARITY_DISP_CLK               (1 << 17)
+#define DI_GEN_DI_CLK_EXT                      (1 << 20)
+#define DI_GEN_DI_VSYNC_EXT                    (1 << 21)
+
+#define DI_POL_DRDY_DATA_POLARITY              (1 << 7)
+#define DI_POL_DRDY_POLARITY_15                        (1 << 4)
+
+#define DI_VSYNC_SEL_OFFSET                    13
+
+static inline u32 ipu_di_read(struct ipu_di *di, unsigned offset)
+{
+       return readl(di->base + offset);
+}
+
+static inline void ipu_di_write(struct ipu_di *di, u32 value, unsigned offset)
+{
+       writel(value, di->base + offset);
+}
+
+static int ipu_di_clk_calc_div(unsigned long inrate, unsigned long outrate)
+{
+       u64 tmp = inrate;
+       int div;
+
+       tmp *= 16;
+
+       do_div(tmp, outrate);
+
+       div = tmp;
+
+       if (div < 0x10)
+               div = 0x10;
+
+#ifdef WTF_IS_THIS
+       /*
+        * Freescale has this in their Kernel. It is neither clear what
+        * it does nor why it does it
+        */
+       if (div & 0x10)
+               div &= ~0x7;
+       else {
+               /* Round up divider if it gets us closer to desired pix clk */
+               if ((div & 0xC) == 0xC) {
+                       div += 0x10;
+                       div &= ~0xF;
+               }
+       }
+#endif
+       return div;
+}
+
+static unsigned long clk_di_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out);
+       unsigned long outrate;
+       u32 div = ipu_di_read(di, DI_BS_CLKGEN0);
+
+       if (div < 0x10)
+               div = 0x10;
+
+       outrate = (parent_rate / div) * 16;
+
+       return outrate;
+}
+
+static long clk_di_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out);
+       unsigned long outrate;
+       int div;
+       u32 val;
+
+       div = ipu_di_clk_calc_div(*prate, rate);
+
+       outrate = (*prate / div) * 16;
+
+       val = ipu_di_read(di, DI_GENERAL);
+
+       if (!(val & DI_GEN_DI_CLK_EXT) && outrate > *prate / 2)
+               outrate = *prate / 2;
+
+       dev_dbg(di->ipu->dev,
+               "%s: inrate: %ld div: 0x%08x outrate: %ld wanted: %ld\n",
+                       __func__, *prate, div, outrate, rate);
+
+       return outrate;
+}
+
+static int clk_di_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out);
+       int div;
+       u32 clkgen0;
+
+       clkgen0 = ipu_di_read(di, DI_BS_CLKGEN0) & ~0xfff;
+
+       div = ipu_di_clk_calc_div(parent_rate, rate);
+
+       ipu_di_write(di, clkgen0 | div, DI_BS_CLKGEN0);
+
+       dev_dbg(di->ipu->dev, "%s: inrate: %ld desired: %ld div: 0x%08x\n",
+                       __func__, parent_rate, rate, div);
+       return 0;
+}
+
+static u8 clk_di_get_parent(struct clk_hw *hw)
+{
+       struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out);
+       u32 val;
+
+       val = ipu_di_read(di, DI_GENERAL);
+
+       return val & DI_GEN_DI_CLK_EXT ? 1 : 0;
+}
+
+static int clk_di_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out);
+       u32 val;
+
+       val = ipu_di_read(di, DI_GENERAL);
+
+       if (index)
+               val |= DI_GEN_DI_CLK_EXT;
+       else
+               val &= ~DI_GEN_DI_CLK_EXT;
+
+       ipu_di_write(di, val, DI_GENERAL);
+
+       return 0;
+}
+
+static struct clk_ops clk_di_ops = {
+       .round_rate = clk_di_round_rate,
+       .set_rate = clk_di_set_rate,
+       .recalc_rate = clk_di_recalc_rate,
+       .set_parent = clk_di_set_parent,
+       .get_parent = clk_di_get_parent,
+};
+
+static void ipu_di_data_wave_config(struct ipu_di *di,
+                                    int wave_gen,
+                                    int access_size, int component_size)
+{
+       u32 reg;
+       reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) |
+           (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET);
+       ipu_di_write(di, reg, DI_DW_GEN(wave_gen));
+}
+
+static void ipu_di_data_pin_config(struct ipu_di *di, int wave_gen, int di_pin,
+               int set, int up, int down)
+{
+       u32 reg;
+
+       reg = ipu_di_read(di, DI_DW_GEN(wave_gen));
+       reg &= ~(0x3 << (di_pin * 2));
+       reg |= set << (di_pin * 2);
+       ipu_di_write(di, reg, DI_DW_GEN(wave_gen));
+
+       ipu_di_write(di, (down << 16) | up, DI_DW_SET(wave_gen, set));
+}
+
+static void ipu_di_sync_config(struct ipu_di *di, struct di_sync_config *config,
+               int start, int count)
+{
+       u32 reg;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               struct di_sync_config *c = &config[i];
+               int wave_gen = start + i + 1;
+
+               if ((c->run_count >= 0x1000) || (c->offset_count >= 0x1000) ||
+                               (c->repeat_count >= 0x1000) ||
+                               (c->cnt_up >= 0x400) ||
+                               (c->cnt_down >= 0x400)) {
+                       dev_err(di->ipu->dev, "DI%d counters out of range.\n",
+                                       di->id);
+                       return;
+               }
+
+               reg = DI_SW_GEN0_RUN_COUNT(c->run_count) |
+                       DI_SW_GEN0_RUN_SRC(c->run_src) |
+                       DI_SW_GEN0_OFFSET_COUNT(c->offset_count) |
+                       DI_SW_GEN0_OFFSET_SRC(c->offset_src);
+               ipu_di_write(di, reg, DI_SW_GEN0(wave_gen));
+
+               reg = DI_SW_GEN1_CNT_POL_GEN_EN(c->cnt_polarity_gen_en) |
+                       DI_SW_GEN1_CNT_CLR_SRC(c->cnt_clr_src) |
+                       DI_SW_GEN1_CNT_POL_TRIGGER_SRC(
+                                       c->cnt_polarity_trigger_src) |
+                       DI_SW_GEN1_CNT_POL_CLR_SRC(c->cnt_polarity_clr_src) |
+                       DI_SW_GEN1_CNT_DOWN(c->cnt_down) |
+                       DI_SW_GEN1_CNT_UP(c->cnt_up);
+
+               /* Enable auto reload */
+               if (c->repeat_count == 0)
+                       reg |= DI_SW_GEN1_AUTO_RELOAD;
+
+               ipu_di_write(di, reg, DI_SW_GEN1(wave_gen));
+
+               reg = ipu_di_read(di, DI_STP_REP(wave_gen));
+               reg &= ~(0xffff << (16 * ((wave_gen - 1) & 0x1)));
+               reg |= c->repeat_count << (16 * ((wave_gen - 1) & 0x1));
+               ipu_di_write(di, reg, DI_STP_REP(wave_gen));
+       }
+}
+
+static void ipu_di_sync_config_interlaced(struct ipu_di *di,
+               struct ipu_di_signal_cfg *sig)
+{
+       u32 h_total = sig->width + sig->h_sync_width +
+               sig->h_start_width + sig->h_end_width;
+       u32 v_total = sig->height + sig->v_sync_width +
+               sig->v_start_width + sig->v_end_width;
+       u32 reg;
+       struct di_sync_config cfg[] = {
+               {
+                       .run_count = h_total / 2 - 1,
+                       .run_src = DI_SYNC_CLK,
+               }, {
+                       .run_count = h_total - 11,
+                       .run_src = DI_SYNC_CLK,
+                       .cnt_down = 4,
+               }, {
+                       .run_count = v_total * 2 - 1,
+                       .run_src = DI_SYNC_INT_HSYNC,
+                       .offset_count = 1,
+                       .offset_src = DI_SYNC_INT_HSYNC,
+                       .cnt_down = 4,
+               }, {
+                       .run_count = v_total / 2 - 1,
+                       .run_src = DI_SYNC_HSYNC,
+                       .offset_count = sig->v_start_width,
+                       .offset_src = DI_SYNC_HSYNC,
+                       .repeat_count = 2,
+                       .cnt_clr_src = DI_SYNC_VSYNC,
+               }, {
+                       .run_src = DI_SYNC_HSYNC,
+                       .repeat_count = sig->height / 2,
+                       .cnt_clr_src = 4,
+               }, {
+                       .run_count = v_total - 1,
+                       .run_src = DI_SYNC_HSYNC,
+               }, {
+                       .run_count = v_total / 2 - 1,
+                       .run_src = DI_SYNC_HSYNC,
+                       .offset_count = 9,
+                       .offset_src = DI_SYNC_HSYNC,
+                       .repeat_count = 2,
+                       .cnt_clr_src = DI_SYNC_VSYNC,
+               }, {
+                       .run_src = DI_SYNC_CLK,
+                       .offset_count = sig->h_start_width,
+                       .offset_src = DI_SYNC_CLK,
+                       .repeat_count = sig->width,
+                       .cnt_clr_src = 5,
+               }, {
+                       .run_count = v_total - 1,
+                       .run_src = DI_SYNC_INT_HSYNC,
+                       .offset_count = v_total / 2,
+                       .offset_src = DI_SYNC_INT_HSYNC,
+                       .cnt_clr_src = DI_SYNC_HSYNC,
+                       .cnt_down = 4,
+               }
+       };
+
+       ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
+
+       /* set gentime select and tag sel */
+       reg = ipu_di_read(di, DI_SW_GEN1(9));
+       reg &= 0x1FFFFFFF;
+       reg |= (3 - 1) << 29 | 0x00008000;
+       ipu_di_write(di, reg, DI_SW_GEN1(9));
+
+       ipu_di_write(di, v_total / 2 - 1, DI_SCR_CONF);
+}
+
+static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
+               struct ipu_di_signal_cfg *sig, int div)
+{
+       u32 h_total = sig->width + sig->h_sync_width + sig->h_start_width +
+               sig->h_end_width;
+       u32 v_total = sig->height + sig->v_sync_width + sig->v_start_width +
+               sig->v_end_width;
+       struct di_sync_config cfg[] = {
+               {
+                       .run_count = h_total - 1,
+                       .run_src = DI_SYNC_CLK,
+               } , {
+                       .run_count = h_total - 1,
+                       .run_src = DI_SYNC_CLK,
+                       .offset_count = div * sig->v_to_h_sync,
+                       .offset_src = DI_SYNC_CLK,
+                       .cnt_polarity_gen_en = 1,
+                       .cnt_polarity_trigger_src = DI_SYNC_CLK,
+                       .cnt_down = sig->h_sync_width * 2,
+               } , {
+                       .run_count = v_total - 1,
+                       .run_src = DI_SYNC_INT_HSYNC,
+                       .cnt_polarity_gen_en = 1,
+                       .cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
+                       .cnt_down = sig->v_sync_width * 2,
+               } , {
+                       .run_src = DI_SYNC_HSYNC,
+                       .offset_count = sig->v_sync_width + sig->v_start_width,
+                       .offset_src = DI_SYNC_HSYNC,
+                       .repeat_count = sig->height,
+                       .cnt_clr_src = DI_SYNC_VSYNC,
+               } , {
+                       .run_src = DI_SYNC_CLK,
+                       .offset_count = sig->h_sync_width + sig->h_start_width,
+                       .offset_src = DI_SYNC_CLK,
+                       .repeat_count = sig->width,
+                       .cnt_clr_src = 5,
+               } , {
+                       /* unused */
+               } , {
+                       /* unused */
+               } , {
+                       /* unused */
+               } , {
+                       /* unused */
+               },
+       };
+
+       ipu_di_write(di, v_total - 1, DI_SCR_CONF);
+       ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
+}
+
+int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
+{
+       u32 reg;
+       u32 di_gen, vsync_cnt;
+       u32 div;
+       u32 h_total, v_total;
+       int ret;
+       unsigned long round;
+       struct clk *parent;
+
+       dev_dbg(di->ipu->dev, "disp %d: panel size = %d x %d\n",
+               di->id, sig->width, sig->height);
+
+       if ((sig->v_sync_width == 0) || (sig->h_sync_width == 0))
+               return -EINVAL;
+
+       if (sig->clkflags & IPU_DI_CLKMODE_EXT)
+               parent = di->clk_di;
+       else
+               parent = di->clk_ipu;
+
+       ret = clk_set_parent(di->clk_di_pixel, parent);
+       if (ret) {
+               dev_err(di->ipu->dev,
+                       "setting pixel clock to parent %s failed with %d\n",
+                               __clk_get_name(parent), ret);
+               return ret;
+       }
+
+       if (sig->clkflags & IPU_DI_CLKMODE_SYNC)
+               round = clk_get_rate(parent);
+       else
+               round = clk_round_rate(di->clk_di_pixel, sig->pixelclock);
+
+       ret = clk_set_rate(di->clk_di_pixel, round);
+
+       h_total = sig->width + sig->h_sync_width + sig->h_start_width +
+               sig->h_end_width;
+       v_total = sig->height + sig->v_sync_width + sig->v_start_width +
+               sig->v_end_width;
+
+       mutex_lock(&di_mutex);
+
+       div = ipu_di_read(di, DI_BS_CLKGEN0) & 0xfff;
+       div = div / 16;         /* Now divider is integer portion */
+
+       /* Setup pixel clock timing */
+       /* Down time is half of period */
+       ipu_di_write(di, (div << 16), DI_BS_CLKGEN1);
+
+       ipu_di_data_wave_config(di, SYNC_WAVE, div - 1, div - 1);
+       ipu_di_data_pin_config(di, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
+
+       di_gen = ipu_di_read(di, DI_GENERAL) & DI_GEN_DI_CLK_EXT;
+       di_gen |= DI_GEN_DI_VSYNC_EXT;
+
+       if (sig->interlaced) {
+               ipu_di_sync_config_interlaced(di, sig);
+
+               /* set y_sel = 1 */
+               di_gen |= 0x10000000;
+               di_gen |= DI_GEN_POLARITY_5;
+               di_gen |= DI_GEN_POLARITY_8;
+
+               vsync_cnt = 7;
+
+               if (sig->Hsync_pol)
+                       di_gen |= DI_GEN_POLARITY_3;
+               if (sig->Vsync_pol)
+                       di_gen |= DI_GEN_POLARITY_2;
+       } else {
+               ipu_di_sync_config_noninterlaced(di, sig, div);
+
+               vsync_cnt = 3;
+
+               if (sig->Hsync_pol)
+                       di_gen |= DI_GEN_POLARITY_2;
+               if (sig->Vsync_pol)
+                       di_gen |= DI_GEN_POLARITY_3;
+       }
+
+       if (!sig->clk_pol)
+               di_gen |= DI_GEN_POLARITY_DISP_CLK;
+
+       ipu_di_write(di, di_gen, DI_GENERAL);
+
+       ipu_di_write(di, (--vsync_cnt << DI_VSYNC_SEL_OFFSET) | 0x00000002,
+                    DI_SYNC_AS_GEN);
+
+       reg = ipu_di_read(di, DI_POL);
+       reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
+
+       if (sig->enable_pol)
+               reg |= DI_POL_DRDY_POLARITY_15;
+       if (sig->data_pol)
+               reg |= DI_POL_DRDY_DATA_POLARITY;
+
+       ipu_di_write(di, reg, DI_POL);
+
+       mutex_unlock(&di_mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_di_init_sync_panel);
+
+int ipu_di_enable(struct ipu_di *di)
+{
+       clk_prepare_enable(di->clk_di_pixel);
+
+       ipu_module_enable(di->ipu, di->module);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_di_enable);
+
+int ipu_di_disable(struct ipu_di *di)
+{
+       ipu_module_disable(di->ipu, di->module);
+
+       clk_disable_unprepare(di->clk_di_pixel);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_di_disable);
+
+int ipu_di_get_num(struct ipu_di *di)
+{
+       return di->id;
+}
+EXPORT_SYMBOL_GPL(ipu_di_get_num);
+
+static DEFINE_MUTEX(ipu_di_lock);
+
+struct ipu_di *ipu_di_get(struct ipu_soc *ipu, int disp)
+{
+       struct ipu_di *di;
+
+       if (disp > 1)
+               return ERR_PTR(-EINVAL);
+
+       di = ipu->di_priv[disp];
+
+       mutex_lock(&ipu_di_lock);
+
+       if (di->inuse) {
+               di = ERR_PTR(-EBUSY);
+               goto out;
+       }
+
+       di->inuse = true;
+out:
+       mutex_unlock(&ipu_di_lock);
+
+       return di;
+}
+EXPORT_SYMBOL_GPL(ipu_di_get);
+
+void ipu_di_put(struct ipu_di *di)
+{
+       mutex_lock(&ipu_di_lock);
+
+       di->inuse = false;
+
+       mutex_unlock(&ipu_di_lock);
+}
+EXPORT_SYMBOL_GPL(ipu_di_put);
+
+int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id,
+               unsigned long base,
+               u32 module, struct clk *clk_ipu)
+{
+       struct ipu_di *di;
+       int ret;
+       const char *di_parent[2];
+       struct clk_init_data init = {
+               .ops = &clk_di_ops,
+               .num_parents = 2,
+               .flags = 0,
+       };
+
+       if (id > 1)
+               return -ENODEV;
+
+       di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL);
+       if (!di)
+               return -ENOMEM;
+
+       ipu->di_priv[id] = di;
+
+       di->clk_di = devm_clk_get(dev, id ? "di1" : "di0");
+       if (IS_ERR(di->clk_di))
+               return PTR_ERR(di->clk_di);
+
+       di->module = module;
+       di->id = id;
+       di->clk_ipu = clk_ipu;
+       di->base = devm_ioremap(dev, base, PAGE_SIZE);
+       if (!di->base)
+               return -ENOMEM;
+
+       di_parent[0] = __clk_get_name(di->clk_ipu);
+       di_parent[1] = __clk_get_name(di->clk_di);
+
+       ipu_di_write(di, 0x10, DI_BS_CLKGEN0);
+
+       init.parent_names = (const char **)&di_parent;
+       di->clk_name = kasprintf(GFP_KERNEL, "%s_di%d_pixel",
+                       dev_name(dev), id);
+       if (!di->clk_name)
+               return -ENOMEM;
+
+       init.name = di->clk_name;
+
+       di->clk_hw_out.init = &init;
+       di->clk_di_pixel = clk_register(dev, &di->clk_hw_out);
+
+       if (IS_ERR(di->clk_di_pixel)) {
+               ret = PTR_ERR(di->clk_di_pixel);
+               goto failed_clk_register;
+       }
+
+       dev_info(dev, "DI%d base: 0x%08lx remapped to %p\n",
+                       id, base, di->base);
+       di->inuse = false;
+       di->ipu = ipu;
+
+       return 0;
+
+failed_clk_register:
+
+       kfree(di->clk_name);
+
+       return ret;
+}
+
+void ipu_di_exit(struct ipu_soc *ipu, int id)
+{
+       struct ipu_di *di = ipu->di_priv[id];
+
+       clk_unregister(di->clk_di_pixel);
+       kfree(di->clk_name);
+}
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c b/drivers/staging/imx-drm/ipu-v3/ipu-dmfc.c
new file mode 100644 (file)
index 0000000..91821bc
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 <linux/export.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include "imx-ipu-v3.h"
+#include "ipu-prv.h"
+
+#define DMFC_RD_CHAN           0x0000
+#define DMFC_WR_CHAN           0x0004
+#define DMFC_WR_CHAN_DEF       0x0008
+#define DMFC_DP_CHAN           0x000c
+#define DMFC_DP_CHAN_DEF       0x0010
+#define DMFC_GENERAL1          0x0014
+#define DMFC_GENERAL2          0x0018
+#define DMFC_IC_CTRL           0x001c
+#define DMFC_STAT              0x0020
+
+#define DMFC_WR_CHAN_1_28              0
+#define DMFC_WR_CHAN_2_41              8
+#define DMFC_WR_CHAN_1C_42             16
+#define DMFC_WR_CHAN_2C_43             24
+
+#define DMFC_DP_CHAN_5B_23             0
+#define DMFC_DP_CHAN_5F_27             8
+#define DMFC_DP_CHAN_6B_24             16
+#define DMFC_DP_CHAN_6F_29             24
+
+#define DMFC_FIFO_SIZE_64              (3 << 3)
+#define DMFC_FIFO_SIZE_128             (2 << 3)
+#define DMFC_FIFO_SIZE_256             (1 << 3)
+#define DMFC_FIFO_SIZE_512             (0 << 3)
+
+#define DMFC_SEGMENT(x)                        ((x & 0x7) << 0)
+#define DMFC_BURSTSIZE_128             (0 << 6)
+#define DMFC_BURSTSIZE_64              (1 << 6)
+#define DMFC_BURSTSIZE_32              (2 << 6)
+#define DMFC_BURSTSIZE_16              (3 << 6)
+
+struct dmfc_channel_data {
+       int             ipu_channel;
+       unsigned long   channel_reg;
+       unsigned long   shift;
+       unsigned        eot_shift;
+       unsigned        max_fifo_lines;
+};
+
+static const struct dmfc_channel_data dmfcdata[] = {
+       {
+               .ipu_channel    = 23,
+               .channel_reg    = DMFC_DP_CHAN,
+               .shift          = DMFC_DP_CHAN_5B_23,
+               .eot_shift      = 20,
+               .max_fifo_lines = 3,
+       }, {
+               .ipu_channel    = 24,
+               .channel_reg    = DMFC_DP_CHAN,
+               .shift          = DMFC_DP_CHAN_6B_24,
+               .eot_shift      = 22,
+               .max_fifo_lines = 1,
+       }, {
+               .ipu_channel    = 27,
+               .channel_reg    = DMFC_DP_CHAN,
+               .shift          = DMFC_DP_CHAN_5F_27,
+               .eot_shift      = 21,
+               .max_fifo_lines = 2,
+       }, {
+               .ipu_channel    = 28,
+               .channel_reg    = DMFC_WR_CHAN,
+               .shift          = DMFC_WR_CHAN_1_28,
+               .eot_shift      = 16,
+               .max_fifo_lines = 2,
+       }, {
+               .ipu_channel    = 29,
+               .channel_reg    = DMFC_DP_CHAN,
+               .shift          = DMFC_DP_CHAN_6F_29,
+               .eot_shift      = 23,
+               .max_fifo_lines = 1,
+       },
+};
+
+#define DMFC_NUM_CHANNELS      ARRAY_SIZE(dmfcdata)
+
+struct ipu_dmfc_priv;
+
+struct dmfc_channel {
+       unsigned                        slots;
+       unsigned                        slotmask;
+       unsigned                        segment;
+       int                             burstsize;
+       struct ipu_soc                  *ipu;
+       struct ipu_dmfc_priv            *priv;
+       const struct dmfc_channel_data  *data;
+};
+
+struct ipu_dmfc_priv {
+       struct ipu_soc *ipu;
+       struct device *dev;
+       struct dmfc_channel channels[DMFC_NUM_CHANNELS];
+       struct mutex mutex;
+       unsigned long bandwidth_per_slot;
+       void __iomem *base;
+       int use_count;
+};
+
+int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+       mutex_lock(&priv->mutex);
+
+       if (!priv->use_count)
+               ipu_module_enable(priv->ipu, IPU_CONF_DMFC_EN);
+
+       priv->use_count++;
+
+       mutex_unlock(&priv->mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_enable_channel);
+
+void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+
+       mutex_lock(&priv->mutex);
+
+       priv->use_count--;
+
+       if (!priv->use_count)
+               ipu_module_disable(priv->ipu, IPU_CONF_DMFC_EN);
+
+       if (priv->use_count < 0)
+               priv->use_count = 0;
+
+       mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_disable_channel);
+
+static int ipu_dmfc_setup_channel(struct dmfc_channel *dmfc, int slots,
+               int segment, int burstsize)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+       u32 val, field;
+
+       dev_dbg(priv->dev,
+                       "dmfc: using %d slots starting from segment %d for IPU channel %d\n",
+                       slots, segment, dmfc->data->ipu_channel);
+
+       if (!dmfc)
+               return -EINVAL;
+
+       switch (slots) {
+       case 1:
+               field = DMFC_FIFO_SIZE_64;
+               break;
+       case 2:
+               field = DMFC_FIFO_SIZE_128;
+               break;
+       case 4:
+               field = DMFC_FIFO_SIZE_256;
+               break;
+       case 8:
+               field = DMFC_FIFO_SIZE_512;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (burstsize) {
+       case 16:
+               field |= DMFC_BURSTSIZE_16;
+               break;
+       case 32:
+               field |= DMFC_BURSTSIZE_32;
+               break;
+       case 64:
+               field |= DMFC_BURSTSIZE_64;
+               break;
+       case 128:
+               field |= DMFC_BURSTSIZE_128;
+               break;
+       }
+
+       field |= DMFC_SEGMENT(segment);
+
+       val = readl(priv->base + dmfc->data->channel_reg);
+
+       val &= ~(0xff << dmfc->data->shift);
+       val |= field << dmfc->data->shift;
+
+       writel(val, priv->base + dmfc->data->channel_reg);
+
+       dmfc->slots = slots;
+       dmfc->segment = segment;
+       dmfc->burstsize = burstsize;
+       dmfc->slotmask = ((1 << slots) - 1) << segment;
+
+       return 0;
+}
+
+static int dmfc_bandwidth_to_slots(struct ipu_dmfc_priv *priv,
+               unsigned long bandwidth)
+{
+       int slots = 1;
+
+       while (slots * priv->bandwidth_per_slot < bandwidth)
+               slots *= 2;
+
+       return slots;
+}
+
+static int dmfc_find_slots(struct ipu_dmfc_priv *priv, int slots)
+{
+       unsigned slotmask_need, slotmask_used = 0;
+       int i, segment = 0;
+
+       slotmask_need = (1 << slots) - 1;
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++)
+               slotmask_used |= priv->channels[i].slotmask;
+
+       while (slotmask_need <= 0xff) {
+               if (!(slotmask_used & slotmask_need))
+                       return segment;
+
+               slotmask_need <<= 1;
+               segment++;
+       }
+
+       return -EBUSY;
+}
+
+void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+       int i;
+
+       dev_dbg(priv->dev, "dmfc: freeing %d slots starting from segment %d\n",
+                       dmfc->slots, dmfc->segment);
+
+       mutex_lock(&priv->mutex);
+
+       if (!dmfc->slots)
+               goto out;
+
+       dmfc->slotmask = 0;
+       dmfc->slots = 0;
+       dmfc->segment = 0;
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++)
+               priv->channels[i].slotmask = 0;
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++) {
+               if (priv->channels[i].slots > 0) {
+                       priv->channels[i].segment =
+                               dmfc_find_slots(priv, priv->channels[i].slots);
+                       priv->channels[i].slotmask =
+                               ((1 << priv->channels[i].slots) - 1) <<
+                               priv->channels[i].segment;
+               }
+       }
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++) {
+               if (priv->channels[i].slots > 0)
+                       ipu_dmfc_setup_channel(&priv->channels[i],
+                                       priv->channels[i].slots,
+                                       priv->channels[i].segment,
+                                       priv->channels[i].burstsize);
+       }
+out:
+       mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_free_bandwidth);
+
+int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc,
+               unsigned long bandwidth_pixel_per_second, int burstsize)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+       int slots = dmfc_bandwidth_to_slots(priv, bandwidth_pixel_per_second);
+       int segment = 0, ret = 0;
+
+       dev_dbg(priv->dev, "dmfc: trying to allocate %ldMpixel/s for IPU channel %d\n",
+                       bandwidth_pixel_per_second / 1000000,
+                       dmfc->data->ipu_channel);
+
+       ipu_dmfc_free_bandwidth(dmfc);
+
+       mutex_lock(&priv->mutex);
+
+       if (slots > 8) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       segment = dmfc_find_slots(priv, slots);
+       if (segment < 0) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ipu_dmfc_setup_channel(dmfc, slots, segment, burstsize);
+
+out:
+       mutex_unlock(&priv->mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth);
+
+int ipu_dmfc_init_channel(struct dmfc_channel *dmfc, int width)
+{
+       struct ipu_dmfc_priv *priv = dmfc->priv;
+       u32 dmfc_gen1;
+
+       dmfc_gen1 = readl(priv->base + DMFC_GENERAL1);
+
+       if ((dmfc->slots * 64 * 4) / width > dmfc->data->max_fifo_lines)
+               dmfc_gen1 |= 1 << dmfc->data->eot_shift;
+       else
+               dmfc_gen1 &= ~(1 << dmfc->data->eot_shift);
+
+       writel(dmfc_gen1, priv->base + DMFC_GENERAL1);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_init_channel);
+
+struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipu_channel)
+{
+       struct ipu_dmfc_priv *priv = ipu->dmfc_priv;
+       int i;
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++)
+               if (dmfcdata[i].ipu_channel == ipu_channel)
+                       return &priv->channels[i];
+       return ERR_PTR(-ENODEV);
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_get);
+
+void ipu_dmfc_put(struct dmfc_channel *dmfc)
+{
+       ipu_dmfc_free_bandwidth(dmfc);
+}
+EXPORT_SYMBOL_GPL(ipu_dmfc_put);
+
+int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base,
+               struct clk *ipu_clk)
+{
+       struct ipu_dmfc_priv *priv;
+       int i;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->base = devm_ioremap(dev, base, PAGE_SIZE);
+       if (!priv->base)
+               return -ENOMEM;
+
+       priv->dev = dev;
+       priv->ipu = ipu;
+       mutex_init(&priv->mutex);
+
+       ipu->dmfc_priv = priv;
+
+       for (i = 0; i < DMFC_NUM_CHANNELS; i++) {
+               priv->channels[i].priv = priv;
+               priv->channels[i].ipu = ipu;
+               priv->channels[i].data = &dmfcdata[i];
+       }
+
+       writel(0x0, priv->base + DMFC_WR_CHAN);
+       writel(0x0, priv->base + DMFC_DP_CHAN);
+
+       /*
+        * We have a total bandwidth of clkrate * 4pixel divided
+        * into 8 slots.
+        */
+       priv->bandwidth_per_slot = clk_get_rate(ipu_clk) / 8;
+
+       dev_dbg(dev, "dmfc: 8 slots with %ldMpixel/s bandwidth each\n",
+                       priv->bandwidth_per_slot / 1000000);
+
+       writel(0x202020f6, priv->base + DMFC_WR_CHAN_DEF);
+       writel(0x2020f6f6, priv->base + DMFC_DP_CHAN_DEF);
+       writel(0x00000003, priv->base + DMFC_GENERAL1);
+
+       return 0;
+}
+
+void ipu_dmfc_exit(struct ipu_soc *ipu)
+{
+}
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-dp.c b/drivers/staging/imx-drm/ipu-v3/ipu-dp.c
new file mode 100644 (file)
index 0000000..26aecaf
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include "imx-ipu-v3.h"
+#include "ipu-prv.h"
+
+#define DP_SYNC 0
+#define DP_ASYNC0 0x60
+#define DP_ASYNC1 0xBC
+
+#define DP_COM_CONF            0x0
+#define DP_GRAPH_WIND_CTRL     0x0004
+#define DP_FG_POS              0x0008
+#define DP_CSC_A_0             0x0044
+#define DP_CSC_A_1             0x0048
+#define DP_CSC_A_2             0x004C
+#define DP_CSC_A_3             0x0050
+#define DP_CSC_0               0x0054
+#define DP_CSC_1               0x0058
+
+#define DP_COM_CONF_FG_EN              (1 << 0)
+#define DP_COM_CONF_GWSEL              (1 << 1)
+#define DP_COM_CONF_GWAM               (1 << 2)
+#define DP_COM_CONF_GWCKE              (1 << 3)
+#define DP_COM_CONF_CSC_DEF_MASK       (3 << 8)
+#define DP_COM_CONF_CSC_DEF_OFFSET     8
+#define DP_COM_CONF_CSC_DEF_FG         (3 << 8)
+#define DP_COM_CONF_CSC_DEF_BG         (2 << 8)
+#define DP_COM_CONF_CSC_DEF_BOTH       (1 << 8)
+
+struct ipu_dp_priv;
+
+struct ipu_dp {
+       u32 flow;
+       bool in_use;
+       bool foreground;
+       enum ipu_color_space in_cs;
+};
+
+struct ipu_flow {
+       struct ipu_dp foreground;
+       struct ipu_dp background;
+       enum ipu_color_space out_cs;
+       void __iomem *base;
+       struct ipu_dp_priv *priv;
+};
+
+struct ipu_dp_priv {
+       struct ipu_soc *ipu;
+       struct device *dev;
+       void __iomem *base;
+       struct ipu_flow flow[3];
+       struct mutex mutex;
+       int use_count;
+};
+
+static u32 ipu_dp_flow_base[] = {DP_SYNC, DP_ASYNC0, DP_ASYNC1};
+
+static inline struct ipu_flow *to_flow(struct ipu_dp *dp)
+{
+       if (dp->foreground)
+               return container_of(dp, struct ipu_flow, foreground);
+       else
+               return container_of(dp, struct ipu_flow, background);
+}
+
+int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable,
+               u8 alpha, bool bg_chan)
+{
+       struct ipu_flow *flow = to_flow(dp);
+       struct ipu_dp_priv *priv = flow->priv;
+       u32 reg;
+
+       mutex_lock(&priv->mutex);
+
+       reg = readl(flow->base + DP_COM_CONF);
+       if (bg_chan)
+               reg &= ~DP_COM_CONF_GWSEL;
+       else
+               reg |= DP_COM_CONF_GWSEL;
+       writel(reg, flow->base + DP_COM_CONF);
+
+       if (enable) {
+               reg = readl(flow->base + DP_GRAPH_WIND_CTRL) & 0x00FFFFFFL;
+               writel(reg | ((u32) alpha << 24),
+                            flow->base + DP_GRAPH_WIND_CTRL);
+
+               reg = readl(flow->base + DP_COM_CONF);
+               writel(reg | DP_COM_CONF_GWAM, flow->base + DP_COM_CONF);
+       } else {
+               reg = readl(flow->base + DP_COM_CONF);
+               writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF);
+       }
+
+       ipu_srm_dp_sync_update(priv->ipu);
+
+       mutex_unlock(&priv->mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_set_global_alpha);
+
+int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos)
+{
+       struct ipu_flow *flow = to_flow(dp);
+       struct ipu_dp_priv *priv = flow->priv;
+
+       writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS);
+
+       ipu_srm_dp_sync_update(priv->ipu);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_set_window_pos);
+
+static void ipu_dp_csc_init(struct ipu_flow *flow,
+               enum ipu_color_space in,
+               enum ipu_color_space out,
+               u32 place)
+{
+       u32 reg;
+
+       reg = readl(flow->base + DP_COM_CONF);
+       reg &= ~DP_COM_CONF_CSC_DEF_MASK;
+
+       if (in == out) {
+               writel(reg, flow->base + DP_COM_CONF);
+               return;
+       }
+
+       if (in == IPUV3_COLORSPACE_RGB && out == IPUV3_COLORSPACE_YUV) {
+               writel(0x099 | (0x12d << 16), flow->base + DP_CSC_A_0);
+               writel(0x03a | (0x3a9 << 16), flow->base + DP_CSC_A_1);
+               writel(0x356 | (0x100 << 16), flow->base + DP_CSC_A_2);
+               writel(0x100 | (0x329 << 16), flow->base + DP_CSC_A_3);
+               writel(0x3d6 | (0x0000 << 16) | (2 << 30),
+                               flow->base + DP_CSC_0);
+               writel(0x200 | (2 << 14) | (0x200 << 16) | (2 << 30),
+                               flow->base + DP_CSC_1);
+       } else {
+               writel(0x095 | (0x000 << 16), flow->base + DP_CSC_A_0);
+               writel(0x0cc | (0x095 << 16), flow->base + DP_CSC_A_1);
+               writel(0x3ce | (0x398 << 16), flow->base + DP_CSC_A_2);
+               writel(0x095 | (0x0ff << 16), flow->base + DP_CSC_A_3);
+               writel(0x000 | (0x3e42 << 16) | (1 << 30),
+                               flow->base + DP_CSC_0);
+               writel(0x10a | (1 << 14) | (0x3dd6 << 16) | (1 << 30),
+                               flow->base + DP_CSC_1);
+       }
+
+       reg |= place;
+
+       writel(reg, flow->base + DP_COM_CONF);
+}
+
+int ipu_dp_setup_channel(struct ipu_dp *dp,
+               enum ipu_color_space in,
+               enum ipu_color_space out)
+{
+       struct ipu_flow *flow = to_flow(dp);
+       struct ipu_dp_priv *priv = flow->priv;
+
+       mutex_lock(&priv->mutex);
+
+       dp->in_cs = in;
+
+       if (!dp->foreground)
+               flow->out_cs = out;
+
+       if (flow->foreground.in_cs == flow->background.in_cs) {
+               /*
+                * foreground and background are of same colorspace, put
+                * colorspace converter after combining unit.
+                */
+               ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
+                               DP_COM_CONF_CSC_DEF_BOTH);
+       } else {
+               if (flow->foreground.in_cs == flow->out_cs)
+                       /*
+                        * foreground identical to output, apply color
+                        * conversion on background
+                        */
+                       ipu_dp_csc_init(flow, flow->background.in_cs,
+                                       flow->out_cs, DP_COM_CONF_CSC_DEF_BG);
+               else
+                       ipu_dp_csc_init(flow, flow->foreground.in_cs,
+                                       flow->out_cs, DP_COM_CONF_CSC_DEF_FG);
+       }
+
+       ipu_srm_dp_sync_update(priv->ipu);
+
+       mutex_unlock(&priv->mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_setup_channel);
+
+int ipu_dp_enable_channel(struct ipu_dp *dp)
+{
+       struct ipu_flow *flow = to_flow(dp);
+       struct ipu_dp_priv *priv = flow->priv;
+
+       mutex_lock(&priv->mutex);
+
+       if (!priv->use_count)
+               ipu_module_enable(priv->ipu, IPU_CONF_DP_EN);
+
+       priv->use_count++;
+
+       if (dp->foreground) {
+               u32 reg;
+
+               reg = readl(flow->base + DP_COM_CONF);
+               reg |= DP_COM_CONF_FG_EN;
+               writel(reg, flow->base + DP_COM_CONF);
+
+               ipu_srm_dp_sync_update(priv->ipu);
+       }
+
+       mutex_unlock(&priv->mutex);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_enable_channel);
+
+void ipu_dp_disable_channel(struct ipu_dp *dp)
+{
+       struct ipu_flow *flow = to_flow(dp);
+       struct ipu_dp_priv *priv = flow->priv;
+
+       mutex_lock(&priv->mutex);
+
+       priv->use_count--;
+
+       if (dp->foreground) {
+               u32 reg, csc;
+
+               reg = readl(flow->base + DP_COM_CONF);
+               csc = reg & DP_COM_CONF_CSC_DEF_MASK;
+               if (csc == DP_COM_CONF_CSC_DEF_FG)
+                       reg &= ~DP_COM_CONF_CSC_DEF_MASK;
+
+               reg &= ~DP_COM_CONF_FG_EN;
+               writel(reg, flow->base + DP_COM_CONF);
+
+               writel(0, flow->base + DP_FG_POS);
+               ipu_srm_dp_sync_update(priv->ipu);
+       }
+
+       if (!priv->use_count)
+               ipu_module_disable(priv->ipu, IPU_CONF_DP_EN);
+
+       if (priv->use_count < 0)
+               priv->use_count = 0;
+
+       mutex_unlock(&priv->mutex);
+}
+EXPORT_SYMBOL_GPL(ipu_dp_disable_channel);
+
+struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow)
+{
+       struct ipu_dp_priv *priv = ipu->dp_priv;
+       struct ipu_dp *dp;
+
+       if (flow > 5)
+               return ERR_PTR(-EINVAL);
+
+       if (flow & 1)
+               dp = &priv->flow[flow >> 1].foreground;
+       else
+               dp = &priv->flow[flow >> 1].background;
+
+       if (dp->in_use)
+               return ERR_PTR(-EBUSY);
+
+       dp->in_use = true;
+
+       return dp;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_get);
+
+void ipu_dp_put(struct ipu_dp *dp)
+{
+       dp->in_use = false;
+}
+EXPORT_SYMBOL_GPL(ipu_dp_put);
+
+int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
+{
+       struct ipu_dp_priv *priv;
+       int i;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       priv->dev = dev;
+       priv->ipu = ipu;
+
+       ipu->dp_priv = priv;
+
+       priv->base = devm_ioremap(dev, base, PAGE_SIZE);
+       if (!priv->base) {
+               kfree(priv);
+               return -ENOMEM;
+       }
+
+       mutex_init(&priv->mutex);
+
+       for (i = 0; i < 3; i++) {
+               priv->flow[i].foreground.foreground = 1;
+               priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
+               priv->flow[i].priv = priv;
+       }
+
+       return 0;
+}
+
+void ipu_dp_exit(struct ipu_soc *ipu)
+{
+}
diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-prv.h b/drivers/staging/imx-drm/ipu-v3/ipu-prv.h
new file mode 100644 (file)
index 0000000..5518028
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
+ * Copyright (C) 2005-2009 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.
+ *
+ * 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 __IPU_PRV_H__
+#define __IPU_PRV_H__
+
+struct ipu_soc;
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include "imx-ipu-v3.h"
+
+#define IPUV3_CHANNEL_CSI0                      0
+#define IPUV3_CHANNEL_CSI1                      1
+#define IPUV3_CHANNEL_CSI2                      2
+#define IPUV3_CHANNEL_CSI3                      3
+#define IPUV3_CHANNEL_MEM_BG_SYNC              23
+#define IPUV3_CHANNEL_MEM_FG_SYNC              27
+#define IPUV3_CHANNEL_MEM_DC_SYNC              28
+#define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA                31
+#define IPUV3_CHANNEL_MEM_DC_ASYNC             41
+#define IPUV3_CHANNEL_ROT_ENC_MEM              45
+#define IPUV3_CHANNEL_ROT_VF_MEM               46
+#define IPUV3_CHANNEL_ROT_PP_MEM               47
+#define IPUV3_CHANNEL_ROT_ENC_MEM_OUT          48
+#define IPUV3_CHANNEL_ROT_VF_MEM_OUT           49
+#define IPUV3_CHANNEL_ROT_PP_MEM_OUT           50
+#define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA                51
+
+#define IPU_MCU_T_DEFAULT      8
+#define IPU_CM_IDMAC_REG_OFS   0x00008000
+#define IPU_CM_IC_REG_OFS      0x00020000
+#define IPU_CM_IRT_REG_OFS     0x00028000
+#define IPU_CM_CSI0_REG_OFS    0x00030000
+#define IPU_CM_CSI1_REG_OFS    0x00038000
+#define IPU_CM_SMFC_REG_OFS    0x00050000
+#define IPU_CM_DC_REG_OFS      0x00058000
+#define IPU_CM_DMFC_REG_OFS    0x00060000
+
+/* Register addresses */
+/* IPU Common registers */
+#define IPU_CM_REG(offset)     (offset)
+
+#define IPU_CONF                       IPU_CM_REG(0)
+
+#define IPU_SRM_PRI1                   IPU_CM_REG(0x00a0)
+#define IPU_SRM_PRI2                   IPU_CM_REG(0x00a4)
+#define IPU_FS_PROC_FLOW1              IPU_CM_REG(0x00a8)
+#define IPU_FS_PROC_FLOW2              IPU_CM_REG(0x00ac)
+#define IPU_FS_PROC_FLOW3              IPU_CM_REG(0x00b0)
+#define IPU_FS_DISP_FLOW1              IPU_CM_REG(0x00b4)
+#define IPU_FS_DISP_FLOW2              IPU_CM_REG(0x00b8)
+#define IPU_SKIP                       IPU_CM_REG(0x00bc)
+#define IPU_DISP_ALT_CONF              IPU_CM_REG(0x00c0)
+#define IPU_DISP_GEN                   IPU_CM_REG(0x00c4)
+#define IPU_DISP_ALT1                  IPU_CM_REG(0x00c8)
+#define IPU_DISP_ALT2                  IPU_CM_REG(0x00cc)
+#define IPU_DISP_ALT3                  IPU_CM_REG(0x00d0)
+#define IPU_DISP_ALT4                  IPU_CM_REG(0x00d4)
+#define IPU_SNOOP                      IPU_CM_REG(0x00d8)
+#define IPU_MEM_RST                    IPU_CM_REG(0x00dc)
+#define IPU_PM                         IPU_CM_REG(0x00e0)
+#define IPU_GPR                                IPU_CM_REG(0x00e4)
+#define IPU_CHA_DB_MODE_SEL(ch)                IPU_CM_REG(0x0150 + 4 * ((ch) / 32))
+#define IPU_ALT_CHA_DB_MODE_SEL(ch)    IPU_CM_REG(0x0168 + 4 * ((ch) / 32))
+#define IPU_CHA_CUR_BUF(ch)            IPU_CM_REG(0x023C + 4 * ((ch) / 32))
+#define IPU_ALT_CUR_BUF0               IPU_CM_REG(0x0244)
+#define IPU_ALT_CUR_BUF1               IPU_CM_REG(0x0248)
+#define IPU_SRM_STAT                   IPU_CM_REG(0x024C)
+#define IPU_PROC_TASK_STAT             IPU_CM_REG(0x0250)
+#define IPU_DISP_TASK_STAT             IPU_CM_REG(0x0254)
+#define IPU_CHA_BUF0_RDY(ch)           IPU_CM_REG(0x0268 + 4 * ((ch) / 32))
+#define IPU_CHA_BUF1_RDY(ch)           IPU_CM_REG(0x0270 + 4 * ((ch) / 32))
+#define IPU_ALT_CHA_BUF0_RDY(ch)       IPU_CM_REG(0x0278 + 4 * ((ch) / 32))
+#define IPU_ALT_CHA_BUF1_RDY(ch)       IPU_CM_REG(0x0280 + 4 * ((ch) / 32))
+
+#define IPU_INT_CTRL(n)                IPU_CM_REG(0x003C + 4 * (n))
+#define IPU_INT_STAT(n)                IPU_CM_REG(0x0200 + 4 * (n))
+
+#define IPU_DI0_COUNTER_RELEASE                        (1 << 24)
+#define IPU_DI1_COUNTER_RELEASE                        (1 << 25)
+
+#define IPU_IDMAC_REG(offset)  (offset)
+
+#define IDMAC_CONF                     IPU_IDMAC_REG(0x0000)
+#define IDMAC_CHA_EN(ch)               IPU_IDMAC_REG(0x0004 + 4 * ((ch) / 32))
+#define IDMAC_SEP_ALPHA                        IPU_IDMAC_REG(0x000c)
+#define IDMAC_ALT_SEP_ALPHA            IPU_IDMAC_REG(0x0010)
+#define IDMAC_CHA_PRI(ch)              IPU_IDMAC_REG(0x0014 + 4 * ((ch) / 32))
+#define IDMAC_WM_EN(ch)                        IPU_IDMAC_REG(0x001c + 4 * ((ch) / 32))
+#define IDMAC_CH_LOCK_EN_1             IPU_IDMAC_REG(0x0024)
+#define IDMAC_CH_LOCK_EN_2             IPU_IDMAC_REG(0x0028)
+#define IDMAC_SUB_ADDR_0               IPU_IDMAC_REG(0x002c)
+#define IDMAC_SUB_ADDR_1               IPU_IDMAC_REG(0x0030)
+#define IDMAC_SUB_ADDR_2               IPU_IDMAC_REG(0x0034)
+#define IDMAC_BAND_EN(ch)              IPU_IDMAC_REG(0x0040 + 4 * ((ch) / 32))
+#define IDMAC_CHA_BUSY(ch)             IPU_IDMAC_REG(0x0100 + 4 * ((ch) / 32))
+
+#define IPU_NUM_IRQS   (32 * 5)
+
+enum ipu_modules {
+       IPU_CONF_CSI0_EN                = (1 << 0),
+       IPU_CONF_CSI1_EN                = (1 << 1),
+       IPU_CONF_IC_EN                  = (1 << 2),
+       IPU_CONF_ROT_EN                 = (1 << 3),
+       IPU_CONF_ISP_EN                 = (1 << 4),
+       IPU_CONF_DP_EN                  = (1 << 5),
+       IPU_CONF_DI0_EN                 = (1 << 6),
+       IPU_CONF_DI1_EN                 = (1 << 7),
+       IPU_CONF_SMFC_EN                = (1 << 8),
+       IPU_CONF_DC_EN                  = (1 << 9),
+       IPU_CONF_DMFC_EN                = (1 << 10),
+
+       IPU_CONF_VDI_EN                 = (1 << 12),
+
+       IPU_CONF_IDMAC_DIS              = (1 << 22),
+
+       IPU_CONF_IC_DMFC_SEL            = (1 << 25),
+       IPU_CONF_IC_DMFC_SYNC           = (1 << 26),
+       IPU_CONF_VDI_DMFC_SYNC          = (1 << 27),
+
+       IPU_CONF_CSI0_DATA_SOURCE       = (1 << 28),
+       IPU_CONF_CSI1_DATA_SOURCE       = (1 << 29),
+       IPU_CONF_IC_INPUT               = (1 << 30),
+       IPU_CONF_CSI_SEL                = (1 << 31),
+};
+
+struct ipuv3_channel {
+       unsigned int num;
+
+       bool enabled;
+       bool busy;
+
+       struct ipu_soc *ipu;
+};
+
+struct ipu_dc_priv;
+struct ipu_dmfc_priv;
+struct ipu_di;
+struct ipu_devtype;
+
+struct ipu_soc {
+       struct device           *dev;
+       const struct ipu_devtype        *devtype;
+       enum ipuv3_type         ipu_type;
+       spinlock_t              lock;
+       struct mutex            channel_lock;
+
+       void __iomem            *cm_reg;
+       void __iomem            *idmac_reg;
+       struct ipu_ch_param __iomem     *cpmem_base;
+
+       int                     usecount;
+
+       struct clk              *clk;
+
+       struct ipuv3_channel    channel[64];
+
+       int                     irq_start;
+       int                     irq_sync;
+       int                     irq_err;
+
+       struct ipu_dc_priv      *dc_priv;
+       struct ipu_dp_priv      *dp_priv;
+       struct ipu_dmfc_priv    *dmfc_priv;
+       struct ipu_di           *di_priv[2];
+};
+
+void ipu_srm_dp_sync_update(struct ipu_soc *ipu);
+
+int ipu_module_enable(struct ipu_soc *ipu, u32 mask);
+int ipu_module_disable(struct ipu_soc *ipu, u32 mask);
+
+int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id,
+               unsigned long base, u32 module, struct clk *ipu_clk);
+void ipu_di_exit(struct ipu_soc *ipu, int id);
+
+int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base,
+               struct clk *ipu_clk);
+void ipu_dmfc_exit(struct ipu_soc *ipu);
+
+int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base);
+void ipu_dp_exit(struct ipu_soc *ipu);
+
+int ipu_dc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base,
+               unsigned long template_base);
+void ipu_dc_exit(struct ipu_soc *ipu);
+
+int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base);
+void ipu_cpmem_exit(struct ipu_soc *ipu);
+
+#endif                         /* __IPU_PRV_H__ */
diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c
new file mode 100644 (file)
index 0000000..78d3eda
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * i.MX IPUv3 Graphics driver
+ *
+ * Copyright (C) 2011 Sascha Hauer, Pengutronix
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/module.h>
+#include <linux/export.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/fb.h>
+#include <linux/clk.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "ipu-v3/imx-ipu-v3.h"
+#include "imx-drm.h"
+
+#define DRIVER_DESC            "i.MX IPUv3 Graphics"
+
+struct ipu_framebuffer {
+       struct drm_framebuffer  base;
+       void                    *virt;
+       dma_addr_t              phys;
+       size_t                  len;
+};
+
+struct ipu_crtc {
+       struct drm_fb_helper    fb_helper;
+       struct ipu_framebuffer  ifb;
+       int                     num_crtcs;
+       struct device           *dev;
+       struct drm_crtc         base;
+       struct imx_drm_crtc     *imx_crtc;
+       struct ipuv3_channel    *ipu_ch;
+       struct ipu_dc           *dc;
+       struct ipu_dp           *dp;
+       struct dmfc_channel     *dmfc;
+       struct ipu_di           *di;
+       int                     enabled;
+       struct ipu_priv         *ipu_priv;
+       struct drm_pending_vblank_event *page_flip_event;
+       struct drm_framebuffer  *newfb;
+       int                     irq;
+       u32                     interface_pix_fmt;
+       unsigned long           di_clkflags;
+};
+
+#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
+
+static int calc_vref(struct drm_display_mode *mode)
+{
+       unsigned long htotal, vtotal;
+
+       htotal = mode->htotal;
+       vtotal = mode->vtotal;
+
+       if (!htotal || !vtotal)
+               return 60;
+
+       return mode->clock * 1000 / vtotal / htotal;
+}
+
+static int calc_bandwidth(struct drm_display_mode *mode, unsigned int vref)
+{
+       return mode->hdisplay * mode->vdisplay * vref;
+}
+
+static void ipu_fb_enable(struct ipu_crtc *ipu_crtc)
+{
+       if (ipu_crtc->enabled)
+               return;
+
+       ipu_di_enable(ipu_crtc->di);
+       ipu_dmfc_enable_channel(ipu_crtc->dmfc);
+       ipu_idmac_enable_channel(ipu_crtc->ipu_ch);
+       ipu_dc_enable_channel(ipu_crtc->dc);
+       if (ipu_crtc->dp)
+               ipu_dp_enable_channel(ipu_crtc->dp);
+
+       ipu_crtc->enabled = 1;
+}
+
+static void ipu_fb_disable(struct ipu_crtc *ipu_crtc)
+{
+       if (!ipu_crtc->enabled)
+               return;
+
+       if (ipu_crtc->dp)
+               ipu_dp_disable_channel(ipu_crtc->dp);
+       ipu_dc_disable_channel(ipu_crtc->dc);
+       ipu_idmac_disable_channel(ipu_crtc->ipu_ch);
+       ipu_dmfc_disable_channel(ipu_crtc->dmfc);
+       ipu_di_disable(ipu_crtc->di);
+
+       ipu_crtc->enabled = 0;
+}
+
+static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       dev_info(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
+
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+               ipu_fb_enable(ipu_crtc);
+               break;
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+       case DRM_MODE_DPMS_OFF:
+               ipu_fb_disable(ipu_crtc);
+               break;
+       }
+}
+
+static int ipu_page_flip(struct drm_crtc *crtc,
+               struct drm_framebuffer *fb,
+               struct drm_pending_vblank_event *event)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+       int ret;
+
+       if (ipu_crtc->newfb)
+               return -EBUSY;
+
+       ret = imx_drm_crtc_vblank_get(ipu_crtc->imx_crtc);
+       if (ret) {
+               dev_dbg(ipu_crtc->dev, "failed to acquire vblank counter\n");
+               list_del(&event->base.link);
+
+               return ret;
+       }
+
+       ipu_crtc->newfb = fb;
+       ipu_crtc->page_flip_event = event;
+
+       return 0;
+}
+
+static const struct drm_crtc_funcs ipu_crtc_funcs = {
+       .set_config = drm_crtc_helper_set_config,
+       .destroy = drm_crtc_cleanup,
+       .page_flip = ipu_page_flip,
+};
+
+static int ipu_drm_set_base(struct drm_crtc *crtc, int x, int y)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+       struct drm_gem_cma_object *cma_obj;
+       struct drm_framebuffer *fb = crtc->fb;
+       unsigned long phys;
+
+       cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
+       if (!cma_obj) {
+               DRM_LOG_KMS("entry is null.\n");
+               return -EFAULT;
+       }
+
+       phys = cma_obj->paddr;
+       phys += x * (fb->bits_per_pixel >> 3);
+       phys += y * fb->pitches[0];
+
+       dev_dbg(ipu_crtc->dev, "%s: phys: 0x%lx\n", __func__, phys);
+       dev_dbg(ipu_crtc->dev, "%s: xy: %dx%d\n", __func__, x, y);
+
+       ipu_cpmem_set_stride(ipu_get_cpmem(ipu_crtc->ipu_ch), fb->pitches[0]);
+       ipu_cpmem_set_buffer(ipu_get_cpmem(ipu_crtc->ipu_ch),
+                         0, phys);
+
+       return 0;
+}
+
+static int ipu_crtc_mode_set(struct drm_crtc *crtc,
+                              struct drm_display_mode *orig_mode,
+                              struct drm_display_mode *mode,
+                              int x, int y,
+                              struct drm_framebuffer *old_fb)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+       struct drm_framebuffer *fb = ipu_crtc->base.fb;
+       int ret;
+       struct ipu_di_signal_cfg sig_cfg = {};
+       u32 out_pixel_fmt;
+       struct ipu_ch_param __iomem *cpmem = ipu_get_cpmem(ipu_crtc->ipu_ch);
+       int bpp;
+       u32 v4l2_fmt;
+
+       dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
+                       mode->hdisplay);
+       dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
+                       mode->vdisplay);
+
+       ipu_ch_param_zero(cpmem);
+
+       switch (fb->pixel_format) {
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+               v4l2_fmt = V4L2_PIX_FMT_RGB32;
+               bpp = 32;
+               break;
+       case DRM_FORMAT_RGB565:
+               v4l2_fmt = V4L2_PIX_FMT_RGB565;
+               bpp = 16;
+               break;
+       case DRM_FORMAT_RGB888:
+               v4l2_fmt = V4L2_PIX_FMT_RGB24;
+               bpp = 24;
+               break;
+       default:
+               dev_err(ipu_crtc->dev, "unsupported pixel format 0x%08x\n",
+                               fb->pixel_format);
+               return -EINVAL;
+       }
+
+       out_pixel_fmt = ipu_crtc->interface_pix_fmt;
+
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               sig_cfg.interlaced = 1;
+       if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+               sig_cfg.Hsync_pol = 1;
+       if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+               sig_cfg.Vsync_pol = 1;
+
+       sig_cfg.enable_pol = 1;
+       sig_cfg.clk_pol = 0;
+       sig_cfg.width = mode->hdisplay;
+       sig_cfg.height = mode->vdisplay;
+       sig_cfg.pixel_fmt = out_pixel_fmt;
+       sig_cfg.h_start_width = mode->htotal - mode->hsync_end;
+       sig_cfg.h_sync_width = mode->hsync_end - mode->hsync_start;
+       sig_cfg.h_end_width = mode->hsync_start - mode->hdisplay;
+
+       sig_cfg.v_start_width = mode->vtotal - mode->vsync_end;
+       sig_cfg.v_sync_width = mode->vsync_end - mode->vsync_start;
+       sig_cfg.v_end_width = mode->vsync_start - mode->vdisplay;
+       sig_cfg.pixelclock = mode->clock * 1000;
+       sig_cfg.clkflags = ipu_crtc->di_clkflags;
+
+       sig_cfg.v_to_h_sync = 0;
+
+       if (ipu_crtc->dp) {
+               ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB,
+                               IPUV3_COLORSPACE_RGB);
+               if (ret) {
+                       dev_err(ipu_crtc->dev,
+                               "initializing display processor failed with %d\n",
+                               ret);
+                       return ret;
+               }
+               ipu_dp_set_global_alpha(ipu_crtc->dp, 1, 0, 1);
+       }
+
+       ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, sig_cfg.interlaced,
+                       out_pixel_fmt, mode->hdisplay);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "initializing display controller failed with %d\n",
+                               ret);
+               return ret;
+       }
+
+       ret = ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "initializing panel failed with %d\n", ret);
+               return ret;
+       }
+
+       ipu_cpmem_set_resolution(cpmem, mode->hdisplay, mode->vdisplay);
+       ipu_cpmem_set_fmt(cpmem, v4l2_fmt);
+       ipu_cpmem_set_high_priority(ipu_crtc->ipu_ch);
+
+       ret = ipu_dmfc_init_channel(ipu_crtc->dmfc, mode->hdisplay);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "initializing dmfc channel failed with %d\n",
+                               ret);
+               return ret;
+       }
+
+       ret = ipu_dmfc_alloc_bandwidth(ipu_crtc->dmfc,
+                       calc_bandwidth(mode, calc_vref(mode)), 64);
+       if (ret) {
+               dev_err(ipu_crtc->dev,
+                               "allocating dmfc bandwidth failed with %d\n",
+                               ret);
+               return ret;
+       }
+
+       ipu_drm_set_base(crtc, x, y);
+
+       return 0;
+}
+
+static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
+{
+       struct drm_pending_vblank_event *e;
+       struct timeval now;
+       unsigned long flags;
+       struct drm_device *drm = ipu_crtc->base.dev;
+
+       spin_lock_irqsave(&drm->event_lock, flags);
+
+       e = ipu_crtc->page_flip_event;
+       if (!e) {
+               spin_unlock_irqrestore(&drm->event_lock, flags);
+               return;
+       }
+
+       do_gettimeofday(&now);
+       e->event.sequence = 0;
+       e->event.tv_sec = now.tv_sec;
+       e->event.tv_usec = now.tv_usec;
+       ipu_crtc->page_flip_event = NULL;
+
+       imx_drm_crtc_vblank_put(ipu_crtc->imx_crtc);
+
+       list_add_tail(&e->base.link, &e->base.file_priv->event_list);
+
+       wake_up_interruptible(&e->base.file_priv->event_wait);
+
+       spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
+static irqreturn_t ipu_irq_handler(int irq, void *dev_id)
+{
+       struct ipu_crtc *ipu_crtc = dev_id;
+
+       imx_drm_handle_vblank(ipu_crtc->imx_crtc);
+
+       if (ipu_crtc->newfb) {
+               ipu_crtc->base.fb = ipu_crtc->newfb;
+               ipu_crtc->newfb = NULL;
+               ipu_drm_set_base(&ipu_crtc->base, 0, 0);
+               ipu_crtc_handle_pageflip(ipu_crtc);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
+                                 const struct drm_display_mode *mode,
+                                 struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void ipu_crtc_prepare(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_fb_disable(ipu_crtc);
+}
+
+static void ipu_crtc_commit(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_fb_enable(ipu_crtc);
+}
+
+static void ipu_crtc_load_lut(struct drm_crtc *crtc)
+{
+}
+
+static struct drm_crtc_helper_funcs ipu_helper_funcs = {
+       .dpms = ipu_crtc_dpms,
+       .mode_fixup = ipu_crtc_mode_fixup,
+       .mode_set = ipu_crtc_mode_set,
+       .prepare = ipu_crtc_prepare,
+       .commit = ipu_crtc_commit,
+       .load_lut = ipu_crtc_load_lut,
+};
+
+static int ipu_enable_vblank(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       enable_irq(ipu_crtc->irq);
+
+       return 0;
+}
+
+static void ipu_disable_vblank(struct drm_crtc *crtc)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       disable_irq(ipu_crtc->irq);
+}
+
+static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
+               u32 pixfmt)
+{
+       struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
+
+       ipu_crtc->interface_pix_fmt = pixfmt;
+
+       switch (encoder_type) {
+       case DRM_MODE_ENCODER_LVDS:
+               ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
+                       IPU_DI_CLKMODE_EXT;
+               break;
+       case DRM_MODE_ENCODER_NONE:
+               ipu_crtc->di_clkflags = 0;
+               break;
+       }
+
+       return 0;
+}
+
+static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = {
+       .enable_vblank = ipu_enable_vblank,
+       .disable_vblank = ipu_disable_vblank,
+       .set_interface_pix_fmt = ipu_set_interface_pix_fmt,
+       .crtc_funcs = &ipu_crtc_funcs,
+       .crtc_helper_funcs = &ipu_helper_funcs,
+};
+
+static void ipu_put_resources(struct ipu_crtc *ipu_crtc)
+{
+       if (!IS_ERR_OR_NULL(ipu_crtc->ipu_ch))
+               ipu_idmac_put(ipu_crtc->ipu_ch);
+       if (!IS_ERR_OR_NULL(ipu_crtc->dmfc))
+               ipu_dmfc_put(ipu_crtc->dmfc);
+       if (!IS_ERR_OR_NULL(ipu_crtc->dp))
+               ipu_dp_put(ipu_crtc->dp);
+       if (!IS_ERR_OR_NULL(ipu_crtc->di))
+               ipu_di_put(ipu_crtc->di);
+}
+
+static int ipu_get_resources(struct ipu_crtc *ipu_crtc,
+               struct ipu_client_platformdata *pdata)
+{
+       struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
+       int ret;
+
+       ipu_crtc->ipu_ch = ipu_idmac_get(ipu, pdata->dma[0]);
+       if (IS_ERR_OR_NULL(ipu_crtc->ipu_ch)) {
+               ret = PTR_ERR(ipu_crtc->ipu_ch);
+               goto err_out;
+       }
+
+       ipu_crtc->dc = ipu_dc_get(ipu, pdata->dc);
+       if (IS_ERR(ipu_crtc->dc)) {
+               ret = PTR_ERR(ipu_crtc->dc);
+               goto err_out;
+       }
+
+       ipu_crtc->dmfc = ipu_dmfc_get(ipu, pdata->dma[0]);
+       if (IS_ERR(ipu_crtc->dmfc)) {
+               ret = PTR_ERR(ipu_crtc->dmfc);
+               goto err_out;
+       }
+
+       if (pdata->dp >= 0) {
+               ipu_crtc->dp = ipu_dp_get(ipu, pdata->dp);
+               if (IS_ERR(ipu_crtc->dp)) {
+                       ret = PTR_ERR(ipu_crtc->ipu_ch);
+                       goto err_out;
+               }
+       }
+
+       ipu_crtc->di = ipu_di_get(ipu, pdata->di);
+       if (IS_ERR(ipu_crtc->di)) {
+               ret = PTR_ERR(ipu_crtc->di);
+               goto err_out;
+       }
+
+       ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch,
+                       IPU_IRQ_EOF);
+       ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
+                       "imx_drm", ipu_crtc);
+       if (ret < 0) {
+               dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
+               goto err_out;
+       }
+
+       disable_irq(ipu_crtc->irq);
+
+       return 0;
+err_out:
+       ipu_put_resources(ipu_crtc);
+
+       return ret;
+}
+
+static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
+               struct ipu_client_platformdata *pdata)
+{
+       int ret;
+
+       ret = ipu_get_resources(ipu_crtc, pdata);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "getting resources failed with %d.\n",
+                               ret);
+               return ret;
+       }
+
+       ret = imx_drm_add_crtc(&ipu_crtc->base,
+                       &ipu_crtc->imx_crtc,
+                       &ipu_crtc_helper_funcs, THIS_MODULE,
+                       ipu_crtc->dev->parent->of_node, pdata->di);
+       if (ret) {
+               dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
+               goto err_put_resources;
+       }
+
+       return 0;
+
+err_put_resources:
+       ipu_put_resources(ipu_crtc);
+
+       return ret;
+}
+
+static int __devinit ipu_drm_probe(struct platform_device *pdev)
+{
+       struct ipu_client_platformdata *pdata = pdev->dev.platform_data;
+       struct ipu_crtc *ipu_crtc;
+       int ret;
+
+       if (!pdata)
+               return -EINVAL;
+
+       pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+       ipu_crtc = devm_kzalloc(&pdev->dev, sizeof(*ipu_crtc), GFP_KERNEL);
+       if (!ipu_crtc)
+               return -ENOMEM;
+
+       ipu_crtc->dev = &pdev->dev;
+
+       ret = ipu_crtc_init(ipu_crtc, pdata);
+
+       platform_set_drvdata(pdev, ipu_crtc);
+
+       return 0;
+}
+
+static int __devexit ipu_drm_remove(struct platform_device *pdev)
+{
+       struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev);
+
+       imx_drm_remove_crtc(ipu_crtc->imx_crtc);
+
+       ipu_put_resources(ipu_crtc);
+
+       return 0;
+}
+
+static struct platform_driver ipu_drm_driver = {
+       .driver = {
+               .name = "imx-ipuv3-crtc",
+       },
+       .probe = ipu_drm_probe,
+       .remove = __devexit_p(ipu_drm_remove),
+};
+module_platform_driver(ipu_drm_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c
new file mode 100644 (file)
index 0000000..9b51d73
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * i.MX drm driver - parallel display implementation
+ *
+ * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <linux/videodev2.h>
+
+#include "imx-drm.h"
+
+#define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector)
+#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder)
+
+struct imx_parallel_display {
+       struct drm_connector connector;
+       struct imx_drm_connector *imx_drm_connector;
+       struct drm_encoder encoder;
+       struct imx_drm_encoder *imx_drm_encoder;
+       struct device *dev;
+       void *edid;
+       int edid_len;
+       u32 interface_pix_fmt;
+       int mode_valid;
+       struct drm_display_mode mode;
+};
+
+static enum drm_connector_status imx_pd_connector_detect(
+               struct drm_connector *connector, bool force)
+{
+       return connector_status_connected;
+}
+
+static void imx_pd_connector_destroy(struct drm_connector *connector)
+{
+       /* do not free here */
+}
+
+static int imx_pd_connector_get_modes(struct drm_connector *connector)
+{
+       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
+       int num_modes = 0;
+
+       if (imxpd->edid) {
+               drm_mode_connector_update_edid_property(connector, imxpd->edid);
+               num_modes = drm_add_edid_modes(connector, imxpd->edid);
+       }
+
+       if (imxpd->mode_valid) {
+               struct drm_display_mode *mode = drm_mode_create(connector->dev);
+               drm_mode_copy(mode, &imxpd->mode);
+               mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+               drm_mode_probed_add(connector, mode);
+               num_modes++;
+       }
+
+       return num_modes;
+}
+
+static int imx_pd_connector_mode_valid(struct drm_connector *connector,
+                         struct drm_display_mode *mode)
+{
+       return 0;
+}
+
+static struct drm_encoder *imx_pd_connector_best_encoder(
+               struct drm_connector *connector)
+{
+       struct imx_parallel_display *imxpd = con_to_imxpd(connector);
+
+       return &imxpd->encoder;
+}
+
+static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+}
+
+static bool imx_pd_encoder_mode_fixup(struct drm_encoder *encoder,
+                          const struct drm_display_mode *mode,
+                          struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
+{
+       struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
+
+       imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE,
+                       imxpd->interface_pix_fmt);
+}
+
+static void imx_pd_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static void imx_pd_encoder_mode_set(struct drm_encoder *encoder,
+                        struct drm_display_mode *mode,
+                        struct drm_display_mode *adjusted_mode)
+{
+}
+
+static void imx_pd_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static void imx_pd_encoder_destroy(struct drm_encoder *encoder)
+{
+       /* do not free here */
+}
+
+static struct drm_connector_funcs imx_pd_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .detect = imx_pd_connector_detect,
+       .destroy = imx_pd_connector_destroy,
+};
+
+static struct drm_connector_helper_funcs imx_pd_connector_helper_funcs = {
+       .get_modes = imx_pd_connector_get_modes,
+       .best_encoder = imx_pd_connector_best_encoder,
+       .mode_valid = imx_pd_connector_mode_valid,
+};
+
+static struct drm_encoder_funcs imx_pd_encoder_funcs = {
+       .destroy = imx_pd_encoder_destroy,
+};
+
+static struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
+       .dpms = imx_pd_encoder_dpms,
+       .mode_fixup = imx_pd_encoder_mode_fixup,
+       .prepare = imx_pd_encoder_prepare,
+       .commit = imx_pd_encoder_commit,
+       .mode_set = imx_pd_encoder_mode_set,
+       .disable = imx_pd_encoder_disable,
+};
+
+static int imx_pd_register(struct imx_parallel_display *imxpd)
+{
+       int ret;
+
+       drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder);
+
+       imxpd->connector.funcs = &imx_pd_connector_funcs;
+       imxpd->encoder.funcs = &imx_pd_encoder_funcs;
+
+       imxpd->encoder.encoder_type = DRM_MODE_ENCODER_NONE;
+       imxpd->connector.connector_type = DRM_MODE_CONNECTOR_VGA;
+
+       drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs);
+       ret = imx_drm_add_encoder(&imxpd->encoder, &imxpd->imx_drm_encoder,
+                       THIS_MODULE);
+       if (ret) {
+               dev_err(imxpd->dev, "adding encoder failed with %d\n", ret);
+               return ret;
+       }
+
+       drm_connector_helper_add(&imxpd->connector,
+                       &imx_pd_connector_helper_funcs);
+
+       ret = imx_drm_add_connector(&imxpd->connector,
+                       &imxpd->imx_drm_connector, THIS_MODULE);
+       if (ret) {
+               imx_drm_remove_encoder(imxpd->imx_drm_encoder);
+               dev_err(imxpd->dev, "adding connector failed with %d\n", ret);
+               return ret;
+       }
+
+       imxpd->connector.encoder = &imxpd->encoder;
+
+       return 0;
+}
+
+static int __devinit imx_pd_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       const u8 *edidp;
+       struct imx_parallel_display *imxpd;
+       int ret;
+       const char *fmt;
+
+       imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL);
+       if (!imxpd)
+               return -ENOMEM;
+
+       edidp = of_get_property(np, "edid", &imxpd->edid_len);
+       if (edidp)
+               imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL);
+
+       ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
+       if (!ret) {
+               if (!strcmp(fmt, "rgb24"))
+                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24;
+               else if (!strcmp(fmt, "rgb565"))
+                       imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565;
+       }
+
+       imxpd->dev = &pdev->dev;
+
+       ret = imx_pd_register(imxpd);
+       if (ret)
+               return ret;
+
+       ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np);
+
+       platform_set_drvdata(pdev, imxpd);
+
+       return 0;
+}
+
+static int __devexit imx_pd_remove(struct platform_device *pdev)
+{
+       struct imx_parallel_display *imxpd = platform_get_drvdata(pdev);
+       struct drm_connector *connector = &imxpd->connector;
+       struct drm_encoder *encoder = &imxpd->encoder;
+
+       drm_mode_connector_detach_encoder(connector, encoder);
+
+       imx_drm_remove_connector(imxpd->imx_drm_connector);
+       imx_drm_remove_encoder(imxpd->imx_drm_encoder);
+
+       return 0;
+}
+
+static const struct of_device_id imx_pd_dt_ids[] = {
+       { .compatible = "fsl,imx-parallel-display", },
+       { /* sentinel */ }
+};
+
+static struct platform_driver imx_pd_driver = {
+       .probe          = imx_pd_probe,
+       .remove         = __devexit_p(imx_pd_remove),
+       .driver         = {
+               .of_match_table = imx_pd_dt_ids,
+               .name   = "imx-parallel-display",
+               .owner  = THIS_MODULE,
+       },
+};
+
+module_platform_driver(imx_pd_driver);
+
+MODULE_DESCRIPTION("i.MX parallel display driver");
+MODULE_AUTHOR("Sascha Hauer, Pengutronix");
+MODULE_LICENSE("GPL");
index ff93c15d349bba2e23466c9da30daca34565797a..368a2e19b2d4581e04f694df0369761011552665 100644 (file)
@@ -157,7 +157,7 @@ static int temp_to_adc_conversion(long temp, struct omap_bandgap *bg_ptr, int i,
        high = ts_data->adc_end_val - ts_data->adc_start_val;
        mid = (high + low) / 2;
 
-       if (temp < bg_ptr->conv_table[high] || temp > bg_ptr->conv_table[high])
+       if (temp < bg_ptr->conv_table[low] || temp > bg_ptr->conv_table[high])
                return -EINVAL;
 
        while (low < high) {
index 758ce0a8d82e03c59d326b5ce0f6b8bdda425b25..64913aeb0bacceae794a8553fe1178d4c4efa755 100644 (file)
@@ -104,10 +104,10 @@ ssize_t oz_cdev_read(struct file *filp, char __user *buf, size_t count,
        if (pd)
                oz_pd_get(pd);
        spin_unlock_bh(&g_cdev.lock);
-       if (pd == 0)
+       if (pd == NULL)
                return -1;
        ctx = oz_cdev_claim_ctx(pd);
-       if (ctx == 0)
+       if (ctx == NULL)
                goto out2;
        n = ctx->rd_in - ctx->rd_out;
        if (n < 0)
@@ -157,11 +157,11 @@ ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count,
        if (pd)
                oz_pd_get(pd);
        spin_unlock_bh(&g_cdev.lock);
-       if (pd == 0)
+       if (pd == NULL)
                return -1;
        eb = &pd->elt_buff;
        ei = oz_elt_info_alloc(eb);
-       if (ei == 0) {
+       if (ei == NULL) {
                count = 0;
                goto out;
        }
@@ -410,7 +410,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume)
                return 0;
        }
        ctx = kzalloc(sizeof(struct oz_serial_ctx), GFP_ATOMIC);
-       if (ctx == 0)
+       if (ctx == NULL)
                return -ENOMEM;
        atomic_set(&ctx->ref_count, 1);
        ctx->tx_seq_num = 1;
@@ -424,7 +424,7 @@ int oz_cdev_start(struct oz_pd *pd, int resume)
                spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]);
        }
        spin_lock(&g_cdev.lock);
-       if ((g_cdev.active_pd == 0) &&
+       if ((g_cdev.active_pd == NULL) &&
                (memcmp(pd->mac_addr, g_cdev.active_addr, ETH_ALEN) == 0)) {
                oz_pd_get(pd);
                g_cdev.active_pd = pd;
@@ -477,7 +477,7 @@ void oz_cdev_rx(struct oz_pd *pd, struct oz_elt *elt)
        int ix;
 
        ctx = oz_cdev_claim_ctx(pd);
-       if (ctx == 0) {
+       if (ctx == NULL) {
                oz_trace("Cannot claim serial context.\n");
                return;
        }
index f7426b44ee08102f3e5d7397ee9fa009ca8aadc0..6e9f7090c4512f6fc77dfdcd4e636ec7a7ff83f8 100644 (file)
@@ -1197,7 +1197,7 @@ static inline int handle_lcd_special_code(void)
                break;
        }
 
-       /* Check wether one flag was changed */
+       /* Check whether one flag was changed */
        if (oldflags != lcd_flags) {
                /* check whether one of B,C,D flags were changed */
                if ((oldflags ^ lcd_flags) &
@@ -1212,7 +1212,7 @@ static inline int handle_lcd_special_code(void)
                        lcd_write_cmd(0x30
                                      | ((lcd_flags & LCD_FLAG_F) ? 4 : 0)
                                      | ((lcd_flags & LCD_FLAG_N) ? 8 : 0));
-               /* check wether L flag was changed */
+               /* check whether L flag was changed */
                else if ((oldflags ^ lcd_flags) & (LCD_FLAG_L)) {
                        if (lcd_flags & (LCD_FLAG_L))
                                lcd_backlight(1);
index 99e907d462243e09727dbfa8009dee347721fb68..4feecec8609c696e29e745a0b2b7833def2f917b 100644 (file)
@@ -267,7 +267,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
                else
                        ieee->seq_ctrl[0]++;
 
-               /* check wether the managed packet queued greater than 5 */
+               /* check whether the managed packet queued greater than 5 */
                if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) ||
                    (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) ||
                    (ieee->queue_stop)) {
index 9f625bc1b4a1db585f5072faa2a3a3606f095c76..7a0707810fd02922ae772433e89414f54f1ad1ff 100644 (file)
@@ -271,7 +271,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
                else
                        ieee->seq_ctrl[0]++;
 
-               /* check wether the managed packet queued greater than 5 */
+               /* check whether the managed packet queued greater than 5 */
                if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
                                (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
                                (ieee->queue_stop) ) {
index 213829ec7df9cdcc6128263b7c4972b373a90378..afe9c2e763d7747f051f412745fa346c24f2e0af 100644 (file)
@@ -352,12 +352,8 @@ static int rtsx_suspend(struct pci_dev *pci, pm_message_t state)
        struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
        struct rtsx_chip *chip;
 
-       dev_info(&dev->pci->dev, "Ready to suspend\n");
-
-       if (!dev) {
-               dev_err(&dev->pci->dev, "Invalid memory\n");
+       if (!dev)
                return 0;
-       }
 
        /* lock the device pointers */
        mutex_lock(&(dev->dev_mutex));
@@ -391,12 +387,8 @@ static int rtsx_resume(struct pci_dev *pci)
        struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
        struct rtsx_chip *chip;
 
-       dev_info(&dev->pci->dev, "Ready to resume\n");
-
-       if (!dev) {
-               dev_err(&dev->pci->dev, "Invalid memory\n");
+       if (!dev)
                return 0;
-       }
 
        chip = dev->chip;
 
@@ -441,12 +433,8 @@ static void rtsx_shutdown(struct pci_dev *pci)
        struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci);
        struct rtsx_chip *chip;
 
-       dev_info(&dev->pci->dev, "Ready to shutdown\n");
-
-       if (!dev) {
-               dev_err(&dev->pci->dev, "Invalid memory\n");
+       if (!dev)
                return;
-       }
 
        chip = dev->chip;
 
index 383f2cfc1ad28ecf8232db8c8cb51a339730a688..ccad049c1122b442b6ab8d4ccefc29c916691f04 100644 (file)
@@ -789,7 +789,6 @@ void dc_restart(struct channel *);
 void dc_receiver_onoff(struct channel *, u32);
 void dc_transmitter_onoff(struct channel *, u32);
 void dc_set_loopback(struct channel *, u32);
-u32 dc_init_descriptor_list(struct channel *);
 void dc_clear_descriptor_list(struct channel *);
 void dc_drop_descriptor_list(struct channel *);
 void dc_set_output_port(struct channel *);
index 9e81d9036a3372f815503502cddcf2ec7c28e827..daadd6ea4978fffc0c7ee0a3dec3ececbcddbc8a 100644 (file)
@@ -17,6 +17,8 @@
 #include "2t3e3.h"
 #include "ctrl.h"
 
+static int dc_init_descriptor_list(struct channel *sc);
+
 void dc_init(struct channel *sc)
 {
        u32 val;
@@ -307,7 +309,7 @@ void dc_set_loopback(struct channel *sc, u32 mode)
                              SBE_2T3E3_21143_VAL_FULL_DUPLEX_MODE);
 }
 
-u32 dc_init_descriptor_list(struct channel *sc)
+static int dc_init_descriptor_list(struct channel *sc)
 {
        u32 i, j;
        struct sk_buff *m;
@@ -317,7 +319,7 @@ u32 dc_init_descriptor_list(struct channel *sc)
                                            sizeof(t3e3_rx_desc_t), GFP_KERNEL);
        if (sc->ether.rx_ring == NULL) {
                dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
-               return ENOMEM;
+               return -ENOMEM;
        }
 
        if (sc->ether.tx_ring == NULL)
@@ -327,7 +329,7 @@ u32 dc_init_descriptor_list(struct channel *sc)
                kfree(sc->ether.rx_ring);
                sc->ether.rx_ring = NULL;
                dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
-               return ENOMEM;
+               return -ENOMEM;
        }
 
 
@@ -351,7 +353,7 @@ u32 dc_init_descriptor_list(struct channel *sc)
                                sc->ether.tx_ring = NULL;
                                dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:"
                                        " no buffer space for RX ring\n");
-                               return ENOBUFS;
+                               return -ENOBUFS;
                        }
                        sc->ether.rx_data[i] = m;
                }
index cd778b3a02b249cffceeea98974cf9018c30dfbd..8adb17816ad9c44f37388fe433d8086e0208707e 100644 (file)
@@ -67,6 +67,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *
        dev = alloc_hdlcdev(channel);
        if (!dev) {
                printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n");
+               err = -ENOMEM;
                goto free_regions;
        }
 
@@ -82,8 +83,9 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *
        else
                channel->h.slot = 0;
 
-       if (setup_device(dev, channel))
-               goto free_regions;
+       err = setup_device(dev, channel);
+       if (err)
+               goto free_dev;
 
        pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */
        pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFFFFFF);
@@ -92,14 +94,19 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev *
        pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command);
        t3e3_init(channel);
 
-       if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) {
+       err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev);
+       if (err) {
                printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
-               goto free_regions;
+               goto unregister_dev;
        }
 
        pci_set_drvdata(pdev, channel);
        return 0;
 
+unregister_dev:
+       unregister_hdlc_device(dev);
+free_dev:
+       free_netdev(dev);
 free_regions:
        pci_release_regions(pdev);
 disable:
index cb07a0da0f63c890e875cb0778a5590ef55b5f06..eda2e7d73645d785ea4a825ebffd41ad223b0bf6 100644 (file)
@@ -19,7 +19,7 @@ if NET_VENDOR_SILICOM
 
 config SBYPASS
        tristate "Silicom BypassCTL library support"
-       depends on PCI
+       depends on PCI && NET
        depends on m
        ---help---
          If you have a network (Ethernet) controller of this type, say Y
@@ -29,7 +29,7 @@ config SBYPASS
 
 config BPCTL
        tristate "Silicom BypassCTL net support"
-       depends on PCI
+       depends on PCI && NET
        depends on m
        select SBYPASS
        select NET_CORE
index d1cf246ee7bbd8e448679b404c3c673d7cc4b10b..3cfd0516adfa5ea6e7e8986b0150eb09711081c2 100644 (file)
@@ -127,16 +127,12 @@ typedef struct _bpctl_dev {
        int bp_10g9;
        int bp_i80;
        int bp_540;
-
-// selftest stanza
        int (*hard_start_xmit_save) (struct sk_buff *skb,
                                     struct net_device *dev);
        const struct net_device_ops *old_ops;
        struct net_device_ops new_ops;
        int bp_self_test_flag;
        char *bp_tx_data;
-// end selftest stanza 
-//
        struct bypass_pfs_sd bypass_pfs_set;
 
 } bpctl_dev_t;
@@ -168,14 +164,13 @@ static int bp_device_event(struct notifier_block *unused,
        struct net_device *dev = ptr;
        static bpctl_dev_t *pbpctl_dev = NULL, *pbpctl_dev_m = NULL;
        int dev_num = 0, ret = 0, ret_d = 0, time_left = 0;
-       //printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex );
-       //return NOTIFY_DONE;
+       /* printk("BP_PROC_SUPPORT event =%d %s %d\n", event,dev->name, dev->ifindex ); */
+       /* return NOTIFY_DONE; */
        if (!dev)
                return NOTIFY_DONE;
        if (event == NETDEV_REGISTER) {
                {
                        struct ethtool_drvinfo drvinfo;
-                       // char *str=NULL;
                        char cbuf[32];
                        char *buf = NULL;
                        char res[10];
@@ -198,13 +193,6 @@ static int bp_device_event(struct notifier_block *unused,
                        memcpy(&cbuf, drvinfo.bus_info, 32);
                        buf = &cbuf[0];
 
-                       // while(*buf++){
-
-                       /*if(*buf==':'){
-                          buf++;
-                          break;
-                          } */
-                       //}
                        while (*buf++ != ':') ;
                        for (i = 0; i < 10; i++, buf++) {
                                if (*buf == ':')
@@ -245,7 +233,6 @@ static int bp_device_event(struct notifier_block *unused,
        }
        if (event == NETDEV_UNREGISTER) {
                int idx_dev = 0;
-               //if_scan();
                for (idx_dev = 0;
                     ((bpctl_dev_arr[idx_dev].pdev != NULL)
                      && (idx_dev < device_num)); idx_dev++) {
@@ -263,7 +250,6 @@ static int bp_device_event(struct notifier_block *unused,
        }
        if (event == NETDEV_CHANGENAME) {
                int idx_dev = 0;
-               //if_scan();
                for (idx_dev = 0;
                     ((bpctl_dev_arr[idx_dev].pdev != NULL)
                      && (idx_dev < device_num)); idx_dev++) {
@@ -281,7 +267,6 @@ static int bp_device_event(struct notifier_block *unused,
                return NOTIFY_DONE;
 
        }
-       //return NOTIFY_DONE;
 
        switch (event) {
 
@@ -289,7 +274,6 @@ static int bp_device_event(struct notifier_block *unused,
                        if (netif_carrier_ok(dev))
                                return NOTIFY_DONE;
 
-                       //if_scan();
                        if (((dev_num = get_dev_idx(dev->ifindex)) == -1) ||
                            (!(pbpctl_dev = &bpctl_dev_arr[dev_num])))
                                return NOTIFY_DONE;
@@ -441,12 +425,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev,
                                                    BPCTLI_CTRL_EXT_MCLK_DATA));
                        else {
 
-/* To start management : MCLK 1, MDIO 1, output*/
-                               //writel((0x2|0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
+                               /* To start management : MCLK 1, MDIO 1, output*/
                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                                (ctrl_ext | BP10G_MCLK_DATA_OUT
                                                 | BP10G_MDIO_DATA_OUT));
-                               //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl | BP10G_MDIO_DATA | BP10G_MDIO_DIR));  
 
                        }
 
@@ -513,12 +495,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev,
                                                    (BPCTLI_CTRL_EXT_MCLK_DATA)));
                        else {
 
-                               //writel((0x2), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                                ((ctrl_ext |
                                                  BP10G_MDIO_DATA_OUT) &
                                                 ~(BP10G_MCLK_DATA_OUT)));
-                               //  BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl |BP10G_MDIO_DIR|BP10G_MDIO_DATA));
                        }
 
                        usec_delay(PULSE_TIME);
@@ -584,12 +564,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev,
                                                    (BPCTLI_CTRL_EXT_MDIO_DATA)));
                        else {
 
-                               //    writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                                ((ctrl_ext |
                                                  BP10G_MCLK_DATA_OUT) &
                                                 ~BP10G_MDIO_DATA_OUT));
-                               //  BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
                        }
                        usec_delay(PULSE_TIME);
@@ -652,12 +630,10 @@ static void write_pulse(bpctl_dev_t *pbpctl_dev,
                                                      BPCTLI_CTRL_EXT_MDIO_DATA)));
                        else {
 
-                               //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                                (ctrl_ext &
                                                 ~(BP10G_MCLK_DATA_OUT |
                                                   BP10G_MDIO_DATA_OUT)));
-                               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
                        }
 
                        usec_delay(PULSE_TIME);
@@ -684,7 +660,6 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext,
                ctrl = BP10G_READ_REG(pbpctl_dev_c, ESDP);
        }
 
-       //ctrl_ext=BP10G_READ_REG(pbpctl_dev,EODSDP);    
 
        while (i--) {
                if (pbpctl_dev->bp_10g9) {
@@ -735,10 +710,8 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext,
                                                                   BPCTLI_CTRL_EXT_MCLK_DATA)));
                else {
 
-                       // writel(( 0/*0x1*/), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                        BP10G_WRITE_REG(pbpctl_dev, EODSDP, ((ctrl_ext | BP10G_MDIO_DATA_OUT) & ~BP10G_MCLK_DATA_OUT)); /* ? */
-                       //    printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP););
-                       //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR));
+                       /*    printk("0x28=0x%x\n",BP10G_READ_REG(pbpctl_dev,EODSDP);); */
 
                }
 
@@ -791,11 +764,9 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext,
                                                                  (BPCTLI_CTRL_EXT_MDIO_DIR)));
                else {
 
-                       // writel((0x8 /*|0x1*/ ), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                        BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                        (ctrl_ext | BP10G_MCLK_DATA_OUT |
                                         BP10G_MDIO_DATA_OUT));
-                       //BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~BP10G_MDIO_DIR));
 
                }
                if (pbpctl_dev->bp_10g9) {
@@ -812,7 +783,6 @@ static int read_pulse(bpctl_dev_t *pbpctl_dev, unsigned int ctrl_ext,
                        ctrl_ext = BPCTL_READ_REG(pbpctl_dev, CTRL_EXT);
                else
                        ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
-               //ctrl_ext =readl((void *)((pbpctl_dev)->mem_map) + 0x28);
 
                usec_delay(PULSE_TIME);
                if (pbpctl_dev->bp_10g9) {
@@ -934,8 +904,6 @@ static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value,
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
-               //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
        }
        usec_delay(CMND_INTERVAL);
 
@@ -1001,9 +969,7 @@ static void write_reg(bpctl_dev_t *pbpctl_dev, unsigned char value,
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               // BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
-               //   writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
        }
 
        usec_delay(CMND_INTERVAL * 4);
@@ -1109,7 +1075,7 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr)
 
                ctrl_ext = BP10GB_READ_REG(pbpctl_dev, MISC_REG_SPIO);
 
-               //printk("2reg=%x\n", ctrl_ext);
+               printk("2reg=%x\n", ctrl_ext);
 
 #ifdef BP_SYNC_FLAG
                spin_unlock_irqrestore(&pbpctl_dev->bypass_wr_lock, flags);
@@ -1136,13 +1102,11 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr)
                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
        } else {
 
-               //   writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
        }
 
@@ -1209,12 +1173,10 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr)
                                                           BPCTLI_CTRL_EXT_MDIO_DATA)));
        else {
 
-               // writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ; 
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext | BP10G_MCLK_DATA_OUT |
                                 BP10G_MDIO_DATA_OUT));
 
-               // BP10G_WRITE_REG(pbpctl_dev, ESDP, (ctrl &~(BP10G_MDIO_DATA|BP10G_MDIO_DIR)));
 
        }
        usec_delay(PULSE_TIME);
@@ -1278,13 +1240,11 @@ static int read_reg(bpctl_dev_t *pbpctl_dev, unsigned char addr)
                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
        } else {
 
-               //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
        }
 
@@ -1377,13 +1337,11 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev)
                                                           BPCTLI_CTRL_EXT_MCLK_DATA)));
        } else {
 
-               // writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
                ctrl_ext = BP10G_READ_REG(pbpctl_dev, EODSDP);
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
        }
        if (pbpctl_dev->bp_10g9) {
@@ -1441,11 +1399,9 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev)
                                                          (BPCTLI_CTRL_EXT_MDIO_DATA)));
        else {
 
-               //writel((0x8), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                ((ctrl_ext | BP10G_MCLK_DATA_OUT) &
                                 ~BP10G_MDIO_DATA_OUT));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
 
        }
 
@@ -1503,11 +1459,9 @@ static int wdt_pulse(bpctl_dev_t *pbpctl_dev)
                                                           BPCTLI_CTRL_EXT_MDIO_DATA)));
        else {
 
-               //writel((0x0), (void *)(((pbpctl_dev)->mem_map) + 0x28)) ;
                BP10G_WRITE_REG(pbpctl_dev, EODSDP,
                                (ctrl_ext &
                                 ~(BP10G_MCLK_DATA_OUT | BP10G_MDIO_DATA_OUT)));
-               //BP10G_WRITE_REG(pbpctl_dev, ESDP, ((ctrl |BP10G_MDIO_DIR)&~BP10G_MDIO_DATA));
        }
        if ((pbpctl_dev->wdt_status == WDT_STATUS_EN)   /*&&
                                                           (pbpctl_dev->bp_ext_ver<PXG4BPFI_VER) */ )
@@ -1791,14 +1745,14 @@ static bpctl_dev_t *get_status_port_fn(bpctl_dev_t *pbpctl_dev)
                            && ((bpctl_dev_arr[idx_dev].func == 1)
                                && (pbpctl_dev->func == 0))) {
 
-                               return (&(bpctl_dev_arr[idx_dev]));
+                               return &(bpctl_dev_arr[idx_dev]);
                        }
                        if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) &&
                            (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) &&
                            ((bpctl_dev_arr[idx_dev].func == 3)
                             && (pbpctl_dev->func == 2))) {
 
-                               return (&(bpctl_dev_arr[idx_dev]));
+                               return &(bpctl_dev_arr[idx_dev]);
                        }
                }
        }
@@ -1821,14 +1775,14 @@ static bpctl_dev_t *get_master_port_fn(bpctl_dev_t *pbpctl_dev)
                            && ((bpctl_dev_arr[idx_dev].func == 0)
                                && (pbpctl_dev->func == 1))) {
 
-                               return (&(bpctl_dev_arr[idx_dev]));
+                               return &(bpctl_dev_arr[idx_dev]);
                        }
                        if ((bpctl_dev_arr[idx_dev].bus == pbpctl_dev->bus) &&
                            (bpctl_dev_arr[idx_dev].slot == pbpctl_dev->slot) &&
                            ((bpctl_dev_arr[idx_dev].func == 2)
                             && (pbpctl_dev->func == 3))) {
 
-                               return (&(bpctl_dev_arr[idx_dev]));
+                               return &(bpctl_dev_arr[idx_dev]);
                        }
                }
        }
@@ -2537,7 +2491,6 @@ static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state)
                else if (!pbpctl_dev->bp_10g)
                        ctrl = BPCTL_READ_REG(pbpctl_dev, CTRL);
                else
-                       //ctrl =readl((void *)((pbpctl_dev)->mem_map) + 0x20);
                        ctrl = BP10G_READ_REG(pbpctl_dev, ESDP);
 
                if (!tx_state)
@@ -2587,7 +2540,6 @@ static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state)
                                                    BPCTLI_CTRL_SWDPIN0));
 
                        else
-                               //writel((ctrl|(0x1|0x100)), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ;
                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
                                                (ctrl | BP10G_SDP0_DATA |
                                                 BP10G_SDP0_DIR));
@@ -2645,7 +2597,6 @@ static int set_tx(bpctl_dev_t *pbpctl_dev, int tx_state)
                                                             BPCTLI_CTRL_SDP0_DIR)));
                                }
                        } else
-                               //writel(((ctrl|0x100)&~0x1), (void *)(((pbpctl_dev)->mem_map) + 0x20)) ;
                                BP10G_WRITE_REG(pbpctl_dev, ESDP,
                                                ((ctrl | BP10G_SDP0_DIR) &
                                                 ~BP10G_SDP0_DATA));
@@ -3018,7 +2969,7 @@ int std_nic_off(bpctl_dev_t *pbpctl_dev)
 int wdt_time_left(bpctl_dev_t *pbpctl_dev)
 {
 
-       //unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ;
+       /* unsigned long curr_time=((long long)(jiffies*1000))/HZ, delta_time=0,wdt_on_time=((long long)(pbpctl_dev->bypass_wdt_on_time*1000))/HZ; */
        unsigned long curr_time = jiffies, delta_time = 0, wdt_on_time =
            pbpctl_dev->bypass_wdt_on_time, delta_time_msec = 0;
        int time_left = 0;
@@ -3078,8 +3029,8 @@ static int wdt_timer_reload(bpctl_dev_t *pbpctl_dev)
                        ret = wdt_pulse_int(pbpctl_dev);
                else
                        ret = send_wdt_pulse(pbpctl_dev);
-               //if (ret==-1)
-               //    mod_timer(&pbpctl_dev->bp_timer, jiffies+1);
+               /if (ret==-1)
+                   mod_timer(&pbpctl_dev->bp_timer, jiffies+1);*/
                return 1;
        }
        return BP_NOT_CAP;
@@ -3125,7 +3076,6 @@ static void wd_reset_timer(unsigned long param)
        }
 }
 
-//#ifdef PMC_FIX_FLAG
 /*WAIT_AT_PWRUP 0x80   */
 int bp_wait_at_pwup_en(bpctl_dev_t *pbpctl_dev)
 {
@@ -3189,7 +3139,6 @@ int bp_hw_reset_dis(bpctl_dev_t *pbpctl_dev)
        return BP_NOT_CAP;
 }
 
-//#endif /*PMC_FIX_FLAG*/
 
 int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode)
 {
@@ -3245,7 +3194,7 @@ int wdt_exp_mode(bpctl_dev_t *pbpctl_dev, int mode)
 int bypass_fw_ver(bpctl_dev_t *pbpctl_dev)
 {
        if (is_bypass_fn(pbpctl_dev))
-               return ((read_reg(pbpctl_dev, VER_REG_ADDR)));
+               return read_reg(pbpctl_dev, VER_REG_ADDR);
        else
                return BP_NOT_CAP;
 }
@@ -3474,12 +3423,10 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev)
                }
                if (pbpctl_dev->bp_ext_ver >= 0x8) {
 
-                       //BPCTL_BP_WRITE_REG(pbpctl_dev, CTRL_EXT, (BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT))&~BPCTLI_CTRL_EXT_SDP7_DIR);
                        if (pbpctl_dev->bp_10g9) {
                                ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, I2CCTL);
                                BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
                                                (ctrl_ext | BP10G_I2C_CLK_OUT));
-                               //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
                                return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
                                         BP10G_I2C_CLK_IN) != 0 ? 0 : 1);
 
@@ -3518,7 +3465,6 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev)
                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
                                                (ctrl_ext |
                                                 BP10G_SDP7_DATA_OUT));
-                               //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
                                return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
                                         BP10G_SDP7_DATA_IN) != 0 ? 0 : 1);
                        }
@@ -3529,7 +3475,7 @@ static int bypass_status(bpctl_dev_t *pbpctl_dev)
                                 BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
                } else {
                        if ((bypass_status_clear(pbpctl_dev)) >= 0)
-                               return (bypass_from_last_read(pbpctl_dev));
+                               return bypass_from_last_read(pbpctl_dev);
                }
 
        }
@@ -3684,7 +3630,7 @@ int get_bp_prod_caps(bpctl_dev_t *pbpctl_dev)
 {
        if ((pbpctl_dev->bp_caps & SW_CTL_CAP) &&
            (pbpctl_dev->bp_ext_ver >= PXG2TBPI_VER))
-               return (read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR));
+               return read_reg(pbpctl_dev, PRODUCT_CAP_REG_ADDR);
        return BP_NOT_CAP;
 
 }
@@ -3764,7 +3710,6 @@ int tap_status(bpctl_dev_t *pbpctl_dev)
                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
                                                (ctrl_ext |
                                                 BP10G_SDP6_DATA_OUT));
-                               // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x1)!=0?0:1);
                                return ((BP10G_READ_REG(pbpctl_dev_b, EODSDP) &
                                         BP10G_SDP6_DATA_IN) != 0 ? 0 : 1);
                        }
@@ -3774,7 +3719,7 @@ int tap_status(bpctl_dev_t *pbpctl_dev)
                                 BPCTLI_CTRL_SWDPIN0) != 0 ? 1 : 0);
                else {
                        if ((bypass_status_clear(pbpctl_dev)) >= 0)
-                               return (bypass_from_last_read(pbpctl_dev));
+                               return bypass_from_last_read(pbpctl_dev);
                }
 
        }
@@ -3853,19 +3798,16 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev)
                                  DISC_OFF_MASK) == DISC_OFF_MASK) ? 1 : 0);
 
                if (pbpctl_dev->bp_i80) {
-                       //  return((((read_reg(pbpctl_dev,STATUS_DISC_REG_ADDR)) & DISC_OFF_MASK)==DISC_OFF_MASK)?1:0);
                        return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL_EXT)) &
                                 BPCTLI_CTRL_EXT_SDP6_DATA) != 0 ? 1 : 0);
 
                }
                if (pbpctl_dev->bp_540) {
                        ctrl_ext = BP10G_READ_REG(pbpctl_dev_b, ESDP);
-                       //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
                        return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
                                 BP10G_SDP2_DATA) != 0 ? 1 : 0);
 
                }
-               //if (pbpctl_dev->device==SILICOM_PXG2TBI_SSID) {
                if (pbpctl_dev->media_type == bp_copper) {
 
 #if 0
@@ -3876,7 +3818,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev)
                                return (((BPCTL_READ_REG(pbpctl_dev_b, CTRL)) &
                                         BPCTLI_CTRL_SWDPIN1) != 0 ? 1 : 0);
                        else
-                               // return(((readl((void *)((pbpctl_dev)->mem_map) + 0x20)) & 0x2)!=0?1:0); 
                                return ((BP10G_READ_REG(pbpctl_dev_b, ESDP) &
                                         BP10G_SDP1_DATA) != 0 ? 1 : 0);
 
@@ -3887,7 +3828,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev)
                                BP10G_WRITE_REG(pbpctl_dev_b, I2CCTL,
                                                (ctrl_ext |
                                                 BP10G_I2C_DATA_OUT));
-                               //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28))&0x4)!=0?0:1);
                                return ((BP10G_READ_REG(pbpctl_dev_b, I2CCTL) &
                                         BP10G_I2C_DATA_IN) != 0 ? 1 : 0);
 
@@ -3919,8 +3859,6 @@ int disc_off_status(bpctl_dev_t *pbpctl_dev)
                                BP10G_WRITE_REG(pbpctl_dev_b, EODSDP,
                                                (ctrl_ext |
                                                 BP10G_SDP6_DATA_OUT));
-                               // temp=  (((BP10G_READ_REG(pbpctl_dev_b,EODSDP))&BP10G_SDP6_DATA_IN)!=0?1:0);
-                               //return(((readl((void *)((pbpctl_dev)->mem_map) + 0x28)) & 0x1)!=0?1:0);
                                return (((BP10G_READ_REG(pbpctl_dev_b, EODSDP))
                                         & BP10G_SDP6_DATA_IN) != 0 ? 1 : 0);
                        }
@@ -4004,10 +3942,10 @@ int default_pwron_disc_port_status(bpctl_dev_t *pbpctl_dev)
        if (pbpctl_dev_m->bp_caps_ex & DISC_PORT_CAP_EX) {
                if (is_bypass_fn(pbpctl_dev) == 1)
                        return ret;
-               //  return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0);
+               /*  return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */
                else
                        return ret;
-               //   return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0);
+               /*   return((((read_reg(pbpctl_dev,STATUS_TAP_REG_ADDR)) & TX_DISA_MASK)==TX_DISA_MASK)?1:0); */
 
        }
        return ret;
@@ -4060,7 +3998,6 @@ int tpl_hw_status(bpctl_dev_t *pbpctl_dev)
        return BP_NOT_CAP;
 }
 
-//#ifdef PMC_FIX_FLAG
 
 int bp_wait_at_pwup_status(bpctl_dev_t *pbpctl_dev)
 {
@@ -4086,7 +4023,6 @@ int bp_hw_reset_status(bpctl_dev_t *pbpctl_dev)
        return BP_NOT_CAP;
 }
 
-//#endif /*PMC_FIX_FLAG*/
 
 int std_nic_status(bpctl_dev_t *pbpctl_dev)
 {
@@ -4182,17 +4118,13 @@ void bypass_caps_init(bpctl_dev_t *pbpctl_dev)
                else
                        pbpctl_dev->media_type = bp_fiber;
 
-       }
-       //if (!pbpctl_dev->bp_10g)
-       //  pbpctl_dev->media_type=((BPCTL_READ_REG(pbpctl_dev, STATUS))&BPCTLI_STATUS_TBIMODE)?bp_fiber:bp_copper;
-       else {
+       } else {
                if (BP10G_CX4_SERIES(pbpctl_dev->subdevice))
                        pbpctl_dev->media_type = bp_cx4;
                else
                        pbpctl_dev->media_type = bp_fiber;
        }
 
-       //pbpctl_dev->bp_fw_ver=0xa8;
        if (is_bypass_fn(pbpctl_dev)) {
 
                pbpctl_dev->bp_caps |= BP_PWOFF_ON_CAP;
@@ -4366,7 +4298,7 @@ int bypass_off_init(bpctl_dev_t *pbpctl_dev)
        if ((ret = cmnd_on(pbpctl_dev)) < 0)
                return ret;
        if (INTEL_IF_SERIES(pbpctl_dev->subdevice))
-               return (dis_bypass_cap(pbpctl_dev));
+               return dis_bypass_cap(pbpctl_dev);
        wdt_off(pbpctl_dev);
        if (pbpctl_dev->bp_caps & BP_CAP)
                bypass_off(pbpctl_dev);
@@ -4460,7 +4392,7 @@ int bp_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                dev_kfree_skb_irq(skb);
                return 0;
        }
-       return (pbpctl_dev->hard_start_xmit_save(skb, dev));
+       return pbpctl_dev->hard_start_xmit_save(skb, dev);
 }
 #endif
 
@@ -4591,7 +4523,7 @@ int set_bypass_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
 
 int get_bypass_fn(bpctl_dev_t *pbpctl_dev)
 {
-       return (bypass_status(pbpctl_dev));
+       return bypass_status(pbpctl_dev);
 }
 
 int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev)
@@ -4599,7 +4531,7 @@ int get_bypass_change_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (bypass_change_status(pbpctl_dev));
+       return bypass_change_status(pbpctl_dev);
 }
 
 int set_dis_bypass_fn(bpctl_dev_t *pbpctl_dev, int dis_param)
@@ -4625,7 +4557,7 @@ int get_dis_bypass_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (dis_bypass_cap_status(pbpctl_dev));
+       return dis_bypass_cap_status(pbpctl_dev);
 }
 
 int set_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
@@ -4651,7 +4583,7 @@ int get_bypass_pwoff_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (default_pwroff_status(pbpctl_dev));
+       return default_pwroff_status(pbpctl_dev);
 }
 
 int set_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev, int bypass_mode)
@@ -4677,7 +4609,7 @@ int get_bypass_pwup_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (default_pwron_status(pbpctl_dev));
+       return default_pwron_status(pbpctl_dev);
 }
 
 int set_bypass_wd_fn(bpctl_dev_t *pbpctl_dev, int timeout)
@@ -4714,7 +4646,7 @@ int get_wd_expire_time_fn(bpctl_dev_t *pbpctl_dev, int *time_left)
        if (!pbpctl_dev)
                return -1;
 
-       return (wdt_timer(pbpctl_dev, time_left));
+       return wdt_timer(pbpctl_dev, time_left);
 }
 
 int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev)
@@ -4722,7 +4654,7 @@ int reset_bypass_wd_timer_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (wdt_timer_reload(pbpctl_dev));
+       return wdt_timer_reload(pbpctl_dev);
 }
 
 int get_wd_set_caps_fn(bpctl_dev_t *pbpctl_dev)
@@ -4773,7 +4705,7 @@ int get_std_nic_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (std_nic_status(pbpctl_dev));
+       return std_nic_status(pbpctl_dev);
 }
 
 int set_tap_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
@@ -4797,7 +4729,7 @@ int get_tap_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (tap_status(pbpctl_dev));
+       return tap_status(pbpctl_dev);
 }
 
 int set_tap_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
@@ -4834,7 +4766,7 @@ int get_tap_change_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (tap_change_status(pbpctl_dev));
+       return tap_change_status(pbpctl_dev);
 }
 
 int set_dis_tap_fn(bpctl_dev_t *pbpctl_dev, int dis_param)
@@ -4859,7 +4791,7 @@ int get_dis_tap_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (dis_tap_cap_status(pbpctl_dev));
+       return dis_tap_cap_status(pbpctl_dev);
 }
 
 int set_disc_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
@@ -4976,7 +4908,7 @@ int get_disc_port_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (disc_port_status(pbpctl_dev));
+       return disc_port_status(pbpctl_dev);
 }
 
 int set_disc_port_pwup_fn(bpctl_dev_t *pbpctl_dev, int disc_mode)
@@ -5009,7 +4941,7 @@ int get_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (wdt_exp_mode_status(pbpctl_dev));
+       return wdt_exp_mode_status(pbpctl_dev);
 }
 
 int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param)
@@ -5017,7 +4949,7 @@ int set_wd_exp_mode_fn(bpctl_dev_t *pbpctl_dev, int param)
        if (!pbpctl_dev)
                return -1;
 
-       return (wdt_exp_mode(pbpctl_dev, param));
+       return wdt_exp_mode(pbpctl_dev, param);
 }
 
 int reset_cont_fn(bpctl_dev_t *pbpctl_dev)
@@ -5028,7 +4960,7 @@ int reset_cont_fn(bpctl_dev_t *pbpctl_dev)
 
        if ((ret = cmnd_on(pbpctl_dev)) < 0)
                return ret;
-       return (reset_cont(pbpctl_dev));
+       return reset_cont(pbpctl_dev);
 }
 
 int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state)
@@ -5047,7 +4979,7 @@ int set_tx_fn(bpctl_dev_t *pbpctl_dev, int tx_state)
                    (pbpctl_dev_b->bp_tpl_flag))
                        return BP_NOT_CAP;
        }
-       return (set_tx(pbpctl_dev, tx_state));
+       return set_tx(pbpctl_dev, tx_state);
 }
 
 int set_bp_force_link_fn(int dev_num, int tx_state)
@@ -5059,7 +4991,7 @@ int set_bp_force_link_fn(int dev_num, int tx_state)
                return -1;
        bpctl_dev_curr = &bpctl_dev_arr[dev_num];
 
-       return (set_bp_force_link(bpctl_dev_curr, tx_state));
+       return set_bp_force_link(bpctl_dev_curr, tx_state);
 }
 
 int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param)
@@ -5067,7 +4999,7 @@ int set_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev, int param)
        if (!pbpctl_dev)
                return -1;
 
-       return (set_bypass_wd_auto(pbpctl_dev, param));
+       return set_bypass_wd_auto(pbpctl_dev, param);
 }
 
 int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev)
@@ -5075,7 +5007,7 @@ int get_wd_autoreset_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (get_bypass_wd_auto(pbpctl_dev));
+       return get_bypass_wd_auto(pbpctl_dev);
 }
 
 #ifdef BP_SELF_TEST
@@ -5084,7 +5016,7 @@ int set_bp_self_test_fn(bpctl_dev_t *pbpctl_dev, int param)
        if (!pbpctl_dev)
                return -1;
 
-       return (set_bp_self_test(pbpctl_dev, param));
+       return set_bp_self_test(pbpctl_dev, param);
 }
 
 int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev)
@@ -5092,7 +5024,7 @@ int get_bp_self_test_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (get_bp_self_test(pbpctl_dev));
+       return get_bp_self_test(pbpctl_dev);
 }
 
 #endif
@@ -5102,7 +5034,7 @@ int get_bypass_caps_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       return (pbpctl_dev->bp_caps);
+       return pbpctl_dev->bp_caps;
 
 }
 
@@ -5164,7 +5096,7 @@ int get_tx_fn(bpctl_dev_t *pbpctl_dev)
                    (pbpctl_dev_b->bp_tpl_flag))
                        return BP_NOT_CAP;
        }
-       return (tx_status(pbpctl_dev));
+       return tx_status(pbpctl_dev);
 }
 
 int get_bp_force_link_fn(int dev_num)
@@ -5176,7 +5108,7 @@ int get_bp_force_link_fn(int dev_num)
                return -1;
        bpctl_dev_curr = &bpctl_dev_arr[dev_num];
 
-       return (bp_force_link_status(bpctl_dev_curr));
+       return bp_force_link_status(bpctl_dev_curr);
 }
 
 static int get_bypass_link_status(bpctl_dev_t *pbpctl_dev)
@@ -5329,20 +5261,19 @@ int get_tpl_fn(bpctl_dev_t *pbpctl_dev)
 
        if (pbpctl_dev->bp_caps & TPL_CAP) {
                if (pbpctl_dev->bp_caps_ex & TPL2_CAP_EX)
-                       return (tpl2_flag_status(pbpctl_dev));
+                       return tpl2_flag_status(pbpctl_dev);
                ret = pbpctl_dev->bp_tpl_flag;
        }
        return ret;
 }
 
-//#ifdef PMC_FIX_FLAG
 int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
 {
        if (!pbpctl_dev)
                return -1;
 
        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
-               //bp_lock(pbp_device_block);
+               /* bp_lock(pbp_device_block); */
                cmnd_on(pbpctl_dev);
                if (!tap_mode)
                        bp_wait_at_pwup_dis(pbpctl_dev);
@@ -5350,7 +5281,7 @@ int set_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
                        bp_wait_at_pwup_en(pbpctl_dev);
                cmnd_off(pbpctl_dev);
 
-               // bp_unlock(pbp_device_block);
+               /* bp_unlock(pbp_device_block); */
                return BP_OK;
        }
        return BP_NOT_CAP;
@@ -5362,9 +5293,9 @@ int get_bp_wait_at_pwup_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       // bp_lock(pbp_device_block);
+       /* bp_lock(pbp_device_block); */
        ret = bp_wait_at_pwup_status(pbpctl_dev);
-       // bp_unlock(pbp_device_block);
+       /* bp_unlock(pbp_device_block); */
 
        return ret;
 }
@@ -5375,7 +5306,7 @@ int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
                return -1;
 
        if (pbpctl_dev->bp_caps & SW_CTL_CAP) {
-               //   bp_lock(pbp_device_block);
+               /*   bp_lock(pbp_device_block); */
                cmnd_on(pbpctl_dev);
 
                if (!tap_mode)
@@ -5383,7 +5314,7 @@ int set_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev, int tap_mode)
                else
                        bp_hw_reset_en(pbpctl_dev);
                cmnd_off(pbpctl_dev);
-               //    bp_unlock(pbp_device_block);
+               /*    bp_unlock(pbp_device_block); */
                return BP_OK;
        }
        return BP_NOT_CAP;
@@ -5395,15 +5326,14 @@ int get_bp_hw_reset_fn(bpctl_dev_t *pbpctl_dev)
        if (!pbpctl_dev)
                return -1;
 
-       //bp_lock(pbp_device_block);
+       /* bp_lock(pbp_device_block); */
        ret = bp_hw_reset_status(pbpctl_dev);
 
-       //bp_unlock(pbp_device_block);
+       /* bp_unlock(pbp_device_block); */
 
        return ret;
 }
 
-//#endif  /*PMC_FIX_FLAG*/
 
 int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name,
                       char *add_param)
@@ -5420,7 +5350,6 @@ int get_bypass_info_fn(bpctl_dev_t *pbpctl_dev, char *dev_name,
 int get_dev_idx_bsf(int bus, int slot, int func)
 {
        int idx_dev = 0;
-       //if_scan();
        for (idx_dev = 0;
             ((bpctl_dev_arr[idx_dev].pdev != NULL) && (idx_dev < device_num));
             idx_dev++) {
@@ -5496,9 +5425,9 @@ static void if_scan_init(void)
        int idx_dev = 0;
        struct net_device *dev;
        int ifindex;
-       //rcu_read_lock();
-       //rtnl_lock();
-       //rcu_read_lock();
+       /* rcu_read_lock(); */
+       /* rtnl_lock();     */
+       /* rcu_read_lock(); */
 #if 1
 #if (LINUX_VERSION_CODE >= 0x020618)
        for_each_netdev(&init_net, dev)
@@ -5510,7 +5439,6 @@ static void if_scan_init(void)
        {
 
                struct ethtool_drvinfo drvinfo;
-               // char *str=NULL;
                char cbuf[32];
                char *buf = NULL;
                char res[10];
@@ -5533,13 +5461,6 @@ static void if_scan_init(void)
                memcpy(&cbuf, drvinfo.bus_info, 32);
                buf = &cbuf[0];
 
-               // while(*buf++){
-
-               /*if(*buf==':'){
-                  buf++;
-                  break;
-                  } */
-               //}
                while (*buf++ != ':') ;
                for (i = 0; i < 10; i++, buf++) {
                        if (*buf == ':')
@@ -5571,8 +5492,8 @@ static void if_scan_init(void)
 
        }
 #endif
-       //rtnl_unlock();
-       //rcu_read_unlock();
+       /* rtnl_unlock();     */
+       /* rcu_read_unlock(); */
 
 }
 
@@ -5597,17 +5518,17 @@ static long device_ioctl(struct file *file,     /* ditto */
        static bpctl_dev_t *pbpctl_dev;
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
-       //lock_kernel();
+       /* lock_kernel(); */
 #endif
        lock_bpctl();
-       //local_irq_save(flags);
-       /*if(!spin_trylock_irqsave(&bpvm_lock)){
+       /* local_irq_save(flags); */
+       /* if(!spin_trylock_irqsave(&bpvm_lock)){
           local_irq_restore(flags);
-          //unlock_bpctl();
-          //unlock_kernel();
+          unlock_bpctl();
+          unlock_kernel();
           return -1;
           } */
-       //spin_lock_irqsave(&bpvm_lock, flags);
+       /* spin_lock_irqsave(&bpvm_lock, flags); */
 
 /*
 * Switch according to the ioctl called
@@ -5634,18 +5555,19 @@ static long device_ioctl(struct file *file,     /* ditto */
                goto bp_exit;
 
        }
-       //lock_bpctl(); 
-       //preempt_disable();
+       /* lock_bpctl();      */
+       /* preempt_disable(); */
        local_irq_save(flags);
        if (!spin_trylock(&bpvm_lock)) {
                local_irq_restore(flags);
                unlock_bpctl();
-               //unlock_kernel();
                return -1;
        }
-//    preempt_disable();
-       //rcu_read_lock();
-//    spin_lock_irqsave(&bpvm_lock, flags);
+
+/*     preempt_disable();
+       rcu_read_lock();
+       spin_lock_irqsave(&bpvm_lock, flags);
+*/
        if ((bpctl_cmd.in_param[5]) ||
            (bpctl_cmd.in_param[6]) || (bpctl_cmd.in_param[7]))
                dev_idx = get_dev_idx_bsf(bpctl_cmd.in_param[5],
@@ -5657,11 +5579,11 @@ static long device_ioctl(struct file *file,     /* ditto */
                dev_idx = get_dev_idx(bpctl_cmd.in_param[1]);
 
        if (dev_idx < 0 || dev_idx > device_num) {
-               //unlock_bpctl();
-               //preempt_enable();
+               /unlock_bpctl();
+                  preempt_enable(); */
                ret = -EOPNOTSUPP;
-               //preempt_enable();
-               //rcu_read_unlock();
+               /preempt_enable();
+                  rcu_read_unlock();  */
                spin_unlock_irqrestore(&bpvm_lock, flags);
                goto bp_exit;
        }
@@ -5677,8 +5599,8 @@ static long device_ioctl(struct file *file,       /* ditto */
                       bpctl_dev_arr[dev_idx].name);
                bpctl_cmd.status = -1;
                ret = SUCCESS;
-               /*preempt_enable(); */
-               //rcu_read_unlock();
+               /* preempt_enable(); */
+               /* rcu_read_unlock(); */
                spin_unlock_irqrestore(&bpvm_lock, flags);
                goto bp_exit;
 
@@ -5691,8 +5613,8 @@ static long device_ioctl(struct file *file,       /* ditto */
                                     bpctl_dev_arr[dev_idx].name);
                                bpctl_cmd.status = -1;
                                ret = SUCCESS;
-                               /*preempt_enable(); */
-                               //rcu_read_unlock();
+                               /* preempt_enable(); */
+                               /* rcu_read_unlock(); */
                                spin_unlock_irqrestore(&bpvm_lock, flags);
                                goto bp_exit;
                        }
@@ -5825,12 +5747,12 @@ static long device_ioctl(struct file *file,     /* ditto */
        case IOCTL_TX_MSG(GET_BYPASS_CAPS):
                bpctl_cmd.status = get_bypass_caps_fn(pbpctl_dev);
                /*preempt_enable(); */
-               //rcu_read_unlock();
+               /*rcu_read_unlock();*/
                spin_unlock_irqrestore(&bpvm_lock, flags);
                if (copy_to_user
                    (argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd))) {
-                       //unlock_bpctl();
-                       //preempt_enable(); 
+                       /*unlock_bpctl();   */
+                       /*preempt_enable(); */
                        ret = -EFAULT;
                        goto bp_exit;
                }
@@ -5905,7 +5827,6 @@ static long device_ioctl(struct file *file,       /* ditto */
        case IOCTL_TX_MSG(GET_TPL):
                bpctl_cmd.status = get_tpl_fn(pbpctl_dev);
                break;
-//#ifdef PMC_FIX_FLAG
        case IOCTL_TX_MSG(SET_BP_WAIT_AT_PWUP):
                bpctl_cmd.status =
                    set_bp_wait_at_pwup_fn(pbpctl_dev, bpctl_cmd.in_param[2]);
@@ -5922,7 +5843,6 @@ static long device_ioctl(struct file *file,       /* ditto */
        case IOCTL_TX_MSG(GET_BP_HW_RESET):
                bpctl_cmd.status = get_bp_hw_reset_fn(pbpctl_dev);
                break;
-//#endif
 #ifdef BP_SELF_TEST
        case IOCTL_TX_MSG(SET_BP_SELF_TEST):
                bpctl_cmd.status =
@@ -5963,29 +5883,29 @@ static long device_ioctl(struct file *file,     /* ditto */
                break;
 
        default:
-               //    unlock_bpctl();
+               /*    unlock_bpctl(); */
 
                ret = -EOPNOTSUPP;
-               /*preempt_enable(); */
-               //rcu_read_unlock();
+               /* preempt_enable(); */
+               /* rcu_read_unlock();*/
                spin_unlock_irqrestore(&bpvm_lock, flags);
                goto bp_exit;
        }
-       //unlock_bpctl();
-       /*preempt_enable(); */
+       /* unlock_bpctl();   */
+       /* preempt_enable(); */
  bpcmd_exit:
-       //rcu_read_unlock();
+       /* rcu_read_unlock(); */
        spin_unlock_irqrestore(&bpvm_lock, flags);
        if (copy_to_user(argp, (void *)&bpctl_cmd, sizeof(struct bpctl_cmd)))
                ret = -EFAULT;
        ret = SUCCESS;
  bp_exit:
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
-       //unlock_kernel();
+       /* unlock_kernel(); */
 #endif
-       //spin_unlock_irqrestore(&bpvm_lock, flags);
+       /* spin_unlock_irqrestore(&bpvm_lock, flags); */
        unlock_bpctl();
-       //unlock_kernel();
+       /* unlock_kernel(); */
        return ret;
 }
 
@@ -6483,7 +6403,7 @@ static bpmod_info_t tx_ctl_pci_tbl[] = {
        {BROADCOM_VID, BROADCOM_PE10G2_PID, SILICOM_SVID,
         SILICOM_PE10G2BPTT_SSID, PE10G2BPTT, "PE10G2BPTT"},
 
-       //{BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"},
+       /* {BROADCOM_VID, BROADCOM_PE10G2_PID, PCI_ANY_ID, PCI_ANY_ID, PE10G2BPTCX4, "PE10G2BPTCX4"}, */
 
        {0x8086, 0x10c9, SILICOM_SVID /*PCI_ANY_ID */ ,
         SILICOM_PEG4BPI6_SSID /*PCI_ANY_ID */ , PEG4BPI6, "PEG4BPI6"},
@@ -6608,10 +6528,8 @@ static bpmod_info_t tx_ctl_pci_tbl[] = {
 
        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
         SILICOM_PE210G2DBi9SR_SSID, PE210G2DBi9SR, "PE210G2DBi9SR"},
-       //{0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9SRRB_SSID , PE210G2DBi9SRRB, "PE210G2DBi9SRRB"}, 
        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
         SILICOM_PE210G2DBi9LR_SSID, PE210G2DBi9LR, "PE210G2DBi9LR"},
-       //  {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID*/, SILICOM_PE210G2DBi9LRRB_SSID , PE210G2DBi9LRRB, "PE210G2DBi9LRRB"}, 
        {0x8086, 0x10F9, SILICOM_SVID /*PCI_ANY_ID */ ,
         SILICOM_PE310G4DBi940SR_SSID, PE310G4DBi940SR, "PE310G4DBi9SR"},
 
@@ -6673,9 +6591,6 @@ static bpmod_info_t tx_ctl_pci_tbl[] = {
        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ ,
         SILICOM_PE2G6BPi35_SSID /*PCI_ANY_ID */ , PE2G6BPi35, "PE2G6BPi35"},
 
-       // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa0,PE2G6BPi35CX,"PE2G6BPi35CX"},
-       // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa1,PE2G6BPi35CX,"PE2G6BPi35CX"},
-       // {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID*/,0xaa2,PE2G6BPi35CX,"PE2G6BPi35CX"},
 
        {0x8086, PCI_ANY_ID, SILICOM_SVID /*PCI_ANY_ID */ , 0xaa0, PE2G6BPi35CX,
         "PE2G6BPi35CX"},
@@ -6893,7 +6808,7 @@ static int __init bypass_init_module(void)
                            tx_ctl_pci_tbl[idx].subdevice;
                        bpctl_dev_arr[idx_dev].subvendor =
                            tx_ctl_pci_tbl[idx].subvendor;
-                       //bpctl_dev_arr[idx_dev].pdev=pdev1;
+                       /* bpctl_dev_arr[idx_dev].pdev=pdev1; */
                        bpctl_dev_arr[idx_dev].func = PCI_FUNC(pdev1->devfn);
                        bpctl_dev_arr[idx_dev].slot = PCI_SLOT(pdev1->devfn);
                        bpctl_dev_arr[idx_dev].bus = pdev1->bus->number;
@@ -7004,7 +6919,7 @@ static int __init bypass_init_module(void)
 
                                                }
                                        }
-                                       //bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8;
+                                       /* bpctl_dev_arr[idx_dev].bp_fw_ver=0xa8; */
                                        printk("firmware version: 0x%x\n",
                                               bpctl_dev_arr[idx_dev].
                                               bp_fw_ver);
@@ -7175,23 +7090,22 @@ static int __init bypass_init_module(void)
 #ifdef BP_PROC_SUPPORT
        {
                int i = 0;
-               //unsigned long flags;
-               //rcu_read_lock();
+               /* unsigned long flags; */
+               /* rcu_read_lock(); */
                bp_proc_create();
                for (i = 0; i < device_num; i++) {
                        if (bpctl_dev_arr[i].ifindex) {
-                               //spin_lock_irqsave(&bpvm_lock, flags); 
+                               /* spin_lock_irqsave(&bpvm_lock, flags); */
                                bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
                                bypass_proc_create_dev_sd(&bpctl_dev_arr[i]);
-                               //spin_unlock_irqrestore(&bpvm_lock, flags); 
+                               /* spin_unlock_irqrestore(&bpvm_lock, flags); */
                        }
 
                }
-               //rcu_read_unlock();
+               /* rcu_read_unlock(); */
        }
 #endif
 
-       //register_netdevice_notifier(&bp_notifier_block);
        return 0;
 }
 
@@ -7254,13 +7168,13 @@ static void __exit bypass_cleanup_module(void)
 #endif
 
        for (i = 0; i < device_num; i++) {
-               //unsigned long flags;
+               /* unsigned long flags; */
 #ifdef BP_PROC_SUPPORT
-//spin_lock_irqsave(&bpvm_lock, flags);
-//rcu_read_lock();
+/*     spin_lock_irqsave(&bpvm_lock, flags);
+       rcu_read_lock(); */
                bypass_proc_remove_dev_sd(&bpctl_dev_arr[i]);
-//spin_unlock_irqrestore(&bpvm_lock, flags);        
-//rcu_read_unlock();
+/*     spin_unlock_irqrestore(&bpvm_lock, flags);        
+       rcu_read_unlock(); */
 #endif
                remove_bypass_wd_auto(&bpctl_dev_arr[i]);
                bpctl_dev_arr[i].reset_time = 0;
@@ -7302,59 +7216,59 @@ module_exit(bypass_cleanup_module);
 
 int is_bypass_sd(int ifindex)
 {
-       return (is_bypass(get_dev_idx_p(ifindex)));
+       return is_bypass(get_dev_idx_p(ifindex));
 }
 
 int set_bypass_sd(int ifindex, int bypass_mode)
 {
 
-       return (set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode));
+       return set_bypass_fn(get_dev_idx_p(ifindex), bypass_mode);
 }
 
 int get_bypass_sd(int ifindex)
 {
 
-       return (get_bypass_fn(get_dev_idx_p(ifindex)));
+       return get_bypass_fn(get_dev_idx_p(ifindex));
 }
 
 int get_bypass_change_sd(int ifindex)
 {
 
-       return (get_bypass_change_fn(get_dev_idx_p(ifindex)));
+       return get_bypass_change_fn(get_dev_idx_p(ifindex));
 }
 
 int set_dis_bypass_sd(int ifindex, int dis_param)
 {
-       return (set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param));
+       return set_dis_bypass_fn(get_dev_idx_p(ifindex), dis_param);
 }
 
 int get_dis_bypass_sd(int ifindex)
 {
 
-       return (get_dis_bypass_fn(get_dev_idx_p(ifindex)));
+       return get_dis_bypass_fn(get_dev_idx_p(ifindex));
 }
 
 int set_bypass_pwoff_sd(int ifindex, int bypass_mode)
 {
-       return (set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode));
+       return set_bypass_pwoff_fn(get_dev_idx_p(ifindex), bypass_mode);
 
 }
 
 int get_bypass_pwoff_sd(int ifindex)
 {
-       return (get_bypass_pwoff_fn(get_dev_idx_p(ifindex)));
+       return get_bypass_pwoff_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_bypass_pwup_sd(int ifindex, int bypass_mode)
 {
-       return (set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode));
+       return set_bypass_pwup_fn(get_dev_idx_p(ifindex), bypass_mode);
 
 }
 
 int get_bypass_pwup_sd(int ifindex)
 {
-       return (get_bypass_pwup_fn(get_dev_idx_p(ifindex)));
+       return get_bypass_pwup_fn(get_dev_idx_p(ifindex));
 
 }
 
@@ -7368,173 +7282,173 @@ int set_bypass_wd_sd(int if_index, int ms_timeout, int *ms_timeout_set)
 
 int get_bypass_wd_sd(int ifindex, int *timeout)
 {
-       return (get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout));
+       return get_bypass_wd_fn(get_dev_idx_p(ifindex), timeout);
 
 }
 
 int get_wd_expire_time_sd(int ifindex, int *time_left)
 {
-       return (get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left));
+       return get_wd_expire_time_fn(get_dev_idx_p(ifindex), time_left);
 }
 
 int reset_bypass_wd_timer_sd(int ifindex)
 {
-       return (reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex)));
+       return reset_bypass_wd_timer_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_wd_set_caps_sd(int ifindex)
 {
-       return (get_wd_set_caps_fn(get_dev_idx_p(ifindex)));
+       return get_wd_set_caps_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_std_nic_sd(int ifindex, int nic_mode)
 {
-       return (set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode));
+       return set_std_nic_fn(get_dev_idx_p(ifindex), nic_mode);
 
 }
 
 int get_std_nic_sd(int ifindex)
 {
-       return (get_std_nic_fn(get_dev_idx_p(ifindex)));
+       return get_std_nic_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_tap_sd(int ifindex, int tap_mode)
 {
-       return (set_tap_fn(get_dev_idx_p(ifindex), tap_mode));
+       return set_tap_fn(get_dev_idx_p(ifindex), tap_mode);
 
 }
 
 int get_tap_sd(int ifindex)
 {
-       return (get_tap_fn(get_dev_idx_p(ifindex)));
+       return get_tap_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_tap_pwup_sd(int ifindex, int tap_mode)
 {
-       return (set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode));
+       return set_tap_pwup_fn(get_dev_idx_p(ifindex), tap_mode);
 
 }
 
 int get_tap_pwup_sd(int ifindex)
 {
-       return (get_tap_pwup_fn(get_dev_idx_p(ifindex)));
+       return get_tap_pwup_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_tap_change_sd(int ifindex)
 {
-       return (get_tap_change_fn(get_dev_idx_p(ifindex)));
+       return get_tap_change_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_dis_tap_sd(int ifindex, int dis_param)
 {
-       return (set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param));
+       return set_dis_tap_fn(get_dev_idx_p(ifindex), dis_param);
 
 }
 
 int get_dis_tap_sd(int ifindex)
 {
-       return (get_dis_tap_fn(get_dev_idx_p(ifindex)));
+       return get_dis_tap_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_bp_disc_sd(int ifindex, int disc_mode)
 {
-       return (set_disc_fn(get_dev_idx_p(ifindex), disc_mode));
+       return set_disc_fn(get_dev_idx_p(ifindex), disc_mode);
 
 }
 
 int get_bp_disc_sd(int ifindex)
 {
-       return (get_disc_fn(get_dev_idx_p(ifindex)));
+       return get_disc_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_bp_disc_pwup_sd(int ifindex, int disc_mode)
 {
-       return (set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode));
+       return set_disc_pwup_fn(get_dev_idx_p(ifindex), disc_mode);
 
 }
 
 int get_bp_disc_pwup_sd(int ifindex)
 {
-       return (get_disc_pwup_fn(get_dev_idx_p(ifindex)));
+       return get_disc_pwup_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_bp_disc_change_sd(int ifindex)
 {
-       return (get_disc_change_fn(get_dev_idx_p(ifindex)));
+       return get_disc_change_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_bp_dis_disc_sd(int ifindex, int dis_param)
 {
-       return (set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param));
+       return set_dis_disc_fn(get_dev_idx_p(ifindex), dis_param);
 
 }
 
 int get_bp_dis_disc_sd(int ifindex)
 {
-       return (get_dis_disc_fn(get_dev_idx_p(ifindex)));
+       return get_dis_disc_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_wd_exp_mode_sd(int ifindex)
 {
-       return (get_wd_exp_mode_fn(get_dev_idx_p(ifindex)));
+       return get_wd_exp_mode_fn(get_dev_idx_p(ifindex));
 }
 
 int set_wd_exp_mode_sd(int ifindex, int param)
 {
-       return (set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param));
+       return set_wd_exp_mode_fn(get_dev_idx_p(ifindex), param);
 
 }
 
 int reset_cont_sd(int ifindex)
 {
-       return (reset_cont_fn(get_dev_idx_p(ifindex)));
+       return reset_cont_fn(get_dev_idx_p(ifindex));
 
 }
 
 int set_tx_sd(int ifindex, int tx_state)
 {
-       return (set_tx_fn(get_dev_idx_p(ifindex), tx_state));
+       return set_tx_fn(get_dev_idx_p(ifindex), tx_state);
 
 }
 
 int set_tpl_sd(int ifindex, int tpl_state)
 {
-       return (set_tpl_fn(get_dev_idx_p(ifindex), tpl_state));
+       return set_tpl_fn(get_dev_idx_p(ifindex), tpl_state);
 
 }
 
 int set_bp_hw_reset_sd(int ifindex, int status)
 {
-       return (set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status));
+       return set_bp_hw_reset_fn(get_dev_idx_p(ifindex), status);
 
 }
 
 int set_wd_autoreset_sd(int ifindex, int param)
 {
-       return (set_wd_autoreset_fn(get_dev_idx_p(ifindex), param));
+       return set_wd_autoreset_fn(get_dev_idx_p(ifindex), param);
 
 }
 
 int get_wd_autoreset_sd(int ifindex)
 {
-       return (get_wd_autoreset_fn(get_dev_idx_p(ifindex)));
+       return get_wd_autoreset_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_bypass_caps_sd(int ifindex)
 {
-       return (get_bypass_caps_fn(get_dev_idx_p(ifindex)));
+       return get_bypass_caps_fn(get_dev_idx_p(ifindex));
 }
 
 int get_bypass_slave_sd(int ifindex)
@@ -7542,33 +7456,32 @@ int get_bypass_slave_sd(int ifindex)
        bpctl_dev_t *pbpctl_dev_out;
        int ret = get_bypass_slave_fn(get_dev_idx_p(ifindex), &pbpctl_dev_out);
        if (ret == 1)
-               return (pbpctl_dev_out->ifindex);
+               return pbpctl_dev_out->ifindex;
        return -1;
 
 }
 
 int get_tx_sd(int ifindex)
 {
-       return (get_tx_fn(get_dev_idx_p(ifindex)));
+       return get_tx_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_tpl_sd(int ifindex)
 {
-       return (get_tpl_fn(get_dev_idx_p(ifindex)));
+       return get_tpl_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_bp_hw_reset_sd(int ifindex)
 {
-       return (get_bp_hw_reset_fn(get_dev_idx_p(ifindex)));
+       return get_bp_hw_reset_fn(get_dev_idx_p(ifindex));
 
 }
 
 int get_bypass_info_sd(int ifindex, struct bp_info *bp_info)
 {
-       return (get_bypass_info_fn
-               (get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver));
+       return get_bypass_info_fn(get_dev_idx_p(ifindex), bp_info->prod_name, &bp_info->fw_ver);
 }
 
 int bp_if_scan_sd(void)
@@ -7691,11 +7604,11 @@ static struct proc_dir_entry *proc_getdir(char *name,
 #endif
                if (pde == (struct proc_dir_entry *)0) {
 
-                       return (pde);
+                       return pde;
                }
        }
 
-       return (pde);
+       return pde;
 }
 
 int bp_proc_create(void)
index b303c9192e17109e56e1c04847a14248583ae48e..1cfa0b07d725bca700d94de35dc38ccdefa8cc82 100644 (file)
@@ -7057,7 +7057,7 @@ static int ixj_selfprobe(IXJ *j)
                printk(KERN_INFO "Enable Line Monitor\n");
 
        if (ixjdebug & 0x0002)
-               printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
+               printk(KERN_INFO "Set Line Monitor to Asynchronous Mode\n");
 
        if (ixj_WriteDSPCommand(0x7E01, j))             /* Asynchronous Line Monitor */
                return -1;
@@ -7068,7 +7068,7 @@ static int ixj_selfprobe(IXJ *j)
        if (ixj_WriteDSPCommand(0x5151, j))             /* Enable DTMF detection */
                return -1;
 
-       if (ixj_WriteDSPCommand(0x6E01, j))             /* Set Asyncronous Tone Generation */
+       if (ixj_WriteDSPCommand(0x6E01, j))             /* Set Asynchronous Tone Generation */
                return -1;
 
        set_rec_depth(j, 2);    /* Set Record Channel Limit to 2 frames */
index 1ed1474d0b564b78bbc500ef5ce963c1379ab0c4..e5adad08f1c4ffe3a9b5f90cf5fb1f9b7b590f34 100644 (file)
@@ -62,9 +62,9 @@ int dsp_wdt_init(void)
 
        dsp_wdt.fclk = clk_get(NULL, "wdt3_fck");
 
-       if (dsp_wdt.fclk) {
+       if (!IS_ERR(dsp_wdt.fclk)) {
                dsp_wdt.iclk = clk_get(NULL, "wdt3_ick");
-               if (!dsp_wdt.iclk) {
+               if (IS_ERR(dsp_wdt.iclk)) {
                        clk_put(dsp_wdt.fclk);
                        dsp_wdt.fclk = NULL;
                        ret = -EFAULT;
index 92ced35e6b7f001907a1dc1eb14aefdd3ea1cae8..c8d79a7f0e0e3aa91e2af71b8855322add6b168c 100644 (file)
@@ -187,10 +187,14 @@ static void stub_shutdown_connection(struct usbip_device *ud)
        }
 
        /* 1. stop threads */
-       if (ud->tcp_rx)
+       if (ud->tcp_rx) {
                kthread_stop_put(ud->tcp_rx);
-       if (ud->tcp_tx)
+               ud->tcp_rx = NULL;
+       }
+       if (ud->tcp_tx) {
                kthread_stop_put(ud->tcp_tx);
+               ud->tcp_tx = NULL;
+       }
 
        /*
         * 2. close the socket
index bd79d1884c4bc55e3cbe22a7717e5b6188ae7376..620d1beb4587cf7ec308cc262e31b6dd009d115a 100644 (file)
@@ -814,11 +814,14 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
        }
 
        /* kill threads related to this sdev, if v.c. exists */
-       if (vdev->ud.tcp_rx)
+       if (vdev->ud.tcp_rx) {
                kthread_stop_put(vdev->ud.tcp_rx);
-       if (vdev->ud.tcp_tx)
+               vdev->ud.tcp_rx = NULL;
+       }
+       if (vdev->ud.tcp_tx) {
                kthread_stop_put(vdev->ud.tcp_tx);
-
+               vdev->ud.tcp_tx = NULL;
+       }
        pr_info("stop threads\n");
 
        /* active connection is closed */
index 712331b9da9fb57421aa8345c76ab744909af2ac..652ae7085a5f6960ef383b41f121059ae81086a9 100644 (file)
@@ -12,7 +12,6 @@
 #include "localpara.h"
 
 /****************** CONSTANT AND MACRO SECTION ******************************/
-#define _INLINE                                __inline
 
 #define MEDIA_STATE_DISCONNECTED       0
 #define MEDIA_STATE_CONNECTED          1
 
 /* OID_802_11_BSSID */
 s8 sme_get_bssid(void *pcore_data, u8 *pbssid);
-s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid); /* Not use */
+s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid); /* Unused */
 s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid);
 
 /* OID_802_11_SSID */
 s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);
-s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);/* Not use */
+s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);/* Unused */
 s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len);
 
 /* OID_802_11_INFRASTRUCTURE_MODE */
 s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type);
-s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type); /* Not use */
+s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type); /* Unused */
 s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type);
 
 /* OID_802_11_FRAGMENTATION_THRESHOLD */
@@ -138,7 +137,7 @@ s8 sme_set_txrate_policy(void *pcore_data, u8 policy);
 s8 sme_get_txrate_policy(void *pcore_data, u8 *policy);
 s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin);
 s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
-s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
+s8 sme_get_ms_radio_mode(void *pcore_data, u8 *pMsRadioOff);
 s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
 
 void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
index 0970127344e60828e569e1ca87ee6c82cb3f11eb..57a2b058e3dee3eac2d6e5467036d43ef57312b3 100644 (file)
@@ -329,9 +329,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
 
 int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
 {
-       struct net_device *dev = request->wdev->netdev;
+       struct net_device *dev;
        struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
-       wlandevice_t *wlandev = dev->ml_priv;
+       wlandevice_t *wlandev;
        struct p80211msg_dot11req_scan msg1;
        struct p80211msg_dot11req_scan_results msg2;
        struct cfg80211_bss *bss;
@@ -345,6 +345,9 @@ int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
        if (!request)
                return -EINVAL;
 
+       dev = request->wdev->netdev;
+       wlandev = dev->ml_priv;
+
        if (priv->scan_request && priv->scan_request != request)
                return -EBUSY;